In this article, I would like to acquaint readers with the very interesting open-source (GPL3) architecture of the EspoCRM project using the example of creating a new module for this system.application/Espo/Modules : application/Espo/Modules/PM application/Espo/Modules/PM/Controllers/ application/Espo/Modules/PM/Entities/ application/Espo/Modules/PM/Resources/ { "entity": true, "layouts": true, "tab": true, "acl": true, "module": "PM", "customizable": true, "stream": true, "importable": true } { "entity": true, "layouts": true, "tab": false, "acl": true, "module": "PM", "customizable": true, "stream": true, "importable": true } entityDefs metadata. { "fields": { "name": { "type": "varchar", "required": true }, "status": { "type": "enum", "options": [ "Draft", "Active", "Completed", "On Hold", "Dropped" ], "default": "Active" }, "description": { "type": "text" }, "account": { "type": "link" }, "createdAt": { "type": "datetime", "readOnly": true }, "modifiedAt": { "type": "datetime", "readOnly": true }, "createdBy": { "type": "link", "readOnly": true }, "modifiedBy": { "type": "link", "readOnly": true }, "assignedUser": { "type": "link", "required": true }, "teams": { "type": "linkMultiple" } }, "links": { "createdBy": { "type": "belongsTo", "entity": "User" }, "modifiedBy": { "type": "belongsTo", "entity": "User" }, "assignedUser": { "type": "belongsTo", "entity": "User" }, "teams": { "type": "hasMany", "entity": "Team", "relationName": "EntityTeam" }, "account": { "type": "belongsTo", "entity": "Account", "foreign": "projects" }, "projectTasks": { "type": "hasMany", "entity": "ProjectTask", "foreign": "project" } }, "collection": { "sortBy": "createdAt", "asc": false, "boolFilters": [ "onlyMy" ] } } { "fields": { "name": { "type": "varchar", "required": true }, "status": { "type": "enum", "options": [ "Not Started", "Started", "Completed", "Canceled" ], "default": "Not Started" }, "dateStart": { "type": "date" }, "dateEnd": { "type": "date" }, "estimatedEffort": { "type": "float" }, "actualDuration": { "type": "float" }, "description": { "type": "text" }, "project": { "type": "link" }, "createdAt": { "type": "datetime", "readOnly": true }, "modifiedAt": { "type": "datetime", "readOnly": true }, "createdBy": { "type": "link", "readOnly": true }, "modifiedBy": { "type": "link", "readOnly": true }, "assignedUser": { "type": "link", "required": true }, "teams": { "type": "linkMultiple" } }, "links": { "createdBy": { "type": "belongsTo", "entity": "User" }, "modifiedBy": { "type": "belongsTo", "entity": "User" }, "assignedUser": { "type": "belongsTo", "entity": "User" }, "teams": { "type": "hasMany", "entity": "Team", "relationName": "EntityTeam" }, "project": { "type": "belongsTo", "entity": "Project", "foreign": "projectTasks" } }, "collection": { "sortBy": "createdAt", "asc": false, "boolFilters": [ "onlyMy" ] } } clientDefs directory. { "controller": "Controllers.Record" } { "controller": "Controllers.Record" } <?php namespace Espo\Modules\PM\Controllers; class Project extends \Espo\Core\Controllers\Record { } <?php namespace Espo\Modules\PM\Controllers; class ProjectTask extends \Espo\Core\Controllers\Record { } <?php namespace Espo\Modules\PM\Entities; class Project extends \Espo\Core\ORM\Entity { } <?php namespace Espo\Modules\PM\Entities; class ProjectTask extends \Espo\Core\ORM\Entity { } Global.json : { "scopeNames": { "Project": "Project", "ProjectTask": "Project Task" }, "scopeNamesPlural": { "Project": "Projects", "ProjectTask": "Project Tasks" } } { "labels": { "Create Project": "Create Project" }, "fields": { "name": "Name", "status": "Status", "account": "Account" }, "links": { "projectTasks": "Project Tasks" } } { "labels": { "Create ProjectTask": "Create Project Task" }, "fields": { "name": "Name", "status": "Status", "project": "Project", "dateStart": "Date Start", "dateEnd": "Date End", "estimatedEffort": "Estimated Effort (hrs)", "actualDuration": "Actual Duration (hrs)" } } Source: https://habr.com/ru/post/230065/
All Articles