|
65547
|
2312
|
1
|
2026-05-21T07:53:36.279348+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779350016279_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65546
|
2313
|
0
|
2026-05-21T07:53:07.189404+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349987189_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65545
|
2312
|
0
|
2026-05-21T07:53:05.982931+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349985982_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65544
|
NULL
|
0
|
2026-05-21T07:52:36.796429+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349956796_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65543
|
NULL
|
0
|
2026-05-21T07:52:35.661678+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349955661_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65542
|
2311
|
8
|
2026-05-21T07:52:06.394502+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349926394_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65541
|
2310
|
8
|
2026-05-21T07:52:05.334456+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349925334_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65540
|
2311
|
7
|
2026-05-21T07:51:36.020770+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349896020_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65539
|
2310
|
7
|
2026-05-21T07:51:35.019566+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349895019_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65538
|
2311
|
6
|
2026-05-21T07:51:05.654301+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349865654_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65537
|
2310
|
6
|
2026-05-21T07:51:04.690928+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349864690_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65536
|
2311
|
5
|
2026-05-21T07:50:35.284631+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349835284_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65535
|
2310
|
5
|
2026-05-21T07:50:34.376508+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349834376_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65534
|
2311
|
4
|
2026-05-21T07:50:04.854754+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349804854_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65533
|
2310
|
4
|
2026-05-21T07:50:04.048639+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349804048_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65532
|
2311
|
3
|
2026-05-21T07:49:34.429722+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349774429_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65530
|
NULL
|
NULL
|
NULL
|
|
65531
|
2310
|
3
|
2026-05-21T07:49:33.684989+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349773684_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
65529
|
NULL
|
NULL
|
NULL
|
|
65530
|
2311
|
2
|
2026-05-21T07:49:04.048242+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349744048_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65529
|
2310
|
2
|
2026-05-21T07:49:03.363650+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349743363_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
1405148025673151884
|
-8132123592518247404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65528
|
2311
|
1
|
2026-05-21T07:48:32.282959+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349712282_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
slackFV [EMAIL]=.phounit.result.cacheE .prettierig slackFV [EMAIL]=.phounit.result.cacheE .prettierignore= windsurtrulesphpde neloer.onophpide heloer_models.ohophp artisanM'CLAUDE.mdcomooser.isoncomooser.lockdependency-checker.json8 dev ison= ids tytl=infection.ison.distMLINSTAlI.mdMLINTERNAI WERHOOK SFTUP mdEjiminny_storageMiliconsos mdllM Makefile1рackace-lock. sonE phpstan.neon.dist= phostan-baseline.neon<> phpunit.xmlTe raw sal query.saM+ README.mdsô sonar-proiect propertiesE test.ov‹> Untitled Diaaram.xmliusvetur.confio.isM+ WEBHOOK FILTERING_IMPLEMENTATION.mo>1h External Librariesv =° Scratches and Consolesv batabase Consolesv AEU# console (EUlI DEAL RISKS (SU1A DITEUlA EU (EU]v Ajiminny@localhostA console (jiminny@localhost]# Di [liminny@localhostlA HS local [iiminny@localhostlA SF ['iiminny@localhost]& zoho dev [iiminny@localhost]V & PRODA console [PROD]& console 1 [PROD1LDIIPRODCActivityController.ong© ConvertLeadActivities.php= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X# console [euyLeadkepository.ong© PurgeLookupCache.php© SyncPlanhat.phpo synerorlannatpnpA console [STAGING]AcuivityLeadConverted.php© UserAutomatedreporscontroller.phpx© PlaybackController.php)Inteqrationapp/service.onoC) LeadConverted.ono570571C) CreateCommentedEvent.php(C) CreateSmsSentEvent.phpC) PlanhatActivityListener.php© AskAnythingPromptService.php572(C) AutomatedReportsRepositorv.php© AutomatedReportsCommand.phpphp api_v2.phpC) RequestGenerateReportJob.php573574© AutomatedReportResult.php(C) AutomatedReport.oho575use Jiminny \Services \Kiosk \AutomatedReports \ReportSortDirection;A1422 ^ v 576use Jiminny \Services\PlanhatService;use ectumtnace hutp kequestuse Inrowable,class UserAutomatedReportsController extends Controllenpublic const int RESULTS PER_ PAGE = 25:public const string SORT COLUMN = 'sort column':public const strina SORT DIRECTION = "sort direction':public function constructprivate readonly AutomatedReportsRepository $automatedReportsRepository.private readonly AutomatedRenortsService SautomatedRenortsServicelorivate readoni.v AniResponseService samiResponseServi.ce.orivate readoni.v Resnonse Sresnonse.private readonly PlanhatService $planhatService1...poST lanilv1lautomated-renorts/interest 1usadepublic function trackInterest(Request $request): JsonResponse(...}* Othnows ApplicationException58(09 >GET /api/v1/automated-reportspublic function list(Request Srequest): JsonResponse(...}125 0)DELETE/api/vl/automated-reports/kuuidpublic function delete(Request Srequest. string Suuid): JsonResponsef...} -609610--611612613616Tx: AutovSo jiminny vCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN' (owner)' ELSE'' END) AS USEr_i041 A1 A40 V65 ^sa.*t.owner_id FROM social_accounts saNoun usens u on u.ide sa.sociablle 1diJOIN teams t 1..n<->1: on t.id = u.team_idWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * trom automated reports:where id = 54: # 4fdd41f6-dcf0-30d0-b339-7345381b6044|"pat", "podcast"SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from automated_report_results order by id desc;SELECT * FROMWHERE id = 1919:select * fromautomated report results WHERE report id = 54:select * from opportunities where id = 7594349:SELECT * FROM teams WHERE name LIKE '%Lesg': # 711. 692. [EMAIL] * from playbooks where team_id = 711; # event 226147SELEd * FROM Dlavbook catedonies WHERE Dlavbook 1d = 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event':SELECT * SROM eom fields WHEREI1d = 2261471SELECT * FROM crm_field_values WHERE crm_field_id = 226147;SELECT * FROM crm_configurations WHERE id = 692;SELSCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,v.emailsa.*,t.owner id FROM social accounts saJOIN users u on v.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team idWHERE U.team_id = 711 and sa.provider = 'salesforce";SELECT * FROM crm profiles cp JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leadsselect * from calendarsSELECTS 0 hllsupoont Dally • In 4h 40m100% 52• Inu z1 May 10.10.34AskJiminnyReportActivityServiceTestvCascadePlaybook Categorie+0 ..connected. How isi. Can we vali eoneactivity tyee nith orit cabest aeeiewmane o, W dati anwsyggesinsingrow hohow to distinguishThoughts68 Fast Context How are playbook_categories populated and synced from crm_fields / crm_field_values... in 4.14s >Explored 4 files and searched 5 queriesRead ImportActivitvTypes.php #L95-104Searched olavbook cateaories in databaselmiarations (4) >egories|playbook_categories.*create in database/migrations (0)searched playoook_categor in database/migrations (<)Searched activity type in database/migrations (4)SurtingAsk anvthina (*4L)@ Codo Caudo Onue 17 ModiumNN Windeurf Toame 504.60...
|
NULL
|
4726481696127267389
|
NULL
|
click
|
ocr
|
NULL
|
slackFV [EMAIL]=.phounit.result.cacheE .prettierig slackFV [EMAIL]=.phounit.result.cacheE .prettierignore= windsurtrulesphpde neloer.onophpide heloer_models.ohophp artisanM'CLAUDE.mdcomooser.isoncomooser.lockdependency-checker.json8 dev ison= ids tytl=infection.ison.distMLINSTAlI.mdMLINTERNAI WERHOOK SFTUP mdEjiminny_storageMiliconsos mdllM Makefile1рackace-lock. sonE phpstan.neon.dist= phostan-baseline.neon<> phpunit.xmlTe raw sal query.saM+ README.mdsô sonar-proiect propertiesE test.ov‹> Untitled Diaaram.xmliusvetur.confio.isM+ WEBHOOK FILTERING_IMPLEMENTATION.mo>1h External Librariesv =° Scratches and Consolesv batabase Consolesv AEU# console (EUlI DEAL RISKS (SU1A DITEUlA EU (EU]v Ajiminny@localhostA console (jiminny@localhost]# Di [liminny@localhostlA HS local [iiminny@localhostlA SF ['iiminny@localhost]& zoho dev [iiminny@localhost]V & PRODA console [PROD]& console 1 [PROD1LDIIPRODCActivityController.ong© ConvertLeadActivities.php= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X# console [euyLeadkepository.ong© PurgeLookupCache.php© SyncPlanhat.phpo synerorlannatpnpA console [STAGING]AcuivityLeadConverted.php© UserAutomatedreporscontroller.phpx© PlaybackController.php)Inteqrationapp/service.onoC) LeadConverted.ono570571C) CreateCommentedEvent.php(C) CreateSmsSentEvent.phpC) PlanhatActivityListener.php© AskAnythingPromptService.php572(C) AutomatedReportsRepositorv.php© AutomatedReportsCommand.phpphp api_v2.phpC) RequestGenerateReportJob.php573574© AutomatedReportResult.php(C) AutomatedReport.oho575use Jiminny \Services \Kiosk \AutomatedReports \ReportSortDirection;A1422 ^ v 576use Jiminny \Services\PlanhatService;use ectumtnace hutp kequestuse Inrowable,class UserAutomatedReportsController extends Controllenpublic const int RESULTS PER_ PAGE = 25:public const string SORT COLUMN = 'sort column':public const strina SORT DIRECTION = "sort direction':public function constructprivate readonly AutomatedReportsRepository $automatedReportsRepository.private readonly AutomatedRenortsService SautomatedRenortsServicelorivate readoni.v AniResponseService samiResponseServi.ce.orivate readoni.v Resnonse Sresnonse.private readonly PlanhatService $planhatService1...poST lanilv1lautomated-renorts/interest 1usadepublic function trackInterest(Request $request): JsonResponse(...}* Othnows ApplicationException58(09 >GET /api/v1/automated-reportspublic function list(Request Srequest): JsonResponse(...}125 0)DELETE/api/vl/automated-reports/kuuidpublic function delete(Request Srequest. string Suuid): JsonResponsef...} -609610--611612613616Tx: AutovSo jiminny vCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN' (owner)' ELSE'' END) AS USEr_i041 A1 A40 V65 ^sa.*t.owner_id FROM social_accounts saNoun usens u on u.ide sa.sociablle 1diJOIN teams t 1..n<->1: on t.id = u.team_idWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * trom automated reports:where id = 54: # 4fdd41f6-dcf0-30d0-b339-7345381b6044|"pat", "podcast"SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from automated_report_results order by id desc;SELECT * FROMWHERE id = 1919:select * fromautomated report results WHERE report id = 54:select * from opportunities where id = 7594349:SELECT * FROM teams WHERE name LIKE '%Lesg': # 711. 692. [EMAIL] * from playbooks where team_id = 711; # event 226147SELEd * FROM Dlavbook catedonies WHERE Dlavbook 1d = 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event':SELECT * SROM eom fields WHEREI1d = 2261471SELECT * FROM crm_field_values WHERE crm_field_id = 226147;SELECT * FROM crm_configurations WHERE id = 692;SELSCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,v.emailsa.*,t.owner id FROM social accounts saJOIN users u on v.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team idWHERE U.team_id = 711 and sa.provider = 'salesforce";SELECT * FROM crm profiles cp JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leadsselect * from calendarsSELECTS 0 hllsupoont Dally • In 4h 40m100% 52• Inu z1 May 10.10.34AskJiminnyReportActivityServiceTestvCascadePlaybook Categorie+0 ..connected. How isi. Can we vali eoneactivity tyee nith orit cabest aeeiewmane o, W dati anwsyggesinsingrow hohow to distinguishThoughts68 Fast Context How are playbook_categories populated and synced from crm_fields / crm_field_values... in 4.14s >Explored 4 files and searched 5 queriesRead ImportActivitvTypes.php #L95-104Searched olavbook cateaories in databaselmiarations (4) >egories|playbook_categories.*create in database/migrations (0)searched playoook_categor in database/migrations (<)Searched activity type in database/migrations (4)SurtingAsk anvthina (*4L)@ Codo Caudo Onue 17 ModiumNN Windeurf Toame 504.60...
|
65514
|
NULL
|
NULL
|
NULL
|
|
65527
|
2310
|
1
|
2026-05-21T07:48:32.293318+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349712293_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpscreelDOCKER0 SlackFileEditViewGoHistoryWindowHelpscreelDOCKER0 81DEV (-zsh)₴2APP (-zsh)whisper_init_state:whisper_init_state:kv padsize=2.36 MBcompute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state:compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type:1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimizetruewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize =2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu: found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:use graph optimizetruewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-21T10:13:41.913005ZINFO screenpipe_audio::audio_manager::manager: reconciliatior2026-05-21710:15:15.5768762INFO screenpipe_engine::event_driven_capture: content dedup:j Support Daily - in 4h 45 m100% С8• Thu 21 May 10:15:32•••EDQHomeDMsActivityFilesLater•••More+→Describe what you are looking forJiminny ...ThreadsC9 Unreadsà platform-inner-teamGalya Dimitrova, Nikolay Yankov, and youa ThreadsHuddles• Drafts & sentDirectories01External connections* Starred& jiminny-x-integrati...platform-inner-teamChannels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# happy_birthday# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# supportLukas Kovalik 31 minutes agoдобро утро, тази страница не трябва ли да япоказваме само ако няма reportsCleanShot 2026-05-21 at [EMAIL] your questions into ongoing insightsGalya Dimitrova 23 minutes agoДа, би трябвалоLukas Kovalik 22 minutes agoче сега ми го показва и ако имам reportLukas Kovalik 21 minutes agoна neptuneNewNikolay Yankov 6 minutes agoвсичко е наредReply...Also send to à platform-inner-team+AaYou're up to date...
|
NULL
|
4556108544665021624
|
NULL
|
click
|
ocr
|
NULL
|
SlackFileEditViewGoHistoryWindowHelpscreelDOCKER0 SlackFileEditViewGoHistoryWindowHelpscreelDOCKER0 81DEV (-zsh)₴2APP (-zsh)whisper_init_state:whisper_init_state:kv padsize=2.36 MBcompute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state:compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type:1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimizetruewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize =2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu: found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:use graph optimizetruewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-21T10:13:41.913005ZINFO screenpipe_audio::audio_manager::manager: reconciliatior2026-05-21710:15:15.5768762INFO screenpipe_engine::event_driven_capture: content dedup:j Support Daily - in 4h 45 m100% С8• Thu 21 May 10:15:32•••EDQHomeDMsActivityFilesLater•••More+→Describe what you are looking forJiminny ...ThreadsC9 Unreadsà platform-inner-teamGalya Dimitrova, Nikolay Yankov, and youa ThreadsHuddles• Drafts & sentDirectories01External connections* Starred& jiminny-x-integrati...platform-inner-teamChannels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# happy_birthday# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# supportLukas Kovalik 31 minutes agoдобро утро, тази страница не трябва ли да япоказваме само ако няма reportsCleanShot 2026-05-21 at [EMAIL] your questions into ongoing insightsGalya Dimitrova 23 minutes agoДа, би трябвалоLukas Kovalik 22 minutes agoче сега ми го показва и ако имам reportLukas Kovalik 21 minutes agoна neptuneNewNikolay Yankov 6 minutes agoвсичко е наредReply...Also send to à platform-inner-team+AaYou're up to date...
|
65515
|
NULL
|
NULL
|
NULL
|
|
65508
|
2309
|
3
|
2026-05-21T07:44:36.296703+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349476296_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-1052979189915093189
|
-8141130793920488428
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65507
|
2308
|
3
|
2026-05-21T07:44:36.323661+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349476323_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"}]...
|
-6151875786856534370
|
-8717591544076362732
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65506
|
2309
|
2
|
2026-05-21T07:44:21.034497+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349461034_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
Command.php, class
CreateDatabaseUsers.php, class
DatabaseTableCount.php, class
DeleteOldAiCrmNotesCommand.php, class
DeleteS3LeftoversCommand.php, class
DevPostmanCommand.php, final class
DiarizeViaAiParticipantIdentificationCommand.php, class
EncryptTokensCommand.php, class
EngagementStatsRegenerateCommand.php, class
FeatureFlagsHelper.php
FixCrossTenantIssues.php, class
FlushRolesPermissionsCache.php, class
GenerateInternalWebhookToken.php, class
GroupSetDefaultLanguageCommand.php, final class
HelperTruncateCoachingTables.php, class
HubspotJournalPollingCommand.php, class
HubspotWebhookServiceCommand.php, class
ImportRecording.php, class
ImportUsersFromCsvFile.php, final class
IssueMcpTokenCommand.php, class
IterateUsersCommand.php
JiminnyCacheClearCommand.php
JiminnyDebugCommand.php, class
JiminnySetEncryptedTokenManagerModeCommand.php, class
JiminnyTokenInfoCommand.php, class
MakeSlackLiveCoachingChatNotesOn.php, class
ManageScimForTeam.php, class
MarkBranchForEnvironmentPipelineCommand.php, class
MuteOrganizerChannel.php, class
PhpApm.php, class
PropagateCoachingFeedbackCreatedAtToSectionFeedbacks.php, class
PurgeConferences.php, class
PurgeSoftDeletedOpportunitiesCommand.php, class
PurgeSyncBatchesCommand.php, class
RecalculateDealRisksCommand.php, class
RemoveDeleteMarkersCommand.php, class
RemoveExpiredNudgesCommand.php, class
RemoveUnusedParticipantSpeechesCommand.php, class
ResetElasticSearch.php, class
RestoreActivityCrmProviderIdCommand.php, class
RestoreActivityTypeCommand.php, class
RunAiCallScoringForUntypedActivitiesCommand.php
SeedActivities.php
SendNudgeExpirationWarningsCommand.php
SyncActivity.php
TrackImported.php
WhichWorkerIsWorkingOnWhichJob.php
Scheduling, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlists, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Postmark, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reports, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Tracks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Users","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Vocabulary","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Zoom","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Command.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateDatabaseUsers.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseTableCount.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteOldAiCrmNotesCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteS3LeftoversCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DevPostmanCommand.php, final class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DiarizeViaAiParticipantIdentificationCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EncryptTokensCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStatsRegenerateCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlagsHelper.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FixCrossTenantIssues.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FlushRolesPermissionsCache.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateInternalWebhookToken.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GroupSetDefaultLanguageCommand.php, final class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HelperTruncateCoachingTables.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotJournalPollingCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotWebhookServiceCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ImportRecording.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ImportUsersFromCsvFile.php, final class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IssueMcpTokenCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IterateUsersCommand.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyCacheClearCommand.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyDebugCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"JiminnySetEncryptedTokenManagerModeCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"JiminnyTokenInfoCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MakeSlackLiveCoachingChatNotesOn.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageScimForTeam.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MarkBranchForEnvironmentPipelineCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MuteOrganizerChannel.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PhpApm.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PropagateCoachingFeedbackCreatedAtToSectionFeedbacks.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeConferences.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeSoftDeletedOpportunitiesCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeSyncBatchesCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RecalculateDealRisksCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RemoveDeleteMarkersCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RemoveExpiredNudgesCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RemoveUnusedParticipantSpeechesCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetElasticSearch.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RestoreActivityCrmProviderIdCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RestoreActivityTypeCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RunAiCallScoringForUntypedActivitiesCommand.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SeedActivities.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNudgeExpirationWarningsCommand.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncActivity.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TrackImported.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"WhichWorkerIsWorkingOnWhichJob.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Scheduling, folder","depth":9,"on_screen":false,"role_description":"text"}]...
|
4125655130040039617
|
-6409497318090846956
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
Command.php, class
CreateDatabaseUsers.php, class
DatabaseTableCount.php, class
DeleteOldAiCrmNotesCommand.php, class
DeleteS3LeftoversCommand.php, class
DevPostmanCommand.php, final class
DiarizeViaAiParticipantIdentificationCommand.php, class
EncryptTokensCommand.php, class
EngagementStatsRegenerateCommand.php, class
FeatureFlagsHelper.php
FixCrossTenantIssues.php, class
FlushRolesPermissionsCache.php, class
GenerateInternalWebhookToken.php, class
GroupSetDefaultLanguageCommand.php, final class
HelperTruncateCoachingTables.php, class
HubspotJournalPollingCommand.php, class
HubspotWebhookServiceCommand.php, class
ImportRecording.php, class
ImportUsersFromCsvFile.php, final class
IssueMcpTokenCommand.php, class
IterateUsersCommand.php
JiminnyCacheClearCommand.php
JiminnyDebugCommand.php, class
JiminnySetEncryptedTokenManagerModeCommand.php, class
JiminnyTokenInfoCommand.php, class
MakeSlackLiveCoachingChatNotesOn.php, class
ManageScimForTeam.php, class
MarkBranchForEnvironmentPipelineCommand.php, class
MuteOrganizerChannel.php, class
PhpApm.php, class
PropagateCoachingFeedbackCreatedAtToSectionFeedbacks.php, class
PurgeConferences.php, class
PurgeSoftDeletedOpportunitiesCommand.php, class
PurgeSyncBatchesCommand.php, class
RecalculateDealRisksCommand.php, class
RemoveDeleteMarkersCommand.php, class
RemoveExpiredNudgesCommand.php, class
RemoveUnusedParticipantSpeechesCommand.php, class
ResetElasticSearch.php, class
RestoreActivityCrmProviderIdCommand.php, class
RestoreActivityTypeCommand.php, class
RunAiCallScoringForUntypedActivitiesCommand.php
SeedActivities.php
SendNudgeExpirationWarningsCommand.php
SyncActivity.php
TrackImported.php
WhichWorkerIsWorkingOnWhichJob.php
Scheduling, folder...
|
65504
|
NULL
|
NULL
|
NULL
|
|
65505
|
2308
|
2
|
2026-05-21T07:44:20.853701+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349460853_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"}]...
|
-9223056471733185465
|
-8717589928094988012
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes...
|
65503
|
NULL
|
NULL
|
NULL
|
|
65504
|
2309
|
1
|
2026-05-21T07:43:50.657371+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349430657_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
8830251352522217365
|
-8708584105377178620
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65503
|
2308
|
1
|
2026-05-21T07:43:50.471601+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349430471_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlists, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Postmark, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reports, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"on_screen":false,"role_description":"text"}]...
|
-4331963242933399359
|
-8715337578525487852
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65502
|
2309
|
0
|
2026-05-21T07:43:20.284617+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349400284_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
Command.php, class
CreateDatabaseUsers.php, class
DatabaseTableCount.php, class
DeleteOldAiCrmNotesCommand.php, class
DeleteS3LeftoversCommand.php, class
DevPostmanCommand.php, final class
DiarizeViaAiParticipantIdentificationCommand.php, class
EncryptTokensCommand.php, class
EngagementStatsRegenerateCommand.php, class
FeatureFlagsHelper.php
FixCrossTenantIssues.php, class
FlushRolesPermissionsCache.php, class
GenerateInternalWebhookToken.php, class
GroupSetDefaultLanguageCommand.php, final class
HelperTruncateCoachingTables.php, class
HubspotJournalPollingCommand.php, class
HubspotWebhookServiceCommand.php, class
ImportRecording.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlists, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Postmark, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reports, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Tracks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Users","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Vocabulary","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Zoom","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Command.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateDatabaseUsers.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DatabaseTableCount.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteOldAiCrmNotesCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteS3LeftoversCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DevPostmanCommand.php, final class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DiarizeViaAiParticipantIdentificationCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EncryptTokensCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStatsRegenerateCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlagsHelper.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FixCrossTenantIssues.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FlushRolesPermissionsCache.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateInternalWebhookToken.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GroupSetDefaultLanguageCommand.php, final class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HelperTruncateCoachingTables.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotJournalPollingCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HubspotWebhookServiceCommand.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ImportRecording.php, class","depth":10,"on_screen":false,"role_description":"text"}]...
|
-5269841006065165550
|
-6409495119067591404
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
Command.php, class
CreateDatabaseUsers.php, class
DatabaseTableCount.php, class
DeleteOldAiCrmNotesCommand.php, class
DeleteS3LeftoversCommand.php, class
DevPostmanCommand.php, final class
DiarizeViaAiParticipantIdentificationCommand.php, class
EncryptTokensCommand.php, class
EngagementStatsRegenerateCommand.php, class
FeatureFlagsHelper.php
FixCrossTenantIssues.php, class
FlushRolesPermissionsCache.php, class
GenerateInternalWebhookToken.php, class
GroupSetDefaultLanguageCommand.php, final class
HelperTruncateCoachingTables.php, class
HubspotJournalPollingCommand.php, class
HubspotWebhookServiceCommand.php, class
ImportRecording.php, class...
|
65500
|
NULL
|
NULL
|
NULL
|
|
65501
|
2308
|
0
|
2026-05-21T07:43:20.152555+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349400152_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlists, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Postmark, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reports, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"on_screen":false,"role_description":"text"}]...
|
-4331963242933399359
|
-8715337578525487852
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class...
|
65499
|
NULL
|
NULL
|
NULL
|
|
65500
|
NULL
|
0
|
2026-05-21T07:42:49.907216+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349369907_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlists, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Postmark, folder","depth":10,"on_screen":false,"role_description":"text"}]...
|
-2571589278577124073
|
-8717589928094986988
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65499
|
NULL
|
0
|
2026-05-21T07:42:49.824470+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349369824_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlists, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Postmark, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reports, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"on_screen":false,"role_description":"text"}]...
|
4668560580297988277
|
-8715337578525488876
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65498
|
2307
|
24
|
2026-05-21T07:42:19.478300+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349339478_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"}]...
|
-6432662851748720335
|
-8132123592518247404
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf...
|
65496
|
NULL
|
NULL
|
NULL
|
|
65497
|
2306
|
30
|
2026-05-21T07:42:19.478269+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349339478_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"}]...
|
5177837308458605725
|
-8717730082541445868
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags...
|
65495
|
NULL
|
NULL
|
NULL
|
|
65496
|
2307
|
23
|
2026-05-21T07:42:16.285834+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349336285_m2.jpg...
|
PhpStorm
|
faVsco.js – MetadataProcessor.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Close\Processor;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Crm\Metadata\FieldMetadata;
use Jiminny\Services\Crm\Metadata\OrganisationMetadata;
use Jiminny\Services\Crm\Metadata\PipelineMetadata;
use Jiminny\Services\Crm\Metadata\ProfileMetadata;
class MetadataProcessor
{
private ?Configuration $crm = null;
private TeamRepository $teamRepository;
private UserRepository $userRepository;
private CrmConfigurationRepository $crmConfigurationRepository;
private FieldRepository $fieldRepository;
public function __construct(
TeamRepository $teamRepository,
UserRepository $userRepository,
CrmConfigurationRepository $crmConfigurationRepository,
FieldRepository $fieldRepository
) {
$this->teamRepository = $teamRepository;
$this->userRepository = $userRepository;
$this->crmConfigurationRepository = $crmConfigurationRepository;
$this->fieldRepository = $fieldRepository;
}
public function setConfiguration(Configuration $crm): void
{
$this->crm = $crm;
}
/**
* @throws RuntimeException
*/
private function getConfiguration(): Configuration
{
if (! $this->crm instanceof Configuration) {
throw new RuntimeException('Configuration not set');
}
return $this->crm;
}
public function syncOrganisation(OrganisationMetadata $organisationMetadata): void
{
$this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);
}
public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess
{
$businessProcess = $this->crmConfigurationRepository
->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);
// A record type connects an opportunity to a business process (pipeline)
$this->syncRecordType($pipelineMetadata, $businessProcess);
$this->syncPipelineStages($businessProcess, $pipelineMetadata);
return $businessProcess;
}
public function syncProfile(ProfileMetadata $profileMetadata): ?Profile
{
$user = $this->teamRepository->findActiveTeamMemberByEmail(
$this->getConfiguration()->getTeam(),
$profileMetadata->getEmail()
);
if (! $user instanceof User) {
return null;
}
return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());
}
public function syncField(FieldMetadata $fieldMetadata): Field
{
$field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);
if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
}
return $field;
}
private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void
{
$this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());
}
private function syncRecordType(
PipelineMetadata $pipelineMetadata,
?BusinessProcess $pipeline
): void {
$this->crmConfigurationRepository->updateOrCreateRecordType(
$this->getConfiguration(),
$pipelineMetadata,
$pipeline
);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Close\\Processor;\n\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Crm\\Metadata\\FieldMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\OrganisationMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\PipelineMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\ProfileMetadata;\n\nclass MetadataProcessor\n{\n private ?Configuration $crm = null;\n private TeamRepository $teamRepository;\n private UserRepository $userRepository;\n private CrmConfigurationRepository $crmConfigurationRepository;\n private FieldRepository $fieldRepository;\n\n public function __construct(\n TeamRepository $teamRepository,\n UserRepository $userRepository,\n CrmConfigurationRepository $crmConfigurationRepository,\n FieldRepository $fieldRepository\n ) {\n $this->teamRepository = $teamRepository;\n $this->userRepository = $userRepository;\n $this->crmConfigurationRepository = $crmConfigurationRepository;\n $this->fieldRepository = $fieldRepository;\n }\n\n public function setConfiguration(Configuration $crm): void\n {\n $this->crm = $crm;\n }\n\n /**\n * @throws RuntimeException\n */\n private function getConfiguration(): Configuration\n {\n if (! $this->crm instanceof Configuration) {\n throw new RuntimeException('Configuration not set');\n }\n\n return $this->crm;\n }\n\n public function syncOrganisation(OrganisationMetadata $organisationMetadata): void\n {\n $this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);\n }\n\n public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess\n {\n $businessProcess = $this->crmConfigurationRepository\n ->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);\n\n // A record type connects an opportunity to a business process (pipeline)\n $this->syncRecordType($pipelineMetadata, $businessProcess);\n\n $this->syncPipelineStages($businessProcess, $pipelineMetadata);\n\n return $businessProcess;\n }\n\n public function syncProfile(ProfileMetadata $profileMetadata): ?Profile\n {\n $user = $this->teamRepository->findActiveTeamMemberByEmail(\n $this->getConfiguration()->getTeam(),\n $profileMetadata->getEmail()\n );\n\n if (! $user instanceof User) {\n return null;\n }\n\n return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());\n }\n\n public function syncField(FieldMetadata $fieldMetadata): Field\n {\n $field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);\n\n if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {\n $this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());\n }\n\n return $field;\n }\n\n private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void\n {\n $this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());\n }\n\n private function syncRecordType(\n PipelineMetadata $pipelineMetadata,\n ?BusinessProcess $pipeline\n ): void {\n $this->crmConfigurationRepository->updateOrCreateRecordType(\n $this->getConfiguration(),\n $pipelineMetadata,\n $pipeline\n );\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Close\\Processor;\n\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Crm\\Metadata\\FieldMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\OrganisationMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\PipelineMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\ProfileMetadata;\n\nclass MetadataProcessor\n{\n private ?Configuration $crm = null;\n private TeamRepository $teamRepository;\n private UserRepository $userRepository;\n private CrmConfigurationRepository $crmConfigurationRepository;\n private FieldRepository $fieldRepository;\n\n public function __construct(\n TeamRepository $teamRepository,\n UserRepository $userRepository,\n CrmConfigurationRepository $crmConfigurationRepository,\n FieldRepository $fieldRepository\n ) {\n $this->teamRepository = $teamRepository;\n $this->userRepository = $userRepository;\n $this->crmConfigurationRepository = $crmConfigurationRepository;\n $this->fieldRepository = $fieldRepository;\n }\n\n public function setConfiguration(Configuration $crm): void\n {\n $this->crm = $crm;\n }\n\n /**\n * @throws RuntimeException\n */\n private function getConfiguration(): Configuration\n {\n if (! $this->crm instanceof Configuration) {\n throw new RuntimeException('Configuration not set');\n }\n\n return $this->crm;\n }\n\n public function syncOrganisation(OrganisationMetadata $organisationMetadata): void\n {\n $this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);\n }\n\n public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess\n {\n $businessProcess = $this->crmConfigurationRepository\n ->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);\n\n // A record type connects an opportunity to a business process (pipeline)\n $this->syncRecordType($pipelineMetadata, $businessProcess);\n\n $this->syncPipelineStages($businessProcess, $pipelineMetadata);\n\n return $businessProcess;\n }\n\n public function syncProfile(ProfileMetadata $profileMetadata): ?Profile\n {\n $user = $this->teamRepository->findActiveTeamMemberByEmail(\n $this->getConfiguration()->getTeam(),\n $profileMetadata->getEmail()\n );\n\n if (! $user instanceof User) {\n return null;\n }\n\n return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());\n }\n\n public function syncField(FieldMetadata $fieldMetadata): Field\n {\n $field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);\n\n if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {\n $this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());\n }\n\n return $field;\n }\n\n private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void\n {\n $this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());\n }\n\n private function syncRecordType(\n PipelineMetadata $pipelineMetadata,\n ?BusinessProcess $pipeline\n ): void {\n $this->crmConfigurationRepository->updateOrCreateRecordType(\n $this->getConfiguration(),\n $pipelineMetadata,\n $pipeline\n );\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6095796380002900138
|
-4382727891022868675
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Close\Processor;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Crm\Metadata\FieldMetadata;
use Jiminny\Services\Crm\Metadata\OrganisationMetadata;
use Jiminny\Services\Crm\Metadata\PipelineMetadata;
use Jiminny\Services\Crm\Metadata\ProfileMetadata;
class MetadataProcessor
{
private ?Configuration $crm = null;
private TeamRepository $teamRepository;
private UserRepository $userRepository;
private CrmConfigurationRepository $crmConfigurationRepository;
private FieldRepository $fieldRepository;
public function __construct(
TeamRepository $teamRepository,
UserRepository $userRepository,
CrmConfigurationRepository $crmConfigurationRepository,
FieldRepository $fieldRepository
) {
$this->teamRepository = $teamRepository;
$this->userRepository = $userRepository;
$this->crmConfigurationRepository = $crmConfigurationRepository;
$this->fieldRepository = $fieldRepository;
}
public function setConfiguration(Configuration $crm): void
{
$this->crm = $crm;
}
/**
* @throws RuntimeException
*/
private function getConfiguration(): Configuration
{
if (! $this->crm instanceof Configuration) {
throw new RuntimeException('Configuration not set');
}
return $this->crm;
}
public function syncOrganisation(OrganisationMetadata $organisationMetadata): void
{
$this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);
}
public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess
{
$businessProcess = $this->crmConfigurationRepository
->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);
// A record type connects an opportunity to a business process (pipeline)
$this->syncRecordType($pipelineMetadata, $businessProcess);
$this->syncPipelineStages($businessProcess, $pipelineMetadata);
return $businessProcess;
}
public function syncProfile(ProfileMetadata $profileMetadata): ?Profile
{
$user = $this->teamRepository->findActiveTeamMemberByEmail(
$this->getConfiguration()->getTeam(),
$profileMetadata->getEmail()
);
if (! $user instanceof User) {
return null;
}
return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());
}
public function syncField(FieldMetadata $fieldMetadata): Field
{
$field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);
if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
}
return $field;
}
private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void
{
$this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());
}
private function syncRecordType(
PipelineMetadata $pipelineMetadata,
?BusinessProcess $pipeline
): void {
$this->crmConfigurationRepository->updateOrCreateRecordType(
$this->getConfiguration(),
$pipelineMetadata,
$pipeline
);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65495
|
2306
|
29
|
2026-05-21T07:42:16.285823+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349336285_m1.jpg...
|
PhpStorm
|
faVsco.js – MetadataProcessor.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Close\Processor;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Crm\Metadata\FieldMetadata;
use Jiminny\Services\Crm\Metadata\OrganisationMetadata;
use Jiminny\Services\Crm\Metadata\PipelineMetadata;
use Jiminny\Services\Crm\Metadata\ProfileMetadata;
class MetadataProcessor
{
private ?Configuration $crm = null;
private TeamRepository $teamRepository;
private UserRepository $userRepository;
private CrmConfigurationRepository $crmConfigurationRepository;
private FieldRepository $fieldRepository;
public function __construct(
TeamRepository $teamRepository,
UserRepository $userRepository,
CrmConfigurationRepository $crmConfigurationRepository,
FieldRepository $fieldRepository
) {
$this->teamRepository = $teamRepository;
$this->userRepository = $userRepository;
$this->crmConfigurationRepository = $crmConfigurationRepository;
$this->fieldRepository = $fieldRepository;
}
public function setConfiguration(Configuration $crm): void
{
$this->crm = $crm;
}
/**
* @throws RuntimeException
*/
private function getConfiguration(): Configuration
{
if (! $this->crm instanceof Configuration) {
throw new RuntimeException('Configuration not set');
}
return $this->crm;
}
public function syncOrganisation(OrganisationMetadata $organisationMetadata): void
{
$this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);
}
public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess
{
$businessProcess = $this->crmConfigurationRepository
->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);
// A record type connects an opportunity to a business process (pipeline)
$this->syncRecordType($pipelineMetadata, $businessProcess);
$this->syncPipelineStages($businessProcess, $pipelineMetadata);
return $businessProcess;
}
public function syncProfile(ProfileMetadata $profileMetadata): ?Profile
{
$user = $this->teamRepository->findActiveTeamMemberByEmail(
$this->getConfiguration()->getTeam(),
$profileMetadata->getEmail()
);
if (! $user instanceof User) {
return null;
}
return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());
}
public function syncField(FieldMetadata $fieldMetadata): Field
{
$field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);
if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
}
return $field;
}
private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void
{
$this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());
}
private function syncRecordType(
PipelineMetadata $pipelineMetadata,
?BusinessProcess $pipeline
): void {
$this->crmConfigurationRepository->updateOrCreateRecordType(
$this->getConfiguration(),
$pipelineMetadata,
$pipeline
);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Close\\Processor;\n\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Crm\\Metadata\\FieldMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\OrganisationMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\PipelineMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\ProfileMetadata;\n\nclass MetadataProcessor\n{\n private ?Configuration $crm = null;\n private TeamRepository $teamRepository;\n private UserRepository $userRepository;\n private CrmConfigurationRepository $crmConfigurationRepository;\n private FieldRepository $fieldRepository;\n\n public function __construct(\n TeamRepository $teamRepository,\n UserRepository $userRepository,\n CrmConfigurationRepository $crmConfigurationRepository,\n FieldRepository $fieldRepository\n ) {\n $this->teamRepository = $teamRepository;\n $this->userRepository = $userRepository;\n $this->crmConfigurationRepository = $crmConfigurationRepository;\n $this->fieldRepository = $fieldRepository;\n }\n\n public function setConfiguration(Configuration $crm): void\n {\n $this->crm = $crm;\n }\n\n /**\n * @throws RuntimeException\n */\n private function getConfiguration(): Configuration\n {\n if (! $this->crm instanceof Configuration) {\n throw new RuntimeException('Configuration not set');\n }\n\n return $this->crm;\n }\n\n public function syncOrganisation(OrganisationMetadata $organisationMetadata): void\n {\n $this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);\n }\n\n public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess\n {\n $businessProcess = $this->crmConfigurationRepository\n ->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);\n\n // A record type connects an opportunity to a business process (pipeline)\n $this->syncRecordType($pipelineMetadata, $businessProcess);\n\n $this->syncPipelineStages($businessProcess, $pipelineMetadata);\n\n return $businessProcess;\n }\n\n public function syncProfile(ProfileMetadata $profileMetadata): ?Profile\n {\n $user = $this->teamRepository->findActiveTeamMemberByEmail(\n $this->getConfiguration()->getTeam(),\n $profileMetadata->getEmail()\n );\n\n if (! $user instanceof User) {\n return null;\n }\n\n return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());\n }\n\n public function syncField(FieldMetadata $fieldMetadata): Field\n {\n $field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);\n\n if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {\n $this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());\n }\n\n return $field;\n }\n\n private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void\n {\n $this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());\n }\n\n private function syncRecordType(\n PipelineMetadata $pipelineMetadata,\n ?BusinessProcess $pipeline\n ): void {\n $this->crmConfigurationRepository->updateOrCreateRecordType(\n $this->getConfiguration(),\n $pipelineMetadata,\n $pipeline\n );\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Close\\Processor;\n\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Exceptions\\RuntimeException;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmConfigurationRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\UserRepository;\nuse Jiminny\\Services\\Crm\\Metadata\\FieldMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\OrganisationMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\PipelineMetadata;\nuse Jiminny\\Services\\Crm\\Metadata\\ProfileMetadata;\n\nclass MetadataProcessor\n{\n private ?Configuration $crm = null;\n private TeamRepository $teamRepository;\n private UserRepository $userRepository;\n private CrmConfigurationRepository $crmConfigurationRepository;\n private FieldRepository $fieldRepository;\n\n public function __construct(\n TeamRepository $teamRepository,\n UserRepository $userRepository,\n CrmConfigurationRepository $crmConfigurationRepository,\n FieldRepository $fieldRepository\n ) {\n $this->teamRepository = $teamRepository;\n $this->userRepository = $userRepository;\n $this->crmConfigurationRepository = $crmConfigurationRepository;\n $this->fieldRepository = $fieldRepository;\n }\n\n public function setConfiguration(Configuration $crm): void\n {\n $this->crm = $crm;\n }\n\n /**\n * @throws RuntimeException\n */\n private function getConfiguration(): Configuration\n {\n if (! $this->crm instanceof Configuration) {\n throw new RuntimeException('Configuration not set');\n }\n\n return $this->crm;\n }\n\n public function syncOrganisation(OrganisationMetadata $organisationMetadata): void\n {\n $this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);\n }\n\n public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess\n {\n $businessProcess = $this->crmConfigurationRepository\n ->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);\n\n // A record type connects an opportunity to a business process (pipeline)\n $this->syncRecordType($pipelineMetadata, $businessProcess);\n\n $this->syncPipelineStages($businessProcess, $pipelineMetadata);\n\n return $businessProcess;\n }\n\n public function syncProfile(ProfileMetadata $profileMetadata): ?Profile\n {\n $user = $this->teamRepository->findActiveTeamMemberByEmail(\n $this->getConfiguration()->getTeam(),\n $profileMetadata->getEmail()\n );\n\n if (! $user instanceof User) {\n return null;\n }\n\n return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());\n }\n\n public function syncField(FieldMetadata $fieldMetadata): Field\n {\n $field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);\n\n if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {\n $this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());\n }\n\n return $field;\n }\n\n private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void\n {\n $this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());\n }\n\n private function syncRecordType(\n PipelineMetadata $pipelineMetadata,\n ?BusinessProcess $pipeline\n ): void {\n $this->crmConfigurationRepository->updateOrCreateRecordType(\n $this->getConfiguration(),\n $pipelineMetadata,\n $pipeline\n );\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"}]...
|
8357275665674168715
|
-4382727890989249731
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Code changed:
Hide
Sync Changes
Hide This Notification
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Close\Processor;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Exceptions\RuntimeException;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmConfigurationRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\UserRepository;
use Jiminny\Services\Crm\Metadata\FieldMetadata;
use Jiminny\Services\Crm\Metadata\OrganisationMetadata;
use Jiminny\Services\Crm\Metadata\PipelineMetadata;
use Jiminny\Services\Crm\Metadata\ProfileMetadata;
class MetadataProcessor
{
private ?Configuration $crm = null;
private TeamRepository $teamRepository;
private UserRepository $userRepository;
private CrmConfigurationRepository $crmConfigurationRepository;
private FieldRepository $fieldRepository;
public function __construct(
TeamRepository $teamRepository,
UserRepository $userRepository,
CrmConfigurationRepository $crmConfigurationRepository,
FieldRepository $fieldRepository
) {
$this->teamRepository = $teamRepository;
$this->userRepository = $userRepository;
$this->crmConfigurationRepository = $crmConfigurationRepository;
$this->fieldRepository = $fieldRepository;
}
public function setConfiguration(Configuration $crm): void
{
$this->crm = $crm;
}
/**
* @throws RuntimeException
*/
private function getConfiguration(): Configuration
{
if (! $this->crm instanceof Configuration) {
throw new RuntimeException('Configuration not set');
}
return $this->crm;
}
public function syncOrganisation(OrganisationMetadata $organisationMetadata): void
{
$this->crmConfigurationRepository->updateConfiguration($this->getConfiguration(), $organisationMetadata);
}
public function syncPipeline(PipelineMetadata $pipelineMetadata): ?BusinessProcess
{
$businessProcess = $this->crmConfigurationRepository
->updateOrCreatePipeline($this->getConfiguration(), $pipelineMetadata);
// A record type connects an opportunity to a business process (pipeline)
$this->syncRecordType($pipelineMetadata, $businessProcess);
$this->syncPipelineStages($businessProcess, $pipelineMetadata);
return $businessProcess;
}
public function syncProfile(ProfileMetadata $profileMetadata): ?Profile
{
$user = $this->teamRepository->findActiveTeamMemberByEmail(
$this->getConfiguration()->getTeam(),
$profileMetadata->getEmail()
);
if (! $user instanceof User) {
return null;
}
return $this->userRepository->updateOrCreateCrmProfile($user, $profileMetadata->getId());
}
public function syncField(FieldMetadata $fieldMetadata): Field
{
$field = $this->crmConfigurationRepository->updateOrCreateField($this->getConfiguration(), $fieldMetadata);
if ($fieldMetadata->getType() === Field::TYPE_PICKLIST) {
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
}
return $field;
}
private function syncPipelineStages(BusinessProcess $pipeline, PipelineMetadata $pipelineMetadata): void
{
$this->crmConfigurationRepository->updateOrCreatePipelineStages($pipeline, $pipelineMetadata->getStages());
}
private function syncRecordType(
PipelineMetadata $pipelineMetadata,
?BusinessProcess $pipeline
): void {
$this->crmConfigurationRepository->updateOrCreateRecordType(
$this->getConfiguration(),
$pipelineMetadata,
$pipeline
);
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65494
|
2307
|
22
|
2026-05-21T07:42:05.941962+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349325941_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
MetadataProcessor.php, class
MetadataProcessor.php MetadataProcessor.php, class
MetadataProcessor.php, class
96
96
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
MetadataProcessorTest.php, class
MetadataProcessorTest.php, class
182
182
->method('updatePicklistValues')
->method('updatePicklistValues')
Merge Usages from the Same Line
Show Read Access
Show Write Access
Show Results In Generated Code
Show Import Statements
Show $this/self references
Show Options
Preview Source
Project Files...
|
[{"role":"AXCell","text":& [{"role":"AXCell","text":"MetadataProcessor.php, class","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"MetadataProcessor.php, class","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"96","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"96","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"MetadataProcessorTest.php, class","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"MetadataProcessorTest.php, class","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"182","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"182","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"->method('updatePicklistValues')","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"->method('updatePicklistValues')","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Merge Usages from the Same Line","depth":2,"bounds":{"left":0.19015957,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Read Access","depth":2,"bounds":{"left":0.19880319,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Write Access","depth":2,"bounds":{"left":0.20744681,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Results In Generated Code","depth":2,"bounds":{"left":0.21609043,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Import Statements","depth":2,"bounds":{"left":0.22473404,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show $this/self references","depth":2,"bounds":{"left":0.23337767,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Options","depth":2,"bounds":{"left":0.24202128,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Preview Source","depth":2,"bounds":{"left":0.25299203,"top":0.41260973,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Project Files","depth":2,"bounds":{"left":0.26163563,"top":0.41260973,"width":0.03557181,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_expanded":false}]...
|
3422689603319021149
|
-7791483532066909704
|
click
|
accessibility
|
NULL
|
MetadataProcessor.php, class
MetadataProcessor.php MetadataProcessor.php, class
MetadataProcessor.php, class
96
96
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
MetadataProcessorTest.php, class
MetadataProcessorTest.php, class
182
182
->method('updatePicklistValues')
->method('updatePicklistValues')
Merge Usages from the Same Line
Show Read Access
Show Write Access
Show Results In Generated Code
Show Import Statements
Show $this/self references
Show Options
Preview Source
Project Files...
|
65492
|
NULL
|
NULL
|
NULL
|
|
65493
|
2306
|
28
|
2026-05-21T07:42:05.935714+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349325935_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
MetadataProcessor.php, class
MetadataProcessor.php MetadataProcessor.php, class
MetadataProcessor.php, class
96
96
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
MetadataProcessorTest.php, class
MetadataProcessorTest.php, class
182
182
->method('updatePicklistValues')
->method('updatePicklistValues')
Merge Usages from the Same Line
Show Read Access
Show Write Access
Show Results In Generated Code
Show Import Statements
Show $this/self references
Show Options
Preview Source
Project Files
Usages
Settings…...
|
[{"role":"AXCell","text":& [{"role":"AXCell","text":"MetadataProcessor.php, class","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"MetadataProcessor.php, class","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"96","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"96","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"MetadataProcessorTest.php, class","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"MetadataProcessorTest.php, class","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"182","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"182","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXCell","text":"->method('updatePicklistValues')","depth":4,"on_screen":false,"role_description":"cell"},{"role":"AXStaticText","text":"->method('updatePicklistValues')","depth":5,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Merge Usages from the Same Line","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Read Access","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Write Access","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Results In Generated Code","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Import Statements","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show $this/self references","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Show Options","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Preview Source","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Project Files","depth":2,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Usages","depth":1,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Settings…","depth":2,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-3573222964604457793
|
-2891567138022587920
|
click
|
accessibility
|
NULL
|
MetadataProcessor.php, class
MetadataProcessor.php MetadataProcessor.php, class
MetadataProcessor.php, class
96
96
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
$this->fieldRepository->updatePicklistValues($field, $fieldMetadata->getOptions());
MetadataProcessorTest.php, class
MetadataProcessorTest.php, class
182
182
->method('updatePicklistValues')
->method('updatePicklistValues')
Merge Usages from the Same Line
Show Read Access
Show Write Access
Show Results In Generated Code
Show Import Statements
Show $this/self references
Show Options
Preview Source
Project Files
Usages
Settings…...
|
65491
|
NULL
|
NULL
|
NULL
|
|
65492
|
2307
|
21
|
2026-05-21T07:42:01.473570+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349321473_m2.jpg...
|
PhpStorm
|
faVsco.js – FieldRepository.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
3782946305343260838
|
-4131508276899304075
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65491
|
2306
|
27
|
2026-05-21T07:42:01.443310+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349321443_m1.jpg...
|
PhpStorm
|
faVsco.js – FieldRepository.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"}]...
|
6098876064718157734
|
-4167677811951817355
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65490
|
2307
|
20
|
2026-05-21T07:42:00.666858+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349320666_m2.jpg...
|
PhpStorm
|
faVsco.js – FieldRepository.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"}]...
|
1363923065559702658
|
-4131508276899304075
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions...
|
65488
|
NULL
|
NULL
|
NULL
|
|
65489
|
2306
|
26
|
2026-05-21T07:42:00.646466+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349320646_m1.jpg...
|
PhpStorm
|
faVsco.js – FieldRepository.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"}]...
|
6168755295770182110
|
-4131649014932918923
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder...
|
65487
|
NULL
|
NULL
|
NULL
|
|
65488
|
2307
|
19
|
2026-05-21T07:41:53.210431+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349313210_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4235983745889776938
|
-8204421443435123770
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
slackFV [EMAIL]=.phounit.result.cacheE .prettierignore= windsurtrulesphpde neloer.onophpide heloer_models.ohophp artisanM'CLAUDE.mdcomooser.isoncomooser.lockdependency-checker.json8 dev ison= ids tytl=infection.ison.distMLINSTAlI.mdMLINTERNAI WERHOOK SFTUP mdEjiminny_storageMiliconsos mdllM Makefile1рackace-lock. sonE phpstan.neon.dist= phostan-baseline.neon<> phpunit.xmlTe raw sal query.saM+ README.mdsô sonar-proiect propertiesE test.ov‹> Untitled Diaaram.xmliusvetur.confio.isM+ WEBHOOK FILTERING_IMPLEMENTATION.mo>1h External Librariesv =° Scratches and Consolesv batabase Consolesv AEU# console (EUlI DEAL RISKS (SU1A DITEUlA EU (EU]v Ajiminny@localhostA console (jiminny@localhost]# Di [liminny@localhostlA HS local [iiminny@localhostlA SF ['iiminny@localhost]& zoho dev [iiminny@localhost]V & PRODA console [PROD]& console 1 [PROD1LDIIPRODCActivityController.ong© ConvertLeadActivities.php= laravel.log4 SF jiminny@localhost]4 HS_local [jiminny@localhost]& console (PROD] X# console [euyLeadkepository.ong© PurgeLookupCache.php© SyncPlanhat.phpo synerorlannatpnpA console [STAGING]AcuivityLeadConverted.php© UserAutomatedreporscontroller.phpx© PlaybackController.php)Inteqrationapp/service.onoC) LeadConverted.ono570571C) CreateCommentedEvent.php(C) CreateSmsSentEvent.phpC) PlanhatActivityListener.php© AskAnythingPromptService.php572(C) AutomatedReportsRepositorv.php© AutomatedReportsCommand.phpphp api_v2.phpC) RequestGenerateReportJob.php573574© AutomatedReportResult.php(C) AutomatedReport.oho575use Jiminny \Services \Kiosk \AutomatedReports \ReportSortDirection;A1422 ^ v 576use Jiminny \Services\PlanhatService;use ectumtnace hutp kequestuse Inrowable,class UserAutomatedReportsController extends Controllenpublic const int RESULTS PER_ PAGE = 25:public const string SORT COLUMN = 'sort column':public const strina SORT DIRECTION = "sort direction':public function constructprivate readonly AutomatedReportsRepository $automatedReportsRepository.private readonly AutomatedRenortsService SautomatedRenortsServicelorivate readoni.v AniResponseService samiResponseServi.ce.orivate readoni.v Resnonse Sresnonse.private readonly PlanhatService $planhatService1...poST lanilv1lautomated-renorts/interest 1usadepublic function trackInterest(Request $request): JsonResponse(...}* Othnows ApplicationException58(09 >GET /api/v1/automated-reportspublic function list(Request Srequest): JsonResponse(...}125 0)DELETE/api/vl/automated-reports/kuuidpublic function delete(Request Srequest. string Suuid): JsonResponsef...} -609610--611612613616Tx: AutovSo jiminny vCONCAT(u.id, CASE WHEN U.id = t.owner_id THEN' (owner)' ELSE'' END) AS USEr_i041 A1 A40 V65 ^sa.*t.owner_id FROM social_accounts saNoun usens u on u.ide sa.sociablle 1diJOIN teams t 1..n<->1: on t.id = u.team_idWHERE u.team_id = 581 and sa.provider = 'salesforce';SELECT * FROM automated_report_results order by id desc;select * from features;select * from team_features where feature_id = 40;select * from teams where id = 556:select * trom automated reports:where id = 54: # 4fdd41f6-dcf0-30d0-b339-7345381b6044|"pat", "podcast"SELECT * FROM automated report results WHERE uuid to bin( '822fa41b-afd3-43a9-a248-86b0e36f3131') = uuid;select * from automated_report_results order by id desc;SELECT * FROMWHERE id = 1919:select * fromautomated report results WHERE report id = 54:select * from opportunities where id = 7594349:SELECT * FROM teams WHERE name LIKE '%Lesg': # 711. 692. [EMAIL] * from playbooks where team_id = 711; # event 226147SELEd * FROM Dlavbook catedonies WHERE Dlavbook 1d = 55151SELECT * FROM crm_fields WHERE crm_configuration_id = 692 and object_type = 'event':SELECT * SROM eom fields WHEREI1d = 2261471SELECT * FROM crm_field_values WHERE crm_field_id = 226147;SELECT * FROM crm_configurations WHERE id = 692;SELSCTCONCAT(u.id, CASE WHEN u.id = t.owner_id THEN ' (owner)' ELSE '• END) AS user_id,v.emailsa.*,t.owner id FROM social accounts saJOIN users u on v.id = sa.sociable idJOIN teams t 1..n<->1: on t.id = u.team idWHERE U.team_id = 711 and sa.provider = 'salesforce";SELECT * FROM crm profiles cp JOIN users u 1..n<->1: on u.id = co.user id WHERE u.team_id = 711:select * from leadsselect * from calendarsSELECTS 0 hllsupoont Dally • In 4h 40m100% 52• Inu z1 May 10.10.34AskJiminnyReportActivityServiceTestvCascadePlaybook Categorie+0 ..connected. How isi. Can we vali eoneactivity tyee nith orit cabest aeeiewmane o, W dati anwsyggesinsingrow hohow to distinguishThoughts68 Fast Context How are playbook_categories populated and synced from crm_fields / crm_field_values... in 4.14s >Explored 4 files and searched 5 queriesRead ImportActivitvTypes.php #L95-104Searched olavbook cateaories in databaselmiarations (4) >egories|playbook_categories.*create in database/migrations (0)searched playoook_categor in database/migrations (<)Searched activity type in database/migrations (4)SurtingAsk anvthina (*4L)@ Codo Caudo Onue 17 ModiumNN Windeurf Toame 504.60...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65487
|
2306
|
25
|
2026-05-21T07:41:54.865066+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349314865_m1.jpg...
|
PhpStorm
|
faVsco.js – FieldRepository.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Analyzing…","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Repositories\\Crm;\n\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\LazyCollection;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Services\\Crm\\Metadata\\OptionMetadata;\n\nclass FieldRepository\n{\n /**\n * @return Collection<Field>\n */\n public function getAllFieldsForObjectType(Team $team, string $objectType): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->where('object_type', '=', $objectType)\n ->get()\n ;\n }\n\n /**\n * @param Team $team\n * @param string[] $objectTypes\n *\n * @return Collection<Field>\n */\n public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection\n {\n return $team->getCrmConfiguration()\n ->fields()\n ->whereIn('object_type', $objectTypes)\n ->where('is_selectable', true)\n ->orderBy('label')\n ->get()\n ;\n }\n\n public function idOrUuid(int|string $id): ?Field\n {\n /** @var ?Field */\n return Field::idOrUuid($id);\n }\n\n /**\n * @param OptionMetadata[] $options\n */\n public function updatePicklistValues(Field $field, array $options): void\n {\n $field->values()->delete();\n\n foreach ($options as $option) {\n $field->values()->updateOrCreate([\n 'value' => $option->getId(),\n 'label' => $option->getLabel(),\n ], [\n 'sequence' => $option->getSequence(),\n ]);\n }\n }\n\n public function updateOrCreateFieldValue(Field $field, array $data): FieldValue\n {\n /** @var FieldValue */\n return $field->values()->updateOrCreate([\n 'value' => $data['value'],\n ], $data);\n }\n\n public function updateOrCreateOpportunityFieldData(\n Field $field,\n int $layoutEntityId,\n int $opportunityId,\n string $value,\n ): void {\n $field->data()->updateOrCreate([\n 'crm_layout_entity_id' => $layoutEntityId,\n 'crm_field_id' => $field->getId(),\n 'object_type' => Field::OBJECT_OPPORTUNITY,\n 'object_id' => $opportunityId,\n ], ['value' => $value]);\n }\n\n public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field\n {\n /** @var Field */\n return $configuration->fields()->where('crm_provider_id', $fieldId)->first();\n }\n\n /**\n * @param array<string,scalar> $data\n */\n public function updateField(Field $field, array $data): void\n {\n $field->update($data);\n }\n\n public function upsertField(Configuration $configuration, array $data): Field\n {\n /** @var Field */\n return $configuration->fields()->updateOrCreate(\n [\n 'crm_provider_id' => $data['crm_provider_id'],\n 'object_type' => $data['object_type'],\n ],\n $data,\n );\n }\n\n public function findFieldByCrmIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var Field */\n return $configuration->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findAllFilterable(Team $team): LazyCollection\n {\n return $team\n ->getCrmConfiguration()\n ->fields()\n ->where('is_filterable', true)\n ->cursor();\n }\n\n public function findOneByCrmProviderIdAndObjectType(\n Configuration $configuration,\n string $fieldId,\n string $objectType,\n ): ?Field {\n /** @var ?Field */\n return $configuration\n ->fields()\n ->where('crm_provider_id', $fieldId)\n ->where('object_type', $objectType)\n ->first();\n }\n\n public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field\n {\n return $configuration->fields()\n ->where($properties)\n ->first();\n }\n\n public function getPicklistValues(Field $field, ?array $filterValues = []): Collection\n {\n $queryBuilder = $field->values()->orderBy('sequence');\n\n if (! empty($filterValues)) {\n $queryBuilder->whereIn('value', $filterValues);\n }\n\n return $queryBuilder->get();\n }\n\n public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue\n {\n /** @var FieldValue */\n return $this->updateOrCreateFieldValue($field, $picklistValueData);\n }\n\n public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void\n {\n $configuration->fields()\n ->where('object_type', $objectType)\n ->where('crm_provider_id', $crmProviderId)\n ->delete();\n }\n\n /**\n * @param Configuration $configuration\n * @param string $objectType\n * @param string[] $crmProviderIds\n *\n * @return Collection<Field>\n */\n public function identifyTeamCrmFields(\n Configuration $configuration,\n string $objectType,\n array $crmProviderIds,\n ): Collection {\n return $configuration->fields()\n ->where('object_type', $objectType)\n ->whereIn('crm_provider_id', $crmProviderIds)\n ->get();\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
-915585642258243567
|
-2978587871736909979
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
Analyzing…
<?php
declare(strict_types=1);
namespace Jiminny\Repositories\Crm;
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
use Jiminny\Models\Crm\Configuration;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Team;
use Jiminny\Services\Crm\Metadata\OptionMetadata;
class FieldRepository
{
/**
* @return Collection<Field>
*/
public function getAllFieldsForObjectType(Team $team, string $objectType): Collection
{
return $team->getCrmConfiguration()
->fields()
->where('object_type', '=', $objectType)
->get()
;
}
/**
* @param Team $team
* @param string[] $objectTypes
*
* @return Collection<Field>
*/
public function findAllSelectableByObjectTypes(Team $team, array $objectTypes): Collection
{
return $team->getCrmConfiguration()
->fields()
->whereIn('object_type', $objectTypes)
->where('is_selectable', true)
->orderBy('label')
->get()
;
}
public function idOrUuid(int|string $id): ?Field
{
/** @var ?Field */
return Field::idOrUuid($id);
}
/**
* @param OptionMetadata[] $options
*/
public function updatePicklistValues(Field $field, array $options): void
{
$field->values()->delete();
foreach ($options as $option) {
$field->values()->updateOrCreate([
'value' => $option->getId(),
'label' => $option->getLabel(),
], [
'sequence' => $option->getSequence(),
]);
}
}
public function updateOrCreateFieldValue(Field $field, array $data): FieldValue
{
/** @var FieldValue */
return $field->values()->updateOrCreate([
'value' => $data['value'],
], $data);
}
public function updateOrCreateOpportunityFieldData(
Field $field,
int $layoutEntityId,
int $opportunityId,
string $value,
): void {
$field->data()->updateOrCreate([
'crm_layout_entity_id' => $layoutEntityId,
'crm_field_id' => $field->getId(),
'object_type' => Field::OBJECT_OPPORTUNITY,
'object_id' => $opportunityId,
], ['value' => $value]);
}
public function findOneByCrmProviderId(Configuration $configuration, string $fieldId): ?Field
{
/** @var Field */
return $configuration->fields()->where('crm_provider_id', $fieldId)->first();
}
/**
* @param array<string,scalar> $data
*/
public function updateField(Field $field, array $data): void
{
$field->update($data);
}
public function upsertField(Configuration $configuration, array $data): Field
{
/** @var Field */
return $configuration->fields()->updateOrCreate(
[
'crm_provider_id' => $data['crm_provider_id'],
'object_type' => $data['object_type'],
],
$data,
);
}
public function findFieldByCrmIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var Field */
return $configuration->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findAllFilterable(Team $team): LazyCollection
{
return $team
->getCrmConfiguration()
->fields()
->where('is_filterable', true)
->cursor();
}
public function findOneByCrmProviderIdAndObjectType(
Configuration $configuration,
string $fieldId,
string $objectType,
): ?Field {
/** @var ?Field */
return $configuration
->fields()
->where('crm_provider_id', $fieldId)
->where('object_type', $objectType)
->first();
}
public function findOneConfigurationFieldByProperties(Configuration $configuration, array $properties): ?Field
{
return $configuration->fields()
->where($properties)
->first();
}
public function getPicklistValues(Field $field, ?array $filterValues = []): Collection
{
$queryBuilder = $field->values()->orderBy('sequence');
if (! empty($filterValues)) {
$queryBuilder->whereIn('value', $filterValues);
}
return $queryBuilder->get();
}
public function updatePicklistValue(Field $field, array $picklistValueData): FieldValue
{
/** @var FieldValue */
return $this->updateOrCreateFieldValue($field, $picklistValueData);
}
public function deleteObsoleteField(Configuration $configuration, string $objectType, string $crmProviderId): void
{
$configuration->fields()
->where('object_type', $objectType)
->where('crm_provider_id', $crmProviderId)
->delete();
}
/**
* @param Configuration $configuration
* @param string $objectType
* @param string[] $crmProviderIds
*
* @return Collection<Field>
*/
public function identifyTeamCrmFields(
Configuration $configuration,
string $objectType,
array $crmProviderIds,
): Collection {
return $configuration->fields()
->where('object_type', $objectType)
->whereIn('crm_provider_id', $crmProviderIds)
->get();
}
}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65486
|
2306
|
24
|
2026-05-21T07:41:53.210434+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349313210_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-4235983745889776938
|
-8204421443435123770
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
SlackFileEditViewGoHistoryWindowHelpscreelDOCKER0 81DEV (-zsh)₴2APP (-zsh)whisper_init_state:whisper_init_state:kv padsize=2.36 MBcompute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state:compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu: device 0: Metal (type:1)whisper_backend_init_gpu: found GPU device 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrency= trueggml_metal_init: use graph optimizetruewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize =2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)=whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocatingwhisper_backend_init_gpu:device 0: Metal (type: 1)whisper_backend_init_gpu: found GPUdevice 0: Metal (type: 1, cnt: 0)whisper_backend_init_gpu: using Metal backendggml_metal_init: allocatingggml_metal_init: found device: Apple M1ggml_metal_init: picking default device: Apple M1ggml_metal_init:use fusion= trueggml_metal_init:use concurrencytrueggml_metal_init:use graph optimizetruewhisper_backend_init: using BLAS backendwhisper_init_state: kv self size3.15 MBwhisper_init_state: kv cross size =9.44 MBwhisper_init_state: kv padsize=2.36 MBwhisper_init_state: compute buffer (conv)whisper_init_state: compute buffer (encode) =whisper_init_state: compute buffer (cross)whisper_init_state: compute buffer (decode) =14.17 MB65.96 MB8.50 MB96.83 MBggml_metal_free: deallocating2026-05-21T10:13:41.913005ZINFO screenpipe_audio::audio_manager::manager: reconciliatior2026-05-21710:15:15.5768762INFO screenpipe_engine::event_driven_capture: content dedup:j Support Daily - in 4h 45 m100% С8• Thu 21 May 10:15:32•••EDQHomeDMsActivityFilesLater•••More+→Describe what you are looking forJiminny ...ThreadsC9 Unreadsà platform-inner-teamGalya Dimitrova, Nikolay Yankov, and youa ThreadsHuddles• Drafts & sentDirectories01External connections* Starred& jiminny-x-integrati...platform-inner-teamChannels# ai-chapter# alerts# backend# bugs# confusion-clinic# curiosity_lab# engineering# general# happy_birthday# jiminny-bg# platform-tickets# product_launches# random# releases# sofia-office# supportLukas Kovalik 31 minutes agoдобро утро, тази страница не трябва ли да япоказваме само ако няма reportsCleanShot 2026-05-21 at [EMAIL] your questions into ongoing insightsGalya Dimitrova 23 minutes agoДа, би трябвалоLukas Kovalik 22 minutes agoче сега ми го показва и ако имам reportLukas Kovalik 21 minutes agoна neptuneNewNikolay Yankov 6 minutes agoвсичко е наредReply...Also send to à platform-inner-team+AaYou're up to date...
|
65484
|
NULL
|
NULL
|
NULL
|
|
65485
|
2307
|
18
|
2026-05-21T07:41:35.862833+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349295862_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
Command.php, class
CreateDatabaseUsers.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.15990691,"top":0.007980846,"width":0.2662899,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncTeamMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UpdateOpportunitySpecifications.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dev, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dialers, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DTOs","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Elasticsearch","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EngagementStats","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GeckoExport","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Livestream","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Mailboxes, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Migrate","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackThemes","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playbooks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlists, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Postmark, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Reports, folder","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsRetentionPolicyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutomatedReportsSendCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateMockAskJiminnyReportResultCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DeleteReportCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GenerateMarketingReport.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Team.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Usage.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Teams","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Tracks","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Users","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Vocabulary","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Zoom","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Command.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CreateDatabaseUsers.php, class","depth":10,"on_screen":false,"role_description":"text"}]...
|
-4969646139324939661
|
-6409495119138910956
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class
SyncTeamMetadata.php, class
UpdateOpportunitySpecifications.php, class
DealInsights, folder
Dev, folder
Dialers, folder
DTOs
Elasticsearch
EngagementStats
GeckoExport
Livestream
Mailboxes, folder
Migrate
PlaybackThemes
Playbooks
Playlists, folder
Postmark, folder
ProphetAi, folder
Reports, folder
AutomatedReportsCommand.php
AutomatedReportsRetentionPolicyCommand.php
AutomatedReportsSendCommand.php
CreateMockAskJiminnyReportResultCommand.php
DeleteReportCommand.php
GenerateMarketingReport.php, class
Team.php, class
Usage.php, class
Slack
Teams
Tracks
Transcription
Twilio
Users
Vocabulary
Zoom
Command.php, class
CreateDatabaseUsers.php, class...
|
65483
|
NULL
|
NULL
|
NULL
|
|
65484
|
2306
|
23
|
2026-05-21T07:41:35.787977+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349295787_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BackfillOpportunityUserFromAccountCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessHubspotObjectsSyncBatches.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PurgeDeletedOpportunitiesCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ResetGovernorLimits.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SendNotLogged.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupActivityTypeForFollowUp.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCloseCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCopperCrm.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupCrmCommand.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SetupLayouts.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncAccount.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncContact.php","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncFieldMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotActiveDeals.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncHubspotObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncLead.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncObjects.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunitiesMissingFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncOpportunity.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SyncProfileMetadata.php, class","depth":11,"on_screen":false,"role_description":"text"}]...
|
8460510130546683954
|
-6412872269032321772
|
idle
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder
PlaybackPage
Playlist
Prophet
ProphetAi
ProsperWorks
Queue
Router
Saml2
SCIM
Seeder
Sentry
Serializer
Settings
Sidekick
Slack
TeamInsights
TimeMemoryMapper
Transcription
TranscriptionSummary, folder
Twilio, folder
Uploader, folder
UrlGenerator, folder
Utility, folder
Uuid, folder
Waveform, folder
Webhooks, folder
Workflow, folder
Configuration
Console
Commands, folder
Activities
Analytics
Calendars
Crm
Hubspot
IntegrationApp
Traits
AddLayoutEntities.php, class
AutologDelayedCommand.php, class
BackfillOpportunityUserFromAccountCommand.php, class
BullhornCommandAbstract.php, abstract class
BullhornPingCommand.php, class
BullhornSearchCommand.php
BullhornSessionCommand.php
CheckActivityLoggableCommand.php
CleanDuplicateFieldDataCommand.php
FullSyncOpportunityCommand.php
LogActivitiesCommand.php
ManageSyncStrategyCommand.php
MatchCrmObjectsCommand.php
MatchOpportunityActivitiesCommand.php
MigrateProvider.php
ProcessHubspotObjectsSyncBatches.php
PurgeDeletedOpportunitiesCommand.php
ResetGovernorLimits.php
SendNotLogged.php
SetupActivityTypeForFollowUp.php
SetupCloseCrm.php
SetupCopperCrm.php
SetupCrmCommand.php
SetupLayouts.php
SyncAccount.php
SyncContact.php
SyncFieldMetadata.php, class
SyncHubspotActiveDeals.php, class
SyncHubspotObjects.php, class
SyncLead.php, class
SyncObjects.php, class
SyncOpportunitiesMissingFieldDataCommand.php, class
SyncOpportunity.php, class
SyncProfileMetadata.php, class...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65483
|
2307
|
17
|
2026-05-21T07:41:05.419501+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349265419_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.19780585,"top":0.007980846,"width":0.25897607,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"}]...
|
5817002037882781695
|
-8717730082541445868
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
65482
|
2306
|
22
|
2026-05-21T07:41:05.439497+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349265439_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"}]...
|
-3183846560324211647
|
-8717730116901200620
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder...
|
65480
|
NULL
|
NULL
|
NULL
|
|
65481
|
2307
|
16
|
2026-05-21T07:41:04.693708+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349264693_m2.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.040226065,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"bounds":{"left":0.8081782,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"bounds":{"left":0.8234708,"top":0.019952115,"width":0.09208777,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9155585,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"bounds":{"left":0.9268617,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"bounds":{"left":0.9381649,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"bounds":{"left":0.96609044,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"bounds":{"left":0.9773936,"top":0.019952115,"width":0.011303191,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"bounds":{"left":0.9886968,"top":0.019952115,"width":0.011303186,"height":0.025538707},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"bounds":{"left":0.19780585,"top":0.007980846,"width":0.25897607,"height":0.98324025},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.042220745,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"bounds":{"left":0.44547874,"top":0.09736632,"width":0.29022607,"height":0.8818835},"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"bounds":{"left":0.011968086,"top":0.047885075,"width":0.024268618,"height":0.024740623},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.008643617,"height":0.0},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"}]...
|
7089743142087417934
|
-8717591578436149996
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring...
|
65479
|
NULL
|
NULL
|
NULL
|
|
65480
|
2306
|
21
|
2026-05-21T07:41:04.712459+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-21/1779 /Users/lukas/.screenpipe/data/data/2026-05-21/1779349264712_m1.jpg...
|
PhpStorm
|
faVsco.js – SyncCrmFieldsTrait.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"master, menu","depth":5,"on_screen":true,"help_text":"Git Branch: master<br/>74 incoming commits<br/>","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Start Listening for PHP Debug Connections","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"AskJiminnyReportActivityServiceTest","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Run 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Debug 'AskJiminnyReportActivityServiceTest'","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"More Actions","depth":6,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"JetBrains AI","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Everywhere","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"IDE and Project Settings","depth":5,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits;\n\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\Config\\IntegrationAppProviders;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmField;\nuse Jiminny\\Services\\Crm\\IntegrationApp\\DTO\\CrmFieldDefinitionsManager;\nuse RuntimeException;\n\ntrait SyncCrmFieldsTrait\n{\n public function syncFields(): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {\n $fieldManager = new CrmFieldDefinitionsManager();\n\n foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));\n $this->syncObjectTypeFields($fieldType, $crmFields);\n }\n }\n\n return;\n }\n\n foreach ($this->getFieldTypes() as $object) {\n $this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));\n $fields = $this->client->getObjectFields($object);\n foreach ($fields as $fieldDto) {\n $field = $this->importCrmField($fieldDto);\n if ($field->isPicklist()) {\n $this->importPicklistValues($field);\n }\n }\n }\n }\n\n private function syncObjectTypeFields(string $fieldType, array $crmFields): void\n {\n foreach ($crmFields as $crmField) {\n $this->syncCrmField($fieldType, $crmField);\n }\n }\n\n private function syncCrmField(string $fieldType, array $crmField): void\n {\n $fieldData = [\n 'crm_provider_id' => $crmField['crm_id'],\n 'object_type' => $fieldType,\n 'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),\n 'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),\n 'type' => $crmField['type'],\n 'is_selectable' => $crmField['is_selectable'] ?? true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n $field = $fieldRepository->upsertField($this->config, $fieldData);\n\n $this->logger->info('[integration-app] Synced field', [\n 'field' => $field->getLabel(),\n 'team_id' => $this->team?->getId(),\n ]);\n\n $field->refresh();\n if ($field->getType() === Field::TYPE_PICKLIST) {\n $this->importPicklistValues($field);\n }\n }\n\n private function importCrmField(CrmField $crmField): Field\n {\n $fieldData = [\n 'crm_provider_id' => $crmField->getExternalId(),\n 'object_type' => $crmField->getObjectType(),\n 'label' => $crmField->getLabel()\n ? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)\n : '',\n 'description' => $crmField->getDescription()\n ? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)\n : null,\n 'type' => $crmField->getType(),\n 'is_selectable' => true,\n ];\n\n /** @var FieldRepository $fieldRepository */\n $fieldRepository = app(FieldRepository::class);\n\n return $fieldRepository->upsertField($this->config, $fieldData);\n }\n\n /**\n * Works together with SyncTeamMetadata command if new field is added and needs to be synced.\n */\n public function syncField(Field $field): void\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldId = $field->getCrmProviderId();\n $fieldType = $field->getObjectType();\n\n $fieldManager = new CrmFieldDefinitionsManager();\n $fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);\n\n $this->syncCrmField($fieldType, $fieldDefinition);\n } else {\n $fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());\n $this->importCrmField($fieldDto);\n }\n }\n\n public function importPicklistValues(Field $field): array\n {\n if (! $this->editionConfig->supportsCrmFieldsSync()) {\n $fieldManager = new CrmFieldDefinitionsManager();\n $picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());\n } else {\n if (! $field->isPicklist()) {\n return [];\n }\n\n $picklistValues = $this->client->getPicklistValues(\n $field->getObjectType(),\n $field->getCrmProviderId(),\n );\n }\n\n if (empty($picklistValues)) {\n return [];\n }\n\n return $this->importOptions($field, $picklistValues);\n }\n\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $sequence = 0;\n $fieldRepo = app(FieldRepository::class);\n\n foreach ($options as $option) {\n $value = [\n 'value' => $option,\n 'label' => $option,\n 'sequence' => $sequence++,\n ];\n\n $fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);\n }\n\n return $fieldValues;\n }\n\n protected function getFieldTypes(): array\n {\n return match ($this->config->getEdition()) {\n IntegrationAppProviders::MS_DYNAMICS => [\n Field::OBJECT_OPPORTUNITY,\n Field::OBJECT_LEAD,\n Field::OBJECT_CONTACT,\n Field::OBJECT_ACCOUNT,\n Field::OBJECT_TASK,\n ],\n default => throw new RuntimeException('Unsupported CRM provider')\n };\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Sync Changes","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide This Notification","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":false,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Code changed:","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.088194445,"height":0.027777778},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXTextArea","text":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Helpers;\n\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldValue;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\PlaybookCategory;\n\n/**\n * A collection of DB-related internal functionalities or all CRMs.\n */\nclass CrmHelperRepository\n{\n public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory\n {\n /** @var ?PlaybookCategory */\n return $playbook->categories()\n ->where('name', trim($categoryName))\n ->orderBy('id', 'desc')\n ->first();\n }\n\n public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue\n {\n /** @var ?FieldValue */\n return $activityField->values()\n ->where('label', $categoryName)\n ->first();\n }\n\n public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool\n {\n return $activityField->values()\n ->where('label', $categoryName)\n ->exists();\n }\n\n public function hasFeature(Activity $activity, FeatureEnum $featureName): bool\n {\n return $activity->getUser()\n ->getTeam()\n ->hasFeature($featureName);\n }\n}","role_description":"text entry area","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Project","depth":3,"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Project","depth":3,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"New File or Directory…","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Expand Selected","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Collapse All","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Options","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Hide","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.018055556,"height":0.026666667},"on_screen":false,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie, folder","depth":9,"on_screen":false,"role_description":"text"}]...
|
-1566601011576084229
|
-8717730117438055148
|
click
|
accessibility
|
NULL
|
Project: faVsco.js, menu
master, menu
Start Listen Project: faVsco.js, menu
master, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\IntegrationApp\ServiceTraits;
use Jiminny\Models\Crm\Field;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Services\Crm\IntegrationApp\Config\IntegrationAppProviders;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmField;
use Jiminny\Services\Crm\IntegrationApp\DTO\CrmFieldDefinitionsManager;
use RuntimeException;
trait SyncCrmFieldsTrait
{
public function syncFields(): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
if ($this->config->getEdition() === IntegrationAppProviders::ZOHO_CRM) {
$fieldManager = new CrmFieldDefinitionsManager();
foreach ($fieldManager->getFieldDefinitions() as $fieldType => $crmFields) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $fieldType));
$this->syncObjectTypeFields($fieldType, $crmFields);
}
}
return;
}
foreach ($this->getFieldTypes() as $object) {
$this->logger->info(sprintf('[integration-app] Syncing %s fields.', $object));
$fields = $this->client->getObjectFields($object);
foreach ($fields as $fieldDto) {
$field = $this->importCrmField($fieldDto);
if ($field->isPicklist()) {
$this->importPicklistValues($field);
}
}
}
}
private function syncObjectTypeFields(string $fieldType, array $crmFields): void
{
foreach ($crmFields as $crmField) {
$this->syncCrmField($fieldType, $crmField);
}
}
private function syncCrmField(string $fieldType, array $crmField): void
{
$fieldData = [
'crm_provider_id' => $crmField['crm_id'],
'object_type' => $fieldType,
'label' => mb_strimwidth($crmField['label'], 0, Field::LABEL_MAX_LENGTH),
'description' => mb_strimwidth($crmField['description'], 0, Field::DESCRIPTION_MAX_LENGTH),
'type' => $crmField['type'],
'is_selectable' => $crmField['is_selectable'] ?? true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
$field = $fieldRepository->upsertField($this->config, $fieldData);
$this->logger->info('[integration-app] Synced field', [
'field' => $field->getLabel(),
'team_id' => $this->team?->getId(),
]);
$field->refresh();
if ($field->getType() === Field::TYPE_PICKLIST) {
$this->importPicklistValues($field);
}
}
private function importCrmField(CrmField $crmField): Field
{
$fieldData = [
'crm_provider_id' => $crmField->getExternalId(),
'object_type' => $crmField->getObjectType(),
'label' => $crmField->getLabel()
? mb_strimwidth($crmField->getLabel(), 0, Field::LABEL_MAX_LENGTH)
: '',
'description' => $crmField->getDescription()
? mb_strimwidth($crmField->getDescription(), 0, Field::DESCRIPTION_MAX_LENGTH)
: null,
'type' => $crmField->getType(),
'is_selectable' => true,
];
/** @var FieldRepository $fieldRepository */
$fieldRepository = app(FieldRepository::class);
return $fieldRepository->upsertField($this->config, $fieldData);
}
/**
* Works together with SyncTeamMetadata command if new field is added and needs to be synced.
*/
public function syncField(Field $field): void
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldId = $field->getCrmProviderId();
$fieldType = $field->getObjectType();
$fieldManager = new CrmFieldDefinitionsManager();
$fieldDefinition = $fieldManager->findByCrmId($fieldId, $fieldType);
$this->syncCrmField($fieldType, $fieldDefinition);
} else {
$fieldDto = $this->client->getField($field->getObjectType(), $field->getCrmProviderId());
$this->importCrmField($fieldDto);
}
}
public function importPicklistValues(Field $field): array
{
if (! $this->editionConfig->supportsCrmFieldsSync()) {
$fieldManager = new CrmFieldDefinitionsManager();
$picklistValues = $fieldManager->getPicklistValues($field->getCrmProviderId());
} else {
if (! $field->isPicklist()) {
return [];
}
$picklistValues = $this->client->getPicklistValues(
$field->getObjectType(),
$field->getCrmProviderId(),
);
}
if (empty($picklistValues)) {
return [];
}
return $this->importOptions($field, $picklistValues);
}
private function importOptions(Field $field, array $options): array
{
$fieldValues = [];
$sequence = 0;
$fieldRepo = app(FieldRepository::class);
foreach ($options as $option) {
$value = [
'value' => $option,
'label' => $option,
'sequence' => $sequence++,
];
$fieldValues[] = $fieldRepo->updateOrCreateFieldValue($field, $value);
}
return $fieldValues;
}
protected function getFieldTypes(): array
{
return match ($this->config->getEdition()) {
IntegrationAppProviders::MS_DYNAMICS => [
Field::OBJECT_OPPORTUNITY,
Field::OBJECT_LEAD,
Field::OBJECT_CONTACT,
Field::OBJECT_ACCOUNT,
Field::OBJECT_TASK,
],
default => throw new RuntimeException('Unsupported CRM provider')
};
}
}
Sync Changes
Hide This Notification
Code changed:
Hide
<?php
declare(strict_types=1);
namespace Jiminny\Services\Crm\Helpers;
use Jiminny\Models\Activity;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldValue;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\Playbook;
use Jiminny\Models\PlaybookCategory;
/**
* A collection of DB-related internal functionalities or all CRMs.
*/
class CrmHelperRepository
{
public function getPlaybookCategory(Playbook $playbook, string $categoryName): ?PlaybookCategory
{
/** @var ?PlaybookCategory */
return $playbook->categories()
->where('name', trim($categoryName))
->orderBy('id', 'desc')
->first();
}
public function getActivityFieldValueByName(Field $activityField, string $categoryName): ?FieldValue
{
/** @var ?FieldValue */
return $activityField->values()
->where('label', $categoryName)
->first();
}
public function existsActivityFieldValueByName(Field $activityField, string $categoryName): bool
{
return $activityField->values()
->where('label', $categoryName)
->exists();
}
public function hasFeature(Activity $activity, FeatureEnum $featureName): bool
{
return $activity->getUser()
->getTeam()
->hasFeature($featureName);
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide
app ~/jiminny/app
.circleci
.cursor
.github
.sonarlint
.vscode
.windsurf
app, sources root
Actions
Component
Acl
ActionItems
Activity
ActivityAnalytics
ActivitySearch
AiActivityType
AiAutomation
AiCallScoring
AskAnything
Dtos
Events
AskAnythingPromptService.php, class
HistoryService.php, class
AskJiminnyAi
AWS
BillingManagement
Cache
CoachingFeedback
Country
CustomerApi
Database
Datadog
DateTime
DealInsights
DealRisks
ElasticSearch
Eloquent
Encoding
Encryption
ES
Faker
FeatureFlags
FFMpeg
FileSystem
Gecko
Gong
GuzzleHttp
KeyPoints
Kiosk
LanguageDetection
LiveFeed
Locks
Math
MediaPipeline
MeetingBot
MobileSettings
Model, folder
Notification, folder
Nudge, folder
ParagraphBreaker, folder
ParticipantSpeech, folder
PartitionedCookie, folder...
|
NULL
|
NULL
|
NULL
|
NULL
|