diff --git a/docs/administration/fields.md b/docs/administration/fields.md index 8dee06de6..830e90faf 100644 --- a/docs/administration/fields.md +++ b/docs/administration/fields.md @@ -58,7 +58,17 @@ Available items: * Conditions making field read-only * Conditional options – for enum, multi-enum, checklist, array, varchar fields ----- +## Regex + +Any [regex](https://regex-generator.olafneumann.org/) can be used in the "Pattern" property of supported fields. By default, EspoCRM includes the following `patterns`: + +- `$noBadCharacters` +- `$noAsciiSpecialCharacters` +- `$latinLetters` +- `$latinLettersDigits` +- `$latinLettersDigitsWhitespace` +- `$latinLettersWhitespace` +- `$digits` ## Varchar @@ -72,6 +82,28 @@ Parameters: ![Varchar](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/varchar.png) +??? example "Example Varchar JSON Configuration (entityDefs)" + + ``` + "someVarcharFieldName": { + "type": "varchar", + "required": false, + "maxLength": 150, + "default": "some test", + "options": [ + "option 1, option2, option 3", + "another option" + ], + "pattern": "$noBadCharacters", + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + Labels for the options can be updated in the Internationalization files (e.g., `custom/Espo/Custom/Resources/i18n/en_US/TestBaseEntity.json`) + ## Enum Selectbox, only one value can be selected. @@ -81,6 +113,7 @@ Parameters: * Options – a list of values (key => label pairs); a color (style) for each value can be specified (applied when param *Display as Label* is enabled); * Is Sorted – to sort a list alphabetically; * Display as Label – a value will be displayed as a label with color; a color for each option can be specified. +* Style - Defines color properties to the options based on theme. Includes "success", "info", "warning", "primary," and "danger." It's possible to define conditional options with Dynamic Logic. @@ -88,6 +121,34 @@ It's possible to define conditional options with Dynamic Logic. ![Enum detail view](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/enum-detail.png) +??? example "Example Enum JSON Configuration (entityDefs)" + + ``` + "someEnumFieldName": { + "type": "enum", + "options": [ + "Option 1", + "Option 2", + "Option 3" + ], + "style": { + "Option 1": null, + "Option 2": null, + "Option 3": null + }, + "isSorted": true, + "displayAsLabel": false, + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "default": "Option 1", + "tooltip": false, + "isCustom": true + } + ``` + Labels for the options can be updated in the Internationalization files (e.g., `custom/Espo/Custom/Resources/i18n/en_US/TestBaseEntity.json`) + + ## Text A multiline text with markdown support. @@ -104,20 +165,61 @@ Parameters: ![Text detail view](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/text-detail.png) +??? example "Example Text JSON Configuration (entityDefs)" + + ``` + "someTextFieldName": { + "type": "text", + "required": false, + "rowsMin": , + "cutHeight": , + "default": "Some default test text", + "maxLength": 255, + "seeMoreDisabled": false, + "rows": , + "displayRawText": false, + "readOnly": false, + "audited": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Date Date w/o time. Parameters: -* After (field) – a validation: a date value should be after a date value of a specified field; -* Before (field) – a validation: a date value should be before a date value of a specified field; +* After (field) – a validation: a date value should be after a date value of a specified field. See example below; +* Before (field) – a validation: a date value should be before a date value of a specified field. See example below; * Use Numeric Format – if not checked, then words 'today', 'yesterday', 'tomorrow' are in the detail view mode. +* Default - A Javascript function can be provided to this field. See example below. ![Date](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/date.png) ![Date detail view](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/date-detail.png) +??? example "Example Date JSON Configuration (entityDefs)" + + ``` + "someDateFieldName": { + "notNull": false, + "type": "date", + "required": false, + "default": "javascript: return this.dateTime.getDateShiftedFromToday(1, 'days');", + "after": "createdAt", + "before": "modifiedAt", + "useNumericFormat": false, + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Date-Time Date and time. @@ -133,6 +235,25 @@ Parameters: ![Date-Time detail view](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/date-time-detail.png) +??? example "Example Date-Time JSON Configuration (entityDefs)" + + ``` + "someDatetimeFieldName": { + "notNull": false, + "type": "datetime", + "required": false, + "after": "", + "before": "", + "useNumericFormat": false, + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "minuteStep": 30, + "tooltip": false, + "isCustom": true + } + ``` + ## Currency A currency value. A float number with a currency code. @@ -148,6 +269,24 @@ Parameters: ![Currency detail view](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/currency-detail.png) +??? example "Example Currency JSON Configuration (entityDefs)" + + ``` + "someCurrencyFieldName": { + "type": "currency", + "required": false, + "onlyDefaultCurrency": false, + "conversionDisabled": false, + "min": , + "max": , + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Int A whole number. @@ -158,6 +297,24 @@ Parameters: * Max – a validation: max acceptable value; if empty, then no validation applied; * Disable Formatting – if not checked, then a value is formatted with a thousand separator. +??? example "Example Integer JSON Configuration (entityDefs)" + + ``` + "someIntegerFieldName": { + "type": "int", + "required": false, + "default": , + "min": , + "max": , + "disableFormatting": false, + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Float @@ -169,6 +326,25 @@ Parameters: * Max – a validation: max acceptable value; if empty, then no validation applied; * Decimal Places – how many numbers of decimal part to display in read mode. +??? example "Example Float JSON Configuration (entityDefs)" + + ``` + "someFloatFieldName": { + "notNull": false, + "type": "float", + "required": false, + "default": , + "min": , + "max": , + "decimalPlaces": , + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Boolean @@ -176,6 +352,21 @@ A checkbox. Two possible values: true and false. ![Boolean](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/bool.png) +??? example "Example Boolean JSON Configuration (entityDefs)" + + ``` + "someBooleanFieldName": { + "notNull": true, + "type": "bool", + "default": false, + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Multi-Enum A list of values, multiple values can be selected. The list is ordered. @@ -194,6 +385,37 @@ Parameters: * Display as List – each value will be displayed in a new line; * Pattern – a regular expression to check a field value against. +??? example "Example Multi-Enum JSON Configuration (entityDefs)" + + ``` + "someMultiEnumFieldName": { + "type": "multiEnum", + "storeArrayValues": false, + "required": false, + "options": [ + "Option 1", + "Option 2", + "Option 3" + ], + "style": { + "Option 1": null, + "Option 2": null, + "Option 3": null + }, + "isSorted": false, + "allowCustomOptions": false, + "maxCount": , + "displayAsLabel": false, + "displayAsList": false, + "pattern": "$noBadCharacters", + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + Labels for the options can be updated in the Internationalization files (e.g., `custom/Espo/Custom/Resources/i18n/en_US/TestBaseEntity.json`) ## Checklist @@ -205,6 +427,29 @@ Parameters: * Is Sorted – to sort a list alphabetically; * Max Item Count – a validation: how many items can be checked; +??? example "Example Checklist JSON Configuration (entityDefs)" + + ``` + "someChecklistFieldName": { + "type": "checklist", + "storeArrayValues": true, + "required": false, + "options": [ + "Item 1", + "Item 2", + "Item 3", + "Item 4" + ], + "isSorted": false, + "maxCount": , + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + Labels for the options can be updated in the Internationalization files (e.g., `custom/Espo/Custom/Resources/i18n/en_US/TestBaseEntity.json`) ## Array @@ -220,12 +465,49 @@ Parameters: ![Array](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/array.png) +??? example "Example Array JSON Configuration (entityDefs)" + + ``` + "someArrayFieldName": { + "type": "array", + "storeArrayValues": true, + "required": false, + "noEmptyString": false, + "options": [ + "Option 1", + "Option 2", + "Option 3" + ], + "displayAsList": false, + "maxCount": , + "pattern": "$noBadCharacters", + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + Labels for the options can be updated in the Internationalization files (e.g., `custom/Espo/Custom/Resources/i18n/en_US/TestBaseEntity.json`) + ## Address An address with street, city, state, postal code and country. ![Address](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/address.png) +??? example "Example Address JSON Configuration (entityDefs)" + + ``` + "someAddressFieldName": { + "type": "address", + "viewMap": true, + "inlineEditDisabled": true, + "tooltip": true, + "isCustom": true + } + ``` + ## Url For storing links. @@ -235,6 +517,23 @@ Parameters: * Max-length – a max acceptable length of text; * Strip – if checked, then a protocol part and trailing `/` will be stripped. +??? example "Some Example URL Field (entityDefs)" + + ``` + "someUrlFieldName": { + "type": "url", + "required": false, + "default": "https://www.someurl.com", + "maxLength": 255, + "strip": false, + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Wysiwyg @@ -246,6 +545,25 @@ Parameters: * Min Height (px) – a min height of the field (in the edit view mode); * Use Iframe – if checked, then HTML will be placed into IFRAME element. +??? example "Example Wysiwyg JSON Configuration (entityDefs)" + + ``` + "someWysiwygFieldName": { + "type": "wysiwyg", + "required": false, + "default": "Some default text", + "height": , + "minHeight": , + "readOnly": false, + "useIframe": false, + "maxLength": , + "audited": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## File For file uploading. @@ -256,6 +574,42 @@ Parameters: * Max File Size (Mb) – a validation; * Accept – which file types can be accepted; see [info](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers) about file types. +??? example "Example File JSON Configuration (entityDefs)" + + ``` + "someFileName": { + "type": "file", + "required": false, + "sourceList": [ + "Document" + ], + "maxFileSize": , + "accept": [ + "image/*", + "audio/*", + "video/*", + ".zip", + ".pdf", + ".odt", + ".ods", + ".odp", + ".docx", + ".xlsx", + ".pptx", + ".doc", + ".xls", + ".ppt", + ".rtf", + ".csv", + ".md", + ".txt" + ], + "audited": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` ## Image @@ -266,6 +620,21 @@ Parameters: * Preview Size – defines a size of an image displayed on the detail/list view; * Max File Size (Mb) – a validation. +??? example "Example Image JSON Configuration (entityDefs)" + + ``` + "someImageField": { + "type": "image", + "required": false, + "previewSize": "small", + "maxFileSize": , + "audited": false, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Attachment-Multiple Allows to upload multiple files. @@ -277,6 +646,22 @@ Parameters: * Accept – which file types can be accepted; see [info](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Unique_file_type_specifiers) about file types; * Preview Size – defines a size of an image displayed on the detail/list view. +??? example "Example Attachment-Multiple JSON Configuration (entityDefs)" + + ``` + "someAttachmentMultipleName": { + "type": "attachmentMultiple", + "required": false, + "previewSize": "medium", + "sourceList": [], + "maxFileSize": , + "accept": [], + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Number An auto-incrementing number of string type with a possible prefix and specific length. @@ -289,10 +674,40 @@ Parameters: ![Number](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/images/administration/fields/number.png) +??? example "Example Auto-Incrementing Number JSON Configuration (entityDefs)" + + ``` + "someAutoIncrementNumberFieldName": { + "type": "number", + "len": , + "notNull": false, + "unique": false, + "nextNumber": , + "padLength": , + "prefix": "Some Prefix", + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Auto-increment A generated read-only auto-incrementing integer number. +??? example "Example Auto-increment JSON Configuration (entityDefs)" + + ``` + "someAutoIncrementFieldName": { + "type": "autoincrement", + "autoincrement": true, + "unique": true, + "inlineEditDisabled": false, + "tooltip": false, + "isCustom": true + } + ``` + ## Barcode A barcode. Can be printed to PDF. @@ -302,6 +717,22 @@ Parameters: * Code Type – a type of barcode; supported types: CODE128, CODE128A, CODE128B, CODE128C, EAN13, EAN8, EAN5, EAN2, UPC, UPCE, ITF14, pharmacode, QRcode; * Last Character – for EAN13 type, often is `>`. +??? example "Example Barcode JSON Configuration (entityDefs)" + + ``` + "someBarcodeFieldName": { + "type": "barcode", + "len": 255, + "required": false, + "lastChar": ">", + "readOnly": false, + "inlineEditDisabled": false, + "codeType": "CODE128", + "tooltip": false, + "isCustom": true + } + ``` + ## Foreign A field of a related record. Read-only. @@ -311,6 +742,39 @@ Parameters: * Link – defines where the field will be taken from. * Field – a field of a related record. +??? example "Example Foreign Field JSON Configuration (entityDefs)" + + ``` + "someForeignFieldName": { + "readOnly": true, + "type": "foreign", + "link": "", + "field": "", + "view": "views/fields/foreign-varchar", + "tooltip": false, + "isCustom": true + } + ``` + +## Iframe + +??? example "Example iFrame JSON Configuration (entityDefs)" + + ``` + "someTestIframeField": { + "type": "iframe", + "dynamicLogicVisible": null, + "dynamicLogicReadOnly": null, + "dynamicLogicInvalid": null, + "name": "someTestIframeField", + "label": "Some Test Iframe Field", + "inlineEditDisabled": false, + "tooltipText": "test", + "tooltip": false, + "isCustom": true + } + ``` + ## Email A set of email addresses with their parameters: *Opted-out*, *Invalid*, *Primary*. diff --git a/docs/development/entity.md b/docs/development/entity.md new file mode 100644 index 000000000..962df619c --- /dev/null +++ b/docs/development/entity.md @@ -0,0 +1,83 @@ +# Entities + +Entities are models that represent the data in your application. Fields are properties of the model that get stored in the database. + +By default, EspoCRM supports the following Entities: + +- [Base Entity](../entity/entity-base) +- [Entity Plus](../entity/entity-plus) - An Entity that includes Activities, Tasks, and History by default. +- [Event Entity](../entity/entity-event) - An Entity that has calendar properties, by default +- [Person Entity](../entity/entity-person) - An Entity with details for a person, including an attribute to manage personal data. +- [Company Entity](../entity/entity-company) - An Entity with details for a company or organization. + +## Entity Fields +Entities are made up of fields, which describe the entity's data and provide structure to the entity. The types of fields available are described [on the fields page](/administration/fields). + +These fields are organized into an [entityDefs](/development/metadata/entity-defs) file that, by default, is created at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourBaseEntityName}.json` when using the GUI to create the interface. + +When fields are updated via the GUI, updates are also stored in that file. + +If you are creating a module, then the best practice is to organize entities as modules. If you do that, the file should be created at `custom/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{YourBaseEntityName}.json` + +!!! note + If you create an Entity as a Module, but update it via the GUI, then the updates will write to `custom/Espo/Custom/Resources/metadata/entityDefs/{YourBaseEntityName}.json` AND NOT `custom/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{YourBaseEntityName}.json`. If you update via the GUI and want the updates in your module, then you will need to copy the data from the default file into your module file. + +!!! note + The system loads file data from `custom/Espo/Custom` _after_ `custom/Espo/Modules/`. If you define a field in entityDefs in your module and then update it via the GUI, the updates at `custom/Espo/Custom` will supercede your Module. + +## Labels + +While you define your schema in the entityDefs file of your Entity, the naming/labelling of those fields is managed in the Internationalization area of the application. + +For example, if I define somefield "someEnumFieldName" in entityDefs: + +``` +"someEnumFieldName": { + "type": "enum", + "options": [ + "Option 1", + "Option 2", + "Option 3" + ], + "style": { + "Option 1": null, + "Option 2": null, + "Option 3": null + }, + "isSorted": true, + "displayAsLabel": false, + "audited": false, + "readOnly": false, + "inlineEditDisabled": false, + "default": "Option 1", + "tooltip": false, + "isCustom": true +} +``` + +Then the labeling of that field name for the GUI will be managed at `custom/Espo/Custom/Resources/i18n/{someInID}/{SomeEntity}.json` + +For example, in the "en_US" language file, it might look something like this: + +`custom/Espo/Custom/Resources/i18n/en_US/SomeEntity.json` + +``` +{ + "fields": { + "someEnumFieldName": "Enum Field Name for the GUI" + }, + "tooltips": { + "someEnumFieldName": "This is the text for my tooltip" + }, + "options": { + "someEnumFieldName": { + "Option 1": "Option 1 Label for GUI", + "Option 2": "Option 2 Label for GUI", + "Option 3": "Option 3 Label for GUI", + } + } +} +``` + +When defining an Entity from the backend of the application, you need to keep this in mind as translations are not automatically defined for you. + diff --git a/docs/development/entity/entity-base.md b/docs/development/entity/entity-base.md new file mode 100644 index 000000000..9ab4cc1b1 --- /dev/null +++ b/docs/development/entity/entity-base.md @@ -0,0 +1,94 @@ +# Base Entity +The Base Entity refers to an Entity that doesn't have associations to Tasks, Activities, and/or History by default. If your entity needs those relationshps out of the box, refer to [Base Plus](../entity/entity-plus.md). + +Entity properties are defined in an entityDefs file. + +!!! note + + If you create the entity through the GUI, that file will reside at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourBaseEntityName}.json`. + + If you create it as part of a module, the path should be created at `custom/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{YourBaseEntityName}.json`. + +## Example entityDefs file +By default, creating a "Base Entity" from the Admin interface generates the following entityDefs file at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourBaseEntityName}.json`. + +``` +{ + "fields": { + "name": { + "type": "varchar", + "required": true, + "trim": true, + "pattern": "$noBadCharacters" + }, + "description": { + "type": "text" + }, + "createdAt": { + "type": "datetime", + "readOnly": true + }, + "modifiedAt": { + "type": "datetime", + "readOnly": true + }, + "createdBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "modifiedBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "assignedUser": { + "type": "link", + "required": true, + "view": "views/fields/assigned-user" + }, + "teams": { + "type": "linkMultiple", + "view": "views/fields/teams" + } + }, + "links": { + "createdBy": { + "type": "belongsTo", + "entity": "User" + }, + "modifiedBy": { + "type": "belongsTo", + "entity": "User" + }, + "assignedUser": { + "type": "belongsTo", + "entity": "User" + }, + "teams": { + "type": "hasMany", + "entity": "Team", + "relationName": "EntityTeam", + "layoutRelationshipsDisabled": true + } + }, + "collection": { + "orderBy": "createdAt", + "order": "desc" + }, + "indexes": { + "name": { + "columns": [ + "name", + "deleted" + ] + }, + "assignedUser": { + "columns": [ + "assignedUserId", + "deleted" + ] + } + } +} +``` \ No newline at end of file diff --git a/docs/development/entity/entity-company.md b/docs/development/entity/entity-company.md new file mode 100644 index 000000000..c757ce554 --- /dev/null +++ b/docs/development/entity/entity-company.md @@ -0,0 +1,176 @@ +# Company Entity +The Company Entity can be used to create a company or organization distinct from the default "Account" Entity that ships with EspoCRM. It includes address fields and links to Tasks, Meetings, Calls, and Emails (Activities & History) by default. + +!!! note + + If you create the entity through the GUI, that file will reside at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourCompanyEntityName}.json`. + + If you create it as part of a module, the path should be created at `custom/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{YourCompanyEntityName}.json`. + +## Example entityDefs file +By default, creating a "Base Entity" from the Admin interface generates the following entityDefs file at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourCompanyEntityName}.json`. + +``` +{ + "fields": { + "name": { + "type": "varchar", + "required": true, + "trim": true, + "pattern": "$noBadCharacters" + }, + "description": { + "type": "text" + }, + "website": { + "type": "url", + "strip": true + }, + "emailAddress": { + "type": "email" + }, + "phoneNumber": { + "type": "phone", + "typeList": [ + "Office", + "Mobile", + "Fax", + "Other" + ], + "defaultType": "Office" + }, + "billingAddress": { + "type": "address" + }, + "billingAddressStreet": { + "type": "text", + "maxLength": 255, + "dbType": "varchar" + }, + "billingAddressCity": { + "type": "varchar", + "trim": true + }, + "billingAddressState": { + "type": "varchar", + "trim": true + }, + "billingAddressCountry": { + "type": "varchar", + "trim": true + }, + "billingAddressPostalCode": { + "type": "varchar", + "trim": true + }, + "shippingAddress": { + "type": "address", + "view": "crm:views/account/fields/shipping-address" + }, + "shippingAddressStreet": { + "type": "text", + "maxLength": 255, + "dbType": "varchar" + }, + "shippingAddressCity": { + "type": "varchar", + "trim": true + }, + "shippingAddressState": { + "type": "varchar", + "trim": true + }, + "shippingAddressCountry": { + "type": "varchar", + "trim": true + }, + "shippingAddressPostalCode": { + "type": "varchar", + "trim": true + }, + "createdAt": { + "type": "datetime", + "readOnly": true + }, + "modifiedAt": { + "type": "datetime", + "readOnly": true + }, + "createdBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "modifiedBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "assignedUser": { + "type": "link", + "required": false, + "view": "views/fields/assigned-user" + }, + "teams": { + "type": "linkMultiple", + "view": "views/fields/teams" + } + }, + "links": { + "createdBy": { + "type": "belongsTo", + "entity": "User" + }, + "modifiedBy": { + "type": "belongsTo", + "entity": "User" + }, + "assignedUser": { + "type": "belongsTo", + "entity": "User" + }, + "teams": { + "type": "hasMany", + "entity": "Team", + "relationName": "EntityTeam", + "layoutRelationshipsDisabled": true + }, + "meetings": { + "type": "hasMany", + "entity": "Meeting", + "foreign": "parent", + "layoutRelationshipsDisabled": true + }, + "calls": { + "type": "hasMany", + "entity": "Call", + "foreign": "parent", + "layoutRelationshipsDisabled": true + }, + "tasks": { + "type": "hasChildren", + "entity": "Task", + "foreign": "parent", + "layoutRelationshipsDisabled": true + } + }, + "collection": { + "orderBy": "createdAt", + "order": "desc" + }, + "indexes": { + "name": { + "columns": [ + "name", + "deleted" + ] + }, + "assignedUser": { + "columns": [ + "assignedUserId", + "deleted" + ] + } + } +} +``` \ No newline at end of file diff --git a/docs/development/entity/entity-event.md b/docs/development/entity/entity-event.md new file mode 100644 index 000000000..e22ed0f99 --- /dev/null +++ b/docs/development/entity/entity-event.md @@ -0,0 +1,187 @@ +# Event Entity + +!!! note + + If you create the entity through the GUI, that file will reside at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourEventEntityName}.json`. + + If you create it as part of a module, the path should be created at `custom/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{YourEventEntityName}.json`. + +## Example entityDefs file +By default, creating a "Base Entity" from the Admin interface generates the following entityDefs file at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourEventEntityName}.json`. + +``` +{ + "fields": { + "name": { + "type": "varchar", + "required": true, + "trim": true, + "pattern": "$noBadCharacters" + }, + "status": { + "type": "enum", + "options": [ + "Planned", + "Held", + "Not Held" + ], + "default": "Planned", + "style": { + "Held": "success" + }, + "audited": true + }, + "dateStart": { + "type": "datetimeOptional", + "view": "crm:views/meeting/fields/date-start", + "required": true, + "default": "javascript: return this.dateTime.getNow(15);", + "audited": true + }, + "dateEnd": { + "type": "datetimeOptional", + "view": "crm:views/meeting/fields/date-end", + "required": true, + "after": "dateStart" + }, + "isAllDay": { + "type": "bool", + "layoutListDisabled": true, + "layoutDetailDisabled": true, + "layoutMassUpdateDisabled": true + }, + "duration": { + "type": "duration", + "start": "dateStart", + "end": "dateEnd", + "options": [ + 300, + 600, + 900, + 1800, + 2700, + 3600, + 7200, + 10800 + ], + "default": 300, + "notStorable": true, + "select": { + "select": "TIMESTAMPDIFF_SECOND:(dateStart, dateEnd)" + }, + "order": { + "order": [ + [ + "TIMESTAMPDIFF_SECOND:(dateStart, dateEnd)", + "{direction}" + ] + ] + } + }, + "parent": { + "type": "linkParent", + "entityList": [ + "Account", + "Lead", + "Contact" + ] + }, + "description": { + "type": "text" + }, + "reminders": { + "type": "jsonArray", + "notStorable": true, + "view": "crm:views/meeting/fields/reminders", + "layoutListDisabled": true + }, + "createdAt": { + "type": "datetime", + "readOnly": true + }, + "modifiedAt": { + "type": "datetime", + "readOnly": true + }, + "createdBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "modifiedBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "assignedUser": { + "type": "link", + "required": false, + "view": "views/fields/assigned-user" + }, + "teams": { + "type": "linkMultiple", + "view": "views/fields/teams" + } + }, + "links": { + "parent": { + "type": "belongsToParent", + "foreign": "testEntityEventChildren" + }, + "createdBy": { + "type": "belongsTo", + "entity": "User" + }, + "modifiedBy": { + "type": "belongsTo", + "entity": "User" + }, + "assignedUser": { + "type": "belongsTo", + "entity": "User" + }, + "teams": { + "type": "hasMany", + "entity": "Team", + "relationName": "EntityTeam", + "layoutRelationshipsDisabled": true + } + }, + "collection": { + "orderBy": "dateStart", + "order": "desc" + }, + "indexes": { + "dateStartStatus": { + "columns": [ + "dateStart", + "status" + ] + }, + "dateStart": { + "columns": [ + "dateStart", + "deleted" + ] + }, + "status": { + "columns": [ + "status", + "deleted" + ] + }, + "assignedUser": { + "columns": [ + "assignedUserId", + "deleted" + ] + }, + "assignedUserStatus": { + "columns": [ + "assignedUserId", + "status" + ] + } + } +} +``` \ No newline at end of file diff --git a/docs/development/entity/entity-person.md b/docs/development/entity/entity-person.md new file mode 100644 index 000000000..116f33f6f --- /dev/null +++ b/docs/development/entity/entity-person.md @@ -0,0 +1,176 @@ +# Person Entity +The Person Entity has properties specific to an individual including salutation, name fields, and salutation. By default, it includes links to "Call," "Email," and "Meeting" entities (Activities) for tracking communication. It also, by default, includes a link to the Task Entity. + +!!! note + + If you create the entity through the GUI, that file will reside at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourPersonEntityName}.json`. + + If you create it as part of a module, the path should be created at `custom/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{YourPersonEntityName}.json`. + +## Example entityDefs file +By default, creating a "Base Entity" from the Admin interface generates the following entityDefs file at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourPersonEntityName}.json`. + +``` +{ + "fields": { + "name": { + "type": "personName", + "isPersonalData": true + }, + "salutationName": { + "type": "enum", + "options": [ + "", + "Mr.", + "Ms.", + "Mrs.", + "Dr." + ] + }, + "firstName": { + "type": "varchar", + "maxLength": 100, + "trim": true + }, + "lastName": { + "type": "varchar", + "maxLength": 100, + "required": true, + "trim": true + }, + "description": { + "type": "text" + }, + "emailAddress": { + "type": "email", + "isPersonalData": true + }, + "phoneNumber": { + "type": "phone", + "typeList": [ + "Mobile", + "Office", + "Home", + "Fax", + "Other" + ], + "defaultType": "Mobile", + "isPersonalData": true + }, + "address": { + "type": "address", + "isPersonalData": true + }, + "addressStreet": { + "type": "text", + "maxLength": 255, + "dbType": "varchar" + }, + "addressCity": { + "type": "varchar", + "trim": true + }, + "addressState": { + "type": "varchar", + "trim": true + }, + "addressCountry": { + "type": "varchar", + "trim": true + }, + "addressPostalCode": { + "type": "varchar", + "trim": true + }, + "createdAt": { + "type": "datetime", + "readOnly": true + }, + "modifiedAt": { + "type": "datetime", + "readOnly": true + }, + "createdBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "modifiedBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "assignedUser": { + "type": "link", + "required": false, + "view": "views/fields/assigned-user" + }, + "teams": { + "type": "linkMultiple", + "view": "views/fields/teams" + } + }, + "links": { + "createdBy": { + "type": "belongsTo", + "entity": "User" + }, + "modifiedBy": { + "type": "belongsTo", + "entity": "User" + }, + "assignedUser": { + "type": "belongsTo", + "entity": "User" + }, + "teams": { + "type": "hasMany", + "entity": "Team", + "relationName": "EntityTeam", + "layoutRelationshipsDisabled": true + }, + "meetings": { + "type": "hasMany", + "entity": "Meeting", + "foreign": "parent", + "layoutRelationshipsDisabled": true + }, + "calls": { + "type": "hasMany", + "entity": "Call", + "foreign": "parent", + "layoutRelationshipsDisabled": true + }, + "tasks": { + "type": "hasChildren", + "entity": "Task", + "foreign": "parent", + "layoutRelationshipsDisabled": true + } + }, + "collection": { + "orderBy": "createdAt", + "order": "desc" + }, + "indexes": { + "firstName": { + "columns": [ + "firstName", + "deleted" + ] + }, + "name": { + "columns": [ + "firstName", + "lastName" + ] + }, + "assignedUser": { + "columns": [ + "assignedUserId", + "deleted" + ] + } + } +} +``` \ No newline at end of file diff --git a/docs/development/entity/entity-plus.md b/docs/development/entity/entity-plus.md new file mode 100644 index 000000000..d153abfb9 --- /dev/null +++ b/docs/development/entity/entity-plus.md @@ -0,0 +1,124 @@ +# Base Plus Entity + +The Base Plus Entity refers to an Entity that has associations to Tasks, Activities, and History by default. If your entity doesn't need those relationshps out of the box, refer to [Base Entity](../entity/entity-base.md). + +Entity properties are defined in an entityDefs file. + +!!! note + + If you create the entity through the GUI, that file will reside at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourBaseEntityPlusName}.json`. + + If you create it as part of a module, the path should be created at `custom/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{YourBaseEntityPlusName}.json`. + +## Example entityDefs file +By default, creating a "Base Entity" from the Admin interface generates the following entityDefs file at `custom/Espo/Custom/Resources/metadata/entityDefs/{YourBaseEntityPlusName}.json`. + +!!! note + + Note the additional fields in the "links" object. This is where the references to the Task, Meeting, Calls, and Email entities (e.g., Activities & History) are stored. + + +``` +{ + "fields": { + "name": { + "type": "varchar", + "required": true, + "trim": true, + "pattern": "$noBadCharacters" + }, + "description": { + "type": "text" + }, + "createdAt": { + "type": "datetime", + "readOnly": true + }, + "modifiedAt": { + "type": "datetime", + "readOnly": true + }, + "createdBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "modifiedBy": { + "type": "link", + "readOnly": true, + "view": "views/fields/user" + }, + "assignedUser": { + "type": "link", + "required": true, + "view": "views/fields/assigned-user" + }, + "teams": { + "type": "linkMultiple", + "view": "views/fields/teams" + } + }, + "links": { + "createdBy": { + "type": "belongsTo", + "entity": "User" + }, + "modifiedBy": { + "type": "belongsTo", + "entity": "User" + }, + "assignedUser": { + "type": "belongsTo", + "entity": "User" + }, + "teams": { + "type": "hasMany", + "entity": "Team", + "relationName": "EntityTeam", + "layoutRelationshipsDisabled": true + }, + "meetings": { + "type": "hasMany", + "entity": "Meeting", + "foreign": "parent", + "layoutRelationshipsDisabled": true + }, + "calls": { + "type": "hasMany", + "entity": "Call", + "foreign": "parent", + "layoutRelationshipsDisabled": true + }, + "tasks": { + "type": "hasChildren", + "entity": "Task", + "foreign": "parent", + "layoutRelationshipsDisabled": true + }, + "emails": { + "type": "hasChildren", + "entity": "Email", + "foreign": "parent", + "layoutRelationshipsDisabled": true + } + }, + "collection": { + "orderBy": "createdAt", + "order": "desc" + }, + "indexes": { + "name": { + "columns": [ + "name", + "deleted" + ] + }, + "assignedUser": { + "columns": [ + "assignedUserId", + "deleted" + ] + } + } +} +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index c7c074d50..679a6df89 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,6 +9,9 @@ extra_css: markdown_extensions: - mdx_truly_sane_lists + - admonition + - pymdownx.details + - pymdownx.superfences - codehilite: guess_lang: false use_pygments: true @@ -22,6 +25,8 @@ theme: palette: primary: blue grey accent: blue grey + features: + - content.code.copy nav: - 'Home': 'index.md' @@ -163,6 +168,13 @@ nav: - 'Translation': 'development/translation.md' - 'Coding rules': 'development/coding-rules.md' - 'Backend': + - 'Entities': + - 'Types of Entities': 'development/entity.md' + - 'Base Entity': 'development/entity/base-entity.md' + - 'Entity Plus': 'development/entity/entity-plus.md' + - 'Event Entity': 'development/entity/entity-event.md' + - 'Person Entity': 'development/entity/entity-person.md' + - 'Company Entity': 'development/entity/entity-company.md' - 'API': 'development/api.md' - 'Dependency injection': 'development/di.md' - 'Metadata': 'development/metadata.md'