diff --git a/.gitignore b/.gitignore
index ccbfadbd8..bb701bd71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-site/
\ No newline at end of file
+site/
+.venv
+.idea
diff --git a/docs/_static/images/administration/bpm/event-end-compensation-1.png b/docs/_static/images/administration/bpm/event-end-compensation-1.png
new file mode 100644
index 000000000..4d6808b3a
Binary files /dev/null and b/docs/_static/images/administration/bpm/event-end-compensation-1.png differ
diff --git a/docs/_static/images/administration/bpm/event-end-compensation-2.png b/docs/_static/images/administration/bpm/event-end-compensation-2.png
new file mode 100644
index 000000000..5e50b8f94
Binary files /dev/null and b/docs/_static/images/administration/bpm/event-end-compensation-2.png differ
diff --git a/docs/_static/images/administration/bpm/event-intermediate-compensation-boundary.png b/docs/_static/images/administration/bpm/event-intermediate-compensation-boundary.png
new file mode 100644
index 000000000..1ec5a9bd7
Binary files /dev/null and b/docs/_static/images/administration/bpm/event-intermediate-compensation-boundary.png differ
diff --git a/docs/_static/images/administration/bpm/event-intermediate-compensation.png b/docs/_static/images/administration/bpm/event-intermediate-compensation.png
new file mode 100644
index 000000000..1589c4dd1
Binary files /dev/null and b/docs/_static/images/administration/bpm/event-intermediate-compensation.png differ
diff --git a/docs/_static/images/administration/bpm/event-start-compensation.png b/docs/_static/images/administration/bpm/event-start-compensation.png
new file mode 100644
index 000000000..62428938b
Binary files /dev/null and b/docs/_static/images/administration/bpm/event-start-compensation.png differ
diff --git a/docs/_static/images/administration/currency-settings.png b/docs/_static/images/administration/currency-settings.png
deleted file mode 100644
index c38fe42bd..000000000
Binary files a/docs/_static/images/administration/currency-settings.png and /dev/null differ
diff --git a/docs/_static/images/administration/iis/actions.png b/docs/_static/images/administration/iis/actions.png
new file mode 100644
index 000000000..74fdce420
Binary files /dev/null and b/docs/_static/images/administration/iis/actions.png differ
diff --git a/docs/_static/images/administration/iis/conditions.png b/docs/_static/images/administration/iis/conditions.png
new file mode 100644
index 000000000..01eedfd36
Binary files /dev/null and b/docs/_static/images/administration/iis/conditions.png differ
diff --git a/docs/_static/images/administration/iis/confirmation.png b/docs/_static/images/administration/iis/confirmation.png
new file mode 100644
index 000000000..fa490c82a
Binary files /dev/null and b/docs/_static/images/administration/iis/confirmation.png differ
diff --git a/docs/_static/images/administration/iis/edit-module.png b/docs/_static/images/administration/iis/edit-module.png
new file mode 100644
index 000000000..5c9241260
Binary files /dev/null and b/docs/_static/images/administration/iis/edit-module.png differ
diff --git a/docs/_static/images/administration/iis/fast-cgi.png b/docs/_static/images/administration/iis/fast-cgi.png
new file mode 100644
index 000000000..21ca4de68
Binary files /dev/null and b/docs/_static/images/administration/iis/fast-cgi.png differ
diff --git a/docs/_static/images/administration/iis/general.png b/docs/_static/images/administration/iis/general.png
new file mode 100644
index 000000000..d01a2b183
Binary files /dev/null and b/docs/_static/images/administration/iis/general.png differ
diff --git a/docs/_static/images/administration/iis/handler-mappings.png b/docs/_static/images/administration/iis/handler-mappings.png
new file mode 100644
index 000000000..4f9ca2672
Binary files /dev/null and b/docs/_static/images/administration/iis/handler-mappings.png differ
diff --git a/docs/_static/images/administration/iis/iis-manager.png b/docs/_static/images/administration/iis/iis-manager.png
new file mode 100644
index 000000000..35b35d8b7
Binary files /dev/null and b/docs/_static/images/administration/iis/iis-manager.png differ
diff --git a/docs/_static/images/administration/iis/permissions.png b/docs/_static/images/administration/iis/permissions.png
new file mode 100644
index 000000000..f00fb376b
Binary files /dev/null and b/docs/_static/images/administration/iis/permissions.png differ
diff --git a/docs/_static/images/administration/iis/physical-path-2.png b/docs/_static/images/administration/iis/physical-path-2.png
new file mode 100644
index 000000000..1d2cbfe01
Binary files /dev/null and b/docs/_static/images/administration/iis/physical-path-2.png differ
diff --git a/docs/_static/images/administration/iis/physical-path.png b/docs/_static/images/administration/iis/physical-path.png
new file mode 100644
index 000000000..f194821c7
Binary files /dev/null and b/docs/_static/images/administration/iis/physical-path.png differ
diff --git a/docs/_static/images/administration/iis/settings.png b/docs/_static/images/administration/iis/settings.png
new file mode 100644
index 000000000..3772e83d2
Binary files /dev/null and b/docs/_static/images/administration/iis/settings.png differ
diff --git a/docs/_static/images/administration/iis/triggers.png b/docs/_static/images/administration/iis/triggers.png
new file mode 100644
index 000000000..63ad4b15b
Binary files /dev/null and b/docs/_static/images/administration/iis/triggers.png differ
diff --git a/docs/_static/images/administration/iis/verbs.png b/docs/_static/images/administration/iis/verbs.png
new file mode 100644
index 000000000..76b7d350f
Binary files /dev/null and b/docs/_static/images/administration/iis/verbs.png differ
diff --git a/docs/_static/images/administration/iis/virtual-path-2.png b/docs/_static/images/administration/iis/virtual-path-2.png
new file mode 100644
index 000000000..c0050e782
Binary files /dev/null and b/docs/_static/images/administration/iis/virtual-path-2.png differ
diff --git a/docs/_static/images/administration/iis/virtual-path.png b/docs/_static/images/administration/iis/virtual-path.png
new file mode 100644
index 000000000..64b4002dd
Binary files /dev/null and b/docs/_static/images/administration/iis/virtual-path.png differ
diff --git a/docs/_static/images/administration/import/step-1.png b/docs/_static/images/administration/import/step-1.png
index 214da8090..2eac88604 100644
Binary files a/docs/_static/images/administration/import/step-1.png and b/docs/_static/images/administration/import/step-1.png differ
diff --git a/docs/_static/images/administration/import/step-2.png b/docs/_static/images/administration/import/step-2.png
index a1599b772..81ff37de5 100644
Binary files a/docs/_static/images/administration/import/step-2.png and b/docs/_static/images/administration/import/step-2.png differ
diff --git a/docs/_static/images/administration/installation/2.png b/docs/_static/images/administration/installation/2.png
index d09147e61..8424a79ec 100644
Binary files a/docs/_static/images/administration/installation/2.png and b/docs/_static/images/administration/installation/2.png differ
diff --git a/docs/_static/images/administration/ldap-authorization/ldap-configuration-for-ad.png b/docs/_static/images/administration/ldap-authorization/ldap-configuration-for-ad.png
index e8d55a0ce..9e0b9ca6a 100644
Binary files a/docs/_static/images/administration/ldap-authorization/ldap-configuration-for-ad.png and b/docs/_static/images/administration/ldap-authorization/ldap-configuration-for-ad.png differ
diff --git a/docs/_static/images/administration/ldap-authorization/ldap-configuration-for-openldap.png b/docs/_static/images/administration/ldap-authorization/ldap-configuration-for-openldap.png
deleted file mode 100644
index 65edc63e5..000000000
Binary files a/docs/_static/images/administration/ldap-authorization/ldap-configuration-for-openldap.png and /dev/null differ
diff --git a/docs/_static/images/administration/ldap-authorization/ldap-configuration.png b/docs/_static/images/administration/ldap-authorization/ldap-configuration.png
index e8d55a0ce..406e59cd7 100644
Binary files a/docs/_static/images/administration/ldap-authorization/ldap-configuration.png and b/docs/_static/images/administration/ldap-authorization/ldap-configuration.png differ
diff --git a/docs/_static/images/administration/passwords/login-form.png b/docs/_static/images/administration/passwords/login-form.png
new file mode 100644
index 000000000..7d3bdd363
Binary files /dev/null and b/docs/_static/images/administration/passwords/login-form.png differ
diff --git a/docs/_static/images/administration/passwords/user-menu.png b/docs/_static/images/administration/passwords/user-menu.png
new file mode 100644
index 000000000..1916bd5fc
Binary files /dev/null and b/docs/_static/images/administration/passwords/user-menu.png differ
diff --git a/docs/_static/images/administration/phone-numbers/phone-numbers.png b/docs/_static/images/administration/phone-numbers/phone-numbers.png
new file mode 100644
index 000000000..6af97a2f6
Binary files /dev/null and b/docs/_static/images/administration/phone-numbers/phone-numbers.png differ
diff --git a/docs/_static/images/extensions/google-integration/calendar-params.png b/docs/_static/images/extensions/google-integration/calendar-params.png
index c6e1bb8f2..3279a33a9 100644
Binary files a/docs/_static/images/extensions/google-integration/calendar-params.png and b/docs/_static/images/extensions/google-integration/calendar-params.png differ
diff --git a/docs/_static/images/extensions/google-integration/setting-up/3.png b/docs/_static/images/extensions/google-integration/setting-up/3.png
index 3fe3e5eae..9d04e6647 100644
Binary files a/docs/_static/images/extensions/google-integration/setting-up/3.png and b/docs/_static/images/extensions/google-integration/setting-up/3.png differ
diff --git a/docs/_static/images/extensions/google-integration/setting-up/3a.png b/docs/_static/images/extensions/google-integration/setting-up/3a.png
new file mode 100644
index 000000000..e3d2bc907
Binary files /dev/null and b/docs/_static/images/extensions/google-integration/setting-up/3a.png differ
diff --git a/docs/_static/images/extensions/google-integration/setting-up/3b.png b/docs/_static/images/extensions/google-integration/setting-up/3b.png
new file mode 100644
index 000000000..add727ef6
Binary files /dev/null and b/docs/_static/images/extensions/google-integration/setting-up/3b.png differ
diff --git a/docs/_static/images/extensions/google-integration/setting-up/4.png b/docs/_static/images/extensions/google-integration/setting-up/4.png
index ad7b85819..7ac763954 100644
Binary files a/docs/_static/images/extensions/google-integration/setting-up/4.png and b/docs/_static/images/extensions/google-integration/setting-up/4.png differ
diff --git a/docs/_static/images/extensions/google-integration/setting-up/5.png b/docs/_static/images/extensions/google-integration/setting-up/5.png
index d56b03eb7..ad7b85819 100644
Binary files a/docs/_static/images/extensions/google-integration/setting-up/5.png and b/docs/_static/images/extensions/google-integration/setting-up/5.png differ
diff --git a/docs/_static/images/extensions/google-integration/setting-up/5a.png b/docs/_static/images/extensions/google-integration/setting-up/5a.png
new file mode 100644
index 000000000..d56b03eb7
Binary files /dev/null and b/docs/_static/images/extensions/google-integration/setting-up/5a.png differ
diff --git a/docs/_static/images/extensions/outlook-integration/setting-up/1.png b/docs/_static/images/extensions/outlook-integration/setting-up/1.png
index ebffabee0..167dd9b75 100644
Binary files a/docs/_static/images/extensions/outlook-integration/setting-up/1.png and b/docs/_static/images/extensions/outlook-integration/setting-up/1.png differ
diff --git a/docs/_static/images/extensions/outlook-integration/setting-up/5.png b/docs/_static/images/extensions/outlook-integration/setting-up/5.png
index 3adc0a958..913beac9e 100644
Binary files a/docs/_static/images/extensions/outlook-integration/setting-up/5.png and b/docs/_static/images/extensions/outlook-integration/setting-up/5.png differ
diff --git a/docs/_static/images/extensions/outlook-integration/setting-up/9.png b/docs/_static/images/extensions/outlook-integration/setting-up/9.png
index e64a2431c..53be1406b 100644
Binary files a/docs/_static/images/extensions/outlook-integration/setting-up/9.png and b/docs/_static/images/extensions/outlook-integration/setting-up/9.png differ
diff --git a/docs/_static/images/extensions/project-management/board.png b/docs/_static/images/extensions/project-management/board.png
new file mode 100644
index 000000000..b82bea570
Binary files /dev/null and b/docs/_static/images/extensions/project-management/board.png differ
diff --git a/docs/_static/images/extensions/project-management/gantt.png b/docs/_static/images/extensions/project-management/gantt.png
new file mode 100644
index 000000000..ffdc77884
Binary files /dev/null and b/docs/_static/images/extensions/project-management/gantt.png differ
diff --git a/docs/_static/images/extensions/project-management/plan.png b/docs/_static/images/extensions/project-management/plan.png
new file mode 100644
index 000000000..0e9c8b80f
Binary files /dev/null and b/docs/_static/images/extensions/project-management/plan.png differ
diff --git a/docs/_static/images/extensions/project-management/project.png b/docs/_static/images/extensions/project-management/project.png
new file mode 100644
index 000000000..b59eb8468
Binary files /dev/null and b/docs/_static/images/extensions/project-management/project.png differ
diff --git a/docs/_static/images/extensions/sales-pack/price-rule.png b/docs/_static/images/extensions/sales-pack/price-rule.png
new file mode 100644
index 000000000..494ce3c83
Binary files /dev/null and b/docs/_static/images/extensions/sales-pack/price-rule.png differ
diff --git a/docs/_static/images/extensions/voip-integration/3cx-admin-setup.png b/docs/_static/images/extensions/voip-integration/3cx-admin-setup.png
new file mode 100644
index 000000000..376044bbc
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/3cx-admin-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/3cx-admin-update.png b/docs/_static/images/extensions/voip-integration/3cx-admin-update.png
new file mode 100644
index 000000000..e23c74fe8
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/3cx-admin-update.png differ
diff --git a/docs/_static/images/extensions/voip-integration/3cx-integrations-crm.png b/docs/_static/images/extensions/voip-integration/3cx-integrations-crm.png
new file mode 100644
index 000000000..5f3354711
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/3cx-integrations-crm.png differ
diff --git a/docs/_static/images/extensions/voip-integration/3cx-user-settings.png b/docs/_static/images/extensions/voip-integration/3cx-user-settings.png
new file mode 100644
index 000000000..d082a57a2
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/3cx-user-settings.png differ
diff --git a/docs/_static/images/extensions/voip-integration/asterisk-additional-numbers.png b/docs/_static/images/extensions/voip-integration/asterisk-additional-numbers.png
index f521b969a..4d144177d 100644
Binary files a/docs/_static/images/extensions/voip-integration/asterisk-additional-numbers.png and b/docs/_static/images/extensions/voip-integration/asterisk-additional-numbers.png differ
diff --git a/docs/_static/images/extensions/voip-integration/asterisk-admin-setup.png b/docs/_static/images/extensions/voip-integration/asterisk-admin-setup.png
index 42e8f77b0..b3e2c3e05 100644
Binary files a/docs/_static/images/extensions/voip-integration/asterisk-admin-setup.png and b/docs/_static/images/extensions/voip-integration/asterisk-admin-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/asterisk-user-setup.png b/docs/_static/images/extensions/voip-integration/asterisk-user-setup.png
index 5bd2edbc3..134866662 100644
Binary files a/docs/_static/images/extensions/voip-integration/asterisk-user-setup.png and b/docs/_static/images/extensions/voip-integration/asterisk-user-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/binotel-admin-setup.png b/docs/_static/images/extensions/voip-integration/binotel-admin-setup.png
index e7cca524a..b6b8df57c 100644
Binary files a/docs/_static/images/extensions/voip-integration/binotel-admin-setup.png and b/docs/_static/images/extensions/voip-integration/binotel-admin-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/binotel-user-setup.png b/docs/_static/images/extensions/voip-integration/binotel-user-setup.png
index ed627a1c7..5dbdb7c69 100644
Binary files a/docs/_static/images/extensions/voip-integration/binotel-user-setup.png and b/docs/_static/images/extensions/voip-integration/binotel-user-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/call-recording.png b/docs/_static/images/extensions/voip-integration/call-recording.png
index e7188f254..e69313042 100644
Binary files a/docs/_static/images/extensions/voip-integration/call-recording.png and b/docs/_static/images/extensions/voip-integration/call-recording.png differ
diff --git a/docs/_static/images/extensions/voip-integration/iexpbx-admin-setup.png b/docs/_static/images/extensions/voip-integration/iexpbx-admin-setup.png
new file mode 100644
index 000000000..046625d9c
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/iexpbx-admin-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/iexpbx-call-event-webhook.png b/docs/_static/images/extensions/voip-integration/iexpbx-call-event-webhook.png
new file mode 100644
index 000000000..94fe75d9b
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/iexpbx-call-event-webhook.png differ
diff --git a/docs/_static/images/extensions/voip-integration/iexpbx-call-status-webhook.png b/docs/_static/images/extensions/voip-integration/iexpbx-call-status-webhook.png
new file mode 100644
index 000000000..81207f5c0
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/iexpbx-call-status-webhook.png differ
diff --git a/docs/_static/images/extensions/voip-integration/iexpbx-user-settings.png b/docs/_static/images/extensions/voip-integration/iexpbx-user-settings.png
new file mode 100644
index 000000000..48db6a4e7
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/iexpbx-user-settings.png differ
diff --git a/docs/_static/images/extensions/voip-integration/message-tab.png b/docs/_static/images/extensions/voip-integration/message-tab.png
index 045808ccb..36f46aae0 100644
Binary files a/docs/_static/images/extensions/voip-integration/message-tab.png and b/docs/_static/images/extensions/voip-integration/message-tab.png differ
diff --git a/docs/_static/images/extensions/voip-integration/starface-admin-setup.png b/docs/_static/images/extensions/voip-integration/starface-admin-setup.png
index 309bdc80e..732cf50e8 100644
Binary files a/docs/_static/images/extensions/voip-integration/starface-admin-setup.png and b/docs/_static/images/extensions/voip-integration/starface-admin-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/starface-user-settings.png b/docs/_static/images/extensions/voip-integration/starface-user-settings.png
index 6138406ba..7e14eacaa 100644
Binary files a/docs/_static/images/extensions/voip-integration/starface-user-settings.png and b/docs/_static/images/extensions/voip-integration/starface-user-settings.png differ
diff --git a/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-1.png b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-1.png
new file mode 100644
index 000000000..8aad48f0a
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-1.png differ
diff --git a/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-2.png b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-2.png
new file mode 100644
index 000000000..7241b41af
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-2.png differ
diff --git a/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-3.png b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-3.png
new file mode 100644
index 000000000..39cd3cbf6
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-3.png differ
diff --git a/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-4.png b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-4.png
new file mode 100644
index 000000000..2a4d5b2d4
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/troubleshooting-click-to-call-4.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-admin-setup.png b/docs/_static/images/extensions/voip-integration/twilio-admin-setup.png
index 30d50e31a..4e8f50546 100644
Binary files a/docs/_static/images/extensions/voip-integration/twilio-admin-setup.png and b/docs/_static/images/extensions/voip-integration/twilio-admin-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-dashlet.png b/docs/_static/images/extensions/voip-integration/twilio-dashlet.png
index cc3dae587..e1cfc08dc 100644
Binary files a/docs/_static/images/extensions/voip-integration/twilio-dashlet.png and b/docs/_static/images/extensions/voip-integration/twilio-dashlet.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-messaging.png b/docs/_static/images/extensions/voip-integration/twilio-messaging.png
new file mode 100644
index 000000000..b322e2221
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/twilio-messaging.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-role.png b/docs/_static/images/extensions/voip-integration/twilio-role.png
index 7c6f7e19e..72c25616b 100644
Binary files a/docs/_static/images/extensions/voip-integration/twilio-role.png and b/docs/_static/images/extensions/voip-integration/twilio-role.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-routing.png b/docs/_static/images/extensions/voip-integration/twilio-routing.png
index 88fc3a467..1f3ea82e1 100644
Binary files a/docs/_static/images/extensions/voip-integration/twilio-routing.png and b/docs/_static/images/extensions/voip-integration/twilio-routing.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-user-phone.png b/docs/_static/images/extensions/voip-integration/twilio-user-phone.png
index bffc5f3b4..f5fb5bb4a 100644
Binary files a/docs/_static/images/extensions/voip-integration/twilio-user-phone.png and b/docs/_static/images/extensions/voip-integration/twilio-user-phone.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-user-setup.png b/docs/_static/images/extensions/voip-integration/twilio-user-setup.png
index 1d6882316..2d860f938 100644
Binary files a/docs/_static/images/extensions/voip-integration/twilio-user-setup.png and b/docs/_static/images/extensions/voip-integration/twilio-user-setup.png differ
diff --git a/docs/_static/images/extensions/voip-integration/twilio-voice-and-fax.png b/docs/_static/images/extensions/voip-integration/twilio-voice-and-fax.png
new file mode 100644
index 000000000..1a8c3ba9c
Binary files /dev/null and b/docs/_static/images/extensions/voip-integration/twilio-voice-and-fax.png differ
diff --git a/docs/_static/images/user-guide/imap-smtp-configuration/5.png b/docs/_static/images/user-guide/imap-smtp-configuration/5.png
deleted file mode 100644
index baca973fc..000000000
Binary files a/docs/_static/images/user-guide/imap-smtp-configuration/5.png and /dev/null differ
diff --git a/docs/_static/images/user-guide/products/categories.png b/docs/_static/images/user-guide/products/categories.png
new file mode 100644
index 000000000..83d477ffa
Binary files /dev/null and b/docs/_static/images/user-guide/products/categories.png differ
diff --git a/docs/_static/images/user-guide/products/products.png b/docs/_static/images/user-guide/products/products.png
index 9ed527d2a..50bbdf9c7 100644
Binary files a/docs/_static/images/user-guide/products/products.png and b/docs/_static/images/user-guide/products/products.png differ
diff --git a/docs/_static/images/user-guide/reports/dashlet-totals.png b/docs/_static/images/user-guide/reports/dashlet-totals.png
new file mode 100644
index 000000000..07bc93323
Binary files /dev/null and b/docs/_static/images/user-guide/reports/dashlet-totals.png differ
diff --git a/docs/_static/images/user-guide/reports/grid-list-0.png b/docs/_static/images/user-guide/reports/grid-list-0.png
new file mode 100644
index 000000000..7b9aa4c84
Binary files /dev/null and b/docs/_static/images/user-guide/reports/grid-list-0.png differ
diff --git a/docs/_static/images/user-guide/reports/grid-list-1.png b/docs/_static/images/user-guide/reports/grid-list-1.png
new file mode 100644
index 000000000..7085df7ea
Binary files /dev/null and b/docs/_static/images/user-guide/reports/grid-list-1.png differ
diff --git a/docs/_static/images/user-guide/reports/report-filter.png b/docs/_static/images/user-guide/reports/report-filter.png
new file mode 100644
index 000000000..af0be6600
Binary files /dev/null and b/docs/_static/images/user-guide/reports/report-filter.png differ
diff --git a/docs/_static/images/user-guide/working-time-calendar/1.png b/docs/_static/images/user-guide/working-time-calendar/1.png
new file mode 100644
index 000000000..55cdc7c04
Binary files /dev/null and b/docs/_static/images/user-guide/working-time-calendar/1.png differ
diff --git a/docs/_static/images/user-guide/working-time-calendar/2.png b/docs/_static/images/user-guide/working-time-calendar/2.png
new file mode 100644
index 000000000..5bd9cc9f2
Binary files /dev/null and b/docs/_static/images/user-guide/working-time-calendar/2.png differ
diff --git a/docs/_static/images/user-guide/working-time-calendar/3.png b/docs/_static/images/user-guide/working-time-calendar/3.png
new file mode 100644
index 000000000..d2ebebb42
Binary files /dev/null and b/docs/_static/images/user-guide/working-time-calendar/3.png differ
diff --git a/docs/_static/scripts/backup-docker-container.sh b/docs/_static/scripts/backup-docker-container.sh
new file mode 100644
index 000000000..541f5d45c
--- /dev/null
+++ b/docs/_static/scripts/backup-docker-container.sh
@@ -0,0 +1,133 @@
+#!/bin/bash
+
+# This script creates a backup of an EspoCRM Docker container, including both the database and files.
+#
+# EspoCRM - Open Source CRM application.
+# Copyright (C) 2014-2026 EspoCRM, Inc.
+# Website: https://www.espocrm.com
+
+set -e
+
+function printExitError() {
+ local message="$1"
+
+ local red='\033[0;31m'
+ local default='\033[0m'
+
+ printf "\n${red}ERROR${default}: ${message}\n"
+ exit 1
+}
+
+DEFAULT_ESPOCRM_CONTAINER="espocrm"
+DEFAULT_BACKUP_PATH="$(pwd)"
+
+printf "NOTICE\nThis script is designed to work only with the official EspoCRM Docker image:\nhttps://docs.espocrm.com/administration/docker/installation/#install-espocrm-with-docker-compose.\n\n"
+sleep 1
+
+if [ -z "$1" ]; then
+ echo "Enter an EspoCRM container name ($DEFAULT_ESPOCRM_CONTAINER):"
+
+ read ESPOCRM_CONTAINER
+
+ if [ -z "$ESPOCRM_CONTAINER" ]; then
+ ESPOCRM_CONTAINER="$DEFAULT_ESPOCRM_CONTAINER"
+ fi
+else
+ ESPOCRM_CONTAINER="$1"
+fi
+
+if [ -z "$2" ]; then
+ echo "Enter a full path to backup directory ($DEFAULT_BACKUP_PATH):"
+
+ read BACKUP_PATH
+
+ if [ -z "$BACKUP_PATH" ]; then
+ BACKUP_PATH="$DEFAULT_BACKUP_PATH"
+ fi
+else
+ BACKUP_PATH="$2"
+fi
+
+# --- Validate ---
+
+if [ ! -d "$BACKUP_PATH" ]; then
+ mkdir -p "$BACKUP_PATH" || printExitError "Unable to create the directory '$BACKUP_PATH'"
+fi
+
+if [ ! -w "$BACKUP_PATH" ]; then
+ printExitError "Backup directory '$BACKUP_PATH' is not writable"
+fi
+
+DB_CONTAINER=$(docker exec "$ESPOCRM_CONTAINER" printenv ESPOCRM_DATABASE_HOST || echo "")
+
+if [ -z "$DB_CONTAINER" ]; then
+ printExitError "Unable to determine the database container."
+fi
+
+DB_NAME=$(docker exec "$ESPOCRM_CONTAINER" printenv ESPOCRM_DATABASE_NAME || echo "espocrm")
+DB_USER=$(docker exec "$ESPOCRM_CONTAINER" printenv ESPOCRM_DATABASE_USER || echo "espocrm")
+DB_PASS=$(docker exec "$ESPOCRM_CONTAINER" printenv ESPOCRM_DATABASE_PASSWORD || echo "")
+
+if ! docker ps --format '{{.Names}}' | grep -q "^${ESPOCRM_CONTAINER}$"; then
+ printExitError "Container '$ESPOCRM_CONTAINER' is not running"
+fi
+
+if ! docker ps --format '{{.Names}}' | grep -q "^${DB_CONTAINER}$"; then
+ printExitError "Container '$DB_CONTAINER' is not running"
+fi
+
+if [ -z "$DB_PASS" ]; then
+ printExitError "Unable to determine the database from container environment"
+fi
+
+# --- Prepare temp dir and archive name ---
+
+BACKUP_ARCHIVE_NAME="$(date +'%Y-%m-%d_%H%M%S').tar.gz"
+TEMP_DIR="$BACKUP_PATH/espocrm_backup_tmp"
+
+mkdir -p "$TEMP_DIR"
+
+# --- Database backup ---
+
+echo ">>> Backing up database '$DB_NAME'..."
+
+DB_VERSION=$(docker exec "$DB_CONTAINER" mariadb --version 2>/dev/null || docker exec "$DB_CONTAINER" mysql --version 2>/dev/null)
+
+if echo "$DB_VERSION" | grep -qi "mariadb"; then
+ DUMP_CMD="mariadb-dump"
+else
+ DUMP_CMD="mysqldump"
+fi
+
+docker exec "$DB_CONTAINER" \
+ $DUMP_CMD --user="$DB_USER" --password="$DB_PASS" "$DB_NAME" \
+ > "$TEMP_DIR/db.sql" || printExitError "Unable to create a backup for the database '$DB_NAME'"
+
+tar -czf "$TEMP_DIR/db.tar.gz" -C "$TEMP_DIR" "db.sql"
+rm "$TEMP_DIR/db.sql"
+
+echo ">>> Database backup done."
+
+# --- Files backup ---
+
+echo ">>> Backing up EspoCRM files..."
+
+docker run --rm \
+ --volumes-from "${ESPOCRM_CONTAINER}" \
+ -v "${TEMP_DIR}:/backup" \
+ alpine tar czf /backup/files.tar.gz -C /var/www/html . > /dev/null 2>&1
+
+echo ">>> Files backup done."
+
+# --- Bundle into single archive ---
+
+echo ">>> Creating final archive..."
+
+tar czf "$BACKUP_PATH/$BACKUP_ARCHIVE_NAME" -C "$TEMP_DIR" .
+
+# --- Cleanup ---
+
+rm -rf "$TEMP_DIR"
+
+echo ""
+echo "Backup created at '$BACKUP_PATH/$BACKUP_ARCHIVE_NAME'."
diff --git a/docs/_static/scripts/backup.sh b/docs/_static/scripts/backup.sh
index 88a32ee83..6f483c1cf 100644
--- a/docs/_static/scripts/backup.sh
+++ b/docs/_static/scripts/backup.sh
@@ -1,91 +1,152 @@
#!/bin/bash
+# This script creates a backup of an EspoCRM installation, including both the database and files.
+#
+# EspoCRM - Open Source CRM application.
+# Copyright (C) 2014-2026 EspoCRM, Inc.
+# Website: https://www.espocrm.com
+
+set -e
+
+function printExitError() {
+ local message="$1"
+
+ local red='\033[0;31m'
+ local default='\033[0m'
+
+ printf "\n${red}ERROR${default}: ${message}\n"
+ exit 1
+}
+
DEFAULT_PATH_TO_ESPO="/var/www/html"
DEFAULT_BACKUP_PATH=$(pwd)
if [ -z "$1" ]; then
echo "Enter a full path to EspoCRM directory ($DEFAULT_PATH_TO_ESPO):"
+
read PATH_TO_ESPO
if [ -z "$PATH_TO_ESPO" ]; then
- PATH_TO_ESPO=$DEFAULT_PATH_TO_ESPO
+ PATH_TO_ESPO="$DEFAULT_PATH_TO_ESPO"
fi
else
- PATH_TO_ESPO=$1
+ PATH_TO_ESPO="$1"
fi
if [ ! -d "$PATH_TO_ESPO" ]; then
- echo "Error: The directory '$PATH_TO_ESPO' does not exist."
- exit 1
+ printExitError "The directory '$PATH_TO_ESPO' does not exist"
fi
if [ ! -r "$PATH_TO_ESPO" ]; then
- echo "Error: The directory '$PATH_TO_ESPO' is not readable."
- exit 1
+ printExitError "The directory '$PATH_TO_ESPO' is not readable"
fi
if [ -z "$2" ]; then
echo "Enter a full path to backup directory ($DEFAULT_BACKUP_PATH):"
+
read BACKUP_PATH
if [ -z "$BACKUP_PATH" ]; then
- BACKUP_PATH=$DEFAULT_BACKUP_PATH
+ BACKUP_PATH="$DEFAULT_BACKUP_PATH"
fi
else
- BACKUP_PATH=$2
+ BACKUP_PATH="$2"
fi
if [ ! -d "$BACKUP_PATH" ]; then
- echo "Error: The directory '$BACKUP_PATH' does not exist."
- exit 1
+ mkdir -p "$BACKUP_PATH" || printExitError "Unable to create the directory '$BACKUP_PATH'"
fi
if [ ! -w "$BACKUP_PATH" ]; then
- echo "Error: Backup directory '$BACKUP_PATH' is not writable."
- exit 1
+ printExitError "Backup directory '$BACKUP_PATH' is not writable"
fi
-cd $PATH_TO_ESPO
+cd "$PATH_TO_ESPO"
if [ ! -f "data/config.php" ]; then
- echo "Error: The '$PATH_TO_ESPO' is not EspoCRM directory."
- exit 1
+ printExitError "The '$PATH_TO_ESPO' is not EspoCRM directory"
+fi
+
+DB_NAME=$(php -r "\$config=include('data/config.php'); echo @\$config['database']['dbname'];")
+DB_USER=$(php -r "\$config=include('data/config.php'); echo @\$config['database']['user'];")
+DB_PASS=$(php -r "\$config=include('data/config.php'); echo @\$config['database']['password'];")
+
+if [ -z "$DB_NAME" ]; then
+ DB_NAME=$(php -r "\$config=include('data/config-internal.php'); echo @\$config['database']['dbname'];")
fi
-DB_USER=$(php -r "\$config=include('data/config.php'); echo \$config['database']['user'];")
-DB_PASS=$(php -r "\$config=include('data/config.php'); echo \$config['database']['password'];")
-DB_NAME=$(php -r "\$config=include('data/config.php'); echo \$config['database']['dbname'];")
+if [ -z "$DB_USER" ]; then
+ DB_USER=$(php -r "\$config=include('data/config-internal.php'); echo @\$config['database']['user'];")
+fi
+
+if [ -z "$DB_PASS" ]; then
+ DB_PASS=$(php -r "\$config=include('data/config-internal.php'); echo @\$config['database']['password'];")
+fi
+
+if [ -z "$DB_NAME" ]; then
+ printExitError "Unable to determine database name"
+fi
-BACKUP_NAME=$(basename $PATH_TO_ESPO)
+BACKUP_NAME=$(basename "$PATH_TO_ESPO")
BACKUP_ARCHIVE_NAME="$(date +'%Y-%m-%d_%H%M%S').tar.gz"
-cd $BACKUP_PATH
-mkdir $BACKUP_NAME
-cd $BACKUP_NAME
+echo ">>> Backing up database ..."
+
+# Detect database type and set appropriate dump command
+if command -v mariadb-dump &> /dev/null; then
+ DUMP_CMD="mariadb-dump"
+ echo ">>> Detected MariaDB"
+elif mysqldump --version 2>&1 | grep -qi "mariadb"; then
+ DUMP_CMD="mariadb-dump"
+ echo ">>> Detected MariaDB"
+elif command -v mysqldump &> /dev/null; then
+ DUMP_CMD="mysqldump"
+ echo ">>> Detected MySQL"
+else
+ printExitError "Neither MariaDB nor MySQL database found"
+fi
+
+cd "$BACKUP_PATH" || {
+ printExitError "Permission denied on $BACKUP_PATH"
+}
-# Create database dump
-mysqldump --user=$DB_USER --password=$DB_PASS $DB_NAME > "db.sql" || {
- echo "Enter MySQL user:"
+mkdir -p "$BACKUP_NAME"
+cd "$BACKUP_NAME"
+
+# --- Database backup ---
+
+"$DUMP_CMD" --user="$DB_USER" --password="$DB_PASS" "$DB_NAME" > "db.sql" || {
+ echo "Enter database user:"
read DB_USER
- echo "Enter MySQL password:"
+ echo "Enter database password:"
read DB_PASS
- mysqldump --user=$DB_USER --password=$DB_PASS $DB_NAME > "db.sql" || {
- echo "Error: Cannot dump the database '$DB_NAME'. "
- exit 1
+ "$DUMP_CMD" --user="$DB_USER" --password="$DB_PASS" "$DB_NAME" > "db.sql" || {
+ printExitError "Unable to create a backup for the database '$DB_NAME'"
}
}
tar -czf "db.tar.gz" "db.sql"
rm "db.sql"
-# Archive files
-tar -czf "files.tar.gz" -C $PATH_TO_ESPO .
+echo ">>> Database backup done."
+
+# --- Files backup ---
+
+echo ">>> Backing up files..."
+
+tar -czf "files.tar.gz" -C "$PATH_TO_ESPO" .
+
+echo ">>> Files backup done."
+
+# --- Bundle into single archive ---
+
+echo ">>> Creating final archive..."
-# Create a full backup archive
cd ..
-tar czf "$BACKUP_ARCHIVE_NAME" $BACKUP_NAME/
+tar czf "$BACKUP_ARCHIVE_NAME" "$BACKUP_NAME"/
# Remove temporary files
-rm -rf $BACKUP_NAME
+rm -rf "$BACKUP_NAME"
-echo "Backup is created, '$BACKUP_PATH/$BACKUP_ARCHIVE_NAME'."
+echo ""
+echo "Backup is created at '$BACKUP_PATH/$BACKUP_ARCHIVE_NAME'."
diff --git a/docs/administration/2fa.md b/docs/administration/2fa.md
index 697ecf683..330579c4b 100644
--- a/docs/administration/2fa.md
+++ b/docs/administration/2fa.md
@@ -1,19 +1,50 @@
# 2-Factor Authentication
-EspoCRM supports [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm) 2-factor authentication (since version 5.7.0).
+EspoCRM supports the following 2-factor authentication methods:
-Administrator needs to enable 2FA at Administration > Authentication. Then users can enable 2FA for their accounts.
+* TOTP (as of v5.7)
+* Email (as of v7.0)
+* SMS (as of v7.0)
-## Enabling for user
+An administrator needs to enable 2FA at Administration > Authentication and select allowed methods. Then users can enable 2FA for their accounts.
-You need to have an authenticator application installed on your mobile phone (e.g. Google Authenticator).
+## TOTP
-Go to your user profile (from the menu at the top-right corner) and then click *Security* button. Then, enable 2FA, enter your current password and after that scan QR-code with your mobile application.
+[Time-based One-time Password](https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm) is an algorithm that generates a one-time password which uses the current time as a source of uniqueness.
-Next time, when you login to EspoCRM, you will need to enter your username & password, then enter a code from your mobile application.
-## If you lost your TOTP key
+!!! warning
+
+ The server time must be correct. Otherwise, authentication won't work.
+
+### Enabling for user
+
+You need to have an authenticator application installed on your mobile phone (e.g. [Google Authenticator](https://en.wikipedia.org/wiki/Google_Authenticator)).
+
+Go to your user profile (from the menu at the top-right corner) and then click *Security* button. Then, enable 2FA, select the *TOTP* method. After that, scan the QR-code with your mobile application.
+
+Next time when you log in to Espo, you will need to enter your username and password, then enter a code from your mobile application.
+
+### If you lost your TOTP key
If you are not an administrator, you need to contact the administrator to ask them to disable 2FA for your user account.
-If you are an administrator, the only option is to disable 2FA globally by setting `'auth2FA' => false` in `data/config.php`.
+If you are an administrator, the only option is to disable 2FA globally by setting `'auth2FA' => false` in the config file `data/config.php`.
+
+## Authentication via email
+
+When the Email 2FA is used, after a user entered a valid username and password, a code will be sent to their email address. Then, the user needs to enter that code to log in to Espo.
+
+It's highly recommended for users to use a non-primary email address for 2FA. A user should have at least two email addresses (they can be added only by admin).
+
+### Enabling for user
+
+Go to your user profile (from the menu at the top-right corner) and then click *Security* button. Then, enable 2FA and select the *Email* method. Choose an email address (it's highly recommended to choose non-primary one) and then send a code. Then you will need to confirm the code.
+
+## Authentication via SMS
+
+Requires having an implementation for your SMS provider. An extension with SMS providers can be downloaded [here](https://github.com/espocrm/ext-sms-providers/releases).
+
+### Enabling for user
+
+Go to your user profile (from the menu at the top-right corner) and then click *Security* button. Then, enable 2FA and select the *SMS* method. Choose a phone number and then send a code. Then, you will need to confirm the code.
diff --git a/docs/administration/addresses.md b/docs/administration/addresses.md
new file mode 100644
index 000000000..d9b39bd95
--- /dev/null
+++ b/docs/administration/addresses.md
@@ -0,0 +1,13 @@
+# Addresses
+
+## Countries
+
+*As of v8.3.*
+
+An administrator can add country names with their ISO 3166-1 alpha-2 codes (at Administration > Address Countries).
+Added countries will be available in autocompletion in Address fields.
+Countries marked as preferred will be displayed first (on empty input).
+
+Countries can also be [imported](import.md) from a CSV file.
+
+The default predefined country list with English names can be optionally loaded. To do this, follow: Administration > Address Countries > top-right menu > Populate with default country list.
diff --git a/docs/administration/apache-server-configuration.md b/docs/administration/apache-server-configuration.md
index fdad9e9c8..74d880c85 100644
--- a/docs/administration/apache-server-configuration.md
+++ b/docs/administration/apache-server-configuration.md
@@ -1,6 +1,6 @@
# Apache server configuration for EspoCRM
-These instructions are supplementary to the [server configuration](server-configuration.md) guidelines. Note that all configuration settings listed here are made on Ubuntu server.
+These instructions are supplementary to the [server configuration](server-configuration.md) guidelines. Note that all configuration settings listed here are made on an Ubuntu server.
## PHP requirements
@@ -8,14 +8,49 @@ To install all necessary libraries, run these commands in the terminal:
```
sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-zip php-imap php-mbstring php-curl
+sudo apt-get install php-mysql php-json php-gd php-zip php-imap php-mbstring php-curl php-exif php-ldap php-xml
sudo phpenmod imap mbstring
sudo service apache2 restart
```
-## Fixing the issue 'API Error: EspoCRM API is unavailable'
+## Server configuration
-When you are trying to install EspoCRM via browser, you may encounter 'API Error: EspoCRM API is unavailable' error.
+On a **production** environment, the following configuration is recommended:
+
+* The document root should be set to `/path_to_espo/public/`.
+* An alias `/client/` => `/path_to_espo/client/` should be added.
+
+Apache config example:
+
+```
+DocumentRoot /path_to_espo/public/
+Alias /client/ /path_to_espo/client/
+
+
+ AllowOverride None
+
+
+
+ AllowOverride All
+
+```
+
+Note that `/path_to_espo` should be changed to the absolute path of the EspoCRM instance on your server. It can be `/var/www/html` if you extracted EspoCRM package to the default Apache root directory.
+
+The location of the Apache config is usually `/etc/apache2/apache2.conf` (on Ubuntu) but can be different.
+
+You need to have **mod_rewrite** enabled. You can do it by running in the terminal:
+
+```
+sudo a2enmod rewrite
+sudo service apache2 restart
+```
+
+For **non-production environment** you can just set `AllowOverride All` for the root directory. Then the `.htaccess` file in the root directory will handle all rewrite rules.
+
+## Enabling rewrite rules
+
+EspoCRM requires *mod_rewrite* being enabled in Apache. W/o it you may encounter *'API Error: EspoCRM API is unavailable'* error during installation or see an information page prompting to configure your webserver.
To fix it, try the following steps **one by one**. After each step check if the issue is solved. If it works, then further steps are not needed.
@@ -30,23 +65,31 @@ sudo service apache2 restart
### 2. Enable *.htaccess* support
-To enable .htaccess support, add/edit the server configuration settings `/etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf` or `/etc/apache2/apache2.conf` (or `/etc/httpd/conf/httpd.conf`):
+To enable .htaccess support, add or edit the server configuration file. It can be:
+
+* `/etc/apache2/apache2.conf`
+* `/etc/httpd/conf/httpd.conf`
+* `/etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf`
+
+Add the following code:
```
-AllowOverride All
+ AllowOverride All
```
-You need to change */PATH_TO_ESPO/* to the full path to your EspoCRM inctance, e.g. */var/www/html/*.
+You need to change `/PATH_TO_ESPO/` to the full path to your EspoCRM instance. It can be `/var/www/html/`.
+
+Note: On production, it's reasonable to use `/PATH_TO_ESPO/public/` path instead.
-Afterward, restart apache:
+Then restart Apache:
```
sudo service apache2 restart
```
-### 3. Add RewriteBase path (not needed in most cases)
+### 3. Add RewriteBase path (a last resort, not needed in most cases)
Open the file `/ESPOCRM_DIRECTORY/api/v1/.htaccess` and replace the following line:
@@ -82,8 +125,8 @@ For FastCgi module:
```
FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
+ -pass-header Proxy-Authorization \
+ -pass-header HTTP_AUTHORIZATION
```
@@ -92,3 +135,4 @@ To check which module is currently being used, run this command and find the mod
```
apache2ctl -M
```
+
diff --git a/docs/administration/api-before-save-script.md b/docs/administration/api-before-save-script.md
new file mode 100644
index 000000000..03563759b
--- /dev/null
+++ b/docs/administration/api-before-save-script.md
@@ -0,0 +1,152 @@
+# API Before-Save Script
+
+*As of v7.5.*
+
+A [formula](formula.md) script that is invoked on POST and PUT API requests to an entity endpoint before the record is saved.
+It's executed only when the record is created or updated via the API (this also includes actions made through the UI as EspoCRM is a single page application – the frontend communicates with the backend via API). It's not executed when a record is saved from within the system (e.g. in hooks, workflow actions, custom code).
+Can be used for custom validation, duplicate checking and access control. Available at Administration > Entity Manager > {Entity type} > Formula.
+
+!!! note
+
+ API Before-Save Script is not executed when doing mass update.
+
+!!! note
+
+ Avoid accessing related records in API Before-Save Script using a dot (e.g. `account.assignedUserId`). When the script is executed, the relation can be not yet established.
+
+## Special functions
+
+!!! warning
+
+ These functions are available only in *API Before-Save Script*. Using them in other places will produce an error.
+
+### recordService\skipDuplicateCheck
+
+Returns *true* if a *skipDuplicateCheck* HTTP header is passed (when a user is warned about a duplicate but opts to save the record anyway).
+
+!!! example
+
+ ```
+ if (!recordService\skipDuplicateCheck()) {
+ // process duplicate checking
+ }
+ ```
+
+### recordService\throwDuplicateConflict
+
+`recordService\throwDuplicateConflict(RECORD_ID)`
+
+`recordService\throwDuplicateConflict(RECORD_IDS)` – receives a list of IDs.
+
+Throws a duplicate conflict exception. This will show a modal dialog warning the user that the saved record
+might be a duplicate.
+
+!!! example
+
+ ```
+ if (!recordService\skipDuplicateCheck()) {
+ $id = record\findOne('MyEntityType', null, null, 'name=', name);
+
+ if ($id) {
+ recordService\throwDuplicateConflict($id);
+ }
+ }
+ ```
+
+### recordService\throwBadRequest
+
+`recordService\throwBadRequest(MESSAGE, [BODY])`
+
+Throws a Bad Request exception.
+
+!!! example
+
+ ```
+ recordService\throwBadRequest('Invalid value.')`
+ ```
+
+!!! example
+
+ ```
+ $obj = object\create();
+ object\set($obj, 'key', 'value');
+
+ recordService\throwBadRequest('Invalid value.', $obj)`
+ ```
+
+### recordService\throwForbidden
+
+`recordService\throwForbidden(MESSAGE, [BODY])`
+
+Throws a Forbidden exception.
+
+### recordService\throwConflict
+
+`recordService\throwConflict(MESSAGE, [BODY])`
+
+Throws a Conflict exception.
+
+## Examples
+
+### Duplicate checking
+
+Example 1:
+
+```
+if (entity\isNew() && !recordService\skipDuplicateCheck()) {
+ $id = record\findOne('MyEntityType', null, null, 'name=', name);
+
+ if ($id) {
+ recordService\throwDuplicateConflict($id);
+ }
+}
+```
+
+Example 2:
+
+```
+if (entity\isNew() && !recordService\skipDuplicateCheck()) {
+ $ids = list();
+
+ $id = record\findOne('MyEntityType', null, null, 'name=', name);
+
+ if ($id) {
+ $ids = array\push($ids, $id);
+ }
+
+ $id = record\findOne('MyEntityType', null, null, 'emailAddress=', emailAddress);
+
+ if ($id) {
+ $ids = array\push($ids, $id);
+ }
+
+ $ids = array\unique($ids);
+
+ if (array\length($ids)) {
+ recordService\throwDuplicateConflict($ids);
+ }
+}
+```
+
+### Validation
+
+Example 1:
+
+```
+if (status == 'Completed' && !dateCompleted) {
+ recordService\throwBadRequest("Missing `dateCompleted` value.");
+}
+```
+
+### Access control
+
+Example 1:
+
+```
+if (
+ entity\isAttributeChanged('status') &&
+ !array\includes(env\userAttribute('teamsIds'), '6133380f577a93492')
+) {
+ recordService\throwForbidden("Not allowed to change status.");
+}
+```
diff --git a/docs/administration/app-secrets.md b/docs/administration/app-secrets.md
new file mode 100644
index 000000000..4f8ff94a4
--- /dev/null
+++ b/docs/administration/app-secrets.md
@@ -0,0 +1,21 @@
+# App Secrets
+
+*As of v9.0.*
+
+Applications secrets allow you to securely store sensitive values in Espo, such as API keys and passwords. To access them, go to: Administration > App Secrets.
+
+Secrets are stored as instances of the *AppSecret* entity type. It's possible to read them from code and a Formula script.
+
+## Reading in Formula
+
+*As of v9.2.3.*
+
+Example:
+
+```
+$secretValue = ext\appSecret\get($secretName);
+```
+
+## Using in Workflows
+
+In the *Send HTTP Request* action, it's possible to insert secrets into headers using the placeholder *{#secrets.name}*. Where *name* is the secret's name.
diff --git a/docs/administration/b2c.md b/docs/administration/b2c.md
index e9f434bb4..724c7c354 100644
--- a/docs/administration/b2c.md
+++ b/docs/administration/b2c.md
@@ -1,9 +1,9 @@
# Configuring EspoCRM for B2C (Business-to-Client)
-By default, EspoCRM is configured for use in B2B business. But you can easily setup it for B2C.
+By default, EspoCRM is configured for use in B2B business. It's possible to set it up solely for B2C.
-* Check 'B2C Mode' at Administration > Settings.
-* Remove *Account* tab from the navigation menu (Administration > User Interface).
-* Remove *Account* fields from your layouts (Administration > Layout Manager).
-* Disable access to *Account* scope for all your roles (Administration > Roles).
-* Remove Account from picklists of all parent fields (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
+* Check *B2C Mode* at Administration > Settings.
+* Remove the *Account* tab from the navigation menu: Administration > User Interface.
+* Remove the *Account* fields from your layouts: Administration > Layout Manager.
+* Disable access to the *Account* scope in Roles if you allowed it before.
+* Remove the *Account* from picklists of all parent fields: Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent.
diff --git a/docs/administration/backup-and-restore.md b/docs/administration/backup-and-restore.md
index 5e7c9c40b..04eb52acb 100644
--- a/docs/administration/backup-and-restore.md
+++ b/docs/administration/backup-and-restore.md
@@ -1,92 +1,121 @@
# Backup and Restore
-## How to backup EspoCRM manually
+This article outlines backup and restore methods for EspoCRM in various environments:
-EspoCRM consists of files and database data. All these data are needed in order to create a full backup of EspoCRM. Here are the instructions on how to do it on Ubuntu server, with MySQL.
+* [Non-containerized installation](#non-containerized-installation)
+* [Docker installation](#docker-installation)
-### Step 1. Backup files
+## Non-containerized installation
-Create an archive of the directory content of installed EspoCRM. The default path for Ubuntu is `/var/www/html`. You can use this command:
+Refers to a traditional installation that does not use containers.
+
+### Backup with a script
+
+You can use a script to back up all needed data. Login via SSH and run the commands (tested on the Ubuntu server).
+
+#### Step 1. Download a script
```bash
-tar -czf "files.tar.gz" -C /var/www/html .
+wget https://raw.githubusercontent.com/espocrm/documentation/stable/docs/_static/scripts/backup.sh
```
-### Step 2. Backup database
+#### Step 2. Run the script
+
+```bash
+bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
+```
-To backup all your data, you have to know the database name and access credentials. You can find the database name in the configuration file `/ESPOCRM_DIRECTORY/data/config.php` under section `database`. You can use this command to backup your database:
+where
+
+ * `PATH_TO_ESPOCRM` is a path to installed EspoCRM directory
+ * `BACKUP_PATH` is a path to backup directory
+
+For Ubuntu server it is:
```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
+bash ./backup.sh /var/www/html /opt/backups
```
-### Step 3. Copy the backup
+Note: If your MariaDB / MySQL user doesn't have needed rights to dump your database, you will be prompted to enter credentials of another MariaDB / MySQL user.
-That's all. Now, you have to copy the created backup to a safe place.
+After successful creation, you will get a path to the created backup.
+### Manual backup
-## How to backup EspoCRM with a script
+To make a full backup of your EspoCRM instance you need to copy EspoCRM files and dump the database. Here are the instructions on how to do it on an Ubuntu server with MySQL or MariaDB.
-You can use a script to backup all needed data. Login via SSH and run the commands (tested on Ubuntu server).
+#### Step 1. Back up files
-### Download a script
+Create an archive of the entire directory contents of the EspoCRM instance. You can use the following command:
```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/scripts/backup.sh
+tar -czf "files.tar.gz" -C /var/www/html .
```
-### Run the script
+The command above implies that the path to your instance is `/var/www/html`, which is usual default path on Linux servers. Modify it if needed.
+
+#### Step 2. Back up database
+
+To back up all your data, you have to know the database name and credentials for access. You can find the database name in the configuration file `/ESPOCRM_DIRECTORY/data/config-internal.php` under the section *database*. You can use this command to back up your database.
+
+For MariaDB:
```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
+mariadb-dump --user=DATABASE_USER --password=DATABASE_PASSWORD DATABASE_NAME > "db.sql"
```
-where
- * `PATH_TO_ESPOCRM` is a path to installed EspoCRM directory
- * `BACKUP_PATH` is a path to backup directory
-
-For Ubuntu server it is:
+For MySQL:
```bash
-bash ./backup.sh /var/www/html /opt/backups
+mysqldump --user=DATABASE_USER --password=DATABASE_PASSWORD DATABASE_NAME > "db.sql"
```
-Note: If your MySQL user doesn't have needed rights to dump your database, you will be prompted to enter credentials of another MySQL user.
+#### Step 3. Copy the backup
-After successful creation, you will get a path to the created backup.
+That's all. Now, you have to copy the created backup to a safe place.
-## Restore EspoCRM from a backup
+### Manual restore
-You can restore EspoCRM from the backup created as described above.
+You can restore the EspoCRM instance from the backup created as described above.
-### Step 1. Unarchive backup files
+#### Step 1. Unarchive backup files
-To unarchive files, you can use Archive Manager or run the below command. Files need to be placed in the web-server directory.
+To unarchive files, you can use *Archive Manager* or run the below command. Files need to be placed in the web-server directory.
```bash
tar -xzf "files.tar.gz" -C /var/www/html
```
+
where `/var/www/html` is the web-server directory.
-### Step 2. Set required permissions
+#### Step 2. Set required permissions
-The files should be owned by a web-server user and have correct permissions. Please set required permissions by following this [instruction](server-configuration.md#required-permissions-for-unix-based-systems).
+The files should be owned by the web-server user and have correct permissions. Set required permissions by following this [instruction](server-configuration.md#required-permissions-for-unix-based-systems).
-### Step 3. Import database dump
+#### Step 3. Import database dump
-Database dump should be imported to the same database with the same user credentials, otherwise the correction should be made in the configuration file `ESPOCRM_DIRECTORY/data/config.php`. To import your database from the dump, run the command below in a terminal:
+Database dump should be imported to the same database with the same user credentials, otherwise the correction should be made in the configuration file `ESPOCRM_DIRECTORY/data/config-internal.php`. To import your database from the dump, run the command below in a terminal:
+
+For MariaDB:
```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
+mariadb --user=DATABASE_USER --password=DATABASE_PASSWORD DATABASE_NAME < db.sql
```
-### Step 4. Check/configure crontab
+For MySQL:
+
+```bash
+mysql --user=DATABASE_USER --password=DATABASE_PASSWORD DATABASE_NAME < db.sql
+```
+
+#### Step 4. Check/configure crontab
Check if your crontab is configured properly. Run the command below and check if a path to EspoCRM is correct:
```bash
sudo crontab -l -u www-data
```
+
where `www-data` is your web-server user.
If you have to make any changes, use this command:
@@ -95,4 +124,74 @@ If you have to make any changes, use this command:
sudo crontab -l -u www-data
```
-More details about configuring crontab for EspoCRM are described [here](server-configuration.md#setting-up-crontab).
+More details about configuring crontab see [here](server-configuration.md#setting-up-crontab).
+
+## Docker installation
+
+### Backup with a script
+
+!!! important
+
+ Script must be run from the host.
+
+#### Step 1. Download a script
+
+```bash
+wget https://raw.githubusercontent.com/espocrm/documentation/stable/docs/_static/scripts/backup-docker-container.sh
+```
+
+#### Step 2. Run the script
+
+Run one of the following commands at your choice:
+
+```bash
+sudo bash backup-docker-container.sh
+```
+
+or
+
+```bash
+sudo bash backup-docker-container.sh CONTAINER_NAME ./BACKUP_DIR
+```
+
+### Automatic backups
+
+Backups can be scheduled on the host by adding the following entry to the crontab:
+
+```
+0 1 * * * sudo bash /opt/scripts/backup-docker-container.sh CONTAINER_NAME /backup/espocrm >> /backup/espocrm/backup.log 2>&1
+```
+
+### Manual backup
+
+Run the following commands:
+
+```bash
+mkdir ./BACKUP_DIR
+
+# Database
+sudo docker exec CONTAINER_NAME mariadb-dump \
+ -u DATABASE_USER --password=DATABASE_PASSWORD DATABASE_NAME \
+ > ./BACKUP_DIR/db.sql
+
+# Files
+sudo docker exec CONTAINER_NAME tar czf - /var/www/html > ./BACKUP_DIR/files.tar.gz
+```
+
+### Manual restore
+
+Run the following commands:
+
+```bash
+# Database
+sudo docker exec -i CONTAINER_NAME mariadb \
+ -u DATABASE_USER --password=DATABASE_PASSWORD DATABASE_NAME \
+ < ./BACKUP_DIR/db.sql
+
+# Files
+sudo docker exec CONTAINER_NAME sh -c "rm -rf /var/www/html/*"
+cat ./BACKUP_DIR/files.tar.gz | sudo docker exec -i CONTAINER_NAME tar xzf - -C /
+
+# Restart
+sudo docker restart CONTAINER_NAME
+```
diff --git a/docs/administration/bpm-activities.md b/docs/administration/bpm-activities.md
index ea380085f..7b6799aed 100644
--- a/docs/administration/bpm-activities.md
+++ b/docs/administration/bpm-activities.md
@@ -1,6 +1,6 @@
# BPM Activities
-Activities are displayed as rounded rectangles.
+Activities encompass automated tasks, manual tasks, and sub-processes. On a flowchart, they are depicted as gray rectangles.
* [Task](#task)
* [Send Message Task](#send-message-task)
@@ -14,15 +14,15 @@ Activities are displayed as rounded rectangles.
## Task
-Task can execute different actions. Available actions are listed bellow.
+A task can execute different actions. Available actions are listed below.
-The list of actions available for a task is almost the same as for Workflows tool. See more details about [workflow actions](workflows.md#actions).
+The BPM task utilizes actions from the Workflow tool. The list of available actions is almost the same as in Workflows. See more details about [Workflow actions](workflows.md#actions).
### Actions
#### Create Record
-Creates a new record of any entity type.
+Creates a new record of a specific entity type.
#### Create Related Record
@@ -30,13 +30,13 @@ Creates a new record related to the target record.
#### Update Target Record
-Updates the target record. You can utilize formula here.
+Updates the target record. You can also utilize Formula script to set fields with calculated values.
-It's possible to delete the record with the formula expression: `deleted = 1`.
+It's possible to delete the record with the Formula expression: `deleted = 1`.
#### Update Related Record
-Updates the record (or multiple records) related to the target record. You can utilize formula here.
+Updates a record (or multiple records) related to the target record. You can also utilize Formula script to set fields with calculated values.
#### Update Created Record
@@ -60,52 +60,60 @@ Unrelates the target record from another specified record.
#### Apply Assignment Rule
-Assigns the record to some user by a specific rule. Can be applied to the target record, the process record or any record created by the process.
+Assigns the record to a user based on a specific assignment rule. Can be applied to the target record, the process record, or any record created by the process. See [more](workflows.md#apply-assignment-rule).
#### Create Notification
-Creates in-app notification for specific users.
+Creates an in-app notification for specific users. See [more](workflows.md#create-notification).
-Process variables can be used in a message with the placeholder `{$$variable}` (since 2.5.8 version).
+Process variables can be included in a message with such placeholders: `{$$variable}`, where *$variable* is a variable defined in the process.
#### Make Followed
-Makes specific users to follow the target record, the process record or any record created by the process.
-
+Makes specific users to follow the target record, the process record, or any record created by the process.
#### Trigger Another Workflow Rule
-Runs a workflow rule of the sequential type, target record can be switched a related or a record created by the process.
-
+Runs a workflow rule of the sequential type. The target record of the called rule can be the same or be switched to a related record or a record created by the process.
#### Run Service Action
Runs a specific service action. The list of built-in actions is available [here](workflows.md#run-service-action). Developers can create custom service actions.
-
#### Send HTTP Request
-Calls external API (since version 2.4.0).
+Calls an external API endpoint. See [more](workflows.md#send-http-request).
+
+#### Execute Formula Script
+Executes a specific Formula script.
### Formula usage
-When using formula in a task that creates or updates another record, the current entity (for the script) is switched the the record you are creating. To access attributes of the target record you can utilize the function `targetEntity\attribute(ATTRIBUTE)`.
+When using Formula in a task that creates or updates another record, the current entity (for the script) is switched the the record you are creating. To access attributes of the target record you can utilize the function `targetEntity\attribute(ATTRIBUTE)`.
-Example:
+!!! example
-```
-// attribute of the target record
-$someVariable1 = targetEntity\attribute('name');
+ ```
+ // attribute of the target record
+ $someVariable1 = targetEntity\attribute('name');
-// attribute of the record you are creating or updating
-$someVariable2 = name;
+ // attribute of the record you are creating or updating
+ $someVariable2 = name;
-// attribute of the record you are creating or updating
-$someVariable3 = entity\attribute('name');
-```
+ // attribute of the record you are creating or updating
+ $someVariable3 = entity\attribute('name');
+ ```
+
+!!! warning
+
+ In the context of create and update record actions, it's recommended to use Formula only for setting attributes. Use the *Script Task* or *Execute Formula Script* action for any other logic.
-In the context of *update record* actions it's recommended to use formula only for setting attributes. Use *Script Task* for any other logic.
+If the parameter *Isolate Variables* is checked, Formula variables defined within the task won't be exposed outside of the task. The *Return Variables* parameter allows you to specify variables that will be exposed.
+
+!!! note
+
+ If you didn't check the *Isolate Variables* parameter, be aware that all variables defined in Execute Formula Script actions will remain available throughout the process and even after it finishes. Since some variables may contain sensitive data or consume disk space, checking the Isolate Variables parameter is recommended.
----
@@ -124,19 +132,21 @@ An email can be sent to:
* Specific contacts
* Followers of target record
-You can specify which email address the email will sent from.
+You can specify which email address the email will be sent from.
-If you specify a *Reply-to* address, a sent email will contain it in a *Reply-to* header. It will facilitate a recipient to reply to that address instead of the address specified in the *From* field.
+If you specify a *Reply-To* address, a sent email will contain it in the *Reply-To* header. It will facilitate a recipient to reply to that address instead of the address specified in the *From* field.
-It's possible to use process variables to specify email address (recipient or sender) with *Specific email address* option, e.g. `{$$emailAddress}`, where *emailAddress* is a variable defined in the process before. Available since version 2.4.5.
+When you use *Specific email address* option, it's possible to use process variables. E.g. `{$$emailAddress}`, where *$emailAddress* is a variable defined in the process before.
-Email Template is used to generate the email. You can use regular placeholders (both in body and subject) to substitue field values of the target record. You can also use process variables (defined in Script Task) in the template with placeholders like `{$$variableName}` (since advanced pack 2.4).
+An Email Template is used to generate the email. You can use regular placeholders (both in body and subject) to substitute field values of the target record. You can also insert process variables (defined in a Script Task) in an email template with placeholders like `{$$variable}`.
-You can catch a reply on the sent email with *Message Intermediate Event* further in the process.
+You can catch a reply to a sent email with Message Intermediate Event further in the process.
+
+Additional attachments can be added to an email using the *Attachments Variable* parameter. Specify a Formula variable name that contains an attachment ID or an array of attachment IDs. You can generate needed attachments in a Formula script in a previous action. As of v3.6.
### Opting-out
-It's possible to add opt-out link to an email body. Opting out can be caught within a process with Catching Signal Event with the signal name `optOut.ENTITY_TYPE.{$id}`, where *ENTITY_TYPE* should be replaced with entity type (e.g. Lead), *{$id}* is a placeholder standing for the target record ID. Signal name usage example: `optOut.Lead.{$id}`.
+It's possible to add opt-out link to an email body. Opting out can be caught within the process with Catching Signal Event with the signal name `optOut.ENTITY_TYPE.{$id}`, where *ENTITY_TYPE* should be replaced with an entity type (e.g. Lead), *{$id}* is a placeholder standing for the target record ID. Signal name usage example: `optOut.Lead.{$id}`.
### Tracking URLs
@@ -146,13 +156,13 @@ See a [separate article](bpm-tracking-urls.md).
## User Task
-It stops the flow until a user (specified explicitly or selected by an assignment rule) resolves the task. Process User Task record will be created in the system. By default there are three action types: Approve, Review, Accomplish.
+It stops the flow until a user (specified explicitly or selected by an assignment rule) resolves the task. A Process User Task record will be created in the system. By default, there are 3 action types: Approve, Review, and Accomplish.
* Approve – requires the user to choose between 'Approved' and 'Declined'.
* Review – gives only one option: 'Reviewed'.
* Accomplish – has two options: 'Completed' and 'Failed'.
-The user assigned to the created Process User Task record will receive in-app notification. Administrator can also enable email notifications for Process User Tasks at Administration > Notifications > Email Notifications.
+The user assigned to the created Process User Task record will receive an in-app notification. An administrator can also enable email notifications for Process User Tasks under Administration > Notifications > Email Notifications.
It's possible to specify text with instructions for the user (markdown is supported).
@@ -161,30 +171,41 @@ You can use placeholders in *Name* and *Instructions* fields:
* `{$attribute}` – attribute of target record
* `{$$variable}` – process variable (defined by Script Task)
-Users can also add Process User Tasks **dashlet** on their dashboard to see their actual process user tasks.
+Users can also add the Process User Tasks dashlet on their dashboard to see their active process user tasks.
+
+An administrator can add custom action types in Entity Manager. The resolution options available for a particular action type is controlled by dynamic logic. The logic can be edited as well.
-### Dispaying on detail view
+### Displaying on detail view
-It's possible to display process task on the target entity detail view.
+It's possible to display Process User Tasks on the detail view of the target entity.
#### Using Report Panels
-You can utilize *Report Panels* feature to display process tasks on the record detail view. Create a list report that shows all user tasks (no filters). Then create a report panel (from administration) for needed entity type with this list report selected.
+You can utilize the *Report Panels* feature to display process tasks on the record detail view. Create a Report of the List type that shows all Process User Tasks (no filters). Then, create a Report Panel (Administration > Report Panels) for the needed entity type with this list Report selected.
#### Using created relationship
-It's possible to create Children-to-Parent relationship between some entity type and User Task, then User Tasks will be available in *Relationships* layout of that entity type. Go to Administration > Entity Manager > BpmnUserTask > Relatinships > edit Children-to-Parent, check your entity type at *Foreign Fields*.
+It's possible to create a Children-to-Parent relationship between some entity type and the Process User Task, then Process User Tasks will be available in the *Bottom* layout of that entity type. Go to Administration > Entity Manager > BpmnUserTask > Relationships > edit Children-to-Parent, check your entity type in *Foreign Fields*.
### Resolution
-It's possible to check the resolution of the passed user task in diverging gateways or conditional events, making ramification in the process flow depending on the resolution. User Task resolution is avaible in conditions of geteways and conditional events.
+It's possible to check a resolution of a passed Process User Task with diverging gateways or conditional events. This allows for making ramifications in the process flow depending on a resolution. The User Task resolution is available in conditions of gateways and conditional events.
+
+The resolution (as well as any User Task field) can be also accessed further in the flow with Formula:
+
+```
+$resolution = bpm\createdEntity\attribute('USER_TASK_ELEMENT_ID', 'resolution');
+$resolutionNote = bpm\createdEntity\attribute('USER_TASK_ELEMENT_ID', 'resolutionNote');
+```
+
+The element ID can be obtained from the User Task's detail view.
### Canceling
-Created User Task can be canceled by a process. There are two ways:
+A created User Task can be canceled by a process. There are two ways:
-1. Using 'Update Created Record' action (within Task activity), setting 'Is Canceled' field to 'true'.
-2. Using interrupting boundary event (attached to User Task activity).
+1. Using 'Update Created Record' action (within a Task activity), setting 'Is Canceled' field to 'true'.
+2. Using interrupting boundary event (attached to the User Task activity).

@@ -193,13 +214,17 @@ Created User Task can be canceled by a process. There are two ways:
## Script Task
-Executes the script in [espo-formula](formula.md) language.
+Executes a [Formula](formula.md) script.
-You can store some variables and use them further within the process. All set variables (`$variableName`) will be automatically stored.
+You can store some variables and use them further in the process. All variables you defined in the script will be automatically stored.
```
$myVar1 = 'test';
$myVar2 = id;
+
+// ...
+
+$myVar2 = null;
```
Variables can be utilized in:
@@ -209,51 +234,76 @@ Variables can be utilized in:
* Email templates
* Signal names
* User Task names
+* Email addresses in a Send Message task
-You can update the target record with Script Task, though the more proper way is to use Update Target Record action of the regular Task.
+You can update the target record with a Script Task, though the more proper way is to use the Update Target Record action of a regular Task.
-In Script Task you can define actions that are impossible to do with the regular Task. Examples:
+With the Script Task, you can define actions that are impossible to do with the regular Task. Examples:
* Create a new user and send generated password ([see](formula-scripts-examples.md#creating-new-user))
* Send email with generated PDF in attachment ([see](formula-scripts-examples.md#sending-email-with-generated-pdf-in-attachment))
-Note: It's recommended to **clear temporary variables**, that won't be needed further in the process, in the end of the script.
+If the parameter *Isolate Variables* is checked, Formula variables defined within the task won't be exposed outside of the task. The *Return Variables* parameter allows you to specify variables that will be exposed.
-```
-$tmpVariable = null;
-```
+!!! note
+
+ If you didn't check the *Isolate Variables* parameter, be aware that all defined variables will remain available throughout the process and even after it finishes. Since some variables may contain sensitive data or consume disk space, it might be reasonable to unset them at the end of the script.
+
+ ```
+ $tmpVariable = null;
+ ```
+
+ Though, checking the Isolate Variables parameter is recommended.
----
## Sub-Process
-An isolated process that executes within the current process. The sub-process has it's own flowchart. It starts once the flow reaches its activity element.
+A sub-process is an isolated process that executes within the parent process. A sub-process has it's own flowchart. It starts once the flow reaches its activity element in the parent process.
+
+A sub-process should have one (and only one) regular Start Event.
-Sub-process should have one (and only one) regular Start Event.
+A sub-process can be interrupted by an interrupting boundary event. When a sub-process is successfully ended (not interrupted and not ended with an error), the flow of the parent process proceeds to the next element.
-Sub-process can be interrupted by an interrupting boundary event. When the sub-process is successfully ended (not interrupted, not ended with an error), the flow of the parent process proceeds to the next element.
+It's possible to **pass a different target record** to a sub-process (to switch the target record to another). After you placed the Sub-Process element on a flowchart, click it to edit, then specify the target. It allows you to easily access fields of created records or records related to the target record. For example, to send a notification to the assigned user of the opportunity that was created within the process.
-It possible to **pass a different target** to the sub-process. After you placed a sub-process element on the flowchart, click it to edit, then specify a target. It allows to easily access fields of created records or records related to the target record. E.g. to send notification to the assigned user of the opportunity that was created within the process.
+It's possible to define a target record using a Formula expression. You need to select the target *Record: {EntityType}* and specify a formula expression in the *Target ID Expression* field. The expression should evaluate to the ID of the record.
-When a sub-process is initiated, all formula **variables are copied** from the parent process to the sub-process. Variables of the sub-process are isolated from its parent process. You can specify which variables will be copied to the parent process upon the completion in *Return Variables* parameter. Note: Variable names should be specified without *$* character.
+When a sub-process is initiated, all formula **variables are copied** from the parent process to the sub-process. Variables of the sub-process are isolated from its parent process. You can specify which variables will be copied to the parent process upon the completion in the *Return Variables* parameter. Note: Specify variable names without a leading *$* character.
-When a sub-process is initiated, it receives an information about all records created by the parent process at that moment. The sub-process can access those records. The parent process can access records created by the sub-process only after the sub-process is completed. Once the sub-process is completed, it passes information about created records to the parent process.
+When a sub-process is initiated, it receives an information about all records that have been created by the parent process by that moment. The sub-process can access those records. The parent process can access records created by the sub-process only after the sub-process is completed. Once the sub-process is completed, it passes the information about created records to the parent process.

+### Multi-instance sub-process
+
+*As of v2.10.*
+
+The *Collection Expression* should evaluate to a list of values. Each value will instantiate a separate sub-process. The value will be available in the variable `$inputItem`.
+
+In case of a **sequential** multi-instance sub-process, sub processes will be executed one by one. Otherwise, they execute in parallel.
+
+It's possible to have multiple sub-processes for different targets. By using the Formula function *record\findRelatedMany*, it's possible to have sub-processes for related records. The result of the function is the list of IDs. You need to set the *Target ID Expression* to `$inputItem`.
+
+The result of a multi-instance sub-process can be returned to a specific variable defined by the *Return Collection Variable* field. It will contain an array of objects. Each object will contain return-variables of each sub-process instance.
+
+When a multi-instance sub-process is interrupted by a boundary event, all other instances are cancelled.
+
+The max number of sub-process instances is defined by the config parameter `bpmnSubProcessInstanceMaxCount`. The default value is `20`.
+
----
## Event Sub-Process
-Event Sub-Process has neither ingoing, nor outgoing flows. It is triggered by its Start Event. The start event can be of any type: Conditional, Timer, Signal, Message, Error, Escalation.
+An Event Sub-Process has neither ingoing nor outgoing flows. It is triggered by its Start Event. The start event can be of any type: Conditional, Timer, Signal, Message, Error, Escalation.
-It possible to **pass a different target** to the event sub-process. The event sub-process can *interrupt* its parent process. Whether the sub-process is interrupting is determined by *Is Interrupting* parameter of its start event.
+It is possible to **pass a different target record** to an event sub-process. An event sub-process can *interrupt* its parent process. Whether the sub-process is interrupting is determined by the *Is Interrupting* parameter of its start event.
When an event sub-process is initiated, all formula **variables are copied** from the parent process to the sub-process.
-When an event sub-process is initiated, it receives an information about all records created by the parent process at that moment. The sub-process can access those records. Records created by the event sub-process won't be accessible by the parent process.
+When an event sub-process is initiated, it receives an information about all records that have been created by the parent process by that moment. The sub-process can access those records. Records created by the event sub-process won't be accessible by the parent process.
-Non-interrupting event sub-process can be executed **multiple times**. E.g. a condition occurred multiple times.
+Non-interrupting event sub-process can be executed **multiple times**. For example, when a condition occurred multiple times.

@@ -261,6 +311,6 @@ Non-interrupting event sub-process can be executed **multiple times**. E.g. a co
## Call Activity
-Executes a sub-process defined by a flowchart stored separately. Provides the ability to re-use the same flowchart in different processes. Call Activity sub-process works the same way as a regular sub-process.
+Executes a sub-process defined by a flowchart stored separately. Provides the ability to re-use the same flowchart in different processes. The Call Activity sub-process works the same way as a regular Sub-Process.
-It possible to pass a different target to the sub-process.
+It is possible to pass a different target record to a sub-process.
diff --git a/docs/administration/bpm-compensation.md b/docs/administration/bpm-compensation.md
new file mode 100644
index 000000000..b8a0311f4
--- /dev/null
+++ b/docs/administration/bpm-compensation.md
@@ -0,0 +1,50 @@
+# Compensation in BPM
+
+*As of Advanced Pack v2.14.*
+
+The Compensation mechanism is supposed to perform undo actions when something went wrong. Only successfully completed activities can be compensated. Both tasks and sub-processes can be compensated.
+
+A compensation is initiated by triggering a Compensation Event (usually from an error handler). The throwing compensation event can specify an activity's ID that needs to be compensated. If the ID is omitted, all *visible* *compensable* activities will be compensated in the order reverse to their instantiation.
+
+By utilizing intermediate throwing compensation events, it is possible to establish a specific order in which compensations will be executed.
+
+!!! note
+
+ Compensation can be applied only for activities that were successfully completed. A sub-process that is not yet finished cannot be compensated from outside.
+
+An activity is **compensable** if one of the two following conditions is met:
+
+* Activity has a Boundary Compensation Event attached that is associated with a compensation activity.
+* Activity is a sub-process that contains a Compensation Event Sub-Process.
+
+Boundary compensation:
+
+
+
+When a sub-process is compensated with the boundary event, the compensation activity does not have access to the sub-process internal state (called Black-Box compensation). To be able to access the internal state, use the Compensation Event Sub-Process inside the sub-process.
+
+When the parent process initiates compensation for the sub-process activity, if there's no boundary compensation event attached to that activity, it will check whether the sub-process contains an event sub-process with a compensation start event (called Compensation Handler). Then, it executes the compensation handler. The compensation handler usually is supposed to explicitly throw compensation events to compensate activities of the sub-process.
+
+Compensation event sub-process:
+
+
+
+An activity is considered **visible** from the throwing Event when:
+
+* It is contained in a normal flow at the same level of the process/sub-process.
+* It is contained in the parent process/sub-process of an event sub-process in which the Event is contained.
+
+In the same level:
+
+
+
+From the event sub-process:
+
+
+
+Compensation events:
+
+* [Boundary](bpm-events.md#compensation-intermediate-event-boundary)
+* [Start](bpm-events.md#compensation-start-event)
+* [Intermediate throwing](bpm-events.md#compensation-intermediate-event-throwing)
+* [End](bpm-events.md#compensation-end-event)
diff --git a/docs/administration/bpm-configuration.md b/docs/administration/bpm-configuration.md
new file mode 100644
index 000000000..9de8c9f4c
--- /dev/null
+++ b/docs/administration/bpm-configuration.md
@@ -0,0 +1,27 @@
+# BPM Configuration
+
+## Deferring conditional event checking
+
+*As of v2.8.7.*
+
+Within a period defined by the config parameter `bpmnPendingDeferPeriod` (`"6 hours"` by default), pending conditional event nodes are being checked as soon as possible.
+After that period, they will be checked with an interval defined by the parameter `bpmnPendingDeferIntervalPeriod` (`"10 minutes"` by default).
+This is an optimization measure.
+
+If an entity is updated, it will make nodes related to that entity to be checked one time regardless whether the defer period has been passed.
+
+## Pending event checking limit
+
+The config parameter `bpmnProceedPendingMaxSize` (`20000` by default) limits max number of pending flows that can be processed. Consider increasing it if you usually have a large number of active processes.
+
+## Multi-instance sub-process limit
+
+The max number of sub-process instances (within a multi-instance sub-process) is defined by the config parameter `bpmnSubProcessInstanceMaxCount`. The default value is `20`.
+
+## Running in parallel
+
+*As of v3.10.*
+
+Can be enabled by setting the config parameter `bpmnRunInParallel` to `true`. Running jobs [in parallel](jobs.md#running-jobs-in-parallel-processes) must be also enabled.
+
+For scheduled processes, to process them in parallel, use a Timer Intermediate Event right after the Start Timer event. Scheduled processes are started sequentially even if the *bpmnRunInParallel* parameter is set to true.
diff --git a/docs/administration/bpm-drip-email-campaign.md b/docs/administration/bpm-drip-email-campaign.md
index 0fdb15496..0bf84d457 100644
--- a/docs/administration/bpm-drip-email-campaign.md
+++ b/docs/administration/bpm-drip-email-campaign.md
@@ -1,44 +1,44 @@
# Drip Email Campaign with BPM
-With [BPM tool](bpm.md) it's possible to create drip email campaigns.
+With the [BPM tool](bpm.md) it's possible to create drip email campaigns.
## Campaign starting
-A drip email campaign for an individual target (lead or contact) will be represented as single BPM Process. A process can be started automatically or manually.
+The drip email campaign for an individual target (lead or contact) will be represented as single BPM Process. A process can be started automatically or manually.
-You need to create *Process Flowchart* (at Administraition > Flowcharts) and choose *Lead* (or *Contact*) target type.
+You need to create a *Process Flowchart* (under Administration > Flowcharts) and choose the *Lead* (or *Contact*) target type.
### Starting on lead subscription
-A process instance will be started once a lead has submitted a form (and confirmed opt-in if required) and has been entered into CRM through [Lead Capture](web-to-lead.md).
+A process instance will be started once a Lead enters into the CRM through the [Lead Capture](web-to-lead.md) form.
-You need to use *Signal Start Event* with a specific signal name. Put it on the flowchart layout and click it to edit. Specify the signal name with the value `@leadCapture.LEAD_CAPTURE_ID`, where *LEAD_CAPTURE_ID* is an ID of the lead capture record (can be obtained from its URL).
+You need to use the *Signal Start Event* with a specific signal name. Put it on the flowchart layout and click it to edit. Specify the signal name with the value `@leadCapture.LEAD_CAPTURE_ID`, where *LEAD_CAPTURE_ID* is an ID of the lead capture record (can be obtained from its URL).
### Starting once lead gets related with target list
-Can be useful if you don't utilize Lead Capture tool but use some other logic. You need to do the same steps as in the privious section but use the signal name `@relate.targetLists.TARGET_LIST_ID`, where *TARGET_LIST_ID* is an ID of the target list record (can be obtained from its URL).
+Can be useful if you don't utilize the Lead Capture but use some other logic. You need to do the same steps as in the previous section but use the signal name `@relate.targetLists.TARGET_LIST_ID`, where *TARGET_LIST_ID* is an ID of the target list record (can be obtained from its URL).
### Starting manually
-Every BPM process can be started manually (a user needs to have a corresponding permission granted with a role). You can use either *Signal Start Event* or regular *Start Event* in the flowchart.
+Every BPM process can be started manually (a user needs to have a corresponding permission granted with a role). You can use either the *Signal Start Event* or the regular *Start Event* in the flowchart.
## Email sending
-Use multiple *[Send Message Tasks](bpm-activities.md#send-message-task)*. Each item will automatically send a specific email. You need to check *Opt-out link* parameter for these tasks to provide recipients the ability to unsubscribe from the campaign.
+Use multiple *[Send Message Tasks](bpm-activities.md#send-message-task)*. Each item will automatically send a specific email. You need to check *Opt-out link* parameter for these tasks to provide recipients with the ability to unsubscribe from the campaign.
-You need to put *Timer Intermediate Events* between tasks and specify how much time should pass before each next email sending.
+You need to put *Timer Intermediate Events* between tasks and specify how much time should pass before every next email sending.
You also can use [Gateways](bpm-gateways.md) to diverge a flow upon certain conditions.
## Handling opting-out
-Once a target (recipient of an email) clicked on the unsibscribe link, the system broadcasts a signal `optOut.Lead.some-lead-id`, where *some-lead-id* is an actual ID of the lead record.
+Once a target (recipient of an email) clicked on the unsubscribe link, the system broadcasts a signal `optOut.Lead.some-lead-id`, where *some-lead-id* is an actual ID of the lead record.
-We want the whole process to be terminated once lead is opted out.
+We want the whole process to be terminated once a Lead is opted out.
-For this, you need to add *Event Sub-Process*. Put *Signal Start Event* inside the sub-process rectangle and specify the signal name with the value `optOut.Lead.{$id}`. You also need to check the parameter *Is Interuppting* for this event. By setting this parameter, we indicate that the whole parent process should be interrupted once the event is catched.
+For this, you need to add the *Event Sub-Process*. Put a *Signal Start Event* inside the sub-process rectangle and specify the signal name with the value `optOut.Lead.{$id}`. You also need to check the parameter *Is Interrupting* for this event. By setting this parameter, we indicate that the whole parent process should be interrupted once the event is catched.
-Here, inside the sub-process, you can also add *Task* that will do some manipulations with the target record (*Lead*).
+Here, inside the sub-process, you can also add a *Task* that will do some manipulations with the target record (Lead).
## Example
diff --git a/docs/administration/bpm-events.md b/docs/administration/bpm-events.md
index 13618d15e..0cda84eb1 100644
--- a/docs/administration/bpm-events.md
+++ b/docs/administration/bpm-events.md
@@ -1,6 +1,15 @@
# BPM Events
-Events are displayed on a flowchart as circles.
+Events represent something that happens during a business process. They also start, end and interrupt a process flow. Depicted as a circle.
+
+Events can be divided into the following groups:
+
+* Start – green circle. They are entry points of processes and sub-processes.
+* Intermediate – blue circle. Occur between start and end events in a process. Can throw or catch.
+* End – red circle. Define final points of process flows.
+* Boundary – blue circle attached to an activity. They allow to interact with running activities. Technically, they are intermediate catching events.
+
+All available events:
* Start Events
* [Start](#start-event)
@@ -9,6 +18,7 @@ Events are displayed on a flowchart as circles.
* [Signal](#signal-start-event)
* [Error](#error-start-event)
* [Escalation](#escalation-start-event)
+ * [Compensation](#compensation-start-event)
* Intermediate Events
* [Conditional (catching)](#conditional-intermediate-event-catching)
* [Timer (catching)](#timer-intermediate-event-catching)
@@ -16,12 +26,14 @@ Events are displayed on a flowchart as circles.
* [Signal (throwing)](#signal-intermediate-event-throwing)
* [Message (catching)](#message-intermediate-event-catching)
* [Escalation (throwing)](#escalation-intermediate-event-throwing)
+ * [Compensation (throwing)](#compensation-intermediate-event-throwing)
* End Events
* [End](#end-event)
* [Terminate](#terminate-end-event)
* [Error](#error-end-event)
* [Escalation](#escalation-end-event)
* [Signal](#signal-end-event)
+ * [Compensation](#compensation-end-event)
* Boundary Events
* [Error](#error-intermediate-event-boundary)
* [Conditional](#conditional-intermediate-event-boundary)
@@ -29,6 +41,7 @@ Events are displayed on a flowchart as circles.
* [Escalation](#escalation-intermediate-event-boundary)
* [Signal](#signal-intermediate-event-boundary)
* [Message](#message-intermediate-event-boundary)
+ * [Compensation](#compensation-intermediate-event-boundary)
----
@@ -36,31 +49,35 @@ Events are displayed on a flowchart as circles.
### Start Event
-Doesn't have parameters. It's a starting point of the process. Start Event can be initiated manually by a user who has an access to create processes. The user needs to click 'Start Process' button on the list view of processes.
+Doesn't have parameters. It's a starting point of the process. A Start Event can be initiated manually by a user who has access to create processes. This can be done either from the processes list view or from the detail view of a target record.

-Can be used as an entry point of a sub-process.
+Can be also used as an entry point of a sub-process.

### Conditional Start Event
-A starting point of the process. It's supposed to be triggered automatically when specified conditions are met. There are two types of triggers: 'After record created', 'After record saved'.
+A starting point of a process. It's supposed to be triggered automatically when specified conditions are met. There are three types of triggers: 'After record created', 'After record updated', and 'After record saved'. Event conditions are defined in the same way as conditions in the Workflows tool. See [here](workflows.md#conditions).

-Can be used to start an event sub-process.
+Can be also used to start an event sub-process.

+!!! note
+
+ When used to start an event sub-process, the Boundary Start Event is not synced with the flow. Condition checking is run in idle which may cause some delay. A flowchart design should not rely on a condition event being checked immediately.
+
### Timer Start Event
-A starting point of the process. It initiates processes by scheduling. You need to specify the list report that returns records for initiating processes and scheduling in crontab notation.
+A starting point of a process. It initiates processes by scheduling. You need to select a list report (which returns records, each one will initiate a separate process) and specify execution scheduling (in the crontab notation).

-Can be used to start an event sub-process.
+Can be also used to start an event sub-process. In this case, it is scheduled to be triggered at time defined by event parameters.

@@ -68,13 +85,17 @@ Can be used to start an event sub-process.
Can be used to start processes and event sub-processes.
-When it is used to start a process, only object signals can be used.
+When it's used to start a process, only *object signals* can be used.
+
+When it's used to start an event sub-process, it's possible to use placeholders in a signal name. Example: `test.{$id}`, {$id} will be replaced with the ID of the target record.
-When it is used to start an event sub-process, it's possible to use placeholders in a signal name. Example: `test.{$id}`, {$id} will be replaced with target's id.
+!!! note
-Note: Signals are not limited by a process scope. Signal triggered in one BPM process can be caught in another process.
+ Signals are not limited by a process scope. Signal triggered in one BPM process can be caught in another process.
-Note: Signal name can not be empty.
+!!! note
+
+ Signal name cannot be empty.

@@ -84,59 +105,90 @@ See [more info](bpm-signals.md) about signals.
Can only be used to start an event sub-process. It's triggered once an error event is thrown within the same process.
-If Error Code is specified, it will be triggered only when an error with the same code occurs. If Error Code is empty, it will catch any error.
+If the *Error Code* is specified, the event will be triggered only when an error with the same code occurs. If the *Error Code* is empty, it will catch any error.
-It can't be non interrupting, because a process gets terminated once an error event is thrown.
+It cannot be non-interrupting, because the process gets terminated once an error event is thrown.

+It's possible to view an error code and message in the flow log.
+
+The error code and the exception message can be obtained further in the flow with Formula functions `bpm\caughtErrorCode` and `bpm\caughtErrorMessage`.
+
+!!! note
+
+ When an error event sub-process is defined inside a regular sub-process, it can be reasonable to re-throw the error in the end
+ of the event sub-process with the Error End Event. It will propagate the error to the top level.
+
### Escalation Start Event
-Can only be used to start an event sub-process. It's triggered once an escalation event it thrown within the same process.
+Can be used only to start an event sub-process. It's triggered once an escalation event it thrown within the same process.
-If Escalation Code is specified, it will be triggered only when an escalation with the same code occurs. If Escalation Code is empty, it will catch any escalation.
+If the Escalation Code is specified, it will be triggered only when an escalation with the same code occurs. If the Escalation Code is empty, it will catch any escalation.

+### Compensation Start Event
+
+*As of v2.14.*
+
+Starts a sub-process compensation handler. Can be used only in an event sub-process.
+
+When the parent process initiates compensation for the sub-process activity, if there's no boundary compensation event attached to that activity, it will check whether the sub-process contains an event sub-process with a compensation start event (called Compensation Handler). Then, it executes the compensation handler. The compensation handler usually is supposed to explicitly throw compensation events to compensate activities of the sub-process.
+
+
+
+!!! note
+
+ Actual only when the event sub-process is inside a regular sub-process.
+
+In case of a multi-instance sub-process, the compensation handler is processed for each completed instance of the sub-process.
+
----
## Intermediate Events
### Conditional Intermediate Event (Catching)
-This event stops the flow until specified criteria is met.
+This event stops the flow until specified criteria is met. Event conditions are defined in the same way as conditions in the Workflow tool. See [here](workflows.md#conditions). Note that BPM tool introduces [additional functions](bpm-formula.md) that can be used in a Formula script.

### Timer Intermediate Event (Catching)
-This event stops the flow and waits as long as it is specified by the event's parameters.
+This event stops the flow and waits as long as it's determined by event's parameters.
-For more complex timer settings you can utilize [formula](formula.md). Formula scripts should return Date-Time value (in UTC timezone). Once this time comes, the flow will be proceeded to the next element.
+For more complex timer settings you can utilize a [Formula](formula.md) script. Formula scripts should return a Date-Time value (date-time string in the UTC timezone). Once this time arrives, the flow is proceeded to the next element.
-By utilizing datetime\closest formula function it's possible to set the timer to a specific time in the future, e.g. the beginning of the next working day.
+By utilizing *datetime\closest* Formula function, it's possible to set the timer to a specific time in the future, e.g. the beginning of the next working day.

### Signal Intermediate Event (Catching)
-Stops the flow until a specific signal catched. Placeholders can be used in a signal name.
+Stops the flow until a specific signal is catched. Placeholders can be used in a signal name.
+
+!!! note
-Note: Signal name can not be empty.
+ Signal name can not be empty.
See [more info](bpm-signals.md) about signals.
### Signal Intermediate Event (Throwing)
-Broadcasts a specified signal. Placeholders can be used in a signal name. Example: `test.{$id}`, {$id} will be replaced with target's id.
+Broadcasts a specified signal. Placeholders can be used in a signal name. Example: `test.{$id}`, {$id} will be replaced with the ID of the target record.
-If the first character of the signal name is `@`, it will broadcast an object signal along with the current target record. This signal type can be used only to initiate a new process or trigger a workflow rule.
+If the first character of a signal name is `@`, it will broadcast an object signal along with the current target record. This signal type can be used only to initiate a new process or trigger a workflow rule.

-Note: Signals are not limited by a process scope. Signal triggered in one BPM process can be caught in another process.
+!!! note
+
+ Signals are not limited by a process scope. Signal triggered in one BPM process can be caught in another process.
-Note: Signal name can not be empty.
+!!! note
+
+ Signal name can not be empty.
See [more info](bpm-signals.md) about signals.
@@ -146,20 +198,29 @@ Stops the flow until an email is received.
Only emails sent not by internal users can trigger the event.
-It's possible to utilize the event in pair with *Send Message* task. The event will wait until the sent email is replied. Specify that email in *Replied To* parameter.
+It's possible to utilize the event in pair with the *Send Message* task. The event will wait until the sent email is replied. Specify that email in the *Replied To* parameter.
-*Related To* parameter requires that email was related (via Parent field) to a specific record.
+The *Related To* parameter requires that the email was related (via the Parent field) to a specific record.
-There is the ability to specify formula conditions that the email should satisfy to trigger the event. You can utilize it to skip auto-response emails or to catch emails containing a specific ID. Formula example: `string\contains(body, $id)`.
+There is the ability to specify Formula conditions that the email should satisfy to trigger the event. You can utilize it to skip auto-response emails or to catch emails containing a specific ID. Formula example: `string\contains(body, $id)`.

### Escalation Intermediate Event (Throwing)
-Throws an escalation. Escalation Code can be specified. Escalation can be catched by a boundary event (if it's thrown within a sub-process) or by event sub-process.
+Throws an escalation. The Escalation Code can be specified. An escalation can be catched by a boundary event (if it's thrown within a sub-process) or by an event sub-process.

+### Compensation Intermediate Event (Throwing)
+
+*As of v2.14.*
+
+Behaves the same as the [compensation end event](#compensation-end-event) with the only difference that it continues flow execution to the next element.
+
+Can be useful to ensure processing of multiple compensations in a specific order.
+
+
----
@@ -167,26 +228,29 @@ Throws an escalation. Escalation Code can be specified. Escalation can be catche
### End Event
-Ends the current flow. It doesn't end flows running in parallel. When the flow reaches the end event and there isn't anything running in parallel, then process ends.
+Ends the current flow. It doesn't end flows running in parallel. When the flow reaches an end event and there isn't anything running in parallel, then the process ends.

### Terminate End Event
-Ends all flows. Process is subsequently ended.
+Ends all flows. The process is subsequently ended.

-
### Error End Event
-Terminates the process and triggers an error. Error Code can be specified. Error can be catched by a boundary event (if it's thrown within a sub-process) or by event sub-process.
+Terminates the process and triggers an error. The Error Code can be specified. The error can be catched by a boundary event (if it's thrown within a sub-process) or by an event sub-process.

+!!! note
+
+ Uncaught errors are propagated to the parent process.
+
### Escalation End Event
-Ends the flow and triggers an escalation. Escalation Code can be specified. Escalation can be catched by a boundary event (if it's thrown within a sub-process) or by event sub-process.
+Ends the flow and triggers an escalation. The Escalation Code can be specified. The escalation can be catched by a boundary event (if it's thrown within a sub-process) or by an event sub-process.

@@ -194,40 +258,79 @@ Ends the flow and triggers an escalation. Escalation Code can be specified. Esca
Ends the flow and broadcasts a specified signal.
-Placeholders can be used in a signal name. Example: `test.{$id}`, {$id} will be replaced with target's id.
+Placeholders can be used in a signal name. Example: `test.{$id}`, {$id} will be replaced with the ID of the target record.
If the first character of the signal name is `@`, it will broadcast an object signal along with the current target record. This signal type can be used only to initiate a new process or trigger a workflow rule.
-Note: Signals are not limited by a process scope. Signal triggered in one BPM process can be caught in another process.
+!!! note
+
+ Signals are not limited by a process scope. A signal triggered in one BPM process can be caught in another process.
-Note: Signal name can not be empty.
+!!! note
+
+ Signal name can not be empty.
See [more info](bpm-signals.md) about signals.
+### Compensation End Event
+
+*As of v2.14.*
+
+Initiates compensation and ends the flow once compensation is completed.
+
+Can compensate a specific activity (by specifying an activity's ID, the activity ID can be obtained on the detail view of the activity) or all activities (that are visible from the event). Only completed activities (not failed or interrupted) are compensated.
+
+An activity is considered visible from the throwing Event when:
+
+* It is contained in normal flow at the same level of the process/sub-process.
+* It is contained in the parent process/sub-process of an event sub-process in which the Event is contained.
+
+In the same level:
+
+
+
+From the event sub-process:
+
+
+
+When the activity ID is omitted, all visible completed activities are compensated in the order reverse to their instantiation.
+
+Compensation is supposed to perform undo actions when something went wrong. Usually, compensation is triggered from error handlers.
+
----
## Boundary Events
-Boundary events can be attached to activities (usually sub-processes). Boundary event can interrupt an activity (if param *Is Interrupting* is checked). Non interrupting boundary event can be triggered multiple times.
-
+Boundary events can be attached to activities (usually sub-processes). Boundary event can interrupt an activity (if the *Is Interrupting* parameter is checked). Non-interrupting boundary event can be triggered multiple times.
### Error Intermediate Event (Boundary)
-It's triggered once an error event is thrown withing the activity (sub-process) it's attached to.
+It's triggered once an error event is thrown within the activity (sub-process) it's attached to.
-It can't be non interrupting, because the activity gets terminated once an error event is thrown.
+It cannot be non-interrupting, because the activity gets terminated once an error event is thrown.
-If Error Code is specified, it will be triggered only when an error with the same code occurs. If Error Code is empty, it will catch any error.
+If the Error Code is specified, it will be triggered only when an error with the same code occurs. If the Error Code is empty, it will catch any error.

+It's possible to view the error code and the exception message in the flow log.
+
+The error code and the exception message can be obtained further in the flow with Formula functions `bpm\caughtErrorCode` and `bpm\caughtErrorMessage`.
+
+!!! note
+
+ If the error event is attached to a task with the *Send HTTP Request* action, it's possible to catch a specific response error code (e.g. 404, 403).
+
### Conditional Intermediate Event (Boundary)
-Triggered when specific conditions are met. Note, that non interrupting event can be triggered multiple times, when coditions get met, then get not met, and met again.
+Triggered when specific conditions are met. Note that same non-interrupting events can be triggered multiple times. First, when conditions get fulfilled, then, when conditions get unfulfilled, and so on.

+!!! note
+
+ The Boundary Conditional Event is not synced with the flow. Condition checking is run in idle which may cause some delay. A flowchart design should not rely on a boundary condition event being checked immediately.
### Timer Intermediate Event (Boundary)
@@ -240,20 +343,36 @@ Triggered after a specific period of time. The timer starts once the activity st
It's triggered once an escalation event is thrown within the activity (sub-process) it's attached to.
-If Escalation Code is specified, it will be triggered only when an escalation with the same code occurs. If Escalation Code is empty, it will catch any escalation.
-
+If the Escalation Code is specified, it will be triggered only when an escalation with the same code occurs. If the Escalation Code is empty, it will catch any escalation.

### Signal Intermediate Event (Boundary)
-It's triggered once a specific signal is broadcasted. Note, that a signal can be triggered from anywhere in the system, not necessarily in the same process.
+It's triggered once a specific signal is broadcasted. Note that a signal can be triggered from anywhere in the system, not necessarily from the same process.
-Placeholders can be used in a signal name. E.g. `test.{$id}`, {$id} will be replaced with target's id.
+Placeholders can be used in a signal name. E.g. `test.{$id}`, {$id} will be replaced with the target's ID.

### Message Intermediate Event (Boundary)
Triggered once an email is received. It functions the same as *Message Intermediate Event (Catching)*.
+
+### Compensation Intermediate Event (Boundary)
+
+*As of v2.14.*
+
+Triggered once compensation is initiated for an activity it is attached to. Must be connected with a compensation activity (task or sub-process).
+
+
+
+!!! note
+
+ Compensation can be applied only for activities that were successfully completed.
+
+When it's a sub-process being compensated, the compensation activity does not have access to the sub-process internal state (called Black-Box compensation). To be able to access the internal state, use the compensation event sub-process inside the sub-process instead.
+
+In case of a multi-instance sub-process, the compensation activity is processed for each completed instance of the sub-process.
+
diff --git a/docs/administration/bpm-examples.md b/docs/administration/bpm-examples.md
index 9cca929ff..f52f180d1 100644
--- a/docs/administration/bpm-examples.md
+++ b/docs/administration/bpm-examples.md
@@ -2,13 +2,15 @@
## Downloadable examples
-You can download CSV file with examples and then import it into your EspoCRM instance.
+You can download the CSV file with examples and then import it into your EspoCRM instance.
-1. Download [CSV file](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/csv/bpm-examples.csv) with examples.
-2. In your EspoCRM, go to Administration > Import, select *Process Flowchart* entity type and upload the CSV file. Go throgh import steps.
-3. You will be able to find examples at Administration > Flowcharts.
+1. Download the [CSV file](https://raw.githubusercontent.com/espocrm/documentation/master/docs/_static/csv/bpm-examples.csv) with examples.
+2. In your EspoCRM, go to Administration > Import, select *Process Flowchart* entity type and upload the CSV file. Go through import steps.
+3. You will find imported examples under Administration > Flowcharts.
-Note: These flowcharts are not active, so they won't run until you set them active.
+!!! note
+
+ These flowcharts are not active, so they won't run until you set them active.
Included examples:
diff --git a/docs/administration/bpm-formula.md b/docs/administration/bpm-formula.md
new file mode 100644
index 000000000..fb548ed4f
--- /dev/null
+++ b/docs/administration/bpm-formula.md
@@ -0,0 +1,102 @@
+# BPM Formula Functions
+
+The [BPM tool](bpm.md) provides additional formula functions.
+
+A Formula script can be utilized in conditions, script tasks, and various task actions. Some functions can be used in a workflow (broadcastSignal, startProcess).
+
+* [bpm\targetEntity\attribute](#bpmtargetentityattribute)
+* [bpm\createdEntity\attribute](#bpmcreatedentityattribute)
+* [bpm\processEntity\attribute](#bpmprocessentityattribute)
+* [bpm\startProcess](#bpmstartprocess)
+* [bpm\broadcastSignal](#bpmbroadcastsignal)
+* [bpm\caughtErrorCode](#bpmcaughterrorcode)
+* [bpm\caughtErrorMessage](#bpmcaughterrormessage)
+
+### bpm\targetEntity\attribute
+
+`bpm\targetEntity\attribute(ATTRIBUTE)`
+
+Fetches an attribute value of a target record.
+
+### bpm\createdEntity\attribute
+
+`bpm\createdEntity\attribute(ALIAS_ID, ATTRIBUTE)`
+
+Fetches an attribute value of a record created within a process.
+
+Available records:
+
+* records created within *Task* activities;
+* user tasks;
+* sent messages.
+
+ALIAS_ID can be obtained:
+
+* from the detail view of a *Task* that has an action that creates a record;
+* from the detail view of a *User Task* (ID field);
+* from the detail view of a *Send Message Task* (ID field).
+
+!!! example
+
+ ```
+ $resolutionNote = bpm\createdEntity\attribute('e6cmwnd894', 'resolutionNote');
+ ```
+
+### bpm\processEntity\attribute
+
+`bpm\processEntity\attribute(ATTRIBUTE)`
+
+Fetches an attribute value of a process record.
+
+### bpm\startProcess
+
+`bpm\startProcess(FLOWCHART_ID, TARGET_TYPE, TARGET_ID, [ELEMENT_ID])`
+
+Starts a process.
+
+!!! example
+
+ `bpm\startProcess('flowchart-id', 'Account', 'account-id');`
+
+### bpm\broadcastSignal
+
+* `bpm\broadcastSignal(SIGNAL_NAME)` – broadcast a regular signal
+* `bpm\broadcastSignal(SIGNAL_NAME, ENTITY_TYPE, ENTITY_ID)` – broadcast an object signal
+
+It can be useful to broadcast a custom signal from a workflow rule and then catch it inside a running process. A workflow rule will perform some condition checking and only after that will broadcast the signal.
+
+!!! example "Example, regular signal"
+
+ ```
+ $signalName = string\concatenate(
+ 'notePostedInCaseBySupportManager.',
+ entity\attribute('id')
+ );
+
+ bpm\broadcastSignal($signalName);
+ ```
+
+ Then it will be possible to catch the signal in a BPM process by listening to the signal `notePostedInCaseBySupportManager.{$id}`.
+
+!!! example "Example, object signal"
+
+ Workflow on Quote Item broadcasts a signal when amount is changed.
+
+ ```
+ bpm\broadcastSignal('@quoteItemIsChanged', 'Quote', entity\attribute('quoteId'));
+ ```
+
+ Then it will be possible to catch the signal by a workflow. It can be useful for situations when you need to recalculate something when a related record is changed.
+
+
+### bpm\caughtErrorCode
+
+*As of v2.14.*
+
+Returns the code of a caught error. Error codes are of the string type. Can be used after a catching Error Event.
+
+### bpm\caughtErrorMessage
+
+*As of v2.14.*
+
+Returns the message of a caught exception. Can be used after a catching Error Event.
diff --git a/docs/administration/bpm-gateways.md b/docs/administration/bpm-gateways.md
index ea9681e4a..ee4a64671 100644
--- a/docs/administration/bpm-gateways.md
+++ b/docs/administration/bpm-gateways.md
@@ -1,6 +1,6 @@
# BPM Gateways
-Gateways are displayed as diamonds.
+Gateways diverge and converge flows. Depicted as a yellow diamond. They can be used to determine a path in which the flow will go depending on specific conditions. They can split a flow into multiple parallel flows and join parallel flows into a single one.
* [Exclusive](#exclusive-gateway)
* [Inclusive](#inclusive-gateway)
@@ -13,9 +13,13 @@ Gateways are displayed as diamonds.
Can diverge or converge flows.
-In case of diverging it defines a single flow (path) that will be chosen according specified criteria. The first met condition determines the flow, next conditions are omitted. There is an ability to specify default flow. Default flow is chosen if there are no met conditions. Default flow is marked with a slash sign. There must be at least two outgoing flows to be able to specify diverging criteria.
+In case of diverging, it defines a single flow (path) that will be chosen according specified criteria. The first met condition determines the flow, next conditions are omitted. There is the ability to specify a default flow. The default flow will be chosen if there are no conditions met. The default flow is marked with a slash sign.
-In case of converging it just directs the flow to the outgoing element. It doesn't get blocked after the flow come though, so parallel flows won't be merged into the single flow.
+!!! important
+
+ There must be at least two outgoing flows to be able to specify diverging criteria.
+
+In case of converging, it just directs the flow to the outgoing element. It does not block the flow, hence parallel flows won't be merged into a single flow.

@@ -27,15 +31,23 @@ In case of converging it just directs the flow to the outgoing element. It doesn
Can diverge or converge flows.
-In case of diverging, it can direct to one or multiple parallel flows (paths), depending on accomplishment of criteria of each flow. Default flow is chosen if there are no met conditions. Default flow is marked with a slash sign. There must be at least two outgoing flows to be able to specify diverging criteria.
+In case of diverging, it can direct to one or multiple parallel flows (paths), depending on accomplishment of criteria of each flow. The default flow is chosen if there are no met conditions. The default flow is marked with a slash sign.
+
+!!! important
+
+ There must be at least two outgoing flows to be able to specify diverging criteria.
-If there is a necessity to merge parallel flows produced by a diverging inclusive gateway you need to use a converging inclusive gateway. It will wait for all incoming flows and then continue to the outgoing element.
+If there is a necessity to merge parallel flows produced by a diverging inclusive gateway, you need to use a converging inclusive gateway. It will wait for all incoming flows and only then will continue to the outgoing element.

-Note: Diverging and converging gateways must be balanced.
+!!! note
-Note: If one of parallel flows has been ended for some reason, then diverging gateway will never be processed. The process will be blocked. Avoid a flowchart design that can bring about such a situation.
+ Diverging and converging gateways must be balanced. The number of flows outgoing from a diverging gateway should equal the number of flows incoming to a converging gateway. If between these gateways one of flows splits into nested parallel flows, these nested flows must be converged before the outer converging gateway. And so on.
+
+!!! note
+
+ If one of parallel flows has been ended for some reason, then the diverging converging will never be processed. The process will be blocked. Avoid the flowchart design that can bring about such a situation.
----
@@ -43,15 +55,19 @@ Note: If one of parallel flows has been ended for some reason, then diverging ga
Can diverge or converge flows.
-In case of diverging it splits flow into multiple parallel flows. There are no parameters for this gateway type.
+In case of diverging, it splits the flow into multiple parallel flows. There are no parameters for this gateway type.
-In case of converging it waits until all incoming flows come and then continues to the next outgoing element.
+In case of converging, it waits until all incoming flows come and only then continues to the next outgoing element.

-Note: Diverging and converging gateways must be balanced.
+!!! note
+
+ Diverging and converging gateways must be balanced. The number of flows outgoing from a diverging gateway should equal the number of flows incoming to a converging gateway. If between these gateways one of flows splits into nested parallel flows, these nested flows must be converged before the outer converging gateway. And so on.
+
+!!! note
-Note: If one of parallel flows has been ended for some reason, then diverging gateway will never be processed. The process will be blocked. Avoid a flowchart design that can bring about such a situation.
+ If one of parallel flows has been ended for some reason, then diverging gateway will never be processed. The process will be blocked. Avoid the flowchart design that can bring about such a situation.
----
@@ -59,7 +75,7 @@ Note: If one of parallel flows has been ended for some reason, then diverging ga
Can only diverge flows.
-It stops the flow until any of outgoing events gets triggered. Triggered event determines the single flow. Other outgoing events get rejected.
+It stops the flow until any of outgoing events gets triggered. The triggered event determines the single flow. Other outgoing events get rejected.
Only intermediate events can be on the other end of outgoing sequence flows.
diff --git a/docs/administration/bpm-signals.md b/docs/administration/bpm-signals.md
index 4e4dcf972..bd239d9c5 100644
--- a/docs/administration/bpm-signals.md
+++ b/docs/administration/bpm-signals.md
@@ -1,12 +1,15 @@
# Signals
-Signals are events with a specific name. Signals are broadcasted globally, they are not limited by a process scope. It means that signal triggered in one BPM process can be caught in another process.
+Signals are events with a specific name. Signals are broadcasted globally, they are not limited by a process scope. It means that a signal triggered in one BPM process can be caught in another process.
-Signals feature is a part of Advanced Pack extension and can be utilized in BPM and Workflows tools.
+The signals feature is a part of the Advanced Pack extension and can be utilized in the BPM and Workflows tools.
-There are set of standard signals which are broadcasted upon specific events in the application. These *built-in signals* are listed below in the article.
+How signals are broadcasted:
-It's also possible to broadcast custom signals in BPM process or via code.
+* There are set of standard signals which are broadcasted upon specific events in the application. These *built-in signals* are listed below in the article.
+* It's possible to broadcast [custom signals](bpm-events.md#signal-intermediate-event-throwing) in a BPM process.
+* It's possible to broadcast custom signals using the [Formula function](bpm-formula.md#bpmbroadcastsignal) `bpm\broadcastSignal(SIGNAL_NAME)`.
+* It's possible to broadcast custom signals via PHP code.
There are two types of signals:
@@ -22,109 +25,128 @@ In this article:
## Regular signals
* Can be broadcasted and caught within a running process.
-* Can't be used to start a process or workflow rule.
+* Cannot be used to start a process or a workflow rule.
-Note: Signal Intermediate Events can catch and throw regular signals (in BPM process).
+In BPM processes, the *Signal Intermediate Events* can catch and throw only regular signals.
### Built-in signals
-Note: Parts in upper case (ENTITY_TYPE, ID, LINK_NAME, etc.) will/should be replaced by corresponding values.
+Below is the list of available out-of-the-box signals which are broadcasted in the system upon specific conditions.
-#### Default
-
-* *create.ENTITY_TYPE* – record of ENTITY_TYPE created, e.g. `create.Lead`
-* *update.ENTITY_TYPE.ID* – record update, e.g. `update.Lead.007`
-* *delete.ENTITY_TYPE.ID* – record removed
-* *relate.ENTITY_TYPE.ID.LINK_NAME* – record related with another record (only for *many-to-many*)
-* *relate.ENTITY_TYPE.ID.LINK_NAME.FOREIGN_ID* – record related with another record, id of related recod is specified (only for *many-to-many*)
-* *unrelate.ENTITY_TYPE.ID.LINK_NAME* – record unrelated from another record (only for *many-to-many*)
-* *unrelate.ENTITY_TYPE.ID.LINK_NAME.FOREIGN_ID* – (only for *many-to-many*)
-* *createRelated.ENTITY_TYPE.ID.LINK_NAME* – created celated record, one-to-many relationship, e.g. Opportunity created for Account
-* *createChild.ENTITY_TYPE.ID.CHILD_ENTITY_TYPE* – when created a record related through parent, e.g. Meeting created for Account
-* *streamPost.ENTITY_TYPE.ID* – when somebody posted in stream
+!!! note
-#### Contacts/Leads
+ Signal name parts written in the upper case (e.g. ENTITY_TYPE, ID, LINK_NAME) must be replaced with corresponding values. E.g. when an Account with an ID `abc01` is updated, a signal `update.Account.abc01` is broadcasted. See the naming clarification below.
-* *leadCapture.ENTITY_TYPE.ID* – when lead (or contact) is processed through Lead Capture (confirmed opt-in if it's enabled)
-* *leadCapture.ENTITY_TYPE.ID.LEAD_CAPTURE_ID* – the same, but id of Lead Capture record is specified
+#### Default
-* *optOut.ENTITY_TYPE.ID* – person opted-out
-* *optOut.ENTITY_TYPE.ID.TARGET_LIST_ID* – person opted-out from specific target list
-* *cancelOptOut.ENTITY_TYPE.ID* – person opted-in again
-* *cancelOptOut.ENTITY_TYPE.ID.TARGET_LIST_ID*
+* `create.ENTITY_TYPE` – record of ENTITY_TYPE created, e.g. `create.Lead`;
+* `update.ENTITY_TYPE.ID` – record update, e.g. `update.Lead.aabbcc01`;
+* `delete.ENTITY_TYPE.ID` – record removed;
+* `relate.ENTITY_TYPE.ID.LINK_NAME` – record related with another record (only for *many-to-many*);
+* `relate.ENTITY_TYPE.ID.LINK_NAME.FOREIGN_ID` – record related with another record, ID of the related record is specified (only for *many-to-many*);
+* `unrelate.ENTITY_TYPE.ID.LINK_NAME` – record unrelated from another record (only for *many-to-many*);
+* `unrelate.ENTITY_TYPE.ID.LINK_NAME.FOREIGN_ID` – (only for *many-to-many*);
+* `createRelated.ENTITY_TYPE.ID.LINK_NAME` – created a related record, one-to-many relationship, e.g. Opportunity created for Account;
+* `createChild.ENTITY_TYPE.ID.CHILD_ENTITY_TYPE` – when created a record related through a parent, e.g. Meeting created for Account;
+* `streamPost.ENTITY_TYPE.ID` – when somebody posted in the stream;
-* *eventAccepted.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE* – person accepted meeting/call invitation
-* *eventAccepted.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID* – person accepted meeting/call invitation, event id is specified
+#### Contacts/Leads
-* *eventTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE* – person set Tentative status in meeting/call invitation
-* *eventTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID*
+* `leadCapture.ENTITY_TYPE.ID` – when a Lead (or Contact) is processed through the Lead Capture (confirmed opt-in if the double opt-in is enabled);
+* `leadCapture.ENTITY_TYPE.ID.LEAD_CAPTURE_ID` – the same, but the ID of a Lead Capture record is specified;
+* `optOut.ENTITY_TYPE.ID` – person opted-out;
+* `optOut.ENTITY_TYPE.ID.TARGET_LIST_ID` – person opted-out from a specific target list;
+* `cancelOptOut.ENTITY_TYPE.ID` – person opted-in again;
+* `cancelOptOut.ENTITY_TYPE.ID.TARGET_LIST_ID`;
+* `eventAccepted.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE` – person accepted a meeting/call invitation;
+* `eventAccepted.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID` – person accepted a meeting/call invitation, event id is specified;
+* `eventTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE` – person set Tentative status in a meeting/call invitation;
+* `eventTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID`;
+* `eventAcceptedTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE` – person set Accepted or Tentative status in a meeting/call invitation;
+* `eventAcceptedTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID`;
+* `eventDeclined.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE` – person declined a meeting/call invitation;
+* `eventDeclined.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID`
-* *eventAcceptedTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE* – person set Accepted or Tentative status in meeting/call invitation
-* *eventAcceptedTentative.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID*
+#### Contacts/Leads/Accounts/Users
-* *eventDeclined.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE* – person declined meeting/call invitation
-* *eventDeclined.ENTITY_TYPE.ID.EVENT_ENTITY_TYPE.EVENT_ID*
+* `clickUrl.ENTITY_TYPE.ID` – recipient opened a tracking URL , see [here](bpm-tracking-urls.md);
+* `clickUrl.ENTITY_TYPE.ID.CAMPAIGN_TRACKING_URL_ID` – recipient opened a specific tracking URL;
-#### Contacts/Leads/Accounts/Users
+#### Other
-* *clickUrl.ENTITY_TYPE.ID* – recipient opened a tracking url
-* *clickUrl.ENTITY_TYPE.ID.CAMPAIGN_TRACKING_URL_ID* – recipient opened a specfic tracking url
+* `clickUniqueUrl.UNIQUE_ID` – recipient opened a tracking URL with a unique ID, see [here](bpm-tracking-urls.md);
### Placeholders
-You can use placeholders when you define a signal name that will be broadcasted by the throwing event in the BPM process.
+When defining a signal name in Signal Events in a BPM Flowchart, you can use placeholders:
* `{$attribute}` – attribute of target record
* `{$$variable}` – formula variable
-E.g. `mySignal.{$status}.{$id}` – *type* and *id* are attributes of the target record. Placeholders will be replaced with attribute values, so the actual signal name will look like `mySigal.New.someIdValue`.
-
+E.g. `mySignal.{$status}.{$id}` – *status* and *id* are attributes of the target record. Placeholders will be replaced with attribute values, so the actual signal name will look like `mySignal.New.someIdValue`.
## Object signals
* Broadcasted along with the entity (record).
* Prefixed with `@` character.
* Can be used only to initiate a new process or workflow rule.
-* Can't by caught withing a running process.
+* Can't be caught within a running process.
* Can be broadcasted by a running process.
-Note: Signal Intermediate Event (Catching) can't catch object signals.
+!!! note
-Example: A process triggers signal *@approve*. A target record of *Lead* entity type is attached to the signal. You have another BPM flowchart for *Lead* entity type that starts with *@approve* signal. In this case, a new process will be started, and lead record from the first process will be passed as a target record of the second process.
+ Signal Intermediate Event (Catching) can't catch object signals.
+
+Example: A process triggers signal *@approve*. A target record of the *Lead* entity type is attached to the signal. You have another BPM flowchart for the *Lead* entity type that starts with the *@approve* signal. In this case, a new process will be started, and the Lead record from the first process will be passed as a target record of the second process.
### Built-in signals
-Note: Parts in upper case (LINK_NAME, FOREIGN_ID, etc.) will/should be replaced by corresponding values.
+Below is the list of available out-of-the-box signals that are broadcasted in the system.
+
+!!! note
+
+ Signal name parts written in the upper case (e.g LINK_NAME, FOREIGN_ID) must be replaced with corresponding values. See the naming clarification below.
#### Default
-* *@create* – record created
-* *@update* – record updated
-* *@delete* – record removed
-* *@relate.LINK_NAME* – record related with another record (only for *many-to-many*)
-* *@relate.LINK_NAME.FOREIGN_ID* – record related with another record, id of related recod is specified (only for *many-to-many*)
-* *@unrelate.LINK_NAME* – record unrelated from another record (only for *many-to-many*)
-* *@unrelate.LINK_NAME.FOREIGN_ID*
+* `@create` – record created;
+* `@update` – record updated;
+* `@delete` – record removed (can't be used in BPM);
+* `@relate.LINK_NAME` – record related with another record (only for *many-to-many*); the foreign ID is passed in the `id` parameter;
+* `@relate.LINK_NAME.FOREIGN_ID` – record related with another record, an ID of related record is specified (only for *many-to-many*);
+* `@unrelate.LINK_NAME` – record unrelated from another record; the foreign ID is passed in the `id` parameter;
+* `@unrelate.LINK_NAME.FOREIGN_ID`
#### Contacts/Leads:
-* *@leadCapture* – when lead (or contact) is processed through Lead Capture (confirmed opt-in if it's enabled)
-* *@leadCapture.LEAD_CAPTURE_ID*
-* *@optOut* – person opted-out
-* *@optOut.TARGET_LIST_ID* – person opted-out from specific target list
-* *@cancelOptOut* – person opted-in again
-* *@cancelOptOut.TARGET_LIST_ID*
+* `@leadCapture` – when a Lead (or Contact) is processed through the Lead Capture (confirmed opt-in if it's enabled);
+* `@leadCapture.LEAD_CAPTURE_ID`
+* `@optOut` – person opted-out;
+* `@optOut.TARGET_LIST_ID` – person opted-out from a specific target list;
+* `@cancelOptOut` – person opted-in again;
+* `@cancelOptOut.TARGET_LIST_ID`
#### Contacts/Leads/Accounts/Users
-* *@clickUrl* – recipient opened a tracking url
-* *@clickUrl.CAMPAIGN_TRACKING_URL_ID* – recipient opened a specfic tracking url
+* `@clickUrl` – recipient opened a tracking URL;
+* `@clickUrl.CAMPAIGN_TRACKING_URL_ID` – recipient opened a specific tracking URL;
+#### Meetings/Calls/Events
-## Naming clarification
+* `@eventAccepted.ENTITY_TYPE` – an attendee accepted the event (ENTITY_TYPE can be *Contact*, *Lead*, *User*; as of v3.0.13); the foreign ID is passed in the `id` parameter;
+* `@eventTentative.ENTITY_TYPE` – an attendee set a tentative acceptance status; the foreign ID is passed in the `id` parameter;
+* `@eventDeclined.ENTITY_TYPE` – an attendee declined the event; the foreign ID is passed in the `id` parameter;
+* `@eventAcceptedTentative.ENTITY_TYPE` – an attendee accepted the event or set as tentative (ENTITY_TYPE can be *Contact*, *Lead*, *User*; as of v3.0.13); the foreign ID is passed in the `id` parameter;
-* *ID* – ID of a record that you can obtain from the browser address bar
-* *ENTITY_TYPE* – entity type of the record (not translated), you can obtain it at Administration > Entity Manager
-* *LINK_NAME* – relation name, you can obtain it at Administration > Entity Manager
-* *FOREIGN_ID* – ID of a related record
+### Signal parameters
+
+*As of v3.2.*
+
+Some object signal are passed with additional parameters. These parameters can be accessed with a formula function `workflow\\signalParam('parameterName')`.
+
+## Naming clarification
+* *ID* – an ID of a record that you can obtain from the browser address bar;
+* *ENTITY_TYPE* – an entity type of the record (not translated), you can obtain it at Administration > Entity Manager;
+* *LINK_NAME* – a relation name, you can obtain it at Administration > Entity Manager;
+* *FOREIGN_ID* – an ID of a related record.
diff --git a/docs/administration/bpm-tips.md b/docs/administration/bpm-tips.md
index 3cc8a114d..97875a62d 100644
--- a/docs/administration/bpm-tips.md
+++ b/docs/administration/bpm-tips.md
@@ -2,18 +2,34 @@
## Execution in idle
-When a process is initiated by a user interaction (e.g. after record created), it starts to execute in the web server
-process until the flow reaches a catching event, *send message task* or *user task*, that will switch execution to idle mode (process will continue
+When a process is initiated by a user interaction (e.g. after record is created), it starts to execute in the web server
+process until the flow reaches a catching event, *Send Message Task*, or *User Task*, which will switch execution to the idle mode (process will continue
to run by cron/daemon).
-If you have script tasks that take some time to run it's reasonable to force to switch execution to idle mode.
-To avoid the user waiting until scripts are finished. A trick is to add *Timer Intermidiate Event* with 0 timer value.
-You can add it right after a start event.
+If you have script tasks that take some time to run, it's reasonable to force to switch execution to the idle mode.
+This will prevent a user from waiting until scripts are finished. In worst cases it can even cause a timeout error. The trick is to add *Timer Intermediate Event* with 0 timer value. You can add it right after a start event.
## Unsetting process variables
-All variables defined in *script task* will be stored in the process. If you don't need a specific variable to be used further in the process, it's reasonable to unset it in the end of the script.
+Variables defined in a *Script Task* and *Execute Formula Script* action will be stored in the Process (unless *Isolate Variables* is checked). If you don't need a specific variable to be used further in the process, it's reasonable to unset it in the end of the script.
```
$tempVariable = null;
```
+
+Also consider to unset sensitive data immediately after usage.
+
+## Cleaning up ended processes
+
+Ended Processes are *not* cleaned up automatically, as they may hold information important for the business. You may utilize a scheduled Workflow rule that will handle removal of ended Processes.
+
+## Self-removal
+
+You can set up a BPM process to remove itself. Add *Task* > *Update Process Record*. Add in Formula: `deleted = true;`.
+
+## Displaying processes on record detail view
+
+You can utilize the [Report Panels](../user-guide/reports.md#report-panels) feature to display all related processes on the record detail view.
+
+1. Create a List report for the Process entity type with the *Target* runtime filter.
+2. Create a report panel (Administration > Report Panels) for your entity type, select the report.
diff --git a/docs/administration/bpm-tracking-urls.md b/docs/administration/bpm-tracking-urls.md
index 64f6a96de..4a0ce3514 100644
--- a/docs/administration/bpm-tracking-urls.md
+++ b/docs/administration/bpm-tracking-urls.md
@@ -1,23 +1,48 @@
# Tracking URLs with BPM
-*Available since since Advanced Pack 2.4.6 and EspoCRM 5.7.12.*
+## Non-unique URL
-It's possible to add links into email body and catch when the recipient clicked on it. It provides the ability to automate an interraction with customers.
+It's possible to add links into email body and catch when a recipient clicked on it. It provides the ability to automate interactions with customers.
-Tracking URL can be created at Campaigns > top-right menu > Tracking URLs. Create URL and obtain a generated placeholder (example: `{trackingUrl:5d8206aa9d76df4c8}`). Use that placeholder as a URL of the link in your email template.
+A Tracking URL can be created at Campaigns > top-right menu > Tracking URLs. Create a URL and obtain the generated placeholder (example: `{trackingUrl:5d8206aa9d76df4c8}`). Use that placeholder as a URL of the link in your email template.
-Further in the process flow, you will be able to catch a URL click with *Signal Intermediate Event (Catching)*.
+Further in the process flow, you will be able to catch the URL click with the *Signal Intermediate Event (Catching)*.
-Signal that is broadcasted once the tracking URL with id 'TRACKING_URL_ID' is clicked by a person represented in the system as the entity of 'ENTITY_TYPE' with id 'ID' will be: `clickUrl.ENTITY_TYPE.ID.TRACKING_URL_ID`. See example below.
+When the tracking URL is clicked, the system broadcasts the signal `clickUrl.ENTITY_TYPE.ID.TRACKING_URL_ID`. Where *ENTITY_TYPE* is an entity type of the person stored in the CRM, *ID* is a record ID of the person, *TRACKING_URL_ID* is an ID of the tracking URL record. See the example below.
Process flowchart example:

-In this example, target entity type is *Lead*.
+In this example, the target entity type is *Lead*.
-Signal name, defined in catching event: `clickUrl.Lead.{$id}.5d8206aa9d76df4c8`, where `5d8206aa9d76df4c8` is an ID of *Tracking URL* (can be obtained from the address bar). You need to replace *5d8206aa9d76df4c8* with your ID. `{$id}` is a placeholder that will be automatically replaced with ID of the Lead.
+The signal name, defined in the catching event: `clickUrl.Lead.{$id}.5d8206aa9d76df4c8`, where `5d8206aa9d76df4c8` is an ID of the *Tracking URL* (can be obtained from the address bar). You need to replace *5d8206aa9d76df4c8* with your ID. `{$id}` is a placeholder that will be automatically replaced with the ID of the Lead.
-## Example
+### Example
You can get a downloadable example [here](bpm-examples.md#downloadable-examples).
+
+## Unique URL
+
+*Available as of Advanced Pack 2.7.0 and EspoCRM 6.1.3.*
+
+Useful when the URL must be unique for a specific process. E.g. send an email for a feedback on provided customer support, the email contains unique links to rate quality of support.
+
+The signal `clickUniqueUrl.UNIQUE_ID` will be broadcasted when the URL is opened by a recipient, where *UNIQUE_ID* is a generated ID.
+
+Use code `{trackingUrl:TRACKING_URL_ID.{$$variableName}}` in an email template instead of a *URL:* , where *variableName* is a name of the variable where the generated ID is stored, *TRACKING_URL_ID* is an ID of the Tracking URL record (can be obtained from the address bar). The code will be automatically substituted with a proper URL when the email is sent.
+
+Steps:
+
+1\. Create Tracking URL at Campaigns > top-right menu > Tracking URLs.
+
+
+2\. In BPM: Use an *Execute Formula Script* action or *Script Task* to generate a unique and store it in a variable:
+
+```
+$uniqueId = util\generateId();
+```
+
+3\. In BPM: Add a *Send Message* task. Use an email template with the link `{trackingUrl:TRACKING_URL_ID.{$$uniqueId}}`. Replace `TRACKING_URL_ID` with the ID of the *Tracking URL* record. This link is supposed to be clicked by a recipient.
+
+4\. In BPM: Use a *Signal Catching* event with the signal `clickUniqueUrl.{$$uniqueId}`.
diff --git a/docs/administration/bpm.md b/docs/administration/bpm.md
index 0b79d15fe..0d020203b 100644
--- a/docs/administration/bpm.md
+++ b/docs/administration/bpm.md
@@ -1,14 +1,26 @@
+---
+search:
+ boost: 2
+tags:
+ - automation
+ - bpm
+---
+
# Business Process Management
-Business Process Management (BPM) tool provides the ability to model and automate business processes in EspoCRM. It's an engine executing business processes described in BPMN 2.0 standard. BPM tool is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) extension.
+The Business Process Management (BPM) tool provides the ability to model and automate business processes in EspoCRM in a no-code/low-code way. The engine executes business processes described in the BPMN 2.0 standard.
+
+The BPM tool is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) extension.

### Difference from Workflows tool
-Workflows tool is intended for automation of simple business rules, w/o sequential flow items, when there is no need to display the flow graphically.
+The Workflows tool is intended for automation of simple business rules, without sequential flow items, when there is no need to display the flow graphically.
-BPM tool is intended for more complex business flows, where there can be diverging and converging flows, execution delays, user interactions. A flowchart view makes the business process more comprehensible for a human, a log allows to see how the process was held.
+The BPM tool is intended for more complex business logic, where there can be diverging and converging flows, execution delays, user interactions. The flowchart view makes the business process more comprehensible for a human, the log allows you to see how the process was held.
+
+The BPM tool has all the capabilities of the Workflows tool. If you've used the Workflows tool before, your knowledge will be useful for getting into BPM, as they share a number of features.
In this article:
@@ -16,45 +28,50 @@ In this article:
* [Processes](#processes)
* [Flowchart Elements](#flowchart-elements)
* [Conditions](#conditions)
-* [Additional formula functions](#additional-formula-functions)
## See also
+
* [Examples](bpm-examples.md)
* [Signals](bpm-signals.md)
-* [Drip Email Campaign with BPM](bpm-drip-email-campaign.md)
+* [Compensation](bpm-compensation.md)
+* [BPM specific formula functions](bpm-formula.md)
+* [Drip email campaign with BPM](bpm-drip-email-campaign.md)
* [Tracking URLs with BPM](bpm-tracking-urls.md)
-* [BPM tips](bpm-tips.md)
-
+* [Tips](bpm-tips.md)
+* [Configuration](bpm-configuration.md)
+* [Quick tour](https://app.supademo.com/demo/cmflay16uf28039ozjxxlw5sn)
## Process Flowcharts
-The link to process flowcharts is available from administration panel. It also can be added as a tab on the navigation panel.
+Available under Administration > Flowcharts. An administrator can also add the Process Flowcharts tab to the navigation bar.
-Flowcharts are intended for business processes modeling. Administrator can create and edit flowcharts. Regular users can only view flowcharts.
+Flowcharts are intended for modeling business processes. An administrator can create and edit flowcharts. Regular users can only view flowcharts.
-Every flowchart has its specific entity type (Target Type field). The flowchart determines execution of future process instances. It comprises flowchart elements and connections between elements.
+Every Flowchart has its specific entity type (defined by the *Target Type* field). The Flowchart determines execution of future process instances. It comprises flowchart elements and connections between elements.
-If the process flowchart has the unchecked 'Is Active' field then it won't initiate process instances.
+If a Process Flowchart has the unchecked *Is Active* field, then it won't initiate process instances.
To show details and parameters of a certain flowchart element you need to click on it. In the edit mode you will be able to edit parameters.
## Processes
-Processes are available at administration panel. The link also can be added as a tab on the navigation panel.
+Available under Administration > Processes. An administrator can also add the Processes tab to the navigation bar.
-The process represents a business process instance. When it's initiated, it gets the status 'Started'. When the process is finished, it gets the status 'Ended'.
+A Process represents a business process instance. When it's initiated, it gets the status *Started*. When the Process is finished, it gets the status *Ended*.
-The process is executed according to the flowchart. The flowchart of the process can't be changed after the process is started.
+A Process is executed according to its Flowchart. The Flowchart of a Process can't be changed after the Process is started.
-The process is obligatorily related to a single target record.
+A Process is obligatorily related to a single target record.
-Processes can be **started**:
+Processes can be started:
-* Automatically – Upon specific conditions, signal, or scheduling, described in the flowchart; this is the main method.
-* Manually – To start process manually, the user needs to click *Start Process* button on the list view of processes, or on the record detail view from the dropdown in the top-right corner.
-* With Workflow rule – *Start BPM Process* action, it allows to pass a related record as a target for the process.
+* Automatically – Upon specific conditions, signal, or scheduling, described in the Flowchart.
+* Manually – To start process manually, a user needs to click the *Start Process* button on the Processes list view, or on the record detail view from the dropdown in the top-right corner.
+* By a Workflow rule – using the *Start BPM Process* action in a rule. It allows you to pass the workflow's target record or a related record as a target for the new process.
-The execution of the process is visualized with colors highlighting flow nodes:
+By using a Workflow with the manual trigger, it's possible to have a button on the detail view that will start a particular process.
+
+The execution of a Process is visualized with colors highlighting statuses of flow nodes:
* green – processed;
* yellow – pending;
@@ -63,34 +80,43 @@ The execution of the process is visualized with colors highlighting flow nodes:

-**Only one process** for the same target record and flowchart can be active **at the same time**. It means that if you have multiple start events, once one of them is triggered (the process is started), other start events will be ignored while the process is active.
+**Only one Process** for the same target record and Flowchart can be active at the same time. It means that if you have multiple Start Events, once one of them is triggered (the process is started), other Start Events will be ignored while the Process is active.
+
+Usually Processes start their execution flow from a Start Event (green colored circle). One Process Flowchart can have multiple Start Events.
### Manipulating
-A process can be **stopped manually** by a user who has an 'edit' access to the process. You can do it from the dropdown menu next to the Edit button.
+A Process can be **stopped manually** by a user who has edit access to that Process. You can do it from the dropdown menu next to the *Edit* button.
-It's possible to **manually reject or interrupt** pending and active flow nodes. You can do it from the Log panel on the process detail view in the dropdown menu of a specific flow node. Note, that after rejecting a flow node it's possible that the process will become suspended and won't ever end by itself. You will need either manually stop it or start a flow from any node to continue executing.
+It's possible to **manually reject or interrupt** pending and active flow nodes. You can do it from the *Log* panel on the Process detail view in the dropdown menu of a specific Flow Node. Note that in some cases after rejecting a Flow Node the Process becomes suspended and won't ever end by itself. You will need to either manually stop it or start a flow from any node to continue executing.
-It's possible to **manually start a flow from any element** of an already started process. You need to click on a specific flowchart element on the process detail view and then click the button *Start flow from here*.
+It's possible to **manually start a flow from any element** of an already started Process. You need to click on a specific flowchart element on the Process detail view and then click the button *Start flow from here*.
-### Self-removal
+Ended, stopped and interrupted Processes can be *reactivated* (from the dropdown next to the *Edit* button). After reactivation, the Process does not have any active Flow Nodes. You need to manually start the flow from a specific Flow Node element. Ended Sub-Processes can be reactivated only if their parent Process is active. Meaning that you might need to reactivate the parent Process first.
-You can setup BPM process to remove itself. Add *Task* > *Update Process Record*. Add in formula: `deleted = 1;`.
+### Access control
+
+Only administrators can create or edit Flowcharts. With Roles it's possible to allow regular users to view Flowcharts, and view or edit Processes. Note that a user needs also to have access to the Process Flowchart scope to be able to view Process Flowchart details.
## Flowchart Elements
-* [Events](bpm-events.md)
+See more detail in separate articles:
+
* [Gateways](bpm-gateways.md)
+* [Events](bpm-events.md)
* [Activities](bpm-activities.md)
- * Task
- * Send Message Task
- * User Task
- * Script Task
- * Sub-Process
- * Event Sub-Process
- * Call Activity
-* Flows
- * [Sequence](#sequence-flow)
+
+### Gateways
+
+Gateways diverge and converge flows. Depicted as a yellow diamond. They can be used to determine a path in which the flow will go depending on specific conditions. They can split the flow into multiple parallel flows and join parallel flows into a single one.
+
+### Events
+
+Events represent something that happens during a business process. They also start, end and interrupt the process flow. Depicted as a circle.
+
+### Activities
+
+Automated tasks, manual tasks and sub-processes. Represented as a gray rectangle.
### Flows
@@ -102,40 +128,13 @@ Represented as a solid arrow. It indicates the order in which process elements w
Conditional events, exclusive and inclusive diverging gateways have conditions that determine the flow of the process.
-Through UI there is an ability to check conditions for the following records:
+Through the UI, there is the ability to check conditions for the following records:
* Target record;
* Records related to the target through many-to-one and children-to-parent relationships;
-* Records created by the process via tasks;
-* User task records, which allows checking the resolution.
-
-It's also possible to define conditions in [Espo-formula](formula.md) language.
-
-Conditions in BPM tool are the same as in Workflow feature. See more details about [workflow's conditions](workflows.md#conditions).
-
-## Additional formula functions
-
-Formula can be utilized in conditions, script tasks, various task actions.
-
-Available since version 2.4.0.
-
-#### bpm\targetEntity\attribute
-
-`bpm\targetEntity\attribute(ATTRIBUTE)` Fetches an attribute value of a target record.
-
-#### bpm\createdEntity\attribute
-
-`bpm\createdEntity\attribute(ALIAS_ID, ATTRIBUTE)` Fetches an attribute value of a record created within a process. ALIAS_ID can be obtained from the detail view of Task, that has an action creating a record.
-
-#### bpm\processEntity\attribute
-
-`bpm\processEntity\attribute(ATTRIBUTE)` Fetches an attribute value of a process record.
-
-#### bpm\startProcess
-
-`bpm\startProcess(FLOWCHART_ID, TARGET_TYPE, TARGET_ID, [ELEMENT_ID])` Starts a process. Available since Advanced Pack 2.5.2.
-
-Example:
+* Records created by the Process via tasks;
+* User Task records, what allows checking a task resolution.
-`bpm\startProcess('flowchart-id', 'Account', 'account-id');`
+It's also possible to define conditions with [Formula](formula.md) expressions. Example: `status == 'New' && assignedUserId == null`.
+Conditions in the BPM tool are the same as in the Workflow tool. See more details about [workflow's conditions](workflows.md#conditions).
diff --git a/docs/administration/commands.md b/docs/administration/commands.md
index 94d2bbde6..a2189555d 100644
--- a/docs/administration/commands.md
+++ b/docs/administration/commands.md
@@ -1,5 +1,24 @@
+---
+search:
+ boost: 2
+---
+
# Console Commands
+!!! note
+
+ You can run `php command.php` instead of `bin/command`. May be reasonable if there's no execute permission for *bin/command*. To grant execute permission, run `chmod +x bin/command`.
+
+!!! note
+
+ On Unix-based systems, it is reasonable to run commands under the root (or web server) user.
+
+## List of available commands
+
+```
+bin/command
+```
+
## Clear cache
```
@@ -12,72 +31,135 @@ php clear_cache.php
php rebuild.php
```
-Clears cache, rebuilds database.
+Clears cache, rebuilds database and other things.
+
+### Hard rebuild
+
+*As of v7.4.*
+
+```
+bin/command rebuild --hard
+```
+
+Hard database rebuild. It will drop unused columns, decrease exceeding column lengths, fix index names, set proper collations. It won't drop unused tables (consider removing them manually).
+If a parameter `-y` is specified, it won't prompt for confirmation before running hard rebuild (as of v9.0).
+
+Recommended to have a database backup before running hard rebuild.
## Changing user password
```
-php command.php set-password [username]
+bin/command set-password [username]
```
-where `[username]` is a user name, e.g. `admin`.
+Where `[username]` is a user name, e.g. `admin`.
## Upgrade
```
-php command.php upgrade
+bin/command upgrade
```
-Upgrades EspoCRM instance to the next available version. The upgrade package is downloaded automatically. It may take a few steps to upgrade to the latest version, so you will need to run the same command a few times.
+Upgrades EspoCRM instance to the next available version. The upgrade package is downloaded automatically. It may take a few steps to upgrade to the latest version, so you will need to run the same command multiple times.
+
+See additional parameters [here](upgrading.md#additional-parameters).
## Extension
-Installing:
+Installing or upgrading:
```
-php extension.php path/to/extension/package.zip
+bin/command extension --file="path/to/extension/package.zip"
```
-Installing or upgrading (since v5.9.0):
+Uninstalling:
```
-php command.php extension --file="path/to/extension/package.zip"
+bin/command extension -u --name="Extension Name"
```
-Uninstalling (since v5.9.0):
+Uninstalling by ID:
```
-php command.php extension -u --name="Extension Name"
+bin/command extension -u --id="extension-ID"
```
-Uninstalling by ID (since v5.9.0):
+List all extensions:
```
-php command.php extension -u --id="extension-ID"
+bin/command extension -l
```
## Running job
```
-php command.php run-job JobName
+bin/command run-job JobName
```
-where *JobName* is an intrernal name of the job you want to run.
+Where *JobName* is an internal name of the job you want to run.
+
+!!! example
-Examples:
+ ```
+ bin/command run-job Cleanup
+ bin/command run-job ProcessMassEmail
+ ```
+
+## Version
+
+Print the current version:
```
-php command.php run-job Cleanup
-php command.php run-job ProcessMassEmail
+bin/command version
```
-## Version
+## Setting user password
+
+```
+bin/command set-password {username}
+```
-Since v5.9.0.
+Where `{username}` is a user name, e.g. `admin`.
-Print the current version:
+## Creating admin user
+
+*As of v7.4.*
+
+```
+bin/command create-admin-user {username}
+```
+
+Where `{username}` is a user name, e.g. `admin`.
+
+Can be useful when you need to run an Espo instance from a repository without the need to go through UI installation.
+
+## Import
+
+See more detail [here](import.md#console-commands).
+
+## App info
```
-php command.php version
+bin/command app-info
```
+
+With this command you can get some information about the application (container services, binding, jobs).
+
+## Update app timestamp
+
+*As of v8.1.*
+
+```
+bin/command update-app-timestamp
+```
+
+Updates the app timestamp to the current time. When an Espo instance is updated or an extension is installed or uninstalled, the app timestamp is updated to let the browser know that the old cache is not actual anymore. Sometimes developers may need to update the app timestamp manually, for example, when writing custom JavaScript code.
+
+## Rebuild category paths
+
+```
+bin/command rebuild-category-paths {EntityType}
+```
+
+Rebuilds category paths. For example, for DocumentFolder, WorkflowCategory. May be needed if for some reason paths data is corrupted resulting in not working expanded mode.
diff --git a/docs/administration/config-params.md b/docs/administration/config-params.md
index 9127f9bdc..41a379056 100644
--- a/docs/administration/config-params.md
+++ b/docs/administration/config-params.md
@@ -1,12 +1,23 @@
+---
+search:
+ boost: 2
+---
+
# Config parameters
-Config parameters can be changed or added manually in the file `data/config.php`.
+Config parameters can be changed or added manually in the file `data/config.php`. Parameters can also be added to the file `data/config-internal.php`. Use the **internal config** to store sensitive parameters.
+
+In this article:
-This is not a full list of params. Most of params available in admin UI are not listed here.
+* [List of parameters](#list-of-parameters)
+* [Config files](#config-files)
## List of parameters
+The list of parameters along with their default values. This is not a full list of params. Most of params available in the admin UI are not listed here.
+
* [General](#general)
+* [UI](#ui)
* [Access control](#access-control)
* [Notifications](#notifications)
* [Emails](#emails)
@@ -14,24 +25,32 @@ This is not a full list of params. Most of params available in admin UI are not
* [Clean-up](#clean-up)
* [Passwords](#passwords)
* [Auth](#auth)
+* [Security](#security)
* [Jobs & Daemon](#jobs-daemon)
* [Mass Email](#mass-email)
+* [Kanban](#kanban)
+* [Text search](#text-search)
+* [PDF](#pdf)
+* [Events](#events)
+* [Attachments](#attachments)
+* [Misc](#misc)
### General
* siteUrl – URL of EspoCRM instance;
* useCache – `true`;
-* isDeveloperMode – false – toggle developer mode;
+* isDeveloperMode – `false` – enables developer mode; not to be used on instances installed from a package; only for an instance that is run right from a repository;
* useCacheInDeveloperMode – `false` – to use front-end cache in developer mode; front-end is not cached by default in developer mode;
* maintenanceMode – `false` – only administrators will have access to the system;
* disableCron – `false`;
* useWebSocket – `false`;
+* restrictedMode – `false` – disables for admin users: upgrade via the UI, extension management, changing specific config parameters;
* ajaxTimeout – `60000` – timeout for ajax requests (in milliseconds);
* language – system language;
* timeZone – system timezone;
* exportDelimiter – `','` – default export delimiter;
-* inlineAttachmentUploadMaxSize – `20` – max size of inline attachments (e.g. inline images for emails); in Mb;
* recordListMaxSizeLimit – `200` – max number of records can be fetched in a single GET API request;
+* maxSelectTextAttributeLengthForList – `10000` – text fields are cut when records accessed with a list request;
* displayListViewRecordCount – `true` – to display a number of records on the list view;
* addressCountryList – array of countries available in autocomplete;
* addressCityList – array of cities available in autocomplete;
@@ -39,11 +58,24 @@ This is not a full list of params. Most of params available in admin UI are not
* defaultCurrency – currency applied by default;
* baseCurrency – which currency to use as base when defining rates;
* currencyList – array of available currencies;
+* thumbImageCacheDisabled – `false` – to disable thumb image files being created in `data/upload/thumbs` directory (as of v7.0);
+* globalSearchMaxSize – `10` – how much records is shown in the global search;
+* massActionIdleCountThreshold – `100` – record number threshold after which mass-action is processed in idle (as of v7.1);
+* exportIdleCountThreshold – `1000` – record number threshold after which export is processed in idle (as of v7.1);
+* leadCaptureAllowOrigin – `*` – *Access-Control-Allow-Origin* response header value for the lead capture endpoint;
+* ipAddressServerParam – `REMOTE_ADDR` – server parameter to be used for obtaining a request IP address (as of v7.5);
+
+### UI
+
+* applicationDescription – the text in the meta tag; default value: `EspoCRM – Open Source CRM application` (as of v7.0);
+* adminPanelIframeDisabled – `false` – disables the right iframe-panel on the administration page (as of v7.0);
+* activitiesCreateButtonMaxCount – `3` – a max number of create buttons to display on the Activities page (as of v7.2);
+* listViewSettingsDisabled – `false` – disable list view settings (as of v8.1);
+* tabQuickSearch – `true` – tab quick search in the navbar (as of v8.5);
### Access control
-* aclStrictMode – `true` – see [here](roles-management.md#permissions-by-default);
-* aclAllowDeleteCreated – `true` – whether to allow regular users to delete record they created, even they don't have *delete* access;
+* aclAllowDeleteCreated – `true` – whether to allow regular users to delete record they created, even they don't have *delete* access to;
* aclAllowDeleteCreatedThresholdPeriod – `24 hours` – time window available for deletion of created records;
### Notifications
@@ -51,30 +83,49 @@ This is not a full list of params. Most of params available in admin UI are not
* adminNotifications – `true` – notifications in admin panel;
* adminNotificationsNewVersion – `true` – notifications about new versions in admin panel;
* adminNotificationsNewExtensionVersion – `true` – notifications about new extension versions in admin panel;
+* emailReminderPortionSize – `10` – how much email reminders can be sent at once (as of v7.0);
+* notificationsMaxSize – `5` – how much in-app notifications is shown when the notification panel is shown up;
+* notificationsCheckInterval – `10` – an interval between checks for new notifications (actual only if web socket is not enabled);
+* popupNotificationsCheckInterval – `15` – an interval between checks for new popup notifications (actual only if web socket is not enabled) (as of v7.3.2);
+* reminderMaxCount – `10` – a max number of reminders per event (as of v8.3);
+* notificationGrouping – `true` – notification grouping (as of v9.2);
### Emails
* emailKeepParentTeamsEntityList – `['Case']` – when a related email is fetched, teams of the parent record will be copied to the email; by default, it's available only for cases;
* emailForceUseExternalClient – `false` – when composing an email, all users will be forced to use external client;
+* emailAutoReplySuppressPeriod – `'2 hours'` – an auto-reply email (for group email account) won't be sent to the same recipient if one was already sent in a period of time defined by the parameter; to prevent looping (as of v6.1.8);
+* emailAutoReplyLimit – `5` – a max number of auto-reply emails that can be sent to one recipient within a period defined by the *emailAutoReplySuppressPeriod* parameter (as of v7.0);
+* emailFoldersDisabled – `false` – disables email folders;
+* emailRecipientAddressMaxCount – `100` – max number of addresses allowed in TO, CC, BCC (as of v7.5);
+* emailTemplateHtmlizerDisabled – `false` – disables Handlebars template engine for email templates;
### Stream
-* noteEditThresholdPeriod – `'7 days'` – how much time is available for editing steam posts;
-* noteDeleteThresholdPeriod – `'1 month'` – how much time is available for deleting steam posts;
+* noteEditThresholdPeriod – `'7 days'` – how much time is available for editing stream posts;
+* noteDeleteThresholdPeriod – `'1 month'` – how much time is available for deleting stream posts;
* streamEmailWithContentEntityTypeList – `['Case']` – to display the content of the email in stream; by default, it's available only for cases;
+* recordFollowersLoadLimit – `6` – how much records loaded in the *Followers* field;
+* notePinnedMaxCount – `5` – max number of pinned notes per record;
+* streamReactionsCheckMaxSize – `50` – when refreshing a user's stream, how many posts will be checked for new reactions; as of 9.0;
### Clean-up
-* cleanupJobPeriod – `'10 days'` – job records;
+* cleanupJobPeriod – `'10 days'` – cleaning up deleted Job records;
* cleanupActionHistoryPeriod – `'15 days'` – action history records;
* cleanupAuthTokenPeriod – `'1 month'` – auth tokens;
* cleanupAuthLogPeriod – `'2 months'` – auth log;
+* cleanupAppLog – `true` – app log cleanup (as of v9.1);
+* cleanupAppLogPeriod – `'30 days'` – app log cleanup period (as of v8.3);
* cleanupNotificationsPeriod – `'2 months'` – notifications;
-* cleanupAttachmentsPeriod – `'15 days'` – attachments with roles 'Export File', 'Mail Merge', 'Mass Pdf';
+* cleanupAttachmentsPeriod – `'15 days'` – attachments with roles 'Export File', 'Mail Merge', 'Mass Pdf' and attachments relate for deleted records;
* cleanupOrphanAttachments – `false` – cleaning up attachments that were uploaded but not linked with any record; *cleanupAttachmentsPeriod* is used; an experimental parameter;
-* cleanupAttachmentsFromPeriod – `'3 months'` – attachments related to records that were marked as deleted (*deleted = 1*);
* cleanupBackupPeriod – `'2 months'` – backup of files created during upgrades;
-* cleanupDeletedRecordsPeriod – `'3 months'` – complete deletion of records that were marked as deleted (*deleted = 1*);
+* cleanupDeletedRecordsPeriod – `'2 months'` – complete deletion of records that were marked as deleted (*deleted = 1*);
+* cleanupSubscribers – `true` – cleaning up stream subscribers for not-actual records (as of v7.3);
+* cleanupSubscribersPeriod – `'2 months'` – period for cleaning up subscribers for not-actual records (as of v7.3);
+* cleanupAudit – `true` – to perform cleanup of the audit log;
+* cleanupAuditPeriod – `3 month` – how long audit log records stay before cleanup;
### Passwords
@@ -83,11 +134,40 @@ This is not a full list of params. Most of params available in admin UI are not
* passwordStrengthNumberCount – how many numbers are required for passwords;
* passwordStrengthBothCases – `false` – password must contain letters of both upper and lower case;
* passwordRecoveryRequestLifetime – `3 hours` – how long a password recovery link is valid;
+* passwordChangeRequestNewUserLifetime – `2 days` – how long a password change link for new users is valid (as of v7.1);
+* passwordChangeRequestExistingUserLifetime – `2 days` – how long a password change link (initiated by admin) for existing users is valid (as of v7.1);
### Auth
-* authMaxFailedAttemptNumber – `10` – if number of failed login attempts (within *authFailedAttemptsPeriod*) exceeds the set number, then the system won't allow to login;
-* authFailedAttemptsPeriod – `'60 seconds'` – period taken into account for *authMaxFailedAttemptNumber*;
+* authAnotherUserDisabled – `false` – disable the ability to log in as another user for admins (as of v7.3);
+* authLogDisabled – `false` – disable auth log records (as of v7.4);
+* authApiUserLogDisabled – `false` – disable auth log records for successful connections of API users (as of v7.4);
+* auth2FAEmailCodeLifetimePeriod – `'10 minutes'` – lifetime of email 2FA codes;
+* auth2FASmsCodeLifetimePeriod – `'10 minutes'` – lifetime of SMS 2FA codes;
+
+#### Brute force prevention for IP address
+
+* authMaxFailedAttemptNumber – `10` – if the number of failed login attempts within a specific period exceeds the specified number, then the system won't allow to login;
+* authFailedAttemptsPeriod – `'60 seconds'` – period taken into account;
+* authFailedCodeAttemptsPeriod – `'5 minutes'` – period for checking a number of failed 2FA code check attempts (as of v8.4);
+
+#### Brute force prevention for user name
+
+*As of v9.3.*
+
+* authUsernameFailedAttemptsLimitEnabled – `false` – enables brute force prevention measure delays;
+* authMaxUsernameFailedAttemptNumber – `30` – if the number of failed login attempts within a specific period exceeds the specified number, then the system will do a delay;
+* authUsernameFailedAttemptsPeriod – `'60 seconds'` – period taken into account;
+* authUsernameFailedAttemptsDelay – `2` – delay in seconds;
+
+### Security
+
+* adminUpgradeDisabled – `false` – disables the ability to upgrade or upload extensions via the UI; (as of v8.1);
+* clientSecurityHeadersDisabled – `false` – disable security headers (as of v7.2);
+* clientCspDisabled – `false` – disable Content-Security-Policy header for the client page (as of v7.2);
+* clientCspScriptSourceList – a script source white-list for the Content-Security-Policy header (as of v7.2);
+* clientStrictTransportSecurityHeaderDisabled – `false` – disables `Strict-Transport-Security` header, actual if a webserver adds it (as of v7.3);
+* clientCspFormActionDisabled – `false` – disables addition of `form-action 'self'` in the CSP header (as of v9.0.8);
### Jobs & Daemon
@@ -95,7 +175,7 @@ This is not a full list of params. Most of params available in admin UI are not
* jobPeriod – `7800` – max execution time (in seconds) allocated for a single job; if exceeded then set to *Failed*;
* jobPeriodForActiveProcess – `36000` – max execution time (in seconds) allocated for a single job with active process; if exceeded then set to *Failed*;
* jobRerunAttemptNumber – `1` – number of attempts to re-run failed jobs;
-* jobRunInParallel – `false` – jobs will be executed in parallel processes;
+* jobRunInParallel – `false` – jobs will be executed in parallel processes (see [here](jobs.md#running-jobs-in-parallel-processes));
* jobPoolConcurrencyNumber – `8` – max number of processes run simultaneously;
* cronMinInterval – `2` – min interval (in seconds) between two cron runs;
* daemonMaxProcessNumber – `5` – max number of processes run simultaneously;
@@ -104,8 +184,55 @@ This is not a full list of params. Most of params available in admin UI are not
* jobE0MaxPortion – `100` – max portion of jobs executed in a single process for *e0* queue; this queue is intended for email sending; is run as often as possible;
* jobQ0MaxPortion – `200` – *q0* is a queue for a general usage; is run as often as possible;
* jobQ1MaxPortion – `500` – *q1* is a queue for a general usage; is run every minute;
+* jobGroupMaxPortion – `100` – a portion size for grouped jobs;
### Mass Email
* massEmailMaxAttemptCount – `3` – how many attempts to send an email will be made (can be helpful when SMTP server is gone away);
-* massEmailSiteUrl – to override the default site url (can be helpful if there's no access to your CRM from the internet, but you need to handle opting out & tracking urls; you will need to configure your server to handle requests to the specified URL);
+* massEmailSiteUrl – to override the default site URL (can be helpful if there's no access to your CRM from the internet, but you need to handle opting out & tracking URLs; you will need to configure your server to handle requests to the specified URL);
+
+### Kanban
+
+* kanbanMaxOrderNumber – `50` – a number of records that can be ordered within a group; as of v6.1;
+* kanbanMinColumnWidth – `220` – a min width of column; the horizontal scrolling will appear to prevent column being shrunk less than the specified value; as of v7.1;
+
+### Text search
+
+* textFilterContainsMinLength – `4` – actual if *Use 'contains' operator when filtering varchar fields* parameter is enabled;
+
+
+### PDF
+
+* pdfEngine – `Tcpdf` – what PDF engine to use; as of v6.1;
+* pdfFontFace – default font face;
+* pdfFontSize – default font size;
+
+### Events
+
+* eventAssignedUserIsAttendeeDisabled – `false` – If set *true*, then assigned user won't be automatically added to an attendee list (for meetings and calls);
+* eventInvitationForceSystemSmtp – `false` – To send invitation emails from system SMTP (otherwise a user's personal account can be used); as of v7.3;
+* busyRangesMaxRange – A max timeline range on which free/busy slots are displayed on the Scheduler panel.
+
+### Attachments
+
+* attachmentUploadMaxSize – `256` – max size of attachments in Mb; as of v7.2;
+* attachmentUploadChunkSize – `4` – chunk size in Mb; attachments uploaded by chunk; `0` disables uploading by chunk; as of v7.2;
+* inlineAttachmentUploadMaxSize – `20` – max size of inline attachments in Mb (e.g. inline images for emails);
+
+### Misc
+
+* starsLimit – 500 – max number of stars a user can give per entity type;
+* phoneNumberMaxCount – 10 – max number of phone numbers per record;
+* emailAddressMaxCount – 10 – max number of email addresses per record;
+* iframeSandboxExcludeDomainList – array of domains that do not require adding `sandbox="allow-scripts"` in the Iframe dashlet; as of v9.0.7;
+* leadCaptureSiteUrl – to override the default site URL (can be helpful if there's no access to your CRM from the internet, but you want to expose the lead capture; you will need to configure your server to handle requests to the specified URL); as of v9.2;
+* wysiwygCodeEditorDisabled – `false` – disable the Wysiwyg field code editor; as of v8.2;
+* customPrefixDisabled – `false` – disable adding a *c* prefix to custom entity types, fields and links; as of v8.2; setting to true may cause conflicts; highly discouraged, voids official support;
+
+## Config files
+
+* `data/config.php` – the main config; can be written by the application or manually;
+* `data/config-internal.php` – for storing sensitive parameters that should never make their way to the front-end; can be written by the application or manually;
+* `data/config-override.php` – overrides parameters of the main config, supposed to be written only manually; you can read environment variables in there; as of v8.2;
+* `data/config-override-internal.php` – overrides parameters of the main config, supposed to be written only manually; for storing sensitive parameters; as of v8.2.
+
diff --git a/docs/administration/cron-on-windows.md b/docs/administration/cron-on-windows.md
new file mode 100644
index 000000000..4061677e6
--- /dev/null
+++ b/docs/administration/cron-on-windows.md
@@ -0,0 +1,36 @@
+# Setting up Cron on Windows
+
+!!! note
+
+ All configuration settings listed here are made on **Windows Server 2019**.
+
+To setup crontab on Windows system, take the following steps:
+
+1\. Login as administrator into your EspoCRM instance.
+
+2\. Go to the Scheduled Jobs section in the administrator panel (Menu > Administration > Scheduled Jobs) and copy the string for the crontab, replace `php.exe` instead of `php-cgi.exe` and add `"` symbols to the start and the end of the `php.exe` path. It looks like this one:
+
+```
+"C:\Program Files\PHP\v8.2\php.exe" -f C:\inetpub\wwwroot\733\cron.php
+```
+
+3\. Create a batch file by using Notepad and save with the *.bat* extension with string from step 2.
+
+4\. From the Windows Start menu, select Administrative Tools and then Task Scheduler.
+
+5\. Create a folder inside Windows directory and Task inside.
+
+6\. Configure the Task with the following settings and click `OK`:
+
+
+
+
+
+
+
+
+
+
+
+7\. Right-click on the created Task and Click on `Run`.
+
diff --git a/docs/administration/currency.md b/docs/administration/currency.md
index 8fde60278..ba84b90a5 100644
--- a/docs/administration/currency.md
+++ b/docs/administration/currency.md
@@ -1,3 +1,8 @@
+---
+search:
+ boost: 2
+---
+
# Currency
In this article:
@@ -6,57 +11,74 @@ In this article:
* [Currency conversion](#currency-conversion)
* [Currency rates API](#currency-rates-api)
* [Adding missing currency](#adding-missing-currency)
+* [Conversion via formula](#conversion-via-formula)
+* [Decimal data type](#decimal-data-type)
## Settings & rates
-Administrator can configure currency-related parameters and rates at Administration > Currency.
+An administrator can configure currency-related parameters and rates at Administration > Currency. It's possible to specify which currencies will be available in the system in the *Currency List* parameter.
+
+Parameters:
+
+* Currency List – The currencies available in the system.
+* Default Currency – The currency that is pre-set when creating a new record. Currency values are converted to the default currency when filtering records by a currency field, sorting by a currency field, generating a Grid report with currency fields.
+* Base Currency – The currency used as a base when specifying currency rates. It is usually the local currency in which the company operates.
+
+### Exchange rates
-You can specify which currencies will be available in the system in *Currency List* parameter.
+*As of v9.3.*
-*Default Currency* – which currency will be set by default when creating a new record. A currency to which all currency fields will be converted to when filtering, sorting, reporting.
+Currency exchange rates are available under: Administration > Currency > Currency Rates button in the top-right corner. They can be also reached from the Global Search with the search *Currencies* query. The Currencies tab can be added to the navigation bar.
-*Base Currency* – which currency to use as a base to specify rates.
+Currency exchange rates can be viewed or edited by:
-
+- Admin users
+- Users with access to the Currency scope
+
+A rate entry has a mandatory *Date* field. The rate with the latest non-future date is used as the current rate.
### Default currency for specific field
-It's possible to specify an exclusive default currency for a specific field.
+It's possible to set an exclusive default currency for a specific field.
-Example for *amount* field of *Opportunity*. Set *Default* value at Administration > Entity Manager > Opportunity > fields > amountCurrency.
+For example, for the *Amount* field of the *Opportunity*, set the *Default* value at Administration > Entity Manager > Opportunity > fields > amountCurrency.
## Currency conversion
-### Currency Converted field
+### Converted field
+
+All fields of *Currency* type are paired with a special read-only field of *Currency Converted* type. When you create a new Currency field, a Converted field is created automatically. This field represents a value converted to *Default Currency* based on current currency rates. This field is used for sorting by currency field, filtering, comparison, reporting. The field is read-only.
-All fields of *Currency* type are paired with a special read-only field of *Currency Converted* type. When you create a new Currency field, Converted field is created automatically. This field represents a value converted to *Default Currency* based on current currency rates. This field is used for sorting by currency field, filtering, comparison, reporting.
+!!! note
-Note, that when currency rates are changed, the value of Currency Converted field is also changed. Technically the value is not stored, but calculated on-fly. This can cause an issue that your reports get changed every time currency rates are changed.
+ When currency rates are changed, the value of Currency Converted field is also changed. Technically the value is not stored, but calculated on-fly. This can cause an issue that your reports get changed every time currency rates are changed.
-To store a converted value based on current rates you can:
+To preserve converted values based on current rates you can:
1. Convert currency manually. With mass action from the list view or action on the detail view.
-2. Convert currency automatically with Workflows tool. Convert Currency service action is available for Opportunities, Quotes, Sales Orders, Invoices. E.g. you can setup a workflow that will update currencies for all closed opportunities each week.
-3. Utilize formula to store a current converted value in a separate read-only field. You can use either a regular Before Save Script or Workflow tool.
+2. Convert currency automatically with the Workflows tool. Convert Currency service action is available for Opportunities, Quotes, Sales Orders, Invoices. E.g. you can setup a workflow that will update currencies for all closed opportunities each week.
+3. Utilize Formula to store a current converted value in a separate read-only field. You can use either a regular Before Save Script or the Workflow tool.
-### Storing current converted value (locked)
+### Storing current converted value
Let's assume that you have a currency field named *amount*, and the default currency is *USD*.
-Create a new field of *Currency* type, name it *amountConvertedLocked*, make it read-only,
+Create a new field of *Currency* type, name it *amountLocal*, make it read-only. Note that for non-custom entities the field will be named *cAmountLocal*.
-Add a formula script to Before Save Script at Entity Manager. You can also use this formula in Workflow rule.
+Add a Formula script to the *Before Save Script* in the Entity Manager. You can also use this formula in a Workflow rule.
```
-amountConvertedLocked = amountConverted;
-amountConvertedLockedCurruncy = 'USD';
+amountLocal = amountConverted;
+amountLocalCurrency = 'USD';
```
-You can re-calculate formula for all existing records with mass action on the list view.
+You can re-calculate formula for all existing records with a mass action from the list view.
+
+Note that some entity types may have already such a field implemented.
### Convert currency manually
-It's possible to convert manually all currency fields of a record.
+It's possible to manually convert all currency fields of a record.
1. Mass action on the list view. Select which records you want to update (you can select all results). In *Actions* dropdown, click *Convert Currency*.
2. Action on the detail view. Available in the dropdown next to *Edit* button.
@@ -67,9 +89,7 @@ It's possible to convert manually all currency fields of a record.
## Currency rates API
-Available since 5.8.0.
-
-API User needs to have *Currency* scope enabled in roles.
+The API User needs to have *Currency* scope enabled in Roles.
Request to get all rates: `GET api/v1/CurrencyRate`.
@@ -88,9 +108,9 @@ Rate values are related to *Base Currency* specified in Settings.
## Adding missing currency
-If a currency that you need is missing, you can add it manaully.
+If a currency that you need is missing, you can add it manually.
-Create a file: `custom/Espo/Resources/metadata/app/currency.json`
+Create a file: `custom/Espo/Custom/Resources/metadata/app/currency.json`
```json
{
@@ -105,3 +125,43 @@ Create a file: `custom/Espo/Resources/metadata/app/currency.json`
where *COD* is a 3-letter currency code in [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) standard.
Clear cache at Administration.
+
+## Conversion via formula
+
+Example (conversion from the default currency to EUR, for a field named *amount*):
+
+```
+amountEur = amountConverted * record\attribute('Currency', 'EUR', 'rate');
+```
+
+The field *amountConverted* contains an automatically calculated value in the default currency. Such fields are automatically created for all currency fields.
+
+You can also use the [ext\currency\convert](formula/ext.md#extcurrencyconvert) function to convert currency amounts.
+
+## Decimal data type
+
+*As of v7.4.*
+
+When precision is necessary for a specific currency field, it's recommended to use a Decimal data type. When creating a new currency field, check a corresponding checkbox.
+
+For existing fields, can be enabled manually in metadata > entityDefs:
+
+```json
+{
+ "fields": {
+ "myCurrencyField": {
+ "decimal": true,
+ "precision": 13,
+ "scale": 4
+ }
+ }
+}
+```
+
+Rebuild is required after modifying an existing field. Can take long if the table is big. Run from CLI in this case.
+
+If the parameters *precision* and *scale* are not defined, values 13, 4 are used.
+
+In the application, amount values will be represented as strings (rather than floats).
+
+In templates (PDF, email), you need to use the *numberFormat* helper to print currency values.
diff --git a/docs/administration/dashboards.md b/docs/administration/dashboards.md
index 0afca3574..d84849617 100644
--- a/docs/administration/dashboards.md
+++ b/docs/administration/dashboards.md
@@ -1,25 +1,30 @@
# Dashboards
-All internal users can manage their dashboards: add or remove dashlets and tabs, edit dashlet options.
+All internal users can manage their dashboards, including adding, removing, and configuring dashlets, as well as adding dashboard tabs.
-Admin can edit dashboards of other users. On the user detail view, click Preferences from the dropdown at the top-right corner. There, you can find *Dashboard Layout*.
+An administrator can edit dashboards of other users. On the user detail view, click the *Preferences* item from the dropdown at the top-right corner. There, you can find *Dashboard Layout*.
-Users can reset their dashboard layout to the default. On Preferences edit view, click *Reset Dashboard to Default* from the dropdown next to the *Edit* button. Admin can reset dashboards of other users.
+Users can reset their dashboard layout to the default. On the Preferences edit view, click *Reset Dashboard to Default* from the dropdown next to the *Edit* button. The administrator can reset dashboards of other users.
+
+On the dashboard:
+
+* Dashlets can be dragged by the header.
+* Dashlets can be resized by dragging the lower-right corner.
+* Multiple dashboard tabs can be created to group dashlets by their purpose.
## System default dashboard
-The default dashboard layout will be applied to all new users. It can be changed at Administration > User Interface > Dashboard Layout.
+The default dashboard layout will be applied to all new users. This layout be changed at Administration > User Interface > Dashboard Layout.
## Dashboard Templates
-Available for admin at Administration > Dashboard Templates. Dashboard templates provide the ability to deploy a specific dashboard layout to multiple users. It's possible to deploy for all users of a specific team.
-
+Dashboard templates are available for administrators at Administration > Dashboard Templates. They provide the ability to deploy specific dashboard layouts to multiple users. It's also possible to deploy for all users of a specific team.
## Portal dashboard
-On the edit view of the portal record, you can define its default dashboard layout. It will be applied to all portal users unless a user has a specific *Dashboard Template*.
+On the edit view of the Portal record, you can define its default dashboard layout. It will be applied to all portal users unless a user has a specific *Dashboard Template*.
-When editing *Portal User*, you can specify a dashboard template for the user. This template will override the default template of the portal.
+When editing a *Portal User*, you can specify the Dashboard Template for that user. This template will override the default template of the Portal.
## See also
diff --git a/docs/administration/date-formatting.md b/docs/administration/date-formatting.md
index 1f5796b7f..1c405d9ea 100644
--- a/docs/administration/date-formatting.md
+++ b/docs/administration/date-formatting.md
@@ -3,7 +3,7 @@
* `YYYY` – 4 digit year: `2020`
* `YY` – 2 digit year: `20`
* `M MM` – month number: `1..12`
-* `MMM MMM` – month: `Jan..December`
+* `MMM MMMM` – month: `Jan..December`
* `D DD` – day of month: `1..31`
* `Do` – day of month with ordinal: `1st..31st`
* `ddd dddd` – day of week: `Tue Tuesday`
diff --git a/docs/administration/docker/caddy.md b/docs/administration/docker/caddy.md
new file mode 100644
index 000000000..f4b27238b
--- /dev/null
+++ b/docs/administration/docker/caddy.md
@@ -0,0 +1,121 @@
+# Caddy and EspoCRM
+
+The Caddy web server is an open-source, HTTP/2-enabled web server written in Go.
+
+To connect Caddy and EspoCRM, you can use the Docker Compose environment. Also, you must have your own domain.
+
+1\. Create a folder that will contain your EspoCRM files and database.
+
+2\. Create here a `docker-compose.yml` file:
+
+#### docker-compose.yml
+
+```
+services:
+
+ caddy:
+ image: caddy:latest
+ container_name: caddy
+ restart: always
+ ports:
+ - "80:80"
+ - "443:443"
+ volumes:
+ - ./certs:/etc/caddy/certs # optional: if you have self-signed certificates
+ - ./Caddyfile:/etc/caddy/Caddyfile
+ environment:
+ - ACME_AGREE=true # to automatically obtain certificates
+
+ espocrm-db:
+ image: mariadb:latest
+ container_name: espocrm-db
+ environment:
+ MARIADB_ROOT_PASSWORD: root_password
+ MARIADB_DATABASE: espocrm
+ MARIADB_USER: espocrm
+ MARIADB_PASSWORD: database_password
+ volumes:
+ - espocrm-db:/var/lib/mysql
+ restart: always
+ healthcheck:
+ test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
+ interval: 20s
+ start_period: 10s
+ timeout: 10s
+ retries: 3
+
+ espocrm:
+ image: espocrm/espocrm
+ container_name: espocrm
+ environment:
+ ESPOCRM_DATABASE_PLATFORM: Mysql
+ ESPOCRM_DATABASE_HOST: espocrm-db
+ ESPOCRM_DATABASE_USER: espocrm
+ ESPOCRM_DATABASE_PASSWORD: database_password
+ ESPOCRM_ADMIN_USERNAME: admin
+ ESPOCRM_ADMIN_PASSWORD: password
+ ESPOCRM_SITE_URL: "https://{YOUR_DOMAIN}"
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ depends_on:
+ espocrm-db:
+ condition: service_healthy
+ expose:
+ - 80
+
+ espocrm-daemon:
+ image: espocrm/espocrm
+ container_name: espocrm-daemon
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ depends_on:
+ - espocrm
+ entrypoint: docker-daemon.sh
+
+ espocrm-websocket:
+ image: espocrm/espocrm
+ container_name: espocrm-websocket
+ environment:
+ ESPOCRM_CONFIG_USE_WEB_SOCKET: "true"
+ ESPOCRM_CONFIG_WEB_SOCKET_URL: "wss://{YOUR_DOMAIN}/ws"
+ ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN: "tcp://*:7777"
+ ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN: "tcp://espocrm-websocket:7777"
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ depends_on:
+ - espocrm
+ entrypoint: docker-websocket.sh
+ expose:
+ - 8080
+
+volumes:
+ espocrm:
+ espocrm-db:
+```
+
+3\. Create here a `Caddyfile` text file:
+
+#### Caddyfile
+
+```
+espocrm-example.com {
+ reverse_proxy espocrm:80
+
+ reverse_proxy /ws espocrm-websocket:8080 {
+ header_up Host {host}
+ header_up X-Real-IP {remote}
+ header_up X-Forwarded-For {remote}
+ header_up X-Forwarded-Proto {scheme}
+ }
+
+ # Optional for Self-Signed SSL Certificate
+ # tls /etc/caddy/certs/myserver.crt /etc/caddy/certs/myserver.key
+}
+```
+
+----
+
+Now, start containers with the CLI command `docker compose up -d`.
diff --git a/docs/administration/docker/installation.md b/docs/administration/docker/installation.md
new file mode 100644
index 000000000..8036ebb03
--- /dev/null
+++ b/docs/administration/docker/installation.md
@@ -0,0 +1,324 @@
+# EspoCRM with Docker
+
+In this article:
+
+- [Installing with Docker](#install-espocrm-with-docker)
+- [Installing with Docker Compose](#install-espocrm-with-docker-compose)
+- [Installing with Traefik](#install-espocrm-with-traefik)
+- [Installing with Caddy](#install-espocrm-with-caddy)
+- [Upgrading](#upgrading)
+- [Shutdown and cleanup](#shutdown-and-cleanup-containers)
+- [Running a shell](#running-a-shell)
+- [Environments](#installation-environments)
+- [Config Environments](#config-environments)
+- [Image Variants](#image-variants)
+- [Troubleshooting](#troubleshooting)
+
+
+## Install EspoCRM with Docker
+
+One of the ways to install EspoCRM is by using its official Docker Image. The EspoCRM Container Package contains the Docker image, which incorporates all the required files and dependencies to launch EspoCRM in development or production environments. You can use Docker to run EspoCRM in an isolated environment built with Docker containers.
+
+EspoCRM image requires to run MariaDB or MySQL server:
+
+```
+$ docker run --name mariadb -e MARIADB_ROOT_PASSWORD=password -d mariadb:latest
+```
+
+- `mariadb` — name of MariaDB container,
+- `MARIADB_ROOT_PASSWORD=password` — you can change `password` to any password you want,
+- `mariadb:latest` — [MariaDB image](https://hub.docker.com/_/mariadb/tags) version.
+
+Run EspoCRM container:
+
+```
+$ docker run --name my-espocrm --link mariadb:mariadb -d espocrm/espocrm
+```
+
+- `my-espocrm` — name of EspoCRM container,
+- `mariadb:mariadb` — name (link) of MariaDB container,
+- `espocrm/espocrm` — [EspoCRM image](https://hub.docker.com/r/espocrm/espocrm/tags) version.
+
+#### Run EspoCRM container via a specific port:
+
+```
+$ docker run --name my-espocrm -p 8080:80 --link mariadb:mariadb -d espocrm/espocrm
+```
+
+Then, access it via `http://localhost:8080` with credentials admin and password.
+
+#### Run EspoCRM via a specific IP or a domain with a port:
+
+```
+$ docker run --name my-espocrm -e ESPOCRM_SITE_URL=http://172.20.0.100:8080 -p 8080:80 --link mariadb:mariadb -d espocrm/espocrm
+```
+
+Then, access it via `http://172.20.0.100:8080` with credentials **admin** and **password**.
+
+## Install EspoCRM with Docker Compose
+
+You can use Docker Compose to run EspoCRM in an isolated environment built with Docker containers. Before starting, make sure you have [Compose](https://docs.docker.com/compose/install/) installed.
+
+1\. Create an empty directory.
+
+```
+$ mkdir espocrm-docker
+```
+
+2\. Change into this directory.
+
+```
+$ cd espocrm-docker/
+```
+
+3\. Create a **`docker-compose.yml`** file:
+
+```
+services:
+
+ espocrm-db:
+ image: mariadb:latest
+ container_name: espocrm-db
+ environment:
+ MARIADB_ROOT_PASSWORD: root_password
+ MARIADB_DATABASE: espocrm
+ MARIADB_USER: espocrm
+ MARIADB_PASSWORD: database_password
+ volumes:
+ - espocrm-db:/var/lib/mysql
+ restart: always
+ healthcheck:
+ test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
+ interval: 20s
+ start_period: 10s
+ timeout: 10s
+ retries: 3
+
+ espocrm:
+ image: espocrm/espocrm
+ container_name: espocrm
+ environment:
+ ESPOCRM_DATABASE_PLATFORM: Mysql
+ ESPOCRM_DATABASE_HOST: espocrm-db
+ ESPOCRM_DATABASE_USER: espocrm
+ ESPOCRM_DATABASE_PASSWORD: database_password
+ ESPOCRM_ADMIN_USERNAME: admin
+ ESPOCRM_ADMIN_PASSWORD: password
+ ESPOCRM_SITE_URL: "http://localhost:8080"
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ depends_on:
+ espocrm-db:
+ condition: service_healthy
+ ports:
+ - 8080:80
+
+ espocrm-daemon:
+ image: espocrm/espocrm
+ container_name: espocrm-daemon
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ entrypoint: docker-daemon.sh
+
+ espocrm-websocket:
+ image: espocrm/espocrm
+ container_name: espocrm-websocket
+ environment:
+ ESPOCRM_CONFIG_USE_WEB_SOCKET: "true"
+ ESPOCRM_CONFIG_WEB_SOCKET_URL: "ws://localhost:8081"
+ ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN: "tcp://*:7777"
+ ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN: "tcp://espocrm-websocket:7777"
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ entrypoint: docker-websocket.sh
+ ports:
+ - 8081:8080
+
+volumes:
+ espocrm-db:
+ espocrm:
+```
+
+More about *Installation Environments* you can find [here](#installation-environments).
+
+4\. Build EspoCRM project from directory.
+
+```
+$ docker compose up -d
+```
+
+5\. Bring up EspoCRM in a web browser. You can use http://localhost as the IP address, and open http://localhost:8080 in a web browser.
+
+### Install EspoCRM with Traefik
+
+You can read the instructions for installing EspoCRM in conjunction with Traefik in the Docker Compose environment [here](https://docs.espocrm.com/administration/docker/traefik/).
+
+### Install EspoCRM with Caddy
+
+You can read the instructions for installing EspoCRM in conjunction with Caddy in the Docker Compose environment [here](https://docs.espocrm.com/administration/docker/caddy/).
+
+### Upgrading
+
+In order to upgrade the container created by the `docker-compose.yml`:
+
+1. Open your EspoCRM container directory.
+2. Run the command:
+
+ ```
+ $ docker compose pull && docker compose up -d
+ ```
+
+Within a few minutes the container will be upgraded to the latest version.
+
+### Shutdown and cleanup containers
+
+The `docker compose down` command removes the containers and default network, but preserves EspoCRM database.
+
+The `docker compose down --volumes` removes the containers, default network, and the EspoCRM database.
+
+### Running a shell
+
+In order to enter the container and view the files, make a rebuild, etc., use the following command (`espocrm` is your container name):
+
+```
+$ docker exec -it espocrm bash
+```
+
+## Installation Environments
+
+This is one-time environment variables which are using only for the fresh installation. If you need to define configuration options on the container startup, see the [Config Environments](#config-environments).
+
+#### ESPOCRM_DATABASE_PLATFORM
+
+Database platform. The possible values: `Mysql` or `Postgresql`. The default value is `Mysql`.
+
+#### ESPOCRM_DATABASE_HOST
+
+Database host name for EspoCRM. The default value is `espocrm-db`.
+
+#### ESPOCRM_DATABASE_PORT
+
+Database port for EspoCRM. The default value is empty.
+
+#### ESPOCRM_DATABASE_NAME
+
+Database name for EspoCRM. The default value is `espocrm`.
+
+#### ESPOCRM_DATABASE_USER
+
+Database user for EspoCRM. The default value is `root`.
+
+#### ESPOCRM_DATABASE_PASSWORD
+
+Database password for EspoCRM. The default value is `password`.
+
+#### ESPOCRM_ADMIN_USERNAME
+
+User name for an administrator of EspoCRM. The default value is `admin`.
+
+#### ESPOCRM_ADMIN_PASSWORD
+
+User password for an administrator of EspoCRM. The default value is `password`.
+
+#### ESPOCRM_SITE_URL
+
+The URL of EspoCRM. This option is very important for normal operating of EspoCRM. Examples: `http://172.20.0.100:8080`, `http://my-crm.local`.
+
+### Other optional options
+
+The list of possible values and their default values can be found in EspoCRM Administrator panel > Settings.
+
+- `ESPOCRM_LANGUAGE`
+- `ESPOCRM_DATE_FORMAT`
+- `ESPOCRM_TIME_FORMAT`
+- `ESPOCRM_TIME_ZONE`
+- `ESPOCRM_WEEK_START`
+- `ESPOCRM_DEFAULT_CURRENCY`
+- `ESPOCRM_THOUSAND_SEPARATOR`
+- `ESPOCRM_DECIMAL_MARK`
+
+## Config Environments
+
+These environment variables are using to define configuration parameters of the EspoCRM every time on the container startup. The parameters that can be changed are defined in the `data/config.php` or `data/config-internal.php`.
+
+### Naming
+
+Config environment variables should be converted from the camel-case format. For example:
+The `exportDisabled` config option should be converted to `ESPOCRM_CONFIG_EXPORT_DISABLED`.
+
+### Logger
+
+There are additional options to change the `logger`:
+
+- `ESPOCRM_CONFIG_LOGGER_LEVEL: "DEBUG"`
+- `ESPOCRM_CONFIG_LOGGER_MAX_FILE_NUMBER: 30`
+- `ESPOCRM_CONFIG_LOGGER_PATH: "data/logs/espo.log"`
+
+For more details, visit [documentation](../log.md).
+
+### Allowed types:
+
+#### String
+```
+ESPOCRM_CONFIG_WEB_SOCKET_URL: "wss://my-espocrm.com:8080"
+```
+
+#### Integer
+```
+ESPOCRM_CONFIG_EMAIL_MESSAGE_MAX_SIZE: 10
+```
+
+#### Boolean
+```
+ESPOCRM_CONFIG_USE_WEB_SOCKET: "true"
+```
+
+#### Null
+```
+ESPOCRM_CONFIG_CURRENCY_DECIMAL_PLACES: "null"
+```
+
+## Image Variants
+
+The `espocrm` images come in many flavors, each designed for a specific use case.
+
+- `espocrm:apache`
+- `espocrm:fpm`
+- `espocrm:fpm-alpine`
+- `espocrm:`
+- `espocrm:-apache`
+- `espocrm:-fpm`
+- `espocrm:-fpm-alpine`
+
+## Troubleshooting
+
+### Switching to MySQL 8.4
+
+In MySQL 8.4 there were changes in the authentication procedure, so you may encounter authentication related errors while upgrading EspoCRM. In this case, it is recommended to take the following steps:
+
+1\. Change *authentication plugin* to `caching_sha2_password` for your MySQL users:
+
+Notes:
+
+- Replace the `YOUR_ROOT_PASSWORD` with your MySQL root password.
+- Replace the `YOUR_ESPOCRM_DB_PASSWORD` with your MySQL espocrm user password.
+
+```
+sudo docker exec -i mysql mysql --user=root -p -e "
+ ALTER USER IF EXISTS 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'YOUR_ROOT_PASSWORD';
+ ALTER USER IF EXISTS 'root'@'%' IDENTIFIED WITH caching_sha2_password BY 'YOUR_ROOT_PASSWORD';
+ ALTER USER IF EXISTS 'espocrm'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'YOUR_ESPOCRM_DB_PASSWORD';
+ ALTER USER IF EXISTS 'espocrm'@'%' IDENTIFIED WITH caching_sha2_password BY 'YOUR_ESPOCRM_DB_PASSWORD';"
+```
+
+2\. Remove from *docker-compose.yml* file the following line: `command: --default-authentication-plugin=mysql_native_password`.
+
+3\. Restart and build `mysql` container:
+
+```
+sudo docker stop mysql && sudo docker rm mysql
+docker compose up -d --build
+```
diff --git a/docs/administration/docker/traefik.md b/docs/administration/docker/traefik.md
new file mode 100644
index 000000000..99bb74f34
--- /dev/null
+++ b/docs/administration/docker/traefik.md
@@ -0,0 +1,142 @@
+# Traefik and EspoCRM
+
+Traefik is an open-source reverse proxy that makes it easy to work with microservices and/or just containers with your applications.
+
+To connect Traefik and EspoCRM, you can use the Docker Compose environment. Also, you must have your own domain.
+
+1. Create a folder that will contain your EspoCRM files and database.
+2. Create here a `docker-compose.yml` file:
+
+#### docker-compose.yml
+
+```
+services:
+
+ traefik:
+ image: traefik:latest
+ container_name: traefik
+ command:
+ - --api.insecure=true
+ - --providers.docker=true
+ - --providers.docker.exposedbydefault=false
+ - --entrypoints.websecure.address=:443
+ - --entrypoints.web.address=:80
+ - --entrypoints.web.http.redirections.entryPoint.to=websecure
+ - --entrypoints.web.http.redirections.entryPoint.scheme=https
+ - --entrypoints.web.http.redirections.entrypoint.permanent=true
+ - --certificatesresolvers.esporesolver.acme.tlschallenge=true
+ - --certificatesresolvers.esporesolver.acme.email={EMAIL_ADDRESS}
+ - --certificatesresolvers.esporesolver.acme.storage=/letsencrypt/acme.json
+ ports:
+ - "80:80"
+ - "8080:8080"
+ - "443:443"
+ volumes:
+ - ./letsencrypt:/letsencrypt
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+
+ espocrm-db:
+ image: mariadb:latest
+ container_name: espocrm-db
+ command: --max-allowed-packet=64MB
+ restart: always
+ healthcheck:
+ test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
+ interval: 20s
+ start_period: 10s
+ timeout: 10s
+ retries: 3
+ environment:
+ MARIADB_ROOT_PASSWORD: root_password
+ MARIADB_DATABASE: espocrm
+ MARIADB_USER: espocrm
+ MARIADB_PASSWORD: database_password
+ volumes:
+ - ./espocrm-db:/var/lib/mysql
+
+ espocrm:
+ image: espocrm/espocrm:latest
+ container_name: espocrm
+ environment:
+ ESPOCRM_DATABASE_HOST: espocrm-db
+ ESPOCRM_DATABASE_USER: espocrm
+ ESPOCRM_DATABASE_PASSWORD: database_password
+ ESPOCRM_ADMIN_USERNAME: admin
+ ESPOCRM_ADMIN_PASSWORD: password
+ ESPOCRM_SITE_URL: "https://{ESPOCRM_DOMAIN}"
+ restart: always
+ depends_on:
+ espocrm-db:
+ condition: service_healthy
+ volumes:
+ - ./espocrm:/var/www/html
+ labels:
+ - traefik.enable=true
+ - traefik.http.routers.espocrm-app.rule=Host(`{ESPOCRM_DOMAIN}`)
+ - traefik.http.routers.espocrm-app.entrypoints=websecure
+ - traefik.http.routers.espocrm-app.tls=true
+ - traefik.http.routers.espocrm-app.tls.certresolver=esporesolver
+
+ espocrm-daemon:
+ image: espocrm/espocrm:latest
+ container_name: espocrm-daemon
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ entrypoint: docker-daemon.sh
+
+ espocrm-websocket:
+ image: espocrm/espocrm:latest
+ container_name: espocrm-websocket
+ environment:
+ ESPOCRM_CONFIG_USE_WEB_SOCKET: "true"
+ ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBSCRIBER_DSN: "tcp://*:7777"
+ ESPOCRM_CONFIG_WEB_SOCKET_ZERO_M_Q_SUBMISSION_DSN: "tcp://espocrm-websocket:7777"
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ entrypoint: docker-websocket.sh
+ labels:
+ - traefik.enable=true
+ - traefik.http.routers.espocrm-ws.rule=Host(`{ESPOCRM_DOMAIN}`) && PathPrefix(`/ws`)
+ - traefik.http.routers.espocrm-ws.entrypoints=websecure
+ - traefik.http.routers.espocrm-ws.tls=true
+ - traefik.http.routers.espocrm-ws.tls.certresolver=esporesolver
+ - traefik.http.services.espocrm-ws.loadbalancer.server.port=8080
+
+volumes:
+ espocrm-db:
+ espocrm:
+```
+
+Traefik container commands explanation:
+
+- **api.insecure=true** – *Enable the API in insecure mode. You can access Traefik Dashboard at `your_server_IP:8080`*
+- **providers.docker=true** – *Enable Docker as the provider for Traefik*
+- **providers.docker.exposedbydefault=false** – *Don't expose every container to Traefik, only expose enabled ones*
+- **entrypoints.websecure.address=:443** – *Define an entrypoint for HTTPS on port :443 named websecure*
+- **entrypoints.web.address=:80** – *Define an entrypoint for port :80 named web*
+- **entrypoints.web.http.redirections.entryPoint.to=websecure** – *Redirect all incoming requests to entrypoint websecure*
+- **entrypoints.web.http.redirections.entryPoint.scheme=https** – *Redirection target scheme*
+- **entrypoints.web.http.redirections.entrypoint.permanent=true** – *Apply a permanent redirection*
+- **certificatesresolvers.esporesolver.acme.tlschallenge=true** – *Enable TLS-ALPN-01 to generate and renew ACME certificates*
+- **certificatesresolvers.esporesolver.acme.email=`{EMAIL_ADDRESS}`** – *Setting email for certificates*
+- **certificatesresolvers.esporesolver.acme.storage=/letsencrypt/acme.json** – *Defining acme.json file to store certificates information*
+
+EspoCRM container commands explanation:
+
+- **traefik.enable=true** – *Enable Traefik to proxy main EspoCRM container*
+- **traefik.http.routers.espocrm-app.rule=Host(`{ESPOCRM_DOMAIN}`)** – *Your domain name goes here for the HTTP rule*
+- **traefik.http.routers.espocrm-app.entrypoints=websecure** – *Define entrypoint for HTTPS*
+- **traefik.http.routers.espocrm-app.tls=true** – *Make sure all routers tied to this entrypoint are using HTTPS by default*
+- **traefik.http.routers.espocrm-app.tls.certresolver=esporesolver** – *Define certificates resolvers for HTTPS*
+
+> The labels in the EspoCRM container for WebSocket works in exactly the same way, we only add a prefix to the host and open port 8080 for container.
+
+----
+
+Now, start containers with the CLI command `docker compose up -d`.
+
+You can track the work of Traefik on the Dashboard at *your_server_IP:8080*.
+
+EspoCRM will work with both HTTP and HTTPS on your domain.
diff --git a/docs/administration/dynamic-logic.md b/docs/administration/dynamic-logic.md
index 70cc905f3..cfbb70cb8 100644
--- a/docs/administration/dynamic-logic.md
+++ b/docs/administration/dynamic-logic.md
@@ -1,30 +1,103 @@
-# Dynamic Logic (dynamic forms)
+---
+search:
+ boost: 2
+---
+
+# Dynamic Logic
+
+A dynamic behavior for forms can be achieved by utilizing the Dynamic Logic feature.
## Fields
-Dynamic behavior of forms can be achieved by utilizing Dynamic Logic feature. Dynamic Logic parameters are available for every field. Parameters are available in Entity Manager when you edit or create a field.
+Dynamic Logic parameters are available for every field (Administration > Entity Manager > {Entity Type} > Fields > {field}.
-Dynamic Logic allows to define conditions making certain fields visible, required or read-only. Conditions will be checked automatically when data in the form is changed.
+The Dynamic Logic allows you to define conditions making certain fields visible, required or read-only. Conditions will be
+checked automatically when data in the form is changed.
-For *Enum*, *Array*, *Multi-Enum*, *Checklist* fields it's, possible to define different sets of options that will be available for the field depending on which condition is met. Note, that the order of option list is taken into account.
+For *Enum*, *Array*, *Multi-Enum*, *Checklist* fields it's, possible to define different sets of options that will be
+available for the field depending on which condition is met. Note that the order of option list is taken into account.
Dynamic logic can control:
-* Visibility − if the field is visible or not
-* Required − if the field is required or not
-* Read-only − if the field read-only or not
-* Options − conditions that determine which options are available (for Enum, Array, Multi-Enum, Checklist fields)
+* Visibility − if the field is visible or not;
+* Required − if the field is required or not;
+* Read-only − if the field read-only or not;
+* Options − conditions that determine options available for enum fields;
+* Invalidity − conditions making the field invalid.
Conditions are configured through user interface, no coding required.

+!!! note
+
+ * When a condition for a field checks the value of the same field, it may cause side effects. E.g. making a field read-only when the same field is not empty.
+ * When defining enum options that depend on the current value of the field, you need to include the current value to the option set.
+ * In some cases it may be reasonable to disable the inline-edit functionality for a specific field as it may interfere with the dynamic logic.
+ * Dynamic Logic operates fields on the form, it has no effect on buttons and menu items in the UI.
+ * Dynamic Logic is not applied on the list view.
+
+### Field logic
+
+#### Visible
+
+Is applied only in the frontend.
+
+#### Required
+
+Is applied only in the frontend and in the backend (as of v9.1).
+
+#### Read-only
+
+Is applied only in the frontend. Conditions are checked against the current state of the record. If we change a record without saving it, it changes the current state.
+
+#### Read-only saved-state
+
+*As of v9.1.*
+
+Dynamic logic conditions checked against the saved state of the record. The logic is not applied while editing a record without saving.
+
+* Is not applied when a record is created.
+* Applied in both the frontend and the backend.
+* Applied in mass-update.
+
+Use-case: Make a field Resolution read-only when Status = Completed. It won't be possible to write the Resolution field while the Status is saved as Completed. Even if we change the Status on the form, the Resolution field will still be read-only. But if we change and save the Status, it will be possible to write the Resolution field.
+
+#### Options
+
+A mapping of conditions against option lists. Specific conditions determine what options will be available in an enum field.
+
+For Enum, Array, Multi-Enum and Checklist fields.
+
+### Regular expression
+
+For *Varchar* and *Text* fields, it's possible to define a regular expression to check whether a value matches a specific
+pattern.
+
+An expression should start and end with a slash character.
+
+Example: `/^\d{5}-\d{6}-\d{2}$/`
+
+You can also specify regular expression flags after the ending slash.
+
## Panels
-In Layout Manager, you can specify conditions making a specific panel visible. Edit a panel to specify dynamic logic.
+In the Layout Manager, you can specify conditions making a specific panel visible. Edit the panel to configure the dynamic logic.
Available in the following layouts:
* Detail
* Side Panels
* Bottom Panels
+
+It's also possible to define conditions on which a specific color will be applied to the panel.
+
+## Misc
+
+To determine whether a record is being created, check whether the ID is empty. It can be useful to hide some fields when the record not yet created or to show some panel with instructions described in a panel note.
+
+For dynamic logic that is applied only in the frontend, you may consider additionally using an API Before-Save script for a validation purpose.
+
+## See also
+
+* [Dynamic Logic quick tour](https://app.supademo.com/demo/cmke83sqa1io5qm44yrnnenp8)
diff --git a/docs/administration/emails.md b/docs/administration/emails.md
index b14026438..77de25520 100644
--- a/docs/administration/emails.md
+++ b/docs/administration/emails.md
@@ -1,41 +1,80 @@
+---
+search:
+ boost: 3
+---
+
# Email Administration
-Important: [Cron](server-configuration.md#setting-up-crontab) should be configured in your system to make email fetching work.
+!!! important
+
+ [Cron](server-configuration.md#setting-up-crontab) should be configured in your system to make email fetching work.
## Overview
EspoCRM has the ability to monitor IMAP mailboxes. Emails can be fetched by Group Email Accounts and Personal Email Accounts. Group Email Accounts represent group mailboxes: the most common case is a support-team mailbox. Personal Email Accounts represent personal mailboxes of users.
-As an email is coming, the system tries to link it with the appropriate record (Accounts, Lead, Opportunity, Case). Users who follow that record will receive notification about a new email in the system, even if they are not listed in To or CC of the email.
+As an email is coming, the system tries to link it with an appropriate record (Accounts, Lead, Opportunity, Case). Users who follow that record will receive a notification about the new email in the system, even if they are not recipients of the email.
+
+!!! warning "Important"
+
+ Email records **are not duplicated** in the system, even if they are fetched by different email accounts. If you remove an email record from the CRM, it will be removed for all users. It's recommended to **move to trash** instead. It's also recommended to restrict *delete* access for users in Roles.
+
+An Email record can be assigned to a particular user. By default, the Assigned User field is not available on the layout. The administrator can add it at: Administration > Entity Manager > Side Panel Fields.
+
+## Access control
+
+Access to imported emails is controlled by Roles. It means that if a particular email was imported from a mailbox of some user, other users will be able to see that email if they have access to that email.
+
+If a user has a *read* access level set to *own*, they will be able to see emails that are related to them through at least one of the following links: Users, Assigned Users, Assigned User, Created By. Note than an email is automatically gets related with a user through the Users links if the user's email address is either in the *From*, *To* or *CC*.
+
+There are 4 access levels: No, Own, Team, All.
-Note: Email records are not duplicated in the system if they are fetched by different email accounts. If you remove an email record from the CRM, it will be removed for all users. It's recommended to use **moving to trash** instead. It's recommended to restrict *delete* access for users in Roles.
+## Group email accounts
-## Group Email Accounts
+Group Email Accounts can be accessed at Administration > Group Email Accounts.
Only administrator can setup Group Email Accounts. Group Email Accounts can be used for both receiving and sending emails.
-*Teams* field (of group email account record) determines which teams incoming emails will be assigned to.
+The *Teams* field determines which teams incoming emails will be assigned to.
-If the group email account has SMTP and it's checked as **shared**, then users will be able to use this account to send emails. Access to the account for sending is controlled by Roles through *Group Email Account* permission. If the permission level is set to `Teams`, then users of the teams selected in *Teams* field of the group email account will be able to use the group email account.
+If a Group Email Account has the SMTP enabled and it's checked as **shared**, then users will be able to use this account when sending emails. Access to the account for sending is controlled by Roles through the *Group Email Account* permission. If the permission level is set to *teams*, then users of the teams selected in the *Teams* field of the Group Email Account will be able to use that Group Email Account.
-There is the ability to make the system send an **auto-reply** for incoming emails.
+There is the ability to make the system send an **auto-reply** for emails incoming to a Group Email Account.
+
+### System email account
+
+One Group Email Account needs to be picked as the system default account. All notifications and system emails will be sent from that account.
+
+1. Create and configure a Group Email Account (at Administration > Group Email Accounts).
+2. Navigate to Administration > Outbound Emails.
+3. Specify the email address in the *System Email Address* field. The email address must be exactly the same as in the created Group Email Account (the list of available accounts will be shown in an autocomplete dropdown).
### Email-to-Case
-There is an option to make the system create a new case record from each email incoming to a specific group email account. Cases can be distributed to users of a specific team. There are three available distribution rules: *direct assignment*, *round-robin* and *less-busy*.
+There is an option to make the system create a new Case record from each email incoming to a specific Group Email Account. Cases can be distributed to users of a specific Team. There are three available distribution rules: *Direct Assignment*, *Round-Robin* and *Less-Busy*.
+
+!!! note
+
+ Only the first email in the thread creates a new Case. Every subsequent email will be linked to the existing Case record and a Note will be added to the Stream.
+
+When a user wants to send a reply to a customer, they need to make sure that the Case is selected as a **parent** of the email that is being sent. It will add the group email address to the *Reply-To* field of the email. So the customer's reply will be sent to the group address rather than to the user’s one.
+
+## Personal email accounts
+
+Regular users can set up their own email accounts that need to be monitored (at Emails tab > top right dropdown menu > Personal Email Accounts).
-Note: Only the first email in the thread creates a new case. Every subsequent email will be linked to the existing case record and note will be added to the Stream panel.
+The administrator also can manage Personal Email Accounts of users (at Administration > Personal Email Accounts).
-When a user wants to send a reply to the customer, they need to make sure that the case is selected as a **parent** of the email that is being sent. It will add the group email address to *Reply-To* field of the email. So the customer's reply will be sent to the group address rather than to the user’s one.
+!!! warning "Important"
-## Personal Email Accounts
+ By default, regular users don’t have **access** to Personal Email Accounts. The Administrator needs to allow access to the *Personal Email Accounts* scope in Roles.
-Regular users can set up their own email accounts that need to be monitored. Emails > top right dropdown menu > Personal Email Accounts. Administrator also can manage personal email accounts of users.
+!!! warning "Important"
-Important: By default, regular users don’t have **access** to personal email accounts. Administrator needs to allow access to *Personal Email Accounts* scope in Roles.
+ This is required to have the email functionality working properly. User records need to have their email address (or multiple addresses) set in the *Email* field. Only the administrator can change the *Email* field for users. It's supposed that the user's email address is the same as the email address of the user's Personal Email Account.
-## Email Filters
+## Email filters
-Email Filters allow filtering of incoming emails according to specified criteria. E.g. if you don't want notification messages sent by some application to be imported to EspoCRM, you can create a filter to make EspoCRM skip them.
+Email Filters allow filtering of incoming emails according to specified criteria. For example, if you don't want notification messages sent by some application to be imported to EspoCRM, you can create a filter to make EspoCRM skip them.
-Admin can create **global filters**, applied to all email accounts. Users can create filters for their own personal email account and for the entire inbox.
+The administrator can create **global** filters applied to all email accounts. Users can create filters for their own Personal Email Account and for their entire Inbox.
diff --git a/docs/administration/entity-manager.md b/docs/administration/entity-manager.md
index 2f5216943..dfe6fe142 100644
--- a/docs/administration/entity-manager.md
+++ b/docs/administration/entity-manager.md
@@ -1,13 +1,26 @@
+---
+search:
+ boost: 2
+---
+
# Entity Manager
-Entity Manager is available in Administration panel. It provides the ability to highly customize your EspoCRM instance. You are able to do the following:
+The Entity Manager is an essential part of EspoCRM. It allows using the system as a platform for custom business application development, as well as customizing the default CRM features.
+
+With the Entity Manager, you can:
* Add new entity types.
-* Customize existing entity types: change labels, default order in list view, etc.
-* Configure fields: add new, customize existing ones.
-* Configure relationships: add new, change labels of existing ones.
+* Customize existing entity types: change labels, default order and many other parameters.
+* Configure fields: add new and customize existing ones.
+* Configure relationships: add new, change labels and parameters of existing ones.
+
+The Entity Manager tool is available from the Administration panel.
+
+All customizations made via the Entity Manager are stored in the `custom` directory. You can make customizations on a separate instance, then [copy](#copying-customizations-to-another-instance) them to another instance.
-All customizations made via Entity Manager are stored in `custom/` directory. You can make customizations on a separate instance, then copy *custom* dir to your production instance and run rebuild (from administration panel or CLI).
+!!! note
+
+ When creating a new entity type, a field or relationship in an existing entity type, the system will add a prefix *c* to the name (meaning custom). The purpose of it is to prevent naming conflicts with future versions. This behavior can be disabled with the config parameter `customPrefixDisabled`. Disable it at your own risk.
In this article:
@@ -15,51 +28,76 @@ In this article:
* [Entity type parameters](#entity-type-parameters)
* [Fields](#fields)
* [Relationships](#relationships)
+* [Formula](#formula)
+* [Copying customizations to another instance](#copying-customizations-to-another-instance)
+
+See also:
+
+* [Quick tour](https://app.supademo.com/demo/cmc39h2hnlaf0sn1ru3j5yul5)
## Creating new entity type
-Click *Create Entity* button on Entity Manager main page (Administration > Entity Manager). Specify name, labels and select type. If you select *Person* type, your entity will have Email, Phone, First Name, Last Name and Salutation fields. Check *Stream* if you want to have a stream panel (users will be able to follow records).
+Click the *Create Entity* button on the Entity Manager main page (Administration > Entity Manager). Specify the name, labels and select the type. If you select the *Person* type, your entity will have Email, Phone, First Name, Last Name and Salutation fields. Check the *Stream* if you want to have the Stream panel (users will be able to follow records).
Types:
-* Base - empty entity only with basic fields like Name, Assigned User, Teams, Description.
-* Base Plus - like Base but with Activities, History, Tasks panels.
-* Event - has Date Start, Date End, Duration, Parent, Status fields; available in Calendar and Activities panel (must be [enabled](../user-guide/activities-and-calendar.md#custom-entities-on-calendar) at Administration > Settings).
-* Person - has Email, Phone, First Name, Last Name, Salutation, Address fields; Activities, History, Tasks panels.
-* Company - has Email, Phone, Billing Address, Shipping Address fields; Activities, History, Tasks panels.
+* Base – has only basic fields created by default: Name, Assigned User, Teams, Description.
+* Base Plus – like the Base type but with the Activities, History, Tasks panels.
+* Event – has the Date Start, Date End, Duration, Parent, Status fields; available in the Calendar and in the Activities panel (must be [enabled](../user-guide/activities-and-calendar.md#custom-entities-on-calendar) at Administration > Settings).
+* Person – has the Email, Phone, First Name, Last Name, Salutation, Address fields; the Activities, History, Tasks panels.
+* Company – has the Email, Phone, Billing Address, Shipping Address fields; the Activities, History, Tasks panels.
## Entity type parameters
-If you click *Edit* on a certain entity, you will be able to change parameters of that entity.
-
-* Labels - singular and plural names of the entity.
-* Default order in which records are sorted by in list views.
-* Stream - whether Stream feature is enabled for this entity.
-* Disabled - check if you don't need this entity in your system.
-* Text Filter Fields - what fields to search in for the main text filter and global search.
-* Status field - which field (of enum type) will be used for a record status; required for kanban view.
-* Kanban view - available only if Status Field is specified. Enables Kanban view mode.
-* Full-Text Search - see more [here](../user-guide/text-search.md#full-text-search).
-* Disable record count - the total number won't be displayed on the list view; can decrease loading time when the DB table is big.
-* Color - a specific color for a quick recognition.
-* Icon - the picked icon will be displayed in the side navbar.
+If you click *Edit* on the entity view, you will be able to change parameters of that entity type.
+
+* Labels – singular and plural names of the entity type.
+* Default order – how records are sorted in list views by default.
+* Stream – enables the Stream feature for the entity type.
+* Stars – the ability to star records; stars can be used by users to bookmark specific records.
+* Disabled – check if you don't need this entity type in the system.
+* Text Filter Fields – defines which fields are searched by the main text filter and global search.
+* Status Field – specifies which field (of enum type) will be used to represent the record status; required for the Kanban view.
+* Kanban view – enables the Kanban view mode; the parameter is available only if the Status Field is specified.
+* Full-Text Search – enables full-text search; see more [here](../user-guide/text-search.md#full-text-search).
+* Disable record count – the total number won't be displayed on the list view; can decrease loading time when the DB table is big.
+* Color – a color for a quick recognition.
+* Icon – pick an icon for the entity type.
+* Preserve Audit Log – disables cleanup of the audit log; this parameter is applicable only if Stream is disabled, since if Stream is enabled, audit log records are not being deleted.
+* Collaborators – the ability to [share](roles-management.md#collaborators) records with specific users.
+* Multiple Assigned Users – the ability to assign multiple users to a record.
+* Categories – records can be organized into tree-like categories; available for Base and Base Plus types (as of v9.4).
+* Lockable – enables record locking (as of v9.4).
+
+!!! note
+
+ Some parameters are not available for certain entity types.
## Fields
-By clicking *Fields* link, you will be moved to a separate page. There, you will be able to create new fields or update existing ones.
+By clicking the *Fields* button, you will be moved to a separate page. There, you will be able to create new fields or update existing ones.
+
+See [more detail](fields.md) about fields in the separate article.
-[More detail](fields.md) about fields.
+!!! important
-**Note**: After you have added a new field, you need to put this field on [layouts](layout-manager.md) (Administration > Layout Manager).
+ After you created a new field, you may also need to put this field on [layouts](layout-manager.md) (Administration > Layout Manager).
+ You also need to add the field to the Search Filters layout to be able to search by the field on the list view.
## Relationships
-You can create new relationships between both out-of-the-box and custom entities. Relationship types are listed below.
+You can create custom relationships between entity types. Both standard and custom entities can be related to each other.
+
+It's possible to create a relationship between the same entity type. E.g. a Company can have a parent company and child companies.
+
+It's possible to have multiple relationships between the same entity type pairs. E.g. a Person and an Event can be linked by two relationships: attendees and organizers.
+
+Relationship types are listed below.
#### One-to-Many
-After you have created this relationship, you can put a link field to the detail layout of the right entity and add relationship panel to the left entity.
+After you created the relationship, a *Link* field will be automatically created for the right-side entity type. You can add the link field to the Detail layout (at Administration > Entity Manager > {Entity Type} > Layouts > Detail). You can also add the relationship panel to the left entity type (at Administration > Entity Manager > {Entity Type} > Layouts > Bottom Panels).
#### Many-to-One
@@ -67,32 +105,62 @@ The same as One-to-Many but vice versa.
#### Many-to-Many
-Relationship panels on both sides.
+After you created the relationship, relationship panels will be available on both sides (at Administration > Entity Manager > {Entity Type} > Layouts > Bottom Panels).
#### One-to-One Right
-*Link* field on one side, *Link-One* on another (since 5.8.0).
+The *Link* field will be created in the current entity type (left), the *Link-One* field – in the foreign entity type (right). It does not matter which one-to-one type to choose from the user perspective.
#### One-to-One Left
-The same as previous but vice versa.
+The same as previous but vice versa. The *Link* field will be created in the foreign entity type.
#### Children-to-Parent
-Linking with multiple entity types through *Link-Parent* field (since 5.8.0).
+Linking with multiple entity types through the *Link-Parent* field.
+
+*Foreign Links* checkboxes allows you to create Has-Children links in specific parent entity types. For example, if we check *Account* foreign link, it will create a link in the Account entity type. It will allow to add relationship panel in Account.
### Parameters
-#### Link Multiple Field
+#### Link Multiple field
-The parameter *Link Multiple Field* implies that the field of *Link-Multiple* type will be created along with the relationship. You can put such a field on the layout. It's convenient for quick picking of related records. It's not a good option if your relationship is intended to have a lot of linked records that can slow down loading of the detail view screen.
+The parameter *Link Multiple Field* implies that the field of the *Link-Multiple* type will be created along with the relationship. You can put such a field on the layout. It's convenient for quick picking of related records. It's not a good option if your relationship is intended to have a lot of linked records that can slow down loading of the detail view screen.
Examples of link-multiple fields:
-* *Teams* field - most entities have this field
-* *Contacts* field in *Opportunity*
-* *Contacts* field in *Case*
+* *Teams* field – most entities have this field;
+* *Contacts* field in *Opportunity*;
+* *Contacts* field in *Case*.
#### Audited
-If the parameter *Audited* is checked, then updates of the relationship will be logged in Stream.
+If the parameter **Audited** is checked, then updates of the relationship will be logged in Stream.
+
+## Formula
+
+### Before-save custom script
+
+This [formula](formula.md) script will be executed every time before a record is saved. This provides the ability to automatically set specific fields with values derived from calculation. In addition, some functions can perform actions, for example, email sending and record creation.
+
+To edit the formula script for a specific entity type, follow Administration > Entity Manager > a needed entity type > Formula.
+
+!!! note
+
+ It can be reasonable to set fields that are supposed to be calculated by formula as read-only (Administration > Entity Manager > {Entity Type} > Fields).
+
+An administrator can run *Recalculate Formula* action for specific records from the list view: select records (or all search results) > click *Actions* dropdown > click *Recalculate Formula*.
+
+### API before-save script
+
+*As of v7.5.*
+
+This [formula](formula.md) script is called on create and update API requests, before the record is saved. See more [detail](api-before-save-script.md).
+
+## Copying customizations to another instance
+
+All customizations made through Entity Manager are stored in the `custom/Espo/Custom` folder. You need to copy contents of this folder to another instance and then run rebuild (CLI command `php rebuild.php`).
+
+### Exporting to extension
+
+It's also possible to export customization to an installable extension. On the Entity Manager page, from the dropdown next to *Create Entity* button.
diff --git a/docs/administration/extensions.md b/docs/administration/extensions.md
index 4e2a9d44c..e638f5ff9 100644
--- a/docs/administration/extensions.md
+++ b/docs/administration/extensions.md
@@ -2,7 +2,7 @@
## Installing
-In order to install EspoCRM extension (e.g. Advanced Pack, VoIP Integration):
+In order to install EspoCRM extension (e.g. Advanced Pack):
1. Login as an administrator.
2. Go to Administration > Extensions.
@@ -12,15 +12,17 @@ In order to install EspoCRM extension (e.g. Advanced Pack, VoIP Integration):
## Upgrading
-In order to upgrade an already installed extension (e.g. Advanced Pack, VoIP integration) to a newer version:
+In order to upgrade an already installed extension to a newer version:
1. Download the new version of the needed extension.
-2. Login as an administrator.
+2. Log in as an administrator.
3. Go to Administration > Extensions.
4. Upload your new extension package (zip file) without uninstalling the already installed version.
-5. Click Install button.
+5. Click the **Install** button.
-There's NO need to install intermediate versions. Install just the latest one.
+!!! note
+
+ There's no need to install intermediate versions. Install just the latest one.
## Uninstalling
@@ -29,8 +31,11 @@ Steps to uninstall an extension:
1. Login as an administrator.
2. Go to Administration > Extensions.
3. Find the needed extension on the list of available extensions.
-4. Click Uninstall button.
+4. Click **Uninstall** from the dropdown.
+
+!!! note
+ Uninstalling an extension does not cause data loss (unless the developer deliberately added such a logic). You can install the extension again and continue using it. Though, if you run a hard rebuild after uninstalling, it will remove all custom database columns added by the extension but it won't remove custom tables.
## Deleting
@@ -39,14 +44,19 @@ When an extension is uninstalled, it is still available in the system. It can be
1. Login as an administrator.
2. Go to Administration > Extensions.
3. Find the needed extension in the list of available extensions.
-4. Click Remove button.
+4. Click **Remove** from the dropdown.
## CLI commands
### Installing & upgrading
```
-php extension.php path/to/extension/package.zip
+php command.php extension --file="path/to/extension/package.zip"
```
See more [commands](commands.md#extension).
+
+!!! note
+
+ In some cases, installing extensions via CLI is preferable, as usually PHP configuration for CLI is not as limited as for a web server.
+ For example, if a new version of an extension adds some database index, it can cause a timeout error when upgrading through the UI.
diff --git a/docs/administration/fields.md b/docs/administration/fields.md
index 7af33968f..7c95d9f77 100644
--- a/docs/administration/fields.md
+++ b/docs/administration/fields.md
@@ -12,12 +12,14 @@ The list of field types available for creating:
* [Currency](#currency) – for currency values, a float number and currency code;
* [Int](#int) – a whole number;
* [Float](#float) – a number with a decimal part;
+* [Decimal](#decimal) – a decimal number with fixed-point precision;
* [Boolean](#boolean) – a checkbox;
* [Multi-Enum](#multi-enum) – a list of values, multiple values can be selected;
* [Checklist](#checklist) – a list of checkboxes;
* [Array](#array) – a list of values, similar to Multi-Enum field;
* [Address](#address) – an address with street, city, state, postal code and country;
* [Url](#url) – for storing links;
+* [Url-Multiple](#url-multiple) – for storing multiple links;
* [Wysiwyg](#wysiwyg) – similar to Text field, but with HTML support;
* [File](#file) – for file uploading;
* [Image](#image) – for image uploading;
@@ -37,19 +39,25 @@ Field types not available for creating directly:
## Common field parameters
-* Label – a name of a field displayed on UI;
-* Required – whether a field is mandatory; user won't be able to save a record w/o filling the field;
-* Audited – field changes will be stored in stream;
-* Read-only – a field value can't be specified; can be calculated by formula or workflow rule;
+* Label – a name of the field displayed on the UI;
+* Required – whether the field is mandatory; user won't be able to save a record w/o filling the field;
+* Audited – field changes will be stored in stream and available in the Audit Log;
+* Read-only – a field value can't be specified, but can be calculated by formula or workflow rule;
+* Read-only After Create – a field value can be specified only when creating a record, after that the field will became read-only;
* Default – a value pre-filled when creating a new record;
-* Disable Inline Edit – useful when using dynamic forms logic;
-* Tooltip Text – info about a field for users.
+* Disable Inline Edit – may be useful when using Dynamic Logic;
+* Tooltip Text – information about the field for users (Markdown is supported);
+* Not Lockable – if enabled, the field is not locked when the record is locked.
+
+!!! note
+
+ When the read-only parameter is enabled for a *link* or *link-multiple* field, it won't be possible to create a related record from the relationship panel. It happens because an ID of the current record is passed in the link field.
## Dynamic Logic
-Provides an ability to make forms dynamic. It's possible to define conditions making certain fields visible, required or read-only. Conditions will be checked automatically when data in the form is changed.
+Provides the ability to make forms dynamic. It's possible to define conditions making certain fields visible, required or read-only. Conditions will be checked automatically when data in the form is changed.
-For *Enum*, *Array*, *Multi-Enum*, *Checklist* fields, it's possible to define different sets of options that will be available for the field depending on which condition is met. See more [here](dynamic-logic.md).
+For the *Enum*, *Array*, *Multi-Enum*, *Checklist* fields, it's possible to define different sets of options that will be available for the field depending on which condition is met. See more [here](dynamic-logic.md).
Available items:
@@ -67,8 +75,9 @@ A single-line text.
Parameters:
* Max-length – a max acceptable length of text;
-* Trim – to trim whitespaces from text;
-* Options – a pre-defined list of values for an autocomplete.
+* Options – a pre-defined list of values for an autocomplete;
+* Pattern – a regular expression to check a field value against;
+* Copy to clipboard button.

@@ -76,10 +85,10 @@ Parameters:
Selectbox, only one value can be selected.
-
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);
+* Options Reference – options from another field to re-use (as of v7.5);
* 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.
@@ -99,7 +108,9 @@ Parameters:
* Disable Text Cut – if not checked, then long texts will be shortened and can be expanded (for the detail view mode);
* Number of rows of textarea – a max number of rows before scroll bar appears (for the edit view mode);
* Cut Height (px) – a max height of a text, if longer, then it will be cut (for the detail view mode);
-* Display raw text (no markdown) – to disable markdown support.
+* Display raw text (no markdown) – to disable markdown support;
+* Preview – the ability to preview a Markdown text;
+* Attachment Field – an Attachment-Multiple field to connect the Text field with.

@@ -142,7 +153,9 @@ Parameters:
* Min – a validation: min acceptable value; if empty, then no validation applied;
* Max – a validation: max acceptable value; if empty, then no validation applied;
-* Only default currency – only one (default) currency will be available if enabled (since 5.9.0).
+* Only default currency – only one (default) currency will be available if enabled;
+* Disable Conversion – the currency conversion action won't change the currency of the field;
+* Decimal – use decimal data type (when precision is necessary) (as of v7.4).

@@ -158,7 +171,6 @@ 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.
-
## Float
A number with a decimal part.
@@ -166,8 +178,18 @@ A number with a decimal part.
Parameters:
* Min – a validation: min acceptable value; if empty, then no validation applied;
-* Max – a validation: max acceptable value; if empty, then no validation applied.
+* 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.
+
+## Decimal
+*As of v9.3.0.*
+
+A decimal number with fixed point precision. In the application, the value is represented as string. In the database – as DECIMAL.
+
+* Min – a validation: min acceptable value; if empty, then no validation applied;
+* 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.
## Boolean
@@ -186,11 +208,13 @@ A list of values, multiple values can be selected. The list is ordered.
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);
+* Options Reference – options from another field to re-use (as of v7.5);
* Is Sorted – to sort a list alphabetically;
* Allow Custom Options – if checked, a user can add custom values (not defined by *Options* parameter) by typing text and pressing the enter key;
* Max Item Count – a validation: how many items can be added;
* Display as Label – values will be displayed as a label with color; a color for each option can be specified;
-* Display as List – each value will be displayed in a new line.
+* Display as List – each value will be displayed in a new line;
+* Pattern – a regular expression to check a field value against.
## Checklist
@@ -200,6 +224,7 @@ A list of checkboxes.
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);
+* Options Reference – options from another field to re-use (as of v7.5);
* Is Sorted – to sort a list alphabetically;
* Max Item Count – a validation: how many items can be checked;
@@ -211,9 +236,12 @@ A list of values, similar to Multi-Enum field.
Parameters:
* Options – a list of values (key => label pairs); if no options specified, then a user will be able to add any options;
+* Options Reference – options from another field to re-use;
* Empty string value is not allowed – if not checked, a user can add an empty string as an item;
* Max Item Count – a validation: how many items can be added;
-* Display as List – each value will be displayed in a new line.
+* Display as List – each value will be displayed in a new line;
+* Items Editable – items can be edited; applicable only if no options are specified for the field; as of v9.2;
+* Pattern – a regular expression to check a field value against.

@@ -230,18 +258,29 @@ For storing links.
Parameters:
* Max-length – a max acceptable length of text;
-* Strip – if checked, then `http(s)://` if trailing `/` will be stripped.
+* Strip – if checked, then a protocol part and trailing `/` will be stripped;
+* Copy to clipboard button.
+
+## Url-Multiple
+*As of v7.5.*
+
+For storing multiple links.
+
+Parameters:
+
+* Max Item Count – max number or items;
+* Strip – if checked, then a protocol part and trailing `/` will be stripped.
## Wysiwyg
-Similar to Text field, but with HTML support.
+Similar to the Text field, but with HTML support.
Parameters:
* Height (px) – a height of the field (in the edit view mode); if empty – then height is flexible;
* 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.
+* Use Iframe – if checked, then an HTML content will be placed in an IFRAME element.
## File
@@ -280,9 +319,10 @@ An auto-incrementing number of string type with a possible prefix and specific l
Parameters:
-* Prefex – a text that will be preprended to a number;
+* Prefix – a text that will be preprended to a number;
* Next Number – a number that will be applied to the next created record;
-* Pad Length – a length of the numeric part; if less, then will be padded with zero digits, e.g. `00001`.
+* Pad Length – a length of the numeric part; if less, then will be padded with zero digits, e.g. `00001`;
+* Copy to clipboard button.

@@ -292,8 +332,6 @@ A generated read-only auto-incrementing integer number.
## Barcode
-Since 5.8.0 version.
-
A barcode. Can be printed to PDF.
Parameters:
@@ -308,7 +346,8 @@ A field of a related record. Read-only.
Parameters:
* Link – defines where the field will be taken from.
-* Field – a field of a related record.
+* Field – a field of a related record;
+* Relate on Import – when importing, it will automatically relate a record with a matching foreign record.
## Email
@@ -326,14 +365,26 @@ Parameters:
A record related through *Belongs-To* (*many-to-one* or *one-to-one*) relationship.
+Parameters:
+
+* Create Button – display *Create* button;
+* Autocomplete on empty input – show suggestions even if no characters are entered in the input.
+
## Link-Parent
A record related through *Belongs-To-Parent* relationship. Can be of different entity types.
Parameters:
-* Entity List – a list of entity types available to be related through the field.
+* Entity List – a list of entity types available to be related through the field;
+* Autocomplete on empty input – show suggestions even if no characters are entered in the input.
## Link-Multiple
-A set of records related through *Has-Many* (*many-to-many* or *one-to-many*) relationship. Not all relationships have their link-multiple fields. Only those do, where *Link-Multiple* parameter(s) is enabled.
+A set of records related through *Has-Many* (*many-to-many* or *one-to-many*) relationship. Not all relationships have a link-multiple field. Only those do, where *Link-Multiple* parameter(s) is enabled.
+
+Parameters:
+
+* Max Item Count – the max number of records;
+* Create Button – display *Create* button;
+* Autocomplete on empty input – show suggestions even if no characters are entered in the input.
diff --git a/docs/administration/file-storage.md b/docs/administration/file-storage.md
new file mode 100644
index 000000000..b640a519e
--- /dev/null
+++ b/docs/administration/file-storage.md
@@ -0,0 +1,46 @@
+# File Storage
+
+By default, all uploaded files (attachments) are stored in `data/upload` directory. EspoCRM is shipped with AWS S3 support.
+Developers can also add other providers by implementing `Espo\Core\FileStorage\Storage` interface.
+
+When switching to an external file storage, it's recommended to disable caching for image thumbs by setting in `data/config.php`:
+
+```
+'thumbImageCacheDisabled' => true,
+```
+
+## AWS S3
+
+Parameters need to be set in `data/config-internal.php`:
+
+```
+ 'awsS3Storage' => [
+ 'bucketName' => 'BUCKET_NAME',
+ 'path' => 'OPTIONAL_PATH_WHERE_FILES_WILL_BE_STORED',
+ 'credentials' => [
+ 'key' => 'KEY',
+ 'secret' => 'SECRET',
+ ],
+ 'region' => 'YOUR_REGION',
+ ],
+```
+
+In `data/config.php`:
+
+```
+ 'defaultFileStorage' => 'AwsS3',
+```
+
+Credentials can be omitted, then they will be read from the environment.
+
+It's possible to use non-AWS S3 endpoints with the `endpoint` parameter (as of v8.1). Then, for some providers, you also need to add the parameter `pathStyleEndpoint` set to *true* to use path styled endpoints. The `sendChunkedBody` boolean parameter set to *false* may be needed for some providers that do not support splitting content in chunks.
+
+## Moving existing attachments
+
+After setting up a file storage, all existing attachments will still be stored locally in `data/upload` directory. You can move them manually to the storage and then execute the following SQL query:
+
+```sql
+UPDATE `attachment` SET `storage` = '{StorageName}'
+```
+
+where *{StorageName}* is a name of the storage, e.g. `AwsS3`.
diff --git a/docs/administration/formula-functions.md b/docs/administration/formula-functions.md
new file mode 100644
index 000000000..9b8b294cd
--- /dev/null
+++ b/docs/administration/formula-functions.md
@@ -0,0 +1,222 @@
+---
+search:
+ boost: 2
+---
+
+# Formula Functions
+
+The format of function usage: `groupName\functionName(argument1, argument2, ..., argumentN)`.
+
+Out-of-the-box functions are listed below.
+
+Functions:
+
+* [General](#general)
+* [String](#string)
+* [Datetime](#datetime)
+* [Number](#number)
+* [Entity](#entity)
+* [Record](#record)
+* [Env](#env)
+* [Password](#password)
+* [Array](#array)
+* [Object](#object)
+* [Language](#language)
+* [Json](#json)
+* [Ext](#ext)
+* [Util](#util)
+* [Log](#log)
+
+## General
+
+[general](formula/general.md)
+
+* [list](formula/general.md#list)
+* [ifThenElse](formula/general.md#ifthenelse)
+* [ifThen](formula/general.md#ifthen)
+
+## String
+
+[string](formula/string.md)
+
+* [string\concatenate](formula/string.md#stringconcatenate)
+* [string\substring](formula/string.md#stringsubstring)
+* [string\contains](formula/string.md#stringcontains)
+* [string\pos](formula/string.md#stringpos)
+* [string\test](formula/string.md#stringtest)
+* [string\length](formula/string.md#stringlength)
+* [string\trim](formula/string.md#stringtrim)
+* [string\lowerCase](formula/string.md#stringlowercase)
+* [string\upperCase](formula/string.md#stringuppercase)
+* [string\pad](formula/string.md#stringpad)
+* [string\match](formula/string.md#stringmatch)
+* [string\matchAll](formula/string.md#stringmatchall)
+* [string\matchExtract](formula/string.md#stringmatchextract)
+* [string\replace](formula/string.md#stringreplace)
+* [string\split](formula/string.md#stringsplit)
+
+## Datetime
+
+[datetime](formula/datetime.md)
+
+* [datetime\today](formula/datetime.md#datetimetoday)
+* [datetime\now](formula/datetime.md#datetimenow)
+* [datetime\format](formula/datetime.md#datetimeformat)
+* [datetime\date](formula/datetime.md#datetimedate)
+* [datetime\month](formula/datetime.md#datetimemonth)
+* [datetime\year](formula/datetime.md#datetimeyear)
+* [datetime\hour](formula/datetime.md#datetimehour)
+* [datetime\minute](formula/datetime.md#datetimeminute)
+* [datetime\dayOfWeek](formula/datetime.md#datetimedayofweek)
+* [datetime\diff](formula/datetime.md#datetimediff)
+* [datetime\addSeconds](formula/datetime.md#datetimeaddseconds)
+* [datetime\addMinutes](formula/datetime.md#datetimeaddminutes)
+* [datetime\addHours](formula/datetime.md#datetimeaddhours)
+* [datetime\addDays](formula/datetime.md#datetimeadddays)
+* [datetime\addWeeks](formula/datetime.md#datetimeaddweeks)
+* [datetime\addMonths](formula/datetime.md#datetimeaddmonths)
+* [datetime\addYears](formula/datetime.md#datetimeaddyears)
+* [datetime\closest](formula/datetime.md#datetimeclosest)
+
+## Number
+
+[number](formula/number.md)
+
+* [number\format](formula/number.md#numberformat)
+* [number\abs](formula/number.md#numberabs)
+* [number\power](formula/number.md#numberpower)
+* [number\round](formula/number.md#numberround)
+* [number\floor](formula/number.md#numberfloor)
+* [number\ceil](formula/number.md#numberceil)
+* [number\randomInt](formula/number.md#numberrandomint)
+* [number\parseInt](formula/number.md#numberparseint)
+* [number\parseFloat](formula/number.md#numberparsefloat)
+
+## Entity
+
+[entity](formula/entity.md)
+
+* [entity\isNew](formula/entity.md#entityisnew)
+* [entity\isAttributeChanged](formula/entity.md#entityisattributechanged)
+* [entity\isAttributeNotChanged](formula/entity.md#entityisattributenotchanged)
+* [entity\attribute](formula/entity.md#entityattribute)
+* [entity\setAttribute](formula/entity.md#entitysetattribute)
+* [entity\clearAttribute](formula/entity.md#entityclearattribute)
+* [entity\attributeFetched](formula/entity.md#entityattributefetched)
+* [entity\addLinkMultipleId](formula/entity.md#entityaddlinkmultipleid)
+* [entity\hasLinkMultipleId](formula/entity.md#entityhaslinkmultipleid)
+* [entity\removeLinkMultipleId](formula/entity.md#entityremovelinkmultipleid)
+* [entity\setLinkMultipleColumn](formula/entity.md#entitysetlinkmultiplecolumn)
+* [entity\isRelated](formula/entity.md#entityisrelated)
+* [entity\sumRelated](formula/entity.md#entitysumrelated)
+* [entity\countRelated](formula/entity.md#entitycountrelated)
+* [entity\getLinkColumn](formula/entity.md#entitygetlinkcolumn)
+
+## Record
+
+[record](formula/record.md)
+
+* [record\exists](formula/record.md#recordexists)
+* [record\count](formula/record.md#recordcount)
+* [record\findOne](formula/record.md#recordfindone)
+* [record\findMany](formula/record.md#recordfindmany)
+* [record\findRelatedOne](formula/record.md#recordfindrelatedone)
+* [record\findRelatedMany](formula/record.md#recordfindrelatedmany)
+* [record\attribute](formula/record.md#recordattribute)
+* [record\fetch](formula/record.md#recordfetch)
+* [record\relate](formula/record.md#recordrelate)
+* [record\unrelate](formula/record.md#recordunrelate)
+* [record\create](formula/record.md#recordcreate)
+* [record\update](formula/record.md#recordupdate)
+* [record\delete](formula/record.md#recorddelete)
+* [record\relationColumn](formula/record.md#recordrelationcolumn)
+* [record\updateRelationColumn](formula/record.md#recordupdaterelationcolumn)
+
+## Env
+
+[env](formula/env.md)
+
+* [env\userAttribute](formula/env.md#envuserattribute)
+
+## Password
+
+[password](formula/password.md)
+
+* [password\generate](formula/password.md#passwordgenerate)
+* [password\hash](formula/password.md#passwordhash)
+
+## Array
+
+[array](formula/array.md)
+
+* [array\includes](formula/array.md#arrayincludes)
+* [array\push](formula/array.md#arraypush)
+* [array\length](formula/array.md#arraylength)
+* [array\at](formula/array.md#arrayat)
+* [array\join](formula/array.md#arrayjoin)
+* [array\indexOf](formula/array.md#arrayindexof)
+* [array\removeAt](formula/array.md#arrayremoveat)
+* [array\unique](formula/array.md#arrayunique)
+
+## Object
+
+[object](formula/object.md)
+
+* [object\create](formula/object.md#objectcreate)
+* [object\get](formula/object.md#objectget)
+* [object\set](formula/object.md#objectset)
+* [object\clear](formula/object.md#objectclear)
+* [object\has](formula/object.md#objecthas)
+* [object\cloneDeep](formula/object.md#objectclonedeep)
+
+## Language
+
+[language](formula/language.md)
+
+* [language\translate](formula/language.md#languagetranslate)
+* [language\translateOption](formula/language.md#languagetranslateoption)
+
+## Json
+
+[json](formula/json.md)
+
+* [json\retrieve](formula/json.md#jsonretrieve)
+* [json\encode](formula/json.md#jsonencode)
+
+## Ext
+
+[ext](formula/ext.md)
+
+* [ext\account\findByEmailAddress](formula/ext.md#extaccountfindbyemailaddress)
+* [ext\currency\convert](formula/ext.md#extcurrencyconvert)
+* [ext\email\send](formula/ext.md#extemailsend)
+* [ext\email\applyTemplate](formula/ext.md#extemailapplytemplate)
+* [ext\markdown\transform](formula/ext.md#extmarkdowntransform)
+* [ext\sms\send](formula/ext.md#extsmssend)
+* [ext\pdf\generate](formula/ext.md#extpdfgenerate)
+* [ext\user\sendAccessInfo](formula/ext.md#extusersendaccessinfo)
+* [ext\calendar\userIsBusy](formula/ext.md#extcalendaruserisbusy)
+* [ext\acl\checkEntity](formula/ext.md#extaclcheckentity)
+* [ext\acl\checkScope](formula/ext.md#extaclcheckscope)
+* [ext\acl\getLevel](formula/ext.md#extaclgetlevel)
+* [ext\acl\getPermissionLevel](formula/ext.md#extaclgetpermissionlevel)
+* [ext\oauth\getAccessToken](formula/ext.md#extoauthgetaccesstoken)
+* [ext\appSecret\get](formula/ext.md#extappsecretget)
+
+## Util
+
+[util](formula/util.md)
+
+* [util\generateId](formula/util.md#utilgenerateid)
+* [util\generateRecordId](formula/util.md#utilgeneraterecordid)
+* [util\base64Encode](formula/util.md#utilbase64encode)
+* [util\base64Decode](formula/util.md#utilbase64decode)
+
+## Log
+
+[log](formula/log.md)
+
+* [log\info](formula/log.md#loginfo)
+* [log\notice](formula/log.md#lognotice)
+* [log\warning](formula/log.md#logwarning)
+* [log\error](formula/log.md#logerror)
diff --git a/docs/administration/formula-scripts-examples.md b/docs/administration/formula-scripts-examples.md
index 96d295f8c..26f7fa34e 100644
--- a/docs/administration/formula-scripts-examples.md
+++ b/docs/administration/formula-scripts-examples.md
@@ -14,7 +14,7 @@ $hash = password\hash($password);
$userId = record\create('User',
'userName', $userName,
- 'password', $hash
+ 'password', $hash,
'emailAddress', $emailAddress
);
diff --git a/docs/administration/formula.md b/docs/administration/formula.md
index 74e6aef28..8f0571efe 100644
--- a/docs/administration/formula.md
+++ b/docs/administration/formula.md
@@ -1,968 +1,432 @@
-# Formula (& calculated fields)
+---
+search:
+ boost: 3
+---
-In Entity Manager, it's possible to define script (formula) for a specific entity type. This script will be executed every time before the record is saved.
+# Formula Script
-It provides the ability to automatically set specific fields (attributes) with values derived from calculation. Some functions can also perform some actions.
+Formula Script is a simple scripting language designed specially for EspoCRM. It's a tool that provides the ability to manipulate data and automatically perform operations.
-To edit formula for a specific entity type, follow Administration > Entity Manager > dropdown menu on the right on the row of the entity type > Formula.
+Where it can be used:
-You may also need to set fields, that are supposed to be calculated, read-only via Entity Manager.
+* [Before-save script](entity-manager.md#before-save-custom-script)
+* [API before-save script](api-before-save-script.md)
+* [Workflows](workflows.md) tool (in conditions and actions)
+* [BPM](bpm.md) tool
+* [Formula sandbox](#sandbox)
-The admin can run **Recalculate Formula** action for specific records from the list view: select records (or all search results) > click *Actions* dropdown > click *Recalculate Formula*.
-
-Formula can also be utilized in Workflows and BPM tool.
+Formula scripts are meant to be written directly within the Espo application UI, with no need for environment configuration or building steps. Even users with little or no programming experience can experiment with writing simple scripts, allowing them to fine-tune their system to better suit their needs.
In this article:
* [Syntax](#syntax)
* [Operators](#operators)
-* [Attributes](#operators)
+* [Control structures](#control-structures)
+* [Attributes](#attributes)
* [Functions](#functions)
- * [General](#general)
- * [String](#string)
- * [Datetime](#datetime)
- * [Number](#number)
- * [Entity](#entity)
- * [Record](#record)
- * [Env](#env)
- * [Password](#password)
- * [Array](#array)
- * [Ext](#ext)
* [Values](#values)
* [Variables](#variables)
* [Comments](#comments)
-* [Function arguments](#function-arguments)
+* [Comparison](#comparison)
* [Examples](#examples)
-* [Using formula in Workflows](#using-formula-in-workflows)
+* [Explanation](#explanation)
+* [Function arguments](#function-arguments)
+* [Sandbox](#sandbox)
+* [See also](#see-also)
## Syntax
-EspoCRM formula is written in a simple language designed specifically for this feature.
-
-There are 4 element types that can be used in formula:
-
-* operators
-* functions
-* attributes
-* values
-
-Separated expressions must be delimited by character `;`.
-
-Example:
-
-```
-string\concatenate(name, ' + ', $test);
-```
-where:
-
-* `string\concatenate` – a function
-* `name` – an attribute (of a target entity, to which formula is applied)
-* `' + '` – a value (of string type)
-* `$test` – a variable (supposed to be declared somewhere above)
+There are 6 language elements in Formula script:
+* operators (e.g. `+`, `-`, `*`)
+* control structures (`if`, `while`)
+* functions (e.g. `string\concatenate()`)
+* values (scalars and NULL value, e.g. `'string'`, `100`, `true`, `null`)
+* variables (e.g. `$temp`)
+* attributes (values of the current entity, e.g. `contactId`, `status`)
-## Operators
-
-* `=` - assignment.
-* `||` - logical OR,
-* `&&` - logical AND,
-* `!` - logical NOT,
-* `+`- numeric summation,
-* `-` - numeric subtraction,
-* `*` - numeric multiplication,
-* `/` - numeric division,
-* `%` - numeric modulo,
-* `==` - comparison equals,
-* `!=` - comparison not equals,
-* `>` - comparison greater than,
-* `<` - comparison less than,
-* `>=` - comparison greater than or equals,
-* `<=` - comparison less than or equals.
-
-The priority of operators:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-## Attributes
-
-[Attributes](terms-and-naming.md#attribute) represent field values of the target entity. You can insert available attributes by clicking on the plus button.
+Separate expressions must be delimited by a semicolon character `;`.
-It's possible to access attributes of related entities with the following format `linkName.attributeName`.
+!!! example
+ ```
+ string\concatenate(name, ' + ', $test);
+ ```
+ where:
-## Functions
+ * `string\concatenate` – a function
+ * `name` – an attribute (of a target entity, to which formula is applied)
+ * `' + '` – a value (of string type)
+ * `$test` – a variable (supposed to be declared somewhere above)
-Format of function use: `groupName\functionName(argument1, argument2, ..., argumentN)`.
+Available scalar types:
-Out-of-the-box functions are listed below.
+* string – `'string'`
+* int – `1000`
+* float – `1000.5`
+* boolean – `true` or `false`
-### General
+### Implicit return
-* [ifThenElse](#ifthenelse)
-* [ifThen](#ifthen)
-* [list](#list)
-* [while](#while)
+*As of v9.1.*
-#### ifThenElse
-
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)`
-
-If CONDITION is met, then do CONSEQUENT. If not - then do ALTERNATIVE.
-
-#### ifThen
-
-`ifThen(CONDITION, CONSEQUENT)`
-
-If CONDITION is met, then do CONSEQUENT. If not - do nothing.
-
-CONSEQUENT and ALTERNATIVE can consist of mutliple commands separated by the semicolon `;`.
-
-#### list
-
-`list(VALUE-1, ... VALUE-N)` Returns array.
-
-Useful to create an array for link-multiple IDs. Example: `teamsIds = list($teamId)`.
-
-#### while
-
-`while(CONDITION, STATEMENT)`
-
-Executes STATEMENT repeatedly as long CONDITION is true.
+The last evaluated expression is returned.
Example:
```
-$source = list(0, 1, 2);
-$target = list();
-$i = 0;
-while($i < array\length($source),
- $target = array\push(
- $target,
- array\at($source, $i)
- );
- $i = $i + 1;
-);
+$a = 1;
+$b = $a + 1;
+$b;
```
-### String
-
-* [string\concatenate](#stringconcatenate)
-* [string\substring](#stringsubstring)
-* [string\contains](#stringcontains)
-* [string\pos](#stringpos)
-* [string\test](#stringtest)
-* [string\length](#stringlength)
-* [string\trim](#stringtrim)
-* [string\lowerCase](#stringlowercase)
-* [string\upperCase](#stringuppercase)
-* [string\pad](#stringpad)
-* [string\match](#stringmatch)
-* [string\matchAll](#stringmatchall)
-* [string\replace](#stringreplace)
-
-#### string\concatenate
-
-`string\concatenate(STRING_1, STRING_2)`
-
-Concatenates two or more strings.
-
-#### string\substring
-
-`string\substring(STRING, START, LENGTH)`
-
-Extracts the characters from a STRING by START position and LENGTH.
-
-If LENGTH is omitted, the substring starting from START until the end of the STRING will be returned.
-
-If LENGTH is negative, then that many characters will be omitted from the end of STRING.
-
-#### string\contains
-
-`string\contains(STRING, NEEDLE)`
-
-Whether STRING contains NEEDLE.
-
-#### string\pos
-`string\pos(STRING, NEEDLE)`
-
-Returns possition of NEEDLE in STRING, *false* if not found. (since version 5.7.3)
-
-#### string\test
-`string\test(STRING, REGULAR_EXPRESSION)`
-
-Search a match between REGULAR_EXPRESSION and STRING. Returns TRUE of FALSE.
-
-#### string\length
-`string\length(STRING)`
-
-The length of STRING.
-
-#### string\trim
-`string\trim(STRING)`
-
-Strips whitespace from the beginning and end of STRING.
-
-#### string\lowerCase
-`string\lowerCase(STRING)` Converts letters to lower case.
-
-#### string\upperCase
-`string\upperCase(STRING)`
-
-Converts letters to upper case.
-
-#### string\pad
-`string\pad(STRING, LENGTH, [PAD_STRING], [PAD_TYPE])`
-
-Pads STRING to a certain LENGTH with PAD_STRING.
-
-PAD_STRING by default is a whitespace string `' '`.
-
-PAD_TYPE can be *'right'*, *'left'*, *'both'*. By default it is *'right'*.
-
-#### string\match
-`string\match(STRING, REGULAR_EXPRESSION, [OFFSET])`
-
-Retrieves the first result of matching a STRING against a REGULAR_EXPRESSION. Returns NULL if no matches are found. (available since version 5.8.3.)
-
-Example:
-
-`string\match('{token1} foo {token2} bar', '/{[^}]*}/')`
-
-will return `{token1}`.
-
-The slash character `/` defines the start and the end of a REGULAR_EXPRESSION.
-
-#### string\matchAll
-`string\matchAll(STRING, REGULAR_EXPRESSION, [OFFSET])`
-
-Retrieves all results of matching a STRING against a REGULAR_EXPRESSION. Returns NULL if no matches are found. (available since version 5.8.3)
-
-Example:
-
-`string\matchAll('{token1} foo {token2} bar', '/{[^}]*}/')`
-
-will return an array `['{token1}', '{token2}']`.
-
-#### string\replace
-
-`string\replace(STRING, SEARCH, REPLACE)`
-
-Replaces all occurrences of SEARCH with REPLACE in STRING. (available since version 5.9.0)
-
-Example:
-
-`string\replace('Hello {test}, '{test}, 'world)`
-
-will return `'Hello world'`.
-
-### Datetime
-
-* [datetime\today](#datetimetoday)
-* [datetime\now](#datetimenow)
-* [datetime\format](#datetimeformat)
-* [datetime\date](#datetimedate)
-* [datetime\month](#datetimemonth)
-* [datetime\year](#datetimeyear)
-* [datetime\hour](#datetimehour)
-* [datetime\minute](#datetimeminute)
-* [datetime\dayOfWeek](#datetimedayofweek)
-* [datetime\diff](#datetimediff)
-* [datetime\addMinutes](#datetimeaddminutes)
-* [datetime\addHours](#datetimeaddhours)
-* [datetime\addDays](#datetimeadddays)
-* [datetime\addWeeks](#datetimeaddweeks)
-* [datetime\addMonths](#datetimeaddmonths)
-* [datetime\addYears](#datetimeaddyears)
-* [datetime\closest](#datetimeclosest)
-
-#### datetime\today
-`datetime\today()`
-
-Returns today's date.
-
-#### datetime\now
-`datetime\now()`
-
-Returns current datetime.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])`
-
-Converts date or datetime VALUE into a string formatted according to the application settings or a given timezone and format. TIMEZONE and FORMAT can be omitted. If TIMEZONE is omitted, then default time zone will be used. If FORMAT is omitted, then default format will be used.
-
-Examples:
-
-`datetime\format(closeDate, 'America/New_York', 'MM/DD/YYYY')`
-
-`datetime\format(dateStart, 'America/New_York', 'MM/DD/YYYY hh:mma')`
-
-`datetime\format(dateStart, 'Europe/Amsterdam', 'DD/MM/YYYY HH:mm')`
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])`
-
-Returns date of the month (1-31). `0` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])`
-
-Returns month (1-12). `0` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])`
-
-Returns year. `0` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])`
-
-Returns hour (0-23). `-1` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])`
-
-Returns minute (0-59). `-1` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])`
-
-Returns day of the week (0-6). `-1` if VALUE is empty. `0` - for Sunday. If TIMEZONE is omitted, then system timezone is used.
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)`
-
-Returns the difference between two dates or datetimes. INTERVAL_TYPE can be 'years', 'months', 'days', 'hours', 'minutes'. Returns `null` if failure. The result will be negative if VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)`
-
-Adds MINUTES to datetime VALUE. MINUTES can be negative.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)`
-
-Adds HOURS to datetime VALUE. HOURS can be negative.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)`
-
-Adds DAYS to date or datetime VALUE. DAYS can be negative.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)`
-
-Adds WEEKS to date or datetime VALUE. WEEKS can be negative.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)`
-
-Adds MONTHS to date or datetime VALUE. MONTHS can be negative.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)`
-
-Adds YEARS to date or datetime VALUE. YEARS can be negative.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])`
-
-Returns the closest date or datetime to VALUE based on passed arguments.
-
-TYPE can be one of the following values: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. TARGET is an integer value or a string value. IS_PAST means to find the closest in the past. If TIMEZONE is omitted, then default timezone is used.
-
-Examples:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Will return the closest datetime value in the future with 20:00 time.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Will return `2017-11-01`, the first day of the month.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Will return the next Monday (the beginning of the day).
-
-### Number
-
-* [number\format](#numberformat)
-* [number\abs](#numberabs)
-* [number\round](#numberround)
-* [number\floor](#numberfloor)
-* [number\ceil](#numberceil)
-* [number\randomInt](#numberrandomint)
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])`
-
-Converts numeric VALUE into string formatted according to a specific format or default application settings. If DECIMALS, DECIMAL_MARK OR THOUSAND_SEPARATOR, then system defaults are used.
-
-Examples:
-
-`number\format(2.666667, 2)` - results 2.67;
-
-`number\format(1000, 2)` - results 1,000.00;
-
-`number\format(10.1, 0)` - results 10.
-
-
-#### number\abs
-`number\abs(VALUE)`
-
-Absolute value. Returns null if VALUE is not numeric.
-
-#### number\round
-`number\round(VALUE, PRECISION)`
-
-Returns the rounded value of VALUE to specified PRECISION (number of digits after the decimal point). PRECISION can also be negative or zero (default).
-
-#### number\floor
-`number\floor(VALUE)`
-
-Returns the next lowest integer value by rounding down value if necessary.
-
-#### number\ceil
-`number\ceil(VALUE)`
-
-Returns the next highest integer value by rounding up value if necessary.
-
-#### number\randomInt
-`number\randomInt([MIN, MAX])`
-
-Generates a cryptographic random integer between specified MIN and MAX. If MIN is omitted, then `0` is used. (since v5.9.2)
-
-### Entity
-
-Functions of the *Entity* group operate with a target record. There can be only one target record available in formula-script context. For *Before Update Script*, the target record is the record that is currently updated. For Workflow's *Create Record* action, the target record is the record is being created. For Workflow's conditions, the target record is the target record of the workflow rule.
-
-* [entity\isNew](#entityisnew)
-* [entity\isAttributeChanged](#entityisattributechanged)
-* [entity\isAttributeNotChanged](#entityisattributenotchanged)
-* [entity\attribute](#entityattribute)
-* [entity\setAttribute](#entitysetattribute)
-* [entity\attributeFetched](#entityattributefetched)
-* [entity\addLinkMultipleId](#entityaddlinkmultipleid)
-* [entity\hasLinkMultipleId](#entityhaslinkmultipleid)
-* [entity\removeLinkMultipleId](#entityremovelinkmultipleid)
-* [entity\isRelated](#entityisrelated)
-* [entity\sumRelated](#entitysumrelated)
-* [entity\countRelated](#entitycountrelated)
-* [entity\getLinkColumn](#entitygetlinkcolumn)
-
-#### entity\isNew
-
-`entity\isNew()`
-
-Returns TRUE if the entity is new (being created) and FALSE if not (being updated).
-
-#### entity\isAttributeChanged
-
-`entity\isAttributeChanged(ATTRIBUTE)`
-
-Returns TRUE if ATTRIBUTE of the record was changed.
-
-Example:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-
-`entity\isAttributeNotChanged(ATTRIBUTE)`
-
-Return TRUE if ATTRIBUTE of the record was not changed.
-
-#### entity\attribute
-
-`entity\attribute(ATTRIBUTE)`
-
-An ATTRIBUTE value of a target record. It's also possibe to fetch an attribute of a related record.
-
-`$test = entity\attribute('name')` is equivalent to `$test = name`.
-
-Examples:
-
-`entity\attribute('assignedUserId')`
-
-`entity\attribute('account.name')`
-
-#### entity\setAttribute
-
-`entity\setAttribute(ATTRIBUTE, VALUE)`
-
-Set ATTRIBUTE with a VALUE.
-
-`entity\setAttribute('stage', 'Closed Won')` is equivalent to `stage = 'Closed Won'`.
-
-Example:
-
-`entity\setAttribute('stage', 'Closed Won')`
-
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)`
-
-An ATTRIBUTE value that was set when a target record was fetched from database. Before it was modified.
-
-Example:
-
-`entity\attributeFetched('assignedUserId')`
-
-#### entity\addLinkMultipleId
-
-`entity\addLinkMultipleId(LINK, ID)`
+This script is treated as an expression and the value of the variable $b is returned. Can be useful when Formula is used to evaluate a condition or determine a value.
-Adds ID to Link Multiple field.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)`
-
-Adds the list of ids.
-
-Example:
-
-`entity\addLinkMultipleId('teams', 'someTeamId')`
-
-Add 'someTeamId' to 'teams' field.
-
-
-#### entity\hasLinkMultipleId
-
-`entity\hasLinkMultipleId(LINK, ID)`
-
-Checks whether Link Multiple field has specific ID.
-
-#### entity\removeLinkMultipleId
-
-`entity\removeLinkMultipleId(LINK, ID)`
-
-Removes a specific ID from the Link Multiple field.
-
-#### entity\isRelated
-
-`entity\isRelated(LINK, ID)`
-
-Checks whether a target entity is related with another entity represented by LINK and ID.
-
-#### entity\sumRelated
-
-`entity\sumRelated(LINK, FIELD, [FILTER])`
-
-Sums related records by a specified FIELD with an optional FILTER.
-
-Example:
-
-`entity\sumRelated('opportunities', 'amountConverted', 'won')`
-
-FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../user-guide/reports.md) as a filter. More info [below](#filter).
-
-#### entity\countRelated
-
-`entity\countRelated(LINK, [FILTER])`
-
-Returns a number of related records with an optional FILTER applied.
-
-Example:
-
-`entity\countRelated('opportunities', 'open')`
-
-It's possible to apply a [list report](../user-guide/reports.md) as a filter. More info about filters [below](#filter).
-
-#### entity\getLinkColumn
-
-`entity\getLinkColumn(LINK, ID, COLUMN)`
-
-Fetches a relationship column value (since 5.7.1).
-
-Example:
-
-`entity\getLinkColumn('targetLists', 'TARGET_LIST_ID', 'optedOut')`
-
-
-### Record
-
-* [record\exists](#recordexists)
-* [record\count](#recordcount)
-* [record\findOne](#recordfindone)
-* [record\findRelatedOne](#recordfindrelatedone)
-* [record\findRelatedMany](#recordfindrelatedmany)
-* [record\attribute](#recordattribute)
-* [record\relate](#recordrelate)
-* [record\unrelate](#recordunrelate)
-* [record\create](#recordcreate)
-* [record\update](#recordupdate)
-* [record\relationColumn](#recordrelationcolumn)
-* [record\updateRelationColumn](#recordupdaterelationcolumn)
-
-#### record\exists
-
-`record\exists(ENTITY_TYPE, KEY1, VALUE1, [KEY2, VALUE2 ...])`
-
-Check whether a record with specified criteria exists.
-
-Examples:
-
-`record\exists('Lead', 'emailAddress=', fromAddress)`
-
-`record\exists('Lead', 'status=', list('Assigned', 'In Process'))`
-
-#### record\count
-
-`record\count(ENTITY_TYPE, KEY1, VALUE1, [KEY2, VALUE2 ...])`
-
-Returns a count of records with specified criteria.
-
-`record\count(ENTITY_TYPE, [FILTER])`
-
-Returns a count of records with an optional FILTER applied. More info about filters [below](#filter).
-
-Examples:
-
-`record\count('Opportunity', 'accountId=', id, 'stage=', 'Closed Won')`
-
-`record\count('Opportunity', 'amountConverted>', 1000)`
-
-`record\count('Opportunity', 'open')`
-
-`record\count('Lead', 'status=', list('Assigned', 'In Process'))`
-
-FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../user-guide/reports.md) as a filter. More info [below](#filter).
-
-#### record\findOne
-
-`record\findOne(ENTITY_TYPE, ORDER_BY, ORDER, [KEY1, VALUE1, KEY2, VALUE2 ...])`
-
-Returns a first found ID of a record that matches specific criteria. (since version 5.7.0)
-
-`record\findOne(ENTITY_TYPE, ORDER_BY, ORDER, [FILTER])` Returns a first found ID of a record with an optional FILTER applied. (since version 5.7.0)
-
-Examples:
-
-`record\findOne('Opportunity', 'createdAt', 'desc', 'accountId=', id, 'stage=', 'Closed Won')`
-
-`record\findOne('Opportunity', 'createdAt', 'desc', 'open')`
-
-FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../user-guide/reports.md) as a filter. More info [below](#filter).
-
-#### record\findRelatedOne
-
-`record\findRelatedOne(ENTITY_TYPE, ID, LINK, [ORDER_BY, ORDER, KEY1, VALUE1, KEY2, VALUE2 ...])`
-
-Returns a first found ID of a related record that matches specific criteria. (since version 5.7.0)
-
-`record\findRelatedOne(ENTITY_TYPE, ID, LINK, [ORDER_BY, ORDER, FILTER])`
-
-Returns a first found ID of a related record with an optional FILTER applied. (since version 5.7.0)
+## Operators
-If NULL is passed for ORDER_BY and ORDER then a default order will be applied.
+* `=` – assignment,
+* `??` – null coalescing (as of v7.1),
+* `||` – logical OR,
+* `&&` – logical AND,
+* `!` – logical NOT,
+* `+` – numeric summation,
+* `-` – numeric subtraction,
+* `*` – numeric multiplication,
+* `/` – numeric division,
+* `%` – numeric modulo,
+* `==` – comparison equals,
+* `!=` – comparison not equals,
+* `>` – comparison greater than,
+* `<` – comparison less than,
+* `>=` – comparison greater than or equals,
+* `<=` – comparison less than or equals.
-Examples:
+The priority of operators:
-`record\findRelatedOne('Account', accountId, 'oppotunities', 'createdAt', 'desc', 'stage=', 'Closed Won')`
+* `=`;
+* `??`;
+* `||`;
+* `&&`
+* `==`, `!=`, `>`, `<`, `>=`, `<=`;
+* `+`, `-`;
+* `*`, `/`, `%`.
-`record\findRelatedOne('Account', accountId, 'oppotunities', 'createdAt', 'desc', 'open')`
+## Control structures
-FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../user-guide/reports.md) as a filter. More info [below](#filter).
+### if
-Note: Before version 5.9.0 ORDER_BY and ORDER arguments were mandatory.
+*As of v7.4.*
-#### record\findRelatedMany
+```
+if (CONDITION) {
+ CODE
+}
+
+if (CONDITION) {
+ CODE
+} else {
+ CODE
+}
+
+if (CONDITION) {
+ CODE
+} else if (CONDITION) {
+ CODE
+} else {
+ CODE
+}
+```
-`record\findRelatedMany(ENTITY_TYPE, ID, LINK, LIMIT, [ORDER_BY, ORDER, KEY1, VALUE1, KEY2, VALUE2 ...])`
+### while
-Returns an array of IDs of a related record that matches specific criteria. LIMIT is the max number of record. (since version 5.9.0)
+*As of v7.4.*
-`record\findRelatedMany(ENTITY_TYPE, ID, LINK, LIMIT, [ORDER_BY, ORDER, FILTER])`
+```
+while (CONDITION) {
+ CODE
+}
+
+while (CONDITION1) {
+ if (CONDITION2) {
+ break;
+ }
+
+ if (CONDITION3) {
+ continue;
+ }
+}
+```
-Returns an array of IDs of a related record with an optional FILTER applied. (since version 5.9.0)
+## Attributes
-If NULL is passed for ORDER_BY and ORDER then a default order will be applied.
+[Attributes](terms-and-naming.md#attribute) represent field values of a target entity. You can insert available attributes by clicking the plus button.
-Examples:
+It's possible to access attributes of related entities with the following expression `linkName.attributeName`.
-`record\findRelatedMany('Account', accountId, 'oppotunities', 10, 'createdAt', 'desc', 'stage=', 'Closed Won')`
+The attribute element type was introduced in the language to be able to write like this:
-`record\findRelatedOne('Account', accountId, 'oppotunities', 3, 'createdAt', 'desc', 'open')`
+```
+// Setting an attribute.
+description = 'test';
-FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../user-guide/reports.md) as a filter. More info [below](#filter).
+// Getting an attribute.
+$variable = description;
+```
-This function can be utilized for copying related records from one record to another. Example:
+If we didn't have attributes, we would need to write more verbose:
```
-// copy teams from account to email
-$ids = record\findRelatedMany('Account', $accountId, 'teams', 10);
-record\relate('Email', $emailId, 'teams', $ids);
+entity\setAttribute('description', 'test');
+$variable = entity\getAttribute('description');
```
-#### record\attribute
-
-`record\attribute(ENTITY_TYPE, ID, ATTRIBUTE)`
+## Functions
-Returns an attribute value of a specific record. (since version 5.7.0)
+Format of function usage:
-Examples:
+```
+groupName\functionName(argument1, argument2, ..., argumentN)
+```
-`record\attribute('Opportunity', $opportunityId, 'amountConverted')`
+See the full list of [built-in functions](formula-functions.md).
-`record\attribute('Opportunity', $opportunityId, 'teamsIds')`
+Developers can also create [custom functions](../development/new-function-in-formula.md).
-By utilizing this function along with *record\findOne*, it's possible to fetch attribute values of any record in the system.
+## Values
-#### record\relate
+* Strings. E.g. `'some string'`, `"some string"`.
+* Integer numbers. E.g. `1`, `100`, `40300`.
+* Float numbers. E.g. `5.2`.
+* Booleans: `true`, `false`.
+* Null: `null`.
-`record\relate(ENTITY_TYPE, ID, LINK, FOREIGN_ID)`
+## Variables
-Relates two records. Available since version 5.7.8.
+Variables starts with a dollar sign.
-`record\relate(ENTITY_TYPE, ID, LINK, LIST_OF_IDS)`
+```
+// Assign the value to the variable.
+$someVariableName = 'Test';
-Links a record with multiple records. Available since version 5.9.0.
+// Assign the variable to the attribute (field).
+description = $test;
+```
-Examples:
+### Array appending
-`record\relate('Account', $accountId, 'opportunities', $opportunityId)`
+*As of v9.1.*
-`record\relate('Account', $accountId, 'tasks', list('id1', 'id2'))`
+If a variable is an array, it's possible to append a value to it with the following syntax:
-Note: It won't work in *Before save script* when creating a new record, because the record doesn't exist yet when formula is processed.
+```
+$list[] = 'value';
+```
-#### record\unrelate
+### Incrementing and decrementing
-`record\unrelate(ENTITY_TYPE, ID, LINK, FOREIGN_ID)`
+*As of v9.1.*
-Unlinks two records. Available since version 5.7.8.
+Incrementing an integer variable:
-Example:
+```
+$a++;
+```
-`record\unrelate('Account', $accountId, 'opportunities', $opportunityId)`
+Decrementing an integer variable:
-#### record\create
+```
+$a--;
+```
-`record\create(ENTITY_TYPE, ATTRIBUTE1, VALUE1, [ATTRIBUTE2, VALUE2 ...])`
+### Accessing by key
-Creates a new record of entity type with attributes specified as key-value pairs. Returns id of the created record, or NULL if failure.
+*As of v9.1.*
-Available since version 5.9.0.
+Arrays:
-Examples:
+```
+$list = list();
-`$id = record\create('Meeting', 'emailAddress', 'SOME@ADDRESS.com', 'assignedUserId', 'SOME-USER-ID')`
+$list[0] = '0';
+$list[1] = '1';
+$list[0 + 2] = '2';
-#### record\update
+$v = $list[2];
+```
-`record\update(ENTITY_TYPE, ID, ATTRIBUTE1, VALUE1, [ATTRIBUTE2, VALUE2 ...])`
+Objects:
-Updates an existing record with attributes specified as key-value pairs. Returns TRUE if success, FALSE if failure.
+```
+$o = object\create();
-Available since version 5.9.0.
+$o['a'] = 'a';
-Examples:
+$v = $o['a'];
+```
-`record\update('Meeting', 'SOME-MEETING-ID', 'emailAddress', 'SOME@ADDRESS.com', 'assignedUserId', 'SOME-USER-ID')`
+Reading by a non-existent key results in an error.
-#### record\relationColumn
+Null-coalescing prevents the error:
-`record\relationColumn(ENTITY_TYPE, ID, LINK, FOREIGN_ID, COLUMN)`
+```
+$list = list();
-Returns a relation column. Available since version 5.8.0.
+$v = $list[0] ?? 0;
+```
-Example:
+## Comments
-`record\relationColumn('Account', $accountId, 'contacts', $contactId, 'role')`
+Line comment:
-#### record\updateRelationColumn
+```
+// comment
+```
-`record\updateRelationColumn(ENTITY_TYPE, ID, LINK, FOREIGN_ID, COLUMN, VALUE)`
+Section comment:
-Updates a relation column. Available since version 5.8.0.
+```
+/*
+ comment
+*/
+```
-Example:
+## Comparison
-`record\updateRelationColumn('Account', $accountId, 'contacts', $contactId, 'role', 'CEO')`
+The following comparison operators are available:
-### Env
+* `==` – equals,
+* `!=` – not equals,
+* `>` – greater than,
+* `<` – less than,
+* `>=` – greater than or equals,
+* `<=` – less than or equals.
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)`
+!!! important
-Returns ATTRIBUTE of the current user.
+ A strict comparison is used. If you compare an int `1` to a float `1.0` with `==` operator, they are treated as not equal. You need to compare values of same types or check whether a value falls within a range with `$a - 0.0001 <= $b && $b <= $a + 0.0001`.
-Example:
-`env\userAttribute('id')` - ID of the current user.
+## Examples
-### Password
+!!! example
+
+ ```
+ if (entity\isNew()) {
+ assignedUserId = null;
+ status = 'Assigned';
+ }
+
+ someDateField = ifThen(
+ entity\isNew() && closeDate == null && stage == 'Closed Won',
+ datetime\today()
+ );
+ ```
-Since version 5.7.0.
+!!! example
-#### password\generate
+ ```
+ amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
+ amountCurrency = 'USD';
+ ```
-`password\generate()`
+!!! example
-Generates and returns a password.
+ ```
+ someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
+ ```
-#### password\hash
+!!! example
-`password\hash(PASSWORD)`
+ ```
+ if (entity\isNew() && status == 'Planned' && dateStart == null) {
+ dateStart = datetime\addDays(datetime\now(), 10);
+ } else if (status == 'Held' && dateStart == null) {
+ dateStart = datetime\now();
+ }
+ ```
-Hashes a password. You need to hash the password before setting *password* field of *User* record.
+## Explanation
-Example:
+Functions accept expressions as arguments.
```
-$password = password\generate();
-$hash = password\hash($password);
+someFunction(EXPRESSION1, EXPRESSION2);
```
+Expressions can be:
-### Array
-
-#### array\includes
-`array\includes(LIST, VALUE)`
-
-Returns true if LIST contains VALUE. Can be used for Array and Multi-Enum fields.
+* scalar value
+* variable
+* attribute
+* combination of all those forming an expression
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])`
-
-Adds one or more elements to the end of an array and returns the new array.
-
-Important: An array argument is not passed by reference. You need to re-assign the array to a function result.
-
-Example:
+Scalar STRING as an argument:
```
-$list = array\push($list, 'test');
+someFunction('some string');
```
-#### array\length
-`array\length(LIST)`
-
-Returns the number of elements in LIST.
-
-#### array\at
-`array\at(LIST, INDEX)`
-
-Returns a value by INDEX. (since version 5.8.3)
-
-### Ext
-
-* [ext\account\findByEmailAddressDomain](#extaccountfindbyemailaddressdomain)
-* [ext\email\send](#extemailsend)
-* [ext\email\applyTemplate](#extemailapplytemplate)
-* [ext\pdf\generate](#extpdfgenerate)
-
-#### ext\account\findByEmailAddressDomain
-
-`ext\account\findByEmailAddressDomain(EMAIL_ADDRESS)`
-
-Finds an account by an email address. If no full match found, then tries to find by domain name. Free email provider domains are ignored. Returns ID or null. (Available since 5.8.3).
-
-#### ext\email\send
-
-`ext\email\send(EMAIL_ID)`
-
-Sends an email. EMAIL_ID is an ID of the email record. Returns TRUE if sent, false if not sent. (Available since version 5.9.0)
-
-If *from* address is not set in the email, then system email address will be used. If there's match between *from* address and the address of some group email account, then SMTP setting of the group email account will be used.
-
-Example:
+Scalar INT as an argument:
```
-$id = record\create(
- 'Email',
- 'from', 'from-address@test.com',
- 'to', 'to-address@test.com',
- 'subject', 'Test from formula',
- 'body', 'Hi,\n\nThis is a test.',
- 'isHtml', false,
- 'status', 'Sending',
-);
-ext\email\send($id);
+someFunction(10);
```
-#### ext\email\applyTemplate
-
-`ext\email\send(EMAIL_ID, EMAIL_TEMPLATE_ID, [PARENT_TYPE, PARENT_ID])`
-
-Applies an email template to an existng email record. Parent record can be passed optionally. (Available since version 5.9.0)
-
-Example:
+Scalar FLOAT as an argument:
```
-$emailId = record\create(
- 'Email',
- 'to', 'to-address@test.com',
- 'status', 'Draft',
- 'parentId', entity\attribute('id'),
- 'parentType', 'Case'
-);
-ext\email\applyTemplate($emailId, 'some-email-template-id');
-ext\email\send($emailId);
+someFunction(10.5);
```
-#### ext\pdf\generate
-
-`ext\pdf\generate(ENTITY_TYPE, ENTITY_ID, TEMPLATE_ID, [FILENAME])`
-
-Generates PDF file and returns attachment ID. If failed, then returns NULL. TEMPLATE_ID is an ID of PDF template. (Available since version 5.9.0)
-
-Example:
+Scalar BOOLEAN as an argument:
```
-$attachmentId = ext\pdf\generate(
- 'Lead', entity\attribute('id'), 'pdf-template-id', 'test.pdf'
-);
-$emailId = record\create('Email',
- 'subject', 'Test PDF',
- 'body', 'PDF is attached',
- 'to', entity\attribute('emailAddress'),
- 'attachmentsIds', list($attachmentId)
-);
-ext\email\send($emailId);
+someFunction(true);
```
-## Values
+NULL value as an argument:
-* Strings. E.g. 'some string';
-* Integer numbers. E.g. 1, 100, 40300.
-* Float numbers. E.g. 5.2.
+```
+someFunction(null);
+```
-## Variables
+Expression as an argument:
-It's possible to define custom variables in formula.
```
-$someVariableName = 'Test';
-description = $test;
+someFunction(2 + 2);
```
-## Comments
+Expression as an argument:
-Available since version 5.7.6.
+```
+someFunction(anotherFunction());
+```
-Line comment:
+Variable as an argument:
```
-// comment
+someFunction($someVariable);
```
-Section comment:
+Attribute as an argument:
```
-/*
- comment
-*/
+someFunction(attributeName);
```
## Function arguments
-#### LINK
+Below are explanations of function arguments which are met in the documentation.
-A name of the relationship. Available link names can be found at Administration > Entity Manager > ... > Relationships.
+#### LINK
-Link names must be wrapped in quotes when used as function arguments.
+A name of the relationship. Available link names can be found at Administration > Entity Manager > {Entity Type} > Relationships. More info about links [here](terms-and-naming.md#link).
-More info about links [here](terms-and-naming.md#link).
+Link names must be wrapped in quotes when used as function arguments. Example: `record\relate('Contact', 'someContactId', 'opportunities', 'someContactId')`.
#### ATTRIBUTE
-Attribute name usually is the same as a system field name. Fields are listed in Entity Manager > ... > Fields.
+Attribute name usually is the same as a system field name. Fields are listed at Administration > Entity Manager > {Entity Type} > Fields. More info about attributes [here](terms-and-naming.md#attribute).
Field types having multiple attributes:
@@ -973,62 +437,75 @@ Field types having multiple attributes:
Where *field* is the name of the field.
-Attribute names must be wrapped in quotes when used as function arguments. E.g. `record\attribute('Lead', 'someId', 'assignedUserId')`.
-
-More info about attributes [here](terms-and-naming.md#attribute).
+Attribute names must be wrapped in quotes when used as function arguments. Example: `record\attribute('Lead', 'someId', 'assignedUserId')`.
#### ENTITY_TYPE
-ENTITY_TYPE list is available at Administration > Entity Manager.
-
-Entity type names must be wrapped in quotes when used as function arguments. E.g. `record\attribute('Lead', 'someId', 'assignedUserId')`.
+The list of entity types is available at Administration > Entity Manager. More info about entity types [here](terms-and-naming.md#entity-type).
-More info about entity types [here](terms-and-naming.md#entity-type).
+Entity type names must be wrapped in quotes when used as function arguments. Example: `record\attribute('Lead', 'someId', 'assignedUserId')`.
#### FILTER
-A name of a filter pre-defined in the system. Usually, it is defined in [SelectManager class](../development/select-manager.md). Developers can define own filters in a custom SelectManager class.
+Can be:
-For non-developers, it's possible to apply a [list report](../user-guide/reports.md) as a filter. First, you need to create Report Filter (at Administration page). Then, you can use: `entity\sumRelated('opportunities', 'amountConverted', 'reportFilter5c41a0a396f66725d')`, where '5c41a0a396f66725d' is an ID of Report Filter record, that you can obtain from the URL.
+* primary filter name (as string)
+* where item (as object; as of v9.2)
-## Examples
+##### Primary filter
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'; status = 'Assigned'
-);
-
-someDateField = ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
+A name of a filter pre-defined in the system. Developers can define own [filters](../development/metadata/select-defs.md#primaryfilterclassnamemap).
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
+For non-developers, it's possible to apply a [List Report](../user-guide/reports.md#list-reports) as a filter. First, you need to create a [Report Filter](../user-guide/reports.md#report-filters) (at Administration page). Then, you can use the filter name `reportFilter{filterId}` in functions `record\count`, `record\findOne`, `record\findRelatedOne`, `record\findRelatedMany`, `entity\sumRelated`, `entity\countRelated`.
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
+!!! example
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
+ `entity\sumRelated('opportunities', 'amountConverted', 'reportFilter5c41a0a396f66725d')`
+
+ Where *5c41a0a396f66725d* is an ID of the Report Filter record which you can obtain from the URL.
-```
+##### Where item
+
+*As of v9.2.*
+
+The syntax is the same as for the *where* [parameter](../development/api-search-params.md#where-items) in API requests.
+
+!!! example
+
+ ```
+ $where = object\create();
+ $where['type'] = 'or';
+ $where['value'] = list(
+ (
+ $it = object\create();
+ $it['type'] = 'equals';
+ $it['attribute'] = 'type';
+ $it['value'] = 'Customer';
+ $it;
+ ),
+ (
+ $it = object\create();
+ $it['type'] = 'equals';
+ $it['attribute'] = 'type';
+ $it['value'] = 'Partner';
+ $it;
+ )
+ );
+
+ $output = record\findMany('Account', 10, null, null, $where);
+ ```
+
+## Sandbox
+
+The Formula Sandbox provides the ability to test and debug formula scripts. Available under Administration > Formula Sandbox.
-See also [formula scripts examples](formula-scripts-examples.md).
+Use the function `output\printLine` to print values for debugging purposes.
-## Using formula in Workflows
+You can also utilize the sandbox to run one-time scripts, for example, to modify some data in your system.
-You can utilize formula in workflow conditions and actions. See [workflows documentation](workflows.md) for more information.
+## See also
+* [Formula functions](formula-functions.md)
+* [Formula scripts examples](formula-scripts-examples.md)
+* [Formula quick tour](https://app.supademo.com/demo/cmljmuit94td75351htrpagg2)
+* [Custom functions](../development/new-function-in-formula.md)
diff --git a/docs/administration/formula/array.md b/docs/administration/formula/array.md
new file mode 100644
index 000000000..5d8d0cd83
--- /dev/null
+++ b/docs/administration/formula/array.md
@@ -0,0 +1,117 @@
+# Formula > Functions > Array
+
+* [array\includes](#arrayincludes)
+* [array\push](#arraypush)
+* [array\length](#arraylength)
+* [array\at](#arrayat)
+* [array\join](#arrayjoin)
+* [array\indexOf](#arrayindexof)
+* [array\removeAt](#arrayremoveat)
+* [array\unique](#arrayunique)
+
+## array\includes
+
+`array\includes(LIST, VALUE)`
+
+Returns true if LIST contains VALUE. Can be used for Array and Multi-Enum fields.
+
+## array\push
+
+`array\push(LIST, VALUE1 [, VALUE2 ...])`
+
+Adds one or more elements to the end of an array and returns the new array.
+
+
+!!! warning
+
+ An array argument is not passed by reference. You need to re-assign the array to a function result.
+
+!!! example
+
+ ```
+ $list = array\push($list, 'test');
+ ```
+
+!!! example
+
+ Adding values to a multi-enum field.
+
+ ```
+ someMultiEnumField = array\push(someMultiEnumField, 'New Value 1', 'New Value 2');
+ ```
+
+!!! note
+
+ Alternatively, it's possible to use *[]* syntax: `$list[] = $value;`. As of v9.1.
+
+## array\length
+
+`array\length(LIST)`
+
+Returns the number of elements in LIST.
+
+!!! example
+
+ A number of items in multi-enum field.
+
+ ```
+ $number = array\length(someMultiEnumField);
+ ```
+
+## array\at
+
+`array\at(LIST, INDEX)`
+
+Returns a value by INDEX.
+
+!!! note
+
+ Alternatively, it's possible to use *[]* syntax: `$value = $list[$index];`. As of v9.1.
+
+## array\join
+
+`array\join(LIST, SEPARATOR)`
+
+Joins array elements with a string separator. Returns a string. (as of v6.1.3)
+
+!!! example
+
+ ```
+ $string = array\join($array, $separator);
+ ```
+
+## array\indexOf
+
+`array\indexOf(LIST, ELEMENT)`
+
+Returns a position of the ELEMENT in the LIST. Returns `null` if the ELEMENT not in the LIST. (as of v7.1)
+
+!!! example
+
+ ```
+ $index = array\indexOf($idList, $someId);
+ ```
+
+## array\removeAt
+
+`array\removeAt(LIST, INDEX)`
+
+Removes an element by the INDEX and returns a new array. (as of v7.1)
+
+!!! example
+
+ ```
+ $newArray = array\removeAt($array, $index);
+ ```
+
+## array\unique
+
+`array\unique(LIST)`
+
+Removes duplicates in the LIST and returns a new array. (as of v7.1)
+
+!!! example
+
+ ```
+ $newArray = array\unique($array);
+ ```
diff --git a/docs/administration/formula/datetime.md b/docs/administration/formula/datetime.md
new file mode 100644
index 000000000..12a5d8f18
--- /dev/null
+++ b/docs/administration/formula/datetime.md
@@ -0,0 +1,172 @@
+# Formula > Functions > Datetime
+
+Date and date-time values are represented as strings. E.g. `'2021-01-01'`, `'2021-01-01 10:00'`.
+
+* [datetime\today](#datetimetoday)
+* [datetime\now](#datetimenow)
+* [datetime\format](#datetimeformat)
+* [datetime\date](#datetimedate)
+* [datetime\month](#datetimemonth)
+* [datetime\year](#datetimeyear)
+* [datetime\hour](#datetimehour)
+* [datetime\minute](#datetimeminute)
+* [datetime\dayOfWeek](#datetimedayofweek)
+* [datetime\diff](#datetimediff)
+* [datetime\addSeconds](#datetimeaddseconds)
+* [datetime\addMinutes](#datetimeaddminutes)
+* [datetime\addHours](#datetimeaddhours)
+* [datetime\addDays](#datetimeadddays)
+* [datetime\addWeeks](#datetimeaddweeks)
+* [datetime\addMonths](#datetimeaddmonths)
+* [datetime\addYears](#datetimeaddyears)
+* [datetime\closest](#datetimeclosest)
+
+
+## datetime\today
+
+`datetime\today()`
+
+Returns a today's date (w/o time).
+
+## datetime\now
+
+`datetime\now()`
+
+Returns a current datetime.
+
+## datetime\format
+
+`datetime\format(VALUE, [TIMEZONE], [FORMAT])`
+
+Converts a date or datetime VALUE to a string formatted according to the application settings or a given timezone and ISO format. TIMEZONE and FORMAT can be omitted. If TIMEZONE is omitted, then the default timezone will be used. If FORMAT is omitted, then the default format will be used.
+
+!!! example
+
+ `datetime\format(closeDate, 'America/New_York', 'MM/DD/YYYY')`
+
+ `datetime\format(dateStart, 'America/New_York', 'MM/DD/YYYY hh:mma')`
+
+ `datetime\format(dateStart, 'Europe/Amsterdam', 'DD/MM/YYYY HH:mm')`
+
+## datetime\date
+
+`datetime\date(VALUE, [TIMEZONE])`
+
+Returns date of the month (1-31). `0` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
+
+## datetime\month
+
+`datetime\month(VALUE, [TIMEZONE])`
+
+Returns month (1-12). `0` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
+
+## datetime\year
+
+`datetime\year(VALUE, [TIMEZONE])`
+
+Returns year. `0` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
+
+## datetime\hour
+
+`datetime\hour(VALUE, [TIMEZONE])`
+
+Returns hour (0-23). `-1` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
+
+## datetime\minute
+
+`datetime\minute(VALUE, [TIMEZONE])`
+
+Returns minute (0-59). `-1` if VALUE is empty. If TIMEZONE is omitted, then system timezone is used.
+
+## datetime\dayOfWeek
+
+`datetime\dayOfWeek(VALUE, [TIMEZONE])`
+
+Returns day of the week (0-6). `-1` if VALUE is empty. `0` - for Sunday. If TIMEZONE is omitted, then system timezone is used.
+
+## datetime\diff
+
+`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)`
+
+Returns the difference between two dates or datetimes. INTERVAL_TYPE can be 'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Returns `null` if failure. The result will be negative if VALUE_1 < VALUE_2.
+
+## datetime\addSeconds
+
+*As of v9.2.0.*
+
+`datetime\addMinutes(VALUE, SECONDS)`
+
+Adds SECONDS to a datetime VALUE. SECONDS can be negative. Returns a modified STRING value.
+
+## datetime\addMinutes
+
+`datetime\addMinutes(VALUE, MINUTES)`
+
+Adds MINUTES to a datetime VALUE. MINUTES can be negative. Returns a modified STRING value.
+
+!!! example
+
+ `$modifiedValue = datetime\addMinutes('2021-01-01 00:00', 10)`
+
+## datetime\addHours
+
+`datetime\addHours(VALUE, HOURS)`
+
+Adds HOURS to a datetime VALUE. HOURS can be negative. Returns a modified STRING value.
+
+## datetime\addDays
+
+`datetime\addDays(VALUE, DAYS)`
+
+Adds DAYS to a date or datetime VALUE. DAYS can be negative.
+
+!!! example
+
+ `datetime\addDays(dateStart, 1)`
+
+## datetime\addWeeks
+
+`datetime\addWeeks(VALUE, WEEKS)`
+
+Adds WEEKS to a date or datetime VALUE. WEEKS can be negative. Returns a modified STRING value.
+
+!!! example
+
+ `datetime\addWeeks(dateStart, 4)`
+
+## datetime\addMonths
+
+`datetime\addMonths(VALUE, MONTHS)`
+
+Adds MONTHS to a date or datetime VALUE. MONTHS can be negative. Returns a modified STRING value.
+
+!!! example
+
+ `datetime\addMonths(dateStart, 1)`
+
+## datetime\addYears
+
+`datetime\addYears(VALUE, YEARS)`
+
+!!! example
+
+ `datetime\addYears(dateStart, 1)`
+
+Adds YEARS to a date or datetime VALUE. YEARS can be negative. Returns a modified STRING value.
+
+## datetime\closest
+
+`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])`
+
+Returns the closest date or datetime to VALUE based on passed arguments.
+
+TYPE can be one of the following values: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. TARGET is an integer value or a string value.
+IS_PAST means to find the closest in the past. If TIMEZONE is omitted, then the default timezone is used.
+
+!!! example
+
+ `datetime\closest(datetime\now(), 'time', '20:00')` Will return the closest datetime value in the future with 20:00 time.
+
+ `datetime\closest('2017-11-20', 'date', 1, true)` Will return `2017-11-01`, the first day of the month.
+
+ `datetime\closest(datetime\now(), 'dayOfWeek', 1)` Will return the next Monday (the beginning of the day).
diff --git a/docs/administration/formula/entity.md b/docs/administration/formula/entity.md
new file mode 100644
index 000000000..d957fff34
--- /dev/null
+++ b/docs/administration/formula/entity.md
@@ -0,0 +1,170 @@
+# Formula > Functions > Entity
+
+Functions of the *Entity* group operate with a target record. There can be only one target record available in formula-script context.
+For *Before Update Script*, the target record is the record that is currently updated. For Workflow's *Create Record* action,
+the target record is the record is being created. For Workflow's conditions, the target record is the target record of the workflow rule.
+
+* [entity\isNew](#entityisnew)
+* [entity\isAttributeChanged](#entityisattributechanged)
+* [entity\isAttributeNotChanged](#entityisattributenotchanged)
+* [entity\attribute](#entityattribute)
+* [entity\setAttribute](#entitysetattribute)
+* [entity\clearAttribute](#entityclearattribute)
+* [entity\attributeFetched](#entityattributefetched)
+* [entity\addLinkMultipleId](#entityaddlinkmultipleid)
+* [entity\hasLinkMultipleId](#entityhaslinkmultipleid)
+* [entity\removeLinkMultipleId](#entityremovelinkmultipleid)
+* [entity\setLinkMultipleColumn](#entitysetlinkmultiplecolumn)
+* [entity\isRelated](#entityisrelated)
+* [entity\sumRelated](#entitysumrelated)
+* [entity\countRelated](#entitycountrelated)
+* [entity\getLinkColumn](#entitygetlinkcolumn)
+
+
+## entity\isNew
+
+`entity\isNew()`
+
+Returns TRUE if the entity is new (being created) and FALSE if not (being updated).
+
+## entity\isAttributeChanged
+
+`entity\isAttributeChanged(ATTRIBUTE)`
+
+Returns TRUE if ATTRIBUTE of the record was changed.
+
+!!! example
+
+ `entity\isAttributeChanged('status')`
+
+## entity\isAttributeNotChanged
+
+`entity\isAttributeNotChanged(ATTRIBUTE)`
+
+Return TRUE if ATTRIBUTE of the record was not changed.
+
+## entity\attribute
+
+`entity\attribute(ATTRIBUTE)`
+
+An ATTRIBUTE value of a target record. It's also possible to fetch an attribute of a related record.
+
+`$test = entity\attribute('name')` is equivalent to `$test = name`.
+
+!!! example
+
+ `entity\attribute('assignedUserId')`
+
+ `entity\attribute('account.name')`
+
+## entity\setAttribute
+
+`entity\setAttribute(ATTRIBUTE, VALUE)`
+
+Set an ATTRIBUTE with a VALUE.
+
+`entity\setAttribute('stage', 'Closed Won')` is equivalent to `stage = 'Closed Won'`.
+
+!!! example
+
+ `entity\setAttribute('stage', 'Closed Won')`
+
+## entity\clearAttribute
+
+`entity\clearAttribute(ATTRIBUTE)`
+
+*As of v8.2.*
+
+Clear an ATTRIBUTE.
+
+!!! example
+
+ `entity\clearAttribute('stage')`
+
+## entity\attributeFetched
+
+`entity\attributeFetched(ATTRIBUTE)`
+
+An ATTRIBUTE value that was set when a target record was fetched from database. Before it was modified.
+
+!!! example
+
+ `entity\attributeFetched('assignedUserId')`
+
+Note: Should not be used in workflow and BPM actions, use `workflow\targetEntity\attributeFetched` instead.
+
+## entity\addLinkMultipleId
+
+`entity\addLinkMultipleId(LINK, ID)`
+
+Adds ID to Link Multiple field.
+
+`entity\addLinkMultipleId(LINK, ID_LIST)`
+
+Adds the list of ids.
+
+!!! example
+
+ `entity\addLinkMultipleId('teams', 'someTeamId')`
+
+Add 'someTeamId' to 'teams' field.
+
+## entity\hasLinkMultipleId
+
+`entity\hasLinkMultipleId(LINK, ID)`
+
+Checks whether Link Multiple field has specific ID.
+
+## entity\removeLinkMultipleId
+
+`entity\removeLinkMultipleId(LINK, ID)`
+
+Removes a specific ID from the Link Multiple field.
+
+## entity\setLinkMultipleColumn
+
+`entity\setLinkMultipleColumn(LINK, ID, COLUMN, VALUE)`
+
+*As of v7.4.*
+
+Sets a column value in a link-multiple field.
+
+## entity\isRelated
+
+`entity\isRelated(LINK, ID)`
+
+Checks whether a target entity is related with another entity represented by LINK and ID.
+
+## entity\sumRelated
+
+`entity\sumRelated(LINK, FIELD, [FILTER])`
+
+Sums related records by a specified FIELD with an optional FILTER. Returns a *float* value.
+
+!!! example
+
+ `entity\sumRelated('opportunities', 'amountConverted', 'won')`
+
+FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../../user-guide/reports.md) as a filter. More [info](../formula.md#filter).
+
+## entity\countRelated
+
+`entity\countRelated(LINK, [FILTER])`
+
+Returns a number of related records with an optional FILTER applied.
+
+!!! example
+
+ `entity\countRelated('opportunities', 'open')`
+
+It's possible to apply a [list report](../../user-guide/reports.md) as a filter. More [info](../formula.md#filter).
+
+## entity\getLinkColumn
+
+`entity\getLinkColumn(LINK, ID, COLUMN)`
+
+Fetches a relationship column value.
+
+!!! example
+
+ `entity\getLinkColumn('targetLists', 'TARGET_LIST_ID', 'optedOut')`
diff --git a/docs/administration/formula/env.md b/docs/administration/formula/env.md
new file mode 100644
index 000000000..6d8a21c7e
--- /dev/null
+++ b/docs/administration/formula/env.md
@@ -0,0 +1,12 @@
+# Formula > Functions > Env
+
+## env\userAttribute
+`env\userAttribute(ATTRIBUTE)`
+
+Returns ATTRIBUTE of the current user.
+
+!!! example
+
+ ```
+ env\userAttribute('id') // an ID of the current user
+ ```
diff --git a/docs/administration/formula/ext.md b/docs/administration/formula/ext.md
new file mode 100644
index 000000000..f4064a8c4
--- /dev/null
+++ b/docs/administration/formula/ext.md
@@ -0,0 +1,237 @@
+# Formula > Functions > Ext
+
+* [ext\account\findByEmailAddress](#extaccountfindbyemailaddress)
+* [ext\currency\convert](#extcurrencyconvert)
+* [ext\email\send](#extemailsend)
+* [ext\email\applyTemplate](#extemailapplytemplate)
+* [ext\markdown\transform](#extmarkdowntransform)
+* [ext\sms\send](#extsmssend)
+* [ext\pdf\generate](#extpdfgenerate)
+* [ext\user\sendAccessInfo](#extusersendaccessinfo)
+* [ext\calendar\userIsBusy](#extcalendaruserisbusy)
+* [ext\acl\checkEntity](#extaclcheckentity)
+* [ext\acl\checkScope](#extaclcheckscope)
+* [ext\acl\getLevel](#extaclgetlevel)
+* [ext\acl\getPermissionLevel](#extaclgetpermissionlevel)
+* [ext\oauth\getAccessToken](#extoauthgetaccesstoken)
+* [ext\appSecret\get](#extappsecretget)
+
+## ext\account\findByEmailAddress
+
+`ext\account\findByEmailAddress(EMAIL_ADDRESS)`
+
+Finds an account by an email address. If no full match found, then tries to find by domain name.
+Free email provider domains are ignored. Returns ID or null.
+
+## ext\currency\convert
+
+`ext\currency\convert(AMOUNT, FROM_CODE, [TO_CODE])`
+
+*As of v7.4.*
+
+Converts a currency amount from one currency code (FROM_CODE) to another currency code (TO_CODE). If TO_CODE is omitted, then
+the system default currency is used. Returns an amount represented as string.
+
+!!! example
+
+ ```
+ $convertedValueString = ext\currency\convert(amount, amountCurrency);
+ $convertedValue = number\parseFloat($convertedValue);
+ ```
+
+## ext\email\send
+
+`ext\email\send(EMAIL_ID)`
+
+Sends an email. EMAIL_ID is an ID of an email record. Returns TRUE if sent, false if not sent.
+
+If *from* address is not set in the email, then the system email address will be used. If there's match between *from* address and
+the address of some group email account, then SMTP setting of the group email account will be used.
+
+!!! example
+
+ ```
+ $id = record\create(
+ 'Email',
+ 'from', 'from-address@test.com',
+ 'to', 'to-address@test.com',
+ 'subject', 'Test from formula',
+ 'body', 'Hi,\n\nThis is a test.',
+ 'isHtml', false,
+ 'status', 'Sending'
+ );
+ ext\email\send($id);
+ ```
+
+Multiple email addresses can be specified by using a `;` character as a delimiter.
+
+## ext\email\applyTemplate
+
+`ext\email\applyTemplate(EMAIL_ID, EMAIL_TEMPLATE_ID, [PARENT_TYPE, PARENT_ID])`
+
+Applies an email template to an existing email record. Parent record can be passed optionally.
+
+!!! example
+
+ ```
+ $emailId = record\create(
+ 'Email',
+ 'to', 'to-address@test.com',
+ 'status', 'Draft',
+ 'parentId', entity\attribute('id'),
+ 'parentType', 'Case'
+ );
+ ext\email\applyTemplate($emailId, 'some-email-template-id');
+ ext\email\send($emailId);
+ ```
+
+## ext\markdown\transform
+
+*As of v9.0.*
+
+`ext\markdown\transform(STRING)`
+
+Transforms a markdown text to an HTML. Returns STRING.
+
+## ext\sms\send
+
+*As of v7.0.*
+
+`ext\sms\send(SMS_ID)`
+
+Sends an SMD. SMS_ID is an ID of an SMS record. Returns TRUE if sent, false if not sent.
+
+!!! example
+
+ ```
+ $smsId = record\create(
+ 'Sms',
+ 'to', '+1 000 111 222',
+ 'body', 'This is a test.'
+ );
+
+ ext\sms\send($smsId);
+ ```
+
+If *from* address is not set in the SMS, then the system SMS from number will be used.
+
+The extension with SMS providers can be downloaded [here](https://github.com/espocrm/ext-sms-providers/releases).
+
+## ext\pdf\generate
+
+`ext\pdf\generate(ENTITY_TYPE, ENTITY_ID, TEMPLATE_ID, [FILENAME])`
+
+Generates PDF file and returns attachment ID. If failed, then returns NULL. TEMPLATE_ID is an ID of PDF template.
+
+!!! example
+
+ ```
+ $attachmentId = ext\pdf\generate(
+ 'Lead',
+ entity\attribute('id'),
+ 'pdf-template-id',
+ 'test.pdf'
+ );
+
+ $emailId = record\create('Email',
+ 'subject', 'Test PDF',
+ 'body', 'PDF is attached',
+ 'to', entity\attribute('emailAddress'),
+ 'attachmentsIds', list($attachmentId)
+ );
+
+ ext\email\send($emailId);
+ ```
+
+Note, that this won't work for new records in before-create script because a record is not yet created. It will work in Workflows.
+
+## ext\user\sendAccessInfo
+
+`ext\user\sendAccessInfo(USER_ID)`
+
+Send an email with access info to a specific user (via email). A user password will be reset. The user will be promted to specify their
+new password. This function is useful when creating a new user via formula. (as of v7.1)
+
+!!! example
+
+ ```
+ $userId = record\create(
+ 'User',
+ 'userName', $userName,
+ 'firstName', $firstName,
+ 'lastName', $lastName,
+ 'emailAddress', $emailAddress,
+ 'type', 'portal',
+ 'portalsIds', list($portalId)
+ );
+
+ ext\user\sendAccessInfo($userId);
+ ```
+
+## ext\calendar\userIsBusy
+
+*As of v7.5.*
+
+`ext\calendar\userIsBusy(USER_ID, FROM, TO, [ENTITY_TYPE, ID])`
+
+Returns TRUE if a user is has calendar activities within a given range. FROM and TO should be date-time strings.
+
+If ENTITY_TYPE and ID specified, then this record will be ignored when checking. Useful when editing an existing record.
+
+!!! example
+
+ ```
+ if (entity\isNew() && ext\calendar\userIsBusy(assignedUserId, dateStart, dateEnd)) {
+ // throw exception
+ }
+ ```
+
+## ext\acl\checkEntity
+
+*As of v8.3.*
+
+`ext\acl\checkEntity(USER_ID, ENTITY_TYPE, ID, [ACTION])`
+
+Returns TRUE if a user has access to an entity. Optional ACTION should be one of the values: Create, Read, Edit, Delete, Stream.
+
+
+## ext\acl\checkScope
+
+*As of v8.3.*
+
+`ext\acl\checkScope(USER_ID, SCOPE, [ACTION])`
+
+Returns TRUE if a user has access to a SCOPE. Optional ACTION should be one of the values: Create, Read, Edit, Delete, Stream.
+
+
+## ext\acl\getLevel
+
+*As of v8.3.*
+
+`ext\acl\getLevel(USER_ID, SCOPE, ACTION)`
+
+Returns an access level. ACTION should be one of the values: Create, Read, Edit, Delete, Stream.
+
+## ext\acl\getPermissionLevel
+
+*As of v8.3.*
+
+`ext\acl\getPermissionLevel(USER_ID, PERMISSION)`
+
+Returns a permission level.
+
+## ext\oauth\getAccessToken
+
+*As of v9.1.0.*
+
+`ext\oauth\getAccessToken(ACCOUNT_ID)`
+
+Get an OAuth access token for a specific OAuth Account. The ID of OAuth Account record can be obtained for its URL.
+
+## ext\appSecret\get
+
+*As of v9.2.3.*
+
+`ext\appSecret\get($secretName)`
+
+Get an App Secret.
diff --git a/docs/administration/formula/general.md b/docs/administration/formula/general.md
new file mode 100644
index 000000000..899f86eb3
--- /dev/null
+++ b/docs/administration/formula/general.md
@@ -0,0 +1,56 @@
+# Formula > Functions > General
+
+* [list](#list)
+* [ifThenElse](#ifthenelse)
+* [ifThen](#ifthen)
+
+## list
+
+`list(VALUE-1 [, ... VALUE-N])`
+
+Returns array. Values are passed as arguments of the function.
+
+!!! example
+
+ ```
+ $list = list(0, 1, 2); // will return array [0, 1, 2]
+ ```
+
+Useful to create an array for link-multiple IDs.
+
+!!! example
+
+ ```
+ teamsIds = list($teamId) // `['team-id']`
+ ```
+
+## ifThenElse
+
+`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)`
+
+If CONDITION is met, then return CONSEQUENT. If not, then return ALTERNATIVE.
+
+!!! example
+
+ ```
+ $value = ifThenElse(
+ $someVariable == 'someValue', // if condition is true
+ 'one value', // return this value
+ 'another value' // otherwise, this
+ )
+ ```
+
+## ifThen
+
+`ifThen(CONDITION, CONSEQUENT)`
+
+If CONDITION is met, then return CONSEQUENT. Otherwise, return NULL.
+
+!!! example
+
+ ```
+ ifThen(
+ $someVariable == 'someValue', // if condition is true
+ $anotherVariable = 1, // do this
+ )
+ ```
diff --git a/docs/administration/formula/json.md b/docs/administration/formula/json.md
new file mode 100644
index 000000000..43ae59818
--- /dev/null
+++ b/docs/administration/formula/json.md
@@ -0,0 +1,34 @@
+# Formula > Functions > JSON
+
+* [json\retrieve](#jsonretrieve)
+* [json\encode](#jsonencode)
+
+## json\retrieve
+
+`json\retrieve(JSON, [PATH])`
+
+Retrieves a specific attribute from a JSON string. PATH is a string, items are separated by dots. (as of v6.0)
+
+If PATH is omitted, it will return the whole JSON parsed (as of v8.0.4).
+
+!!! example
+
+ Retrieving *id* from `{"id": "SOME_ID"}`:
+
+ ```
+ $value = json\retrieve($someJsonString, 'id');
+ ```
+
+!!! example
+
+ Retrieving *id* from `[{"id": "SOME_ID"}]`:
+
+ ```
+ $value = json\retrieve($someJsonString, '0.id');
+ ```
+
+## json\encode
+
+`json\encode(VALUE)`
+
+Encodes a VALUE to a json string. (as of v7.1)
diff --git a/docs/administration/formula/language.md b/docs/administration/formula/language.md
new file mode 100644
index 000000000..dac7b36cc
--- /dev/null
+++ b/docs/administration/formula/language.md
@@ -0,0 +1,29 @@
+# Formula > Functions > Language
+
+* [language\translate](#languagetranslate)
+* [language\translateOption](#languagetranslateoption)
+
+## language\translate
+
+`language\translate(LABEL, [CATEGORY, SCOPE])`
+
+Translates a label to the language set as default. (as of v6.0)
+
+!!! example
+
+ ```
+ language\translate('passwordWillBeSent', 'messages', 'User')
+ ```
+
+## language\translateOption
+
+`language\translateOption(OPTION, FIELD, [SCOPE])`
+
+Translates an option of a specific field to the language set as default. The field can be of the following types: Enum, Multi-enum, Checklist,
+Array, Varchar. (as of v6.0)
+
+!!! example
+
+ ```
+ language\translateOption('Customer', 'type', 'Account')
+ ```
diff --git a/docs/administration/formula/log.md b/docs/administration/formula/log.md
new file mode 100644
index 000000000..f1dbc0fa7
--- /dev/null
+++ b/docs/administration/formula/log.md
@@ -0,0 +1,32 @@
+# Formula > Functions > Log
+
+*As of v8.3.*
+
+* [log\info](#loginfo)
+* [log\notice](#lognotice)
+* [log\warning](#logwarning)
+* [log\error](#logerror)
+
+## log\info
+
+`log\info(MESSAGE, [CONTEXT])`
+
+Log a string MESSAGE with the INFO level. An optional CONTEXT should be an object.
+
+## log\notice
+
+`log\notice(MESSAGE, [CONTEXT])`
+
+Log a string MESSAGE with the NOTICE level. An optional CONTEXT should be an object.
+
+## log\warning
+
+`log\warning(MESSAGE, [CONTEXT])`
+
+Log a string MESSAGE with the WARNING level. An optional CONTEXT should be an object.
+
+## log\error
+
+`log\error(MESSAGE, [CONTEXT])`
+
+Log a string MESSAGE with the ERROR level. An optional CONTEXT should be an object.
diff --git a/docs/administration/formula/number.md b/docs/administration/formula/number.md
new file mode 100644
index 000000000..6a02a5689
--- /dev/null
+++ b/docs/administration/formula/number.md
@@ -0,0 +1,74 @@
+# Formula > Functions > Number
+
+* [number\format](#numberformat)
+* [number\abs](#numberabs)
+* [number\power](#numberpower)
+* [number\round](#numberround)
+* [number\floor](#numberfloor)
+* [number\ceil](#numberceil)
+* [number\randomInt](#numberrandomint)
+* [number\parseInt](#numberparseint)
+* [number\parseFloat](#numberparsefloat)
+
+## number\format
+
+`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])`
+
+Converts a numeric VALUE into a string formatted according to a specific format or default application settings. If DECIMALS, DECIMAL_MARK or THOUSAND_SEPARATOR are omitted, then system defaults are used.
+
+!!! example
+
+ `number\format(2.666667, 2)` – results 2.67;
+
+ `number\format(1000, 2)` – results 1,000.00;
+
+ `number\format(10.1, 0)` – results 10.
+
+
+## number\abs
+
+`number\abs(VALUE)`
+
+Absolute value. Returns null if VALUE is not numeric.
+
+## number\power
+
+`number\power(VALUE, EXP)`
+
+Raising VALUE to EXP. VALUE and EXP should be int or float. Returns int or float. (as of v8.2)
+
+## number\round
+
+`number\round(VALUE, PRECISION)`
+
+Returns the rounded value of VALUE to specified PRECISION (number of digits after the decimal point). PRECISION can also be negative or zero (default).
+
+## number\floor
+
+`number\floor(VALUE)`
+
+Returns the next lowest integer value by rounding down the value if necessary.
+
+## number\ceil
+
+`number\ceil(VALUE)`
+
+Returns the next highest integer value by rounding up the value if necessary.
+
+## number\randomInt
+
+`number\randomInt([MIN, MAX])`
+
+Generates a cryptographic random integer between specified MIN and MAX. If MIN is omitted, then `0` is used.
+
+## number\parseInt
+
+`number\parseInt(STRING)`
+
+Converts a string to an integer number. (as of v7.1)
+
+## number\parseFloat
+
+`number\parseFloat(STRING)`
+
+Converts a string to a float number. (as of v7.1)
diff --git a/docs/administration/formula/object.md b/docs/administration/formula/object.md
new file mode 100644
index 000000000..a8e72550b
--- /dev/null
+++ b/docs/administration/formula/object.md
@@ -0,0 +1,66 @@
+# Formula > Functions > Object
+
+* [object\create](#objectcreate)
+* [object\get](#objectget)
+* [object\set](#objectset)
+* [object\clear](#objectclear)
+* [object\has](#objecthas)
+* [object\cloneDeep](#objectclonedeep)
+
+## object\create
+
+`object\create()`
+
+Creates and returns an empty object (key-value map).
+
+## object\get
+
+`object\get(OBJECT, KEY)`
+
+Retrieves a value by a KEY from an OBJECT. Returns NULL if KEY is not set.
+
+!!! note
+
+ Alternatively, it's possible to use *[]* syntax: `$value = $object['key'];`. As of v9.1.
+
+## object\set
+
+`object\set(OBJECT, KEY, VALUE)`
+
+Sets a value by a KEY.
+
+!!! note
+
+ Alternatively, it's possible to use *[]* syntax: `$object['key'] = $value;`. As of v9.1.
+
+!!! example
+
+ ```
+ $object = object\create();
+ object\set($object, 'key', 'some-value');
+ ```
+
+## object\clear
+
+`object\clear(OBJECT, KEY)`
+
+Unsets a value by a KEY.
+
+!!! example
+
+ ```
+ object\clear($object, 'some-key');
+ ```
+
+## object\has
+
+`object\has(OBJECT, KEY)`
+
+Checks whether an OBJECT has a value set by a KEY. Returns a boolean.
+
+
+## object\cloneDeep
+
+`object\cloneDeep(OBJECT)`
+
+Deep clones an OBJECT. (as of v7.1)
diff --git a/docs/administration/formula/password.md b/docs/administration/formula/password.md
new file mode 100644
index 000000000..1ce5a7354
--- /dev/null
+++ b/docs/administration/formula/password.md
@@ -0,0 +1,20 @@
+# Formula > Functions > Password
+
+## password\generate
+
+`password\generate()`
+
+Generates and returns a password.
+
+## password\hash
+
+`password\hash(PASSWORD)`
+
+Hashes a password. You need to hash the password before setting the *password* field for a *User*.
+
+!!! example
+
+ ```
+ $password = password\generate();
+ $hash = password\hash($password);
+ ```
diff --git a/docs/administration/formula/record.md b/docs/administration/formula/record.md
new file mode 100644
index 000000000..009506afb
--- /dev/null
+++ b/docs/administration/formula/record.md
@@ -0,0 +1,284 @@
+# Formula > Functions > Record
+
+* [record\exists](#recordexists)
+* [record\count](#recordcount)
+* [record\findOne](#recordfindone)
+* [record\findMany](#recordfindmany)
+* [record\findRelatedOne](#recordfindrelatedone)
+* [record\findRelatedMany](#recordfindrelatedmany)
+* [record\attribute](#recordattribute)
+* [record\fetch](#recordfetch)
+* [record\relate](#recordrelate)
+* [record\unrelate](#recordunrelate)
+* [record\create](#recordcreate)
+* [record\update](#recordupdate)
+* [record\delete](#recorddelete)
+* [record\relationColumn](#recordrelationcolumn)
+* [record\updateRelationColumn](#recordupdaterelationcolumn)
+
+## record\exists
+
+`record\exists(ENTITY_TYPE, KEY1, VALUE1, [KEY2, VALUE2 ...])`
+
+Check whether a record with specified criteria exists.
+
+`record\exists(ENTITY_TYPE, [FILTER])`
+
+With filter applied. As of v9.2. More [info](../formula.md#filter) about filters.
+
+!!! examples
+
+ `record\exists('Lead', 'emailAddress=', fromAddress)`
+
+ `record\exists('Lead', 'status=', list('Assigned', 'In Process'))`
+
+ `record\exists('Lead', 'body*', '%word%')`
+
+Available operators: `=`, `!=`, `>`, `<`, `>=`, `<=`, `*` (LIKE operator), `!*`. Other querying record functions also support these operators.
+
+## record\count
+
+`record\count(ENTITY_TYPE, KEY1, VALUE1, [KEY2, VALUE2 ...])`
+
+Returns a count of records with specified criteria.
+
+`record\count(ENTITY_TYPE, [FILTER])`
+
+Returns a count of records with an optional FILTER applied. More [info](../formula.md#filter) about filters.
+
+!!! examples
+
+ `record\count('Opportunity', 'accountId=', id, 'stage=', 'Closed Won')`
+
+ `record\count('Opportunity', 'amountConverted>', 1000)`
+
+ `record\count('Opportunity', 'open')`
+
+ `record\count('Lead', 'status=', list('Assigned', 'In Process'))`
+
+FILTER is a name of a primary filter pre-defined in the system. It's also possible to apply a [list report](../../user-guide/reports.md) as a filter.
+More [info](../formula.md#filter).
+
+## record\findOne
+
+`record\findOne(ENTITY_TYPE, ORDER_BY, ORDER, [KEY1, VALUE1, KEY2, VALUE2 ...])`
+
+Returns a first found ID of a record that matches specific criteria.
+
+`record\findOne(ENTITY_TYPE, ORDER_BY, ORDER, [FILTER])` Returns a first found ID of a record with an optional FILTER applied.
+
+!!! examples
+
+ `record\findOne('Opportunity', 'createdAt', 'desc', 'accountId=', id, 'stage=', 'Closed Won')`
+
+ `record\findOne('Opportunity', 'createdAt', 'desc', 'open')`
+
+ `record\findOne('AppSecret', null, null, 'name', 'SECRET_NAME')`
+
+## record\findMany
+
+*As of v8.0*.
+
+`record\findMany(ENTITY_TYPE, LIMIT, ORDER_BY, ORDER, [KEY1, VALUE1, KEY2, VALUE2 ...])`
+
+Returns an array of IDs of records that match specific criteria.
+
+`record\findMany(ENTITY_TYPE, LIMIT, ORDER_BY, ORDER, [FILTER])` With an optional FILTER applied.
+
+!!! examples
+
+ `record\findMany('Opportunity', 10, 'createdAt', 'desc', 'accountId=', id, 'stage=', 'Closed Won')`
+
+ `record\findMany('Opportunity', 5, 'createdAt', 'desc', 'open')`
+
+ORDER_BY and ORDER can be null.
+
+FILTER is a name of a primary filter pre-defined in the system. It's also possible to apply a [list report](../../user-guide/reports.md) as a filter.
+More [info](../formula.md#filter).
+
+## record\findRelatedOne
+
+`record\findRelatedOne(ENTITY_TYPE, ID, LINK, [ORDER_BY, ORDER, KEY1, VALUE1, KEY2, VALUE2 ...])`
+
+Returns a first found ID of a related record that matches specific criteria.
+
+`record\findRelatedOne(ENTITY_TYPE, ID, LINK, [ORDER_BY, ORDER, FILTER])`
+
+Returns a first found ID of a related record with an optional FILTER applied.
+
+If NULL is passed for ORDER_BY and ORDER then a default order will be applied.
+
+!!! examples
+
+ `record\findRelatedOne('Account', accountId, 'opportunities', 'createdAt', 'desc', 'stage=', 'Closed Won')`
+
+ `record\findRelatedOne('Account', accountId, 'opportunities', 'createdAt', 'desc', 'open')`
+
+FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../../user-guide/reports.md) as a filter.
+More [info](../formula.md#filter).
+
+## record\findRelatedMany
+
+`record\findRelatedMany(ENTITY_TYPE, ID, LINK, LIMIT, [ORDER_BY, ORDER, KEY1, VALUE1, KEY2, VALUE2 ...])`
+
+Returns an array of IDs of a related record that matches specific criteria. LIMIT is the max number of record.
+
+`record\findRelatedMany(ENTITY_TYPE, ID, LINK, LIMIT, [ORDER_BY, ORDER, FILTER])`
+
+Returns an array of IDs of a related record with an optional FILTER applied.
+
+If NULL is passed for ORDER_BY and ORDER then a default order will be applied.
+
+!!! examples
+
+ `record\findRelatedMany('Account', accountId, 'opportunities', 10, 'createdAt', 'desc', 'stage=', 'Closed Won')`
+
+ `record\findRelatedMany('Account', accountId, 'opportunities', 3, 'createdAt', 'desc', 'open')`
+
+FILTER is a name of a filter pre-defined in the system. It's also possible to apply a [list report](../../user-guide/reports.md) as a filter. More [info](../formula.md#filter).
+
+This function can be utilized for copying related records from one record to another. Example:
+
+```
+// copy teams from account to email
+$ids = record\findRelatedMany('Account', $accountId, 'teams', 10);
+record\relate('Email', $emailId, 'teams', $ids);
+```
+
+## record\attribute
+
+`record\attribute(ENTITY_TYPE, ID, ATTRIBUTE)`
+
+Returns an attribute value of a specific record.
+
+!!! examples
+
+ `record\attribute('Opportunity', $opportunityId, 'amountConverted')`
+
+ `record\attribute('Opportunity', $opportunityId, 'teamsIds')`
+
+By utilizing this function along with *record\findOne*, it's possible to fetch attribute values of any record in the system.
+
+## record\fetch
+
+*As of v7.5.*
+
+`record\fetch(ENTITY_TYPE, ID)`
+
+Fetches record attributes into an object. Returns NULL if a record does not exists.
+
+!!! example
+
+ ```
+ $o = record\fetch('Account', $accountId);
+
+ if ($o) {
+ $name = object\get($o, 'name');
+ }
+ ```
+
+## record\relate
+
+Relate two records:
+
+`record\relate(ENTITY_TYPE, ID, LINK, FOREIGN_ID)`
+
+Relate a record with multiple records (passed as an array of IDs):
+
+`record\relate(ENTITY_TYPE, ID, LINK, LIST_OF_IDS)`
+
+Relate with column data (as of v9.3.):
+
+`record\relate(ENTITY_TYPE, ID, LINK, FOREIGN_ID, COLUMN_DATA)`
+
+
+!!! examples
+
+ `record\relate('Account', $accountId, 'opportunities', $opportunityId)`
+
+ `record\relate('Account', $accountId, 'tasks', list('id1', 'id2'))`
+
+ ```
+ $columnData = object\create();
+ $columnData['role'] = 'Tester';
+ record\relate('Account', $accountId, 'contacts', $contactId, $columnData);
+ ```
+
+!!! note
+ This function won't work in *Before save script* when applied for the current record. Use an after-save Workflow rule instead.
+
+## record\unrelate
+
+`record\unrelate(ENTITY_TYPE, ID, LINK, FOREIGN_ID)`
+
+Unlinks two records.
+
+!!! example
+
+ `record\unrelate('Account', $accountId, 'opportunities', $opportunityId)`
+
+!!! note
+
+ It won't work in *Before save script* when applied for the current record. Use an after-save Workflow rule instead.
+
+## record\create
+
+`record\create(ENTITY_TYPE, ATTRIBUTE1, VALUE1, [ATTRIBUTE2, VALUE2 ...])`
+
+or
+
+`record\create(ENTITY_TYPE, OBJECT)` (as of v9.0)
+
+Creates a new record of entity type with attributes specified as key-value pairs or in an object. Returns the ID of the created record.
+
+!!! example
+
+ `$id = record\create('Meeting', 'emailAddress', 'SOME@ADDRESS.com', 'assignedUserId', 'SOME-USER-ID')`
+
+## record\update
+
+`record\update(ENTITY_TYPE, ID, ATTRIBUTE1, VALUE1, [ATTRIBUTE2, VALUE2 ...])`
+
+or
+
+`record\update(ENTITY_TYPE, ID, OBJECT)` (as of v9.0)
+
+Updates an existing record with attributes specified as key-value pairs or an object.
+
+!!! example
+
+ `record\update('Meeting', 'SOME-MEETING-ID', 'emailAddress', 'SOME@ADDRESS.com', 'assignedUserId', 'SOME-USER-ID')`
+
+It will update the meeting with ID `SOME-MEETING-ID`, and will set `emailAddress = 'SOME@ADDRESS.com'`, `assignedUserId = 'SOME-USER-ID'`.
+
+## record\delete
+
+`record\delete(ENTITY_TYPE, ID)`
+
+*As of v7.4.*
+
+Removes a record.
+
+## record\relationColumn
+
+`record\relationColumn(ENTITY_TYPE, ID, LINK, FOREIGN_ID, COLUMN)`
+
+Returns a relation column.
+
+!!! example
+
+ `record\relationColumn('Account', $accountId, 'contacts', $contactId, 'role')`
+
+!!! example "Example: Condition checking position in team"
+
+ `record\relationColumn('User', $someUserId, 'teams', 'some-team-id, 'role') == 'Support Manager'`
+
+## record\updateRelationColumn
+
+`record\updateRelationColumn(ENTITY_TYPE, ID, LINK, FOREIGN_ID, COLUMN, VALUE)`
+
+Updates a relation column.
+
+!!! example
+
+ `record\updateRelationColumn('Account', $accountId, 'contacts', $contactId, 'role', 'CEO')`
diff --git a/docs/administration/formula/string.md b/docs/administration/formula/string.md
new file mode 100644
index 000000000..01f1c3e19
--- /dev/null
+++ b/docs/administration/formula/string.md
@@ -0,0 +1,227 @@
+# Formula > Functions > String
+
+* [string\concatenate](#stringconcatenate)
+* [string\substring](#stringsubstring)
+* [string\contains](#stringcontains)
+* [string\pos](#stringpos)
+* [string\test](#stringtest)
+* [string\length](#stringlength)
+* [string\trim](#stringtrim)
+* [string\lowerCase](#stringlowercase)
+* [string\upperCase](#stringuppercase)
+* [string\pad](#stringpad)
+* [string\match](#stringmatch)
+* [string\matchAll](#stringmatchall)
+* [string\matchExtract](#stringmatchextract)
+* [string\replace](#stringreplace)
+* [string\split](#stringsplit)
+
+
+## string\concatenate
+
+`string\concatenate(STRING_1, STRING_2)`
+
+Concatenates two or more strings.
+
+!!! example
+
+ ```
+ $someVariable = string\concatenate('ab', 'cd'); // will return 'abcd'
+ ```
+
+## string\substring
+
+`string\substring(STRING, START, LENGTH)`
+
+Extracts the characters from a STRING by START position and LENGTH.
+
+If LENGTH is omitted, the substring starting from START until the end of the STRING will be returned.
+
+If LENGTH is negative, then that many characters will be omitted from the end of STRING.
+
+!!! example
+
+ ```
+ $someVariable = string\substring('abcde', 1, 2); // will return 'bc'
+
+ $someVariable = string\substring('abcde', 1, -1); // will return 'bcd'
+ ```
+
+## string\contains
+
+`string\contains(STRING, NEEDLE)`
+
+Whether STRING contains NEEDLE.
+
+!!! example
+
+ ```
+ string\contains('hello world', 'world') // will return true
+ ```
+
+## string\pos
+
+`string\pos(STRING, NEEDLE)`
+
+Returns position of NEEDLE in STRING, *false* if not found.
+
+!!! example
+
+ ```
+ string\pos('hello world', 'world') // will return `6`
+ ```
+
+## string\test
+
+`string\test(STRING, REGULAR_EXPRESSION)`
+
+Search a match between REGULAR_EXPRESSION and STRING. Returns TRUE of FALSE.
+
+!!! example
+
+ ```
+ string\test('hello world', '/hello/i') // will return TRUE
+ ```
+
+## string\length
+
+`string\length(STRING)`
+
+The length of STRING.
+
+!!! example
+
+ ```
+ string\length('hello world') // will return `11`
+ ```
+
+## string\trim
+
+`string\trim(STRING)`
+
+Strips whitespace from the beginning and end of STRING.
+
+!!! example
+
+ ```
+ string\trim(' hello world ') // will return `hello world`
+ ```
+
+## string\lowerCase
+
+`string\lowerCase(STRING)`
+
+Converts letters to lower case.
+
+!!! example
+
+ ```
+ string\lowerCase('HELLO world') // will return `hello world`
+ ```
+
+## string\upperCase
+
+`string\upperCase(STRING)`
+
+Converts letters to upper case.
+
+!!! example
+
+ ```
+ string\upperCase('HELLO world') // will return `HELLO WORLD`
+ ```
+
+## string\pad
+
+`string\pad(STRING, LENGTH, [PAD_STRING], [PAD_TYPE])`
+
+Pads STRING to a certain LENGTH with PAD_STRING.
+
+PAD_STRING by default is a whitespace string `' '`.
+
+PAD_TYPE can be *'right'*, *'left'*, *'both'*. By default it is *'right'*.
+
+!!! example
+
+ ```
+ string\pad('100', 5, '*', 'right') // will return `100**`
+ ```
+
+## string\match
+
+`string\match(STRING, REGULAR_EXPRESSION, [OFFSET])`
+
+Retrieves the first result of matching a STRING against a REGULAR_EXPRESSION. Returns NULL if no matches are found.
+
+!!! example
+
+ ```
+ string\match('{token1} foo {token2} bar', '/{[^}]*}/')
+ ```
+
+ Will return `{token1}`.
+
+The slash character `/` defines the start and the end of a REGULAR_EXPRESSION.
+
+## string\matchAll
+
+`string\matchAll(STRING, REGULAR_EXPRESSION, [OFFSET])`
+
+Retrieves all results of matching a STRING against a REGULAR_EXPRESSION. Returns NULL if no matches are found.
+
+!!! example
+
+ ```
+ string\matchAll('{token1} foo {token2} bar', '/{[^}]*}/')
+ ```
+
+ Will return an array `['{token1}', '{token2}']`.
+
+## string\matchExtract
+
+`string\matchExtract(STRING, REGULAR_EXPRESSION)`
+
+*As of v7.4.*
+
+Returns an array of substrings that match parenthesized sub-patterns. Returns NULL if no matches are found.
+
+!!! example
+
+ ```
+ string\matchExtract('values: 1000 2000', '/values\: (.*) (.*)$/')
+ ```
+
+ Will return `['1000', '2000']`.
+
+The slash character `/` defines the start and the end of a REGULAR_EXPRESSION.
+
+## string\replace
+
+`string\replace(STRING, SEARCH, REPLACE)`
+
+Replaces all occurrences of SEARCH with REPLACE in STRING.
+
+!!! example
+
+ ```
+ string\replace('Hello {test}', '{test}', 'world')
+ ```
+
+ Will return `'Hello world'`.
+
+!!! note
+
+ The REPLACE parameter must be a string. Use [number\format](number.md#numberformat) function to cast an integer or a float to a string.
+
+
+## string\split
+
+`string\split(STRING, SEPARATOR)`
+
+Splits a STRING into array of strings by a string SEPARATOR. (as of v7.1)
+
+!!! example
+
+ ```
+ string\split('hello world', ' ') // will return ['hello', 'world']
+ ```
diff --git a/docs/administration/formula/util.md b/docs/administration/formula/util.md
new file mode 100644
index 000000000..26df26f61
--- /dev/null
+++ b/docs/administration/formula/util.md
@@ -0,0 +1,40 @@
+# Formula > Functions > Util
+
+* [util\generateId](#utilgenerateid)
+* [util\generateRecordId](#utilgeneraterecordid)
+* [util\base64Encode](#utilbase64encode)
+* [util\base64Decode](#utilbase64decode)
+
+## util\generateId
+
+Generates a unique ID. Returns a string.
+
+!!! example
+
+ ```
+ $uniqueId = util\generateId();
+ ```
+
+## util\generateRecordId
+
+*As of v7.5.*
+
+Generates an ID that can be used as an ID for an entity. Returns a string.
+
+!!! example
+
+ ```
+ $recordId = util\generateRecordId();
+ ```
+
+## util\base64Encode
+
+*As of v8.3.*
+
+Base64 encode.
+
+## util\base64Decode
+
+*As of v8.3.*
+
+Base64 decode.
diff --git a/docs/administration/iis-server-configuration.md b/docs/administration/iis-server-configuration.md
new file mode 100644
index 000000000..db2888697
--- /dev/null
+++ b/docs/administration/iis-server-configuration.md
@@ -0,0 +1,89 @@
+# IIS server configuration for EspoCRM
+
+*As of v7.0.*
+
+These instructions are supplementary to the [server configuration](server-configuration.md) guidelines. All configuration settings listed here are made on Windows Server 2019.
+
+!!! note
+
+ [URL Rewrite](https://www.iis.net/downloads/microsoft/url-rewrite) must be installed on the IIS server.
+
+To сonfigure IIS server for EspoCRM, do the following steps.
+
+## Step 1. Physical Path adjusting
+
+1.1. Go to **IIS Manager**, select your *Site*.
+
+
+
+1.2. Right-click on *Site* > *Manage Website* > *Advanced Settings*.
+
+
+
+1.3. Specify your EspoCRM public directory path (e.g. `C:\inetpub\wwwroot\EspoCRM-7.2.7\public`) in the *Physical Path* field.
+
+1.4. Click on *OK*.
+
+
+
+## Step 2. Virtual Path adjusting
+
+2.1. Right-click on *Site* in **IIS manager** > *Add Virtual Directory*.
+
+
+
+2.3. Type the *client* name in the *Alias* field.
+
+2.4. Specify your EspoCRM client directory path (e.g. `C:\inetpub\wwwroot\EspoCRM-7.2.7\client`) in the *Physical Path* field.
+
+2.5. Click on *OK*.
+
+
+
+## Step 3. Handler Mappings settings
+
+### Via IIS Manager
+
+3.1. Navigate the **Handler Mappings** scope of your *Site*.
+
+
+
+3.2. Select the *PHP_via_FastCGI* module > *Actions* > *Edit*.
+
+
+
+3.3. Specify `"C:\Program Files\PHP\v7.4\php-cgi.exe"` path in the *Executable (Optional)* field (double quotes are required).
+
+
+
+3.4. Navigate *Request Restrictions* > *Verbs*.
+
+3.5. Specify the verbs to be handled. Select *All verbs* or specify *One of the following verbs:* `GET,HEAD,POST,PUT,DELETE,PATCH`, click on *OK*.
+
+
+
+3.6. Click on *OK* and *Yes*.
+
+
+
+### Via Text Editor (Notepad as Administrator, Sublime Text, VSCode, etc.)
+
+3.1. Open `%windir%\system32\inetsrv\config\applicationhost.config` file.
+
+3.2. Locate the *< handlers >* tag.
+
+3.3. Locate the *"PHP_via_FastCGI"* section, add all HTTP methods modifying `verb="GET,HEAD,POST"` value to `verb="GET,HEAD,POST,PUT,DELETE,PATCH"`.
+
+3.4. Save the *ApplicationHost.config* file.
+
+## Step 4. Permissions
+
+4.1. Open your EspoCRM instance directory, right-click on it > *Properties* > *Security* > *Edit*.
+
+4.2. For user names **IIS_IUSRS**, check all available boxes in the *Allow* column.
+
+
+
+4.3. Click on *Apply* and *OK*.
+
+**Reboot your IIS server after all the steps are done.**
diff --git a/docs/administration/import.md b/docs/administration/import.md
index 85430ebf5..65545f737 100644
--- a/docs/administration/import.md
+++ b/docs/administration/import.md
@@ -2,7 +2,7 @@
Provides the ability to import records from CSV files.
-Administrator can access import at Administration > Import. By default, regular users don't have access. It can be granted with ACL roles. Administrator also can add the Import tab at Administration > User Interface > Tab List.
+An administrator can access the Import tool at Administration > Import. By default, regular users don't have access to Import but it can be granted in Roles. The administrator can also add the *Import* tab to the navbar at Administration > User Interface > Tab List.
In this article:
@@ -10,46 +10,51 @@ In this article:
* [Step 2](#step-2)
* [Import results](#import-results)
* [Importing into Target List](#importing-into-target-list)
+* [Relations](#relations)
* [Console commands](#console-commands)
+* [Errors](#errors)
* [See also](#see-also)
## Step 1
Select what type of records you need to import (*Entity Type* field).
-Select a CSV file. A file should be formated with `UTF-8`.
-Select *What to do?*. Available options: 'Create Only', 'Create & Update', 'Update Only'.
+Select a CSV file. A file should be formatted in *UTF-8*.
+Select *What to do?*. Available options: Create Only, Create & Update, Update Only.
* *Create Only* − import will only create records;
-* *Create & Update* − records will be created, if records with matching field values will be found, they will be updated; you will be able to check what fields to match by on the _Step 2_.
-* *Update only* − only records with matching field values will be found, it will be updated.
+* *Create & Update* − records will be created, if records with matching field values are found, they will be updated; you will be able to check what fields to match by on the _Step 2_.
+* *Update Only* − records with matching field values will be updated.
-Once you select a CSV file, you will be able to see how it will be parsed in *Preview* panel. When you change parameters, the preview will be updated.
+Once you select a CSV file, you will be able to see how it will be parsed in the **Preview** panel. When you change parameters, the preview is updated.
Parameters:
-* *Header Row* − whether CSV file has the first row with field names.
-* *Execute in idle* − is recommended if you have a big bunch of records to be imported; import will be processed via cron; the status will be set to 'Complete' when the import process is finished.
-* *Skip searching for duplicates* − will make the import faster.
-* *Silent mode* − the majority of after-save scripts will be skipped; stream records won't be created, workflows will be skipped; checking will make the import faster.
-* *Run Manually* − you will need to run manually from CLI. Command will be shown after setting up the import. (since v5.10.0)
+* *Header Row* − whether a CSV file has the first row with field names.
+* *Execute in idle* − is recommended if you import a **big number of records**; import will be processed **via cron**; the status will be set to *Complete* when the import process is finished.
+* *Skip searching for duplicates* − will **make the import faster**.
+* *Silent mode* − the majority of after-save scripts will be skipped; Stream notes won't be created, workflows will be skipped; checking will **make the import faster**.
+* *Run Manually* − you will need to start the import manually from CLI. The command will be shown after setting up the import.
+* *Telephone country code* − phone numbers in a regional format will be converted to the international format according the selected country. (as of v8.1)
-Click *Next* button to preceed to the _Step 2_.
+Click the **Next** button to proceed to the _Step 2_.

## Step 2
-Setup the field mapping: how fields correspond to columns of the CSV file. You can skip not needed columns here.
+Set up the field mapping – how fields correspond to columns in the CSV file. Not mapped columns will be ignored.
-In cases of 'Create & Update' and 'Update only', you need to check fields by which records that should be updated will be found. For example, if you check *update by* 'Name' field, then records with the matching name will be updated.
+If the import mode is *Create & Update* or *Update Only*, you also need to check the fields that will be used to find the records to update. For example, if you tick *update by* the Name field, then records where the Name matches the value in the CSV file will be updated.
-Add *default values* you want new and updated records to set with. For example, you can specify 'Assigned User' and 'Teams' that will be applied by default.
+Add **Default Values** that you want new and updated records to set with. For example, you can specify values for the Assigned User and Teams fields to be applied by default.
-After the import is done, you will be able to **revert** created records. You will be able to see which records were recognized as duplicate and which were updated. Duplicate means that there was a similar record in the system. You can remove all imported duplicates at once.
+After import is done, you will have the ability to **revert** created records. You will be able to see which records were recognized as duplicates and which were updated. Duplicate means that there was a similar record in the system. You can remove all imported duplicates at once or remove only specific ones.
-Important: Revert doesn't work with updated records, you can't revert the update.
+!!! important
-Click *Run Import* button to proceed. It may take some time before the import process gets finished. If you want to import a large bunch of records, it's recommended to run import in idle.
+ Revert doesn't work with updated records, you cannot revert the update.
+
+Click the **Run Import** button to proceed. It may take some time before the import process gets finished. If you want to import a large bunch of records, it's recommended to run import *in idle*.

@@ -61,7 +66,11 @@ Once the records are imported and you are sure that imported data is fine, you c
#### Revert import
-*Revert Import* will remove all imported records permanently. Updates caused by import won't be reverted.
+*Revert Import* will remove all imported records permanently.
+
+!!! important
+
+ Updates caused by import are not reverted.
#### Remove duplicates
@@ -69,17 +78,19 @@ This will permanently remove all imported records that were recognized as duplic
#### New import with same params
-Since version 5.10.0.
-
-This will create a new import with the same parameters.
+This will create a new import with the same parameters and field mapping.
## Importing into Target List
-When you import Contacts, Leads or Accounts, you can add them to some target list. On the Step 2, you need to add *Target List* field on *Default Values* panel and select a needed target list record. You can also use 'Update only' or 'Create & Update' import to add existing targets to a target list.
+When you import Contacts, Leads or Accounts, you can add them to a specific Target List. On the Step 2, you need to add the *Target List* field in the *Default Values* panel and select a needed Target List record. You can also use *Update only* or *Create & Update* import type to link existing records with a specific Target List.
-## Console commands
+## Relations
-Since version 5.10.0.
+It's possible to automatically relate imported records by a foreign name. For example, when you import Opportunities, if you have Account names in a CSV but don't have Account IDs, Accounts with corresponding names will be automatically related with imported records. Note that this functionality is only available for many-to-one relationships.
+
+It's also possible to automatically relate imported records by a *Foreign* field other than the Name. The Foreign field should have *Relate on Import* parameter enabled. The feature is available as of v8.2.
+
+## Console commands
Run import:
@@ -87,6 +98,8 @@ Run import:
php command.php import --id={import-id}
```
+The import must be created via the UI before. It should have *Run Manually* parameter checked.
+
Resume failed import (from the last processed row):
```
@@ -107,6 +120,30 @@ php command.php import --file=path/to/csv --params-id={import-id}
*--params-id* is ID of a previously run import. Its parameters will be used for the import.
+## Errors
+
+*As of v7.2.*
+
+All rows that failed to import will be available in the Errors panel on the Import result view. It's possible to view the reason of the failure (usually it's validation), the index of the failed row and values. To view error details, click the *View* action from the dropdown.
+
+There's the ability to export all failed rows back to a CSV (in order to fix them and then re-import).
+
+### Integrity-Constraint-Violation
+
+Occurs when importing an ID that already exists. Most likely, you didn't reverted the previously imported records and try to import them again.
+
+### Validation
+
+Validation is applied for imported records. If a row does not pass validation, the record won't be created.
+
+#### Enum fields
+
+When importing to an enum field, values in a CSV should be the same as values (options) defined for the field in Espo. If your data source uses different values, consider replacing them in the CSV before importing. One can utilize the *VLOOKUP* function in the spreadsheet app or use simple *Find & Replace*.
+
+If you import an empty value, but your enum field does not have an empty option, the validation will not pass.
+
## See also
+* [Import feature quick tour](https://app.supademo.com/demo/cmh1o4qs909i5nitlciznubzc)
+* [Export Import extension](../extensions/export-import/overview.md)
* [Import and export tool for quick data migration](https://www.espocrm.com/tips/import-export/)
diff --git a/docs/administration/installation-by-script.md b/docs/administration/installation-by-script.md
new file mode 100644
index 000000000..a1cfcce1f
--- /dev/null
+++ b/docs/administration/installation-by-script.md
@@ -0,0 +1,692 @@
+# Installation by Script
+
+This script automatically installs EspoCRM as a Docker image with Nginx server and MariaDB database.
+
+## Requirements
+
+1. Operating system:
+
+ * Ubuntu
+ * Debian
+ * Linux Mint
+
+2. Access via command line.
+
+3. Root or sudo access.
+
+## Installation
+
+Open your server's command line and run the commands:
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh
+```
+
+## Installation with SSL/TLS certificate
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --ssl
+```
+
+## Installation without prompts
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh -y --ssl --letsencrypt --domain=my-espocrm.com --email=email@my-domain.com
+```
+
+## Available options
+
+#### `-y` or `--yes`
+
+Skip confirmation prompts during installation.
+
+#### `--ssl`
+
+Installation with SSL/TLS certificate. Ex. `--ssl`. See [installation modes](#installation-modes).
+
+#### `--letsencrypt`
+
+Installation with a Let's Encrypt free certificate. Ex. `--ssl --letsencrypt`. See [installation modes](#1-lets-encrypt-certificate).
+
+#### `--owncertificate`
+
+Installation with an own SSL/TLS certificate. Ex. `--ssl --owncertificate`. See [installation modes](#2-own-ssltls-certificate).
+
+#### `--domain`
+
+Define your domain. Ex. `--domain=my-domain.com` or `--domain=192.168.1.10`.
+
+#### `--email`
+
+Email address for Let's Encrypt certificate. Ex. `--email=email@my-domain.com`.
+
+#### `--clean`
+
+Clean the existing EspoCRM installation and start a new one. This option can be used if you have already installed EspoCRM. Ex. `--clean`.
+
+#### `--public-ip`
+
+Note: For HTTP mode only.
+
+Indicate a public IP address that will be used for EspoCRM installation. Ex. `--public-ip`.
+
+#### `--private-ip`
+
+Note: For HTTP mode only.
+
+Indicate a private (local) IP address that will be used for EspoCRM installation. Ex. `--private-ip`.
+
+#### `--db-root-password`
+
+Define your own MySQL root password instead of the automatically generated one. Ex. `--db-root-password=my-password`.
+
+#### `--db-password`
+
+Define your own MySQL password for EspoCRM installation. Ex. `--db-password=my-password`.
+
+#### `--admin-username`
+
+Define a username of your EspoCRM administrator. Ex. `--admin-username=admin`.
+
+#### `--admin-password`
+
+Define a password of EspoCRM administrator. Ex. `--admin-password=admin-password`.
+
+#### `--command`
+
+Update the `command.sh` for the existing installation. Ex. `--command`.
+
+#### `--backup-path `
+
+A path for the backup. Ex. `--backup-path ="/backup"`.
+
+## Server management
+
+The operation of EspoCRM consists of several services, such as `nginx`, `mariadb`, `daemon`.
+
+In order to update the command tool, see [update the command.sh](#update-the-commandsh).
+
+### Help
+
+In order to display a list of available commands.
+
+```
+sudo /var/www/espocrm/command.sh help
+```
+
+### Status of services
+
+```
+sudo /var/www/espocrm/command.sh status
+```
+
+### Restart services
+
+```
+sudo /var/www/espocrm/command.sh restart
+```
+
+### Start services
+
+```
+sudo /var/www/espocrm/command.sh start
+```
+
+### Build and start services
+
+In order to apply changes in `docker-compose.yml`.
+
+```
+sudo /var/www/espocrm/command.sh build
+```
+
+### Stop services
+
+```
+sudo /var/www/espocrm/command.sh stop
+```
+
+### EspoCRM rebuild
+
+```
+sudo /var/www/espocrm/command.sh rebuild
+```
+
+### EspoCRM upgrade
+
+```
+sudo /var/www/espocrm/command.sh upgrade
+```
+
+### EspoCRM logs
+
+```
+sudo /var/www/espocrm/command.sh logs
+```
+
+### Backup
+
+Create a full backup of EspoCRM.
+
+```
+sudo /var/www/espocrm/command.sh backup "BACKUP_DIRECTORY"
+```
+
+An example: `sudo /var/www/espocrm/command.sh backup /var/www/espocrm-backup`.
+
+### Restore
+
+Restore the backup created by the [backup](#backup) command.
+
+```
+sudo /var/www/espocrm/command.sh restore "BACKUP_ARCHIVE"
+```
+
+An example: `sudo /var/www/espocrm/command.sh restore "/var/www/espocrm-backup/2024-01-01_142051.tar.gz"`.
+
+### Restore on a fresh server
+
+Restore the backup created by the [backup](#backup) command.
+
+#### 1. Configure the environment
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --environment
+```
+
+#### 2. Restore a backup
+
+```
+sudo /var/www/espocrm/command.sh restore "BACKUP_ARCHIVE"
+```
+
+An example: `sudo /var/www/espocrm/command.sh restore "/var/www/espocrm-backup/2024-01-01_142051.tar.gz"`.
+
+#### Restore troubleshooting
+
+In order to fix the `Error response from daemon: network external not found`, run:
+
+```
+sudo bash install.sh --network
+```
+
+and then run the `Step 2` again.
+
+### Clean
+
+Delete old and unnecessary files.
+
+```
+sudo /var/www/espocrm/command.sh clean
+```
+
+### Import SQL dump
+
+Import the database from the SQL dump created by `mariadb-dump`, `mysqldump`, `phpMyAdmin`, etc.
+
+```
+sudo /var/www/espocrm/command.sh import-sql "PATH/DB.sql"
+```
+
+An example: `sudo /var/www/espocrm/command.sh import-sql "/var/www/espocrm-backup/db.sql"`.
+
+### Import SQL dump for one / several tables
+
+Import the database with enabled `DROP TABLE` statement in the SQL dump created by `mariadb-dump`, `mysqldump`, `phpMyAdmin`, etc.
+
+```
+sudo /var/www/espocrm/command.sh import-sql --skip-drop "PATH/DB.sql"
+```
+
+An example: `sudo /var/www/espocrm/command.sh import-sql "/var/www/espocrm-backup/db.sql" --skip-drop`.
+
+### Export a database into the SQL dump
+
+Export the database structure and data into a .sql dump.
+
+```
+sudo /var/www/espocrm/command.sh export-sql "PATH"
+```
+
+An example: `sudo /var/www/espocrm/command.sh export-sql "/var/www/espocrm-backup"`.
+
+### Export a database table into the SQL dump
+
+Export the single database table structure and data into a .sql dump.
+
+Notice: the database tables have different names than Entities. Ex. `TargetList` entity has the `target_list` table.
+
+```
+sudo /var/www/espocrm/command.sh export-table-sql "PATH" "TABLE_NAME"
+```
+
+An example: `sudo /var/www/espocrm/command.sh export-table-sql "/var/www/espocrm-backup" account`.
+
+### Certificate generation
+
+Generate a new Let's Encrypt certificate. It can be used to create a certificate for the first time or after a domain change.
+
+```
+sudo /var/www/espocrm/command.sh cert-generate
+```
+
+### Certificate renewal
+
+Renew an existing Let's Encrypt certificate. It can be used in crontab to automatically renewal.
+
+```
+sudo /var/www/espocrm/command.sh cert-renew
+```
+
+### Apply a domain change
+
+Applying a domain change described [here](#change-a-domain-name).
+
+```
+sudo /var/www/espocrm/command.sh apply-domain
+```
+
+### Enable automatic certificate renewal
+
+Note: This item is relevant only for the Let's Encrypt mode.
+
+Enable automatic certificate renewal. This should be done after moving to another server only.
+
+```
+sudo /var/www/espocrm/command.sh cert-cron-add
+```
+
+### Disable automatic certificate renewal
+
+Note: This item is relevant only for the Let's Encrypt mode.
+
+Disable automatic certificate renewal. This command should be run after changing the installation mode (ex. to own SSL certificate).
+
+```
+sudo /var/www/espocrm/command.sh cert-cron-remove
+```
+
+### Add a cronjob for VoIP Integration connector
+
+Add a cronjob for a VoIP Integration extension after configuring the connector (ex. Asterisk).
+
+```
+sudo /var/www/espocrm/command.sh voip-cron-add CONNECTOR
+```
+
+where `CONNECTOR` is your connector ID, ex. `Asterisk`.
+
+### Remove a cronjob for VoIP Integration connector
+
+Remove a cronjob for a VoIP Integration extension after disabling the connector (ex. Asterisk).
+
+```
+sudo /var/www/espocrm/command.sh voip-cron-remove CONNECTOR
+```
+
+where `CONNECTOR` is your connector ID, ex. `Asterisk`.
+
+## Data
+
+### Structure
+
+```
+.
+├── data
+│ ├── espocrm
+│ ├── mariadb
+│ └── nginx
+├── docker-compose.yaml
+├── command.sh
+```
+
+### Storage location
+
+All data are stored at:
+
+```
+/var/www/espocrm
+```
+
+## Installation modes
+
+### 1. Let's Encrypt certificate
+
+This certificate is a free of charge and can be used by providing an email address.
+
+### 2. Own SSL/TLS certificate
+
+If you need a high-security connection, you have to use your own SSL/TLS certificate. In this mode, EspoCRM will be installed with dummy certificates which should be replaced by real ones.
+
+Post installation steps:
+
+1\. Go to your server directory `/var/www/espocrm/data/nginx/ssl/cert/`.
+
+2\. Replace the following certificates with your own:
+
+- fullchain.pem
+- privkey.pem
+
+**Important!**
+Your own certificates have to substitute the existing certificates and must have the same names.
+
+3\. Restart nginx server:
+
+```
+/var/www/espocrm/restart.sh espocrm-nginx
+```
+
+### 3. HTTP mode
+
+This mode is recommended to use only if you don't have a domain name or want to use your IP address as a domain name.
+
+## Changing installed mode
+
+All the actions can be applied to already installed EspoCRM instance.
+
+### From HTTP to Own SSL/TLS certificate
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --ssl --owncertificate --domain=my-espocrm.com
+```
+
+### From HTTP to Let's Encrypt certificate
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --ssl --letsencrypt --domain=my-espocrm.com --email=email@my-domain.com
+```
+
+### From Own SSL/TLS certificate to Let's Encrypt certificate
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --ssl --letsencrypt --domain=my-espocrm.com --email=email@my-domain.com
+```
+
+### Manually (advanced users only)
+
+1\. Stop your existing EspoCRM instance.
+
+```
+sudo /var/www/espocrm/command.sh stop
+```
+
+2\. Rename your existing directory:
+
+```
+mv /var/www/espocrm /var/www/espocrm-old
+```
+
+3\. Run the installer in the required mode, e.g. `Let's Encrypt certificate` mode:
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --ssl --letsencrypt --domain=my-espocrm.com --email=email@my-domain.com
+```
+
+4\. Copy your existing data to a new installation:
+
+```
+rm -rf /var/www/espocrm/data/espocrm
+rm -rf /var/www/espocrm/data/mariadb
+cp -rp /var/www/espocrm-old/data/espocrm /var/www/espocrm/data
+cp -rp /var/www/espocrm-old/data/mariadb /var/www/espocrm/data
+```
+
+5\. Update your `/var/www/espocrm/docker-compose.yml` file. You have to copy your existing options from `/var/www/espocrm-old/docker-compose.yml` for the services:
+- `espocrm-db`
+- `espocrm`
+
+6\. Restart services via the command:
+
+```
+sudo /var/www/espocrm/command.sh restart
+```
+
+7\. Login as administrator and update your new `Site URL` in Administration > Settings.
+
+## Logs
+
+### Nginx logs
+
+```
+/var/www/espocrm/data/nginx/logs
+```
+
+### EspoCRM logs
+
+```
+/var/www/espocrm/data/espocrm/data/logs
+```
+
+## Update the command.sh
+
+In order to load the latest version of the `command.sh`, run the command:
+
+```
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --command
+```
+
+## Modify PHP settings
+
+This can be achieved by mounting the PHP configuration file and restarting the container.
+
+1\. Login via terminal to your server and open EspoCRM directory `/var/www/espocrm`:
+
+```
+cd /var/www/espocrm
+```
+
+2\. Create the PHP configuration file:
+
+```
+mkdir -p data/php; \
+nano data/php/espocrm.ini
+```
+
+with the content:
+
+```
+expose_php = Off
+display_errors = Off
+display_startup_errors = Off
+log_errors = On
+memory_limit=256M
+max_execution_time=180
+max_input_time=180
+post_max_size=30M
+upload_max_filesize=30M
+date.timezone=UTC
+```
+
+then press `Ctrl + 0` and `Ctrl + X`
+
+3\. Mount the created PHP configuration file to the container:
+
+```
+sudo nano docker-compose.yml
+```
+
+add `./data/php/espocrm.ini:/usr/local/etc/php/conf.d/espocrm.ini` option for `espocrm` container as displayed below:
+
+```
+espocrm:
+ ...
+ volumes:
+ - ./data/espocrm:/var/www/html
+ - ./data/php/espocrm.ini:/usr/local/etc/php/conf.d/espocrm.ini
+ ...
+```
+
+then press `Ctrl + 0` and `Ctrl + X`
+
+4\. Restart the container to apply the changes:
+
+```
+sudo ./command.sh restart espocrm
+```
+
+## Modify Nginx settings
+
+1\. Login via terminal to your server and open EspoCRM directory `/var/www/espocrm`:
+
+```
+cd /var/www/espocrm
+```
+
+2\. Edit the file `./data/nginx/conf.d/default.conf.template`
+
+```
+sudo nano ./data/nginx/conf.d/default.conf.template
+```
+
+3\. Restart the container to apply the changes:
+
+```
+sudo ./command.sh restart espocrm-nginx
+```
+
+## Change a domain name
+
+1\. Login via terminal to your server and open EspoCRM directory `/var/www/espocrm`:
+
+```
+cd /var/www/espocrm
+```
+
+2\. Find and replace the old domain name with the new one in the file `./docker-compose.yml`
+
+```
+sudo nano ./docker-compose.yml
+```
+
+Options to change:
+
+1. `NGINX_HOST`.
+2. `ESPOCRM_CONFIG_SITE_URL`.
+3. `command` under the `espocrm-certbot` service (required only for the letsencrypt mode).
+
+3\. Run the command:
+
+```
+sudo ./command.sh apply-domain
+```
+
+Note: You have to clear your browser cache for this change to take effect.
+
+## Installer migration from v1 to v2
+
+!!! note
+
+ If your MySQL container is not running or restarting, check the [Troubleshooting](#troubleshooting) section.
+
+1\. Export the MySQL database from the corresponding Docker container:
+
+```
+sudo mkdir -p /var/www/backup
+cd /var/www/backup
+sudo docker exec -i espocrm-mysql /usr/bin/mysqldump -uroot -pYOUR_ROOT_PASSWORD espocrm > db.sql
+```
+
+Notes:
+
+- Replace the YOUR_ROOT_PASSWORD with your MySQL root password.
+
+2\. Copy `data` and `custom` folders from *espocrm* directory:
+
+```
+sudo cp -a /var/www/espocrm/data/espocrm/data /var/www/backup/data
+sudo cp -a /var/www/espocrm/data/espocrm/custom /var/www/backup/custom
+```
+
+3\. Install a fresh EspoCRM by a script:
+
+```
+cd ~
+wget -N https://github.com/espocrm/espocrm-installer/releases/latest/download/install.sh
+sudo bash install.sh --db-root-password=YOUR_ROOT_PASSWORD --db-password=YOUR_ESPOCRM_DB_PASSWORD --admin-password=YOUR_ADMIN_PASSWORD --clean
+```
+
+Notes:
+
+- Replace the YOUR_ROOT_PASSWORD with your MySQL root password.
+- Replace the YOUR_ESPOCRM_DB_PASSWORD with your MySQL espocrm user password.
+- Replace the YOUR_ADMIN_PASSWORD with your EspoCRM admin user password.
+
+4\. Stop the services:
+
+```
+sudo /var/www/espocrm/command.sh stop
+```
+
+5\. Replace `data` and `custom` folders in the */var/www/espocrm/data/espocrm* directory with the previously exported ones.
+
+```
+sudo rm -rf /var/www/espocrm/data/espocrm/data
+sudo rm -rf /var/www/espocrm/data/espocrm/custom
+sudo cp -a /var/www/backup/data /var/www/espocrm/data/espocrm
+sudo cp -a /var/www/backup/custom /var/www/espocrm/data/espocrm
+```
+
+6\. Replace `'host' => 'espocrm-mysql'` line with `'host' => 'espocrm-db'` one in the */var/www/espocrm/data/espocrm/data/config-internal.php* file.
+
+7\. Start the services:
+
+```
+sudo /var/www/espocrm/command.sh start
+```
+
+8\. Import previously exported database to MariaDB container:
+
+```
+sudo /var/www/espocrm/command.sh import-sql /var/www/backup/db.sql
+```
+
+9\. Make a rebuild:
+
+```
+sudo /var/www/espocrm/command.sh rebuild
+```
+
+10\. Log in to your instance and check if everything is working well.
+
+## Troubleshooting
+
+If after upgrading the EspoCRM instance with the [upgrade](#espocrm-upgrade) command you get error 500 in your instance and there is nothing in the logs that could be related to this error, one of the reasons could be a MySQL version upgrade (upgrades automatically).
+
+!!! warning
+
+ Make sure that your instance is using MySQL database and not MariaDB one. If it is MariaDB, then the error solution will not work for you in case of using MariaDB database.
+
+To solve this problem and gain access to the instance, follow these steps:
+
+1\. Stop the services:
+
+```
+sudo /var/www/espocrm/command.sh stop
+```
+
+2\. In */var/www/espocrm/docker-compose.yaml* file, remove the following line:
+
+```
+command: --default-authentication-plugin=mysql_native_password
+```
+
+3\. Insert the following line in the same place and save changes:
+
+```
+command: --mysql-native-password=ON
+```
+
+4\. Build and start the services:
+
+```
+sudo /var/www/espocrm/command.sh build
+```
diff --git a/docs/administration/installation.md b/docs/administration/installation.md
index dc4a9633a..f192a5502 100644
--- a/docs/administration/installation.md
+++ b/docs/administration/installation.md
@@ -1,69 +1,57 @@
+---
+search:
+ boost: 2
+---
+
# Installation
### Requirements
-EspoCRM can run on most hosting providers. Requirements are the following:
-
-* PHP 7.2 and later,
-* MySQL 5.7 (and later) or MariaDB 10.1 (and later).
-
-See [server configuration](server-configuration.md) article for more information.
+EspoCRM can run on most hosting providers that support PHP and a MySQL, MariaDB, or PostgreSQL database. See the [server configuration](server-configuration.md) article for more information.
### 1. Download EspoCRM installation package
To get the latest version of EspoCRM, follow the [download page](http://www.espocrm.com/download/) link.
-### 2. Upload EspoCRM files to your Server
+### 2. Upload EspoCRM files to your server
-Once the download is complete, upload the package to your web server.
+Once download is complete, upload the package to your web server.
To upload it, you can use SSH, FTP or the hosting administration panel.
-Extract the archive to your public web server directory (e.g., `public_html`, `www`, etc.).
-
-_Note: If you have only FTP access, you need to extract the archive before uploading to your web server._
-
-### 3. Create MySQL Database for EspoCRM to use
-
-Go to your hosting administration panel, or to SSH, and create a new database and user for EspoCRM (e.g., `MySQL Databases` in cPanel).
+Extract the archive to your public web server directory (e.g. `public_html`, `www`).
-### 4. Run EspoCRM installation process
+!!! note
-Now, open your web browser, and go to the URL with EspoCRM files (e.g., `http://yourdomain.com/espo`).
+ If you have only FTP access, you need to extract the archive before uploading to your web server.
-If you see this screen, you have a "Permission denied" error.
-You need to execute the displayed command in the terminal via SSH to set correct permissions.
-It should be 755 for directories, 644 for files, and 775 for `data` directory.
-Also, make sure that you have the correct _owner_ and _group_. More info about permissions is available [here](server-configuration.md#required-permissions-for-unix-based-systems).
+### 3. Create database for EspoCRM
-
-
-If you see the following screen, the permission is correct and you can start installing EspoCRM.
-
-
+Using your hosting administration panel, or CLI, create a new database and a database user.
-On this page, you can read and accept the License Agreement.
+Grant privileges to the database user. The user must have permission to modify the database schema and full access to read and write data. Alternatively, you can also use the root user if it's a local setup.
-
+### 4. Run EspoCRM installation wizard
-Enter the details for your newly created MySQL database.
+In the browser, open an URL that corresponds to the location where EspoCRM files were extracted (e.g. `https://yourdomain.com/espo` or `https://yourdomain.com` if you extracted to the root).
-
+If you see the screen below, you have the *file permission* issue.
+You need to execute the displayed command in the terminal via SSH to set the correct permissions.
+It should be `755` for directories, `644` for files, and `775` for the `data` directory.
+Also, make sure that you have the correct _owner_ and _group_. In most cases it's `www-data:www-data`. More info about permissions is available [here](server-configuration.md#required-permissions-for-unix-based-systems).
-Enter the user name and password of Administrator EspoCRM.
+
-
+If you see the following screen, the permission are correct and you can start installation.
-On this page you can set the default settings of EspoCRM, such as date and time format, timezone, currency and others.
+
-
+In the next step, enter details of your newly created database.
-Enter SMTP settings for outgoing emails, if you want to have the ability to send emails.
-This step **can be skipped** by clicking the _Next_ button.
-All of these options can be added/changed in EspoCRM after installation.
+Further, you will be asked to specify a desired username and password for an admin user, some system settings (date formats, default timezone, currency, etc.). Optionally, you can configure SMTP credentials for system emails.
-
+!!! note
-Installation is complete. The last thing is to setup cron (or daemon) in your system. It can be done by running `crontab -e` in linux cli and in _Windows Tasks Scheduler_ in Windows systems. More info about jobs is [here](#jobs).
+ All these parameters can be changed in the application after installation.
-
+In the end, the installation wizard will propose to configure cron in your system. It can be done with `crontab -e` command in Linux or _Windows Tasks Scheduler_ in Windows. See more about cron jobs [here](jobs.md).
-We hope you will enjoy working with EspoCRM.
+We hope you enjoy EspoCRM.
diff --git a/docs/administration/jobs.md b/docs/administration/jobs.md
index 4441e3c64..430483e42 100644
--- a/docs/administration/jobs.md
+++ b/docs/administration/jobs.md
@@ -4,14 +4,16 @@ Jobs are tasks executing in the background. They handle operations like sending
In this article:
-* [Scheduled Jobs](#scheduled-jobs)
+* [Scheduled jobs](#scheduled-jobs)
* [Setting up (cron & daemon)](#setting-up)
* [Running jobs in parallel processes](#running-jobs-in-parallel-processes)
-* [Running specific job manually in CLI](#running-specific-job-manually-in-cli)
+* [Parameters](#parameters)
+* [Running jobs in CLI](#running-jobs-in-cli)
+* [Tips](#tips)
-## Scheduled Jobs
+## Scheduled jobs
-Scheduled Jobs are intended for recurring job execution. They are available at Administration > Scheduled Jobs. Scheduling for a specific job can be configured using a crontab notation.
+Scheduled jobs are intended for recurring job execution. They are available at Administration > Scheduled Jobs. Scheduling for a specific job can be configured using the crontab notation.
```
* * * * *
@@ -21,42 +23,44 @@ Scheduled Jobs are intended for recurring job execution. They are available at A
| | | +------ Month of the Year (range: 1-12)
| | +-------- Day of the Month (range: 1-31)
| +---------- Hour (range: 0-23)
++------------ Minute (range: 0-59)
```
If you want a job to be run as often as possible, you need to set the scheduling to `* * * * *`.
-Important: Scheduling works in **UTC timezone**. It doesn't honor the server's timezone. You need to take it into account when you need the scheduling for specific hours.
-
## Setting up
-There are two ways how jobs can be processed: with crontab or daemon.
+There are two job processing setup options:
-### Cron
+* [Crontab](#cron)
+* [Daemon](#daemon)
+
+For both, it's **highly recommended** to turn on processing jobs **in parallel** processes: Administration > Job Settings > Jobs Run in Parallel.
+
+!!! note
-Cron is easy to configure. It's supported by most hosting providers.
+ Parallel processing is not supported in a Windows environment.
-See how to configure cron [here](server-configuration.md#setting-up-crontab).
+### Cron
-In Unix systems, cron is supposed to be run not more often than once a minute. It's possible to overcome this limitation with the following trick.
+The Cron is easy to configure, it's supported by most hosting providers. See how to configure cron [here](server-configuration.md#setting-up-crontab).
-Add multiple lines in crontab with delays in seconds:
+In Unix systems, the cron is supposed to be run not more often than once a minute. It's possible to overcome this limitation by adding multiple crontab actions with different delays:
```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-* * * * * sleep 15; /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-* * * * * sleep 30; /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-* * * * * sleep 45; /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
+* * * * * /usr/bin/php -f /path/to/espo/cron.php > /dev/null 2>&1
+* * * * * sleep 15; /usr/bin/php -f /path/to/espo/cron.php > /dev/null 2>&1
+* * * * * sleep 30; /usr/bin/php -f /path/to/espo/cron.php > /dev/null 2>&1
+* * * * * sleep 45; /usr/bin/php -f /path/to/espo/cron.php > /dev/null 2>&1
```
-Note that command that runs cron may differ depending on your server environment.
+The command that runs cron.php may vary depending on your server environment. You need to replace `/path/to/espo/` with the actual path to your instance.
### Daemon
-Requires *pcntl* and *posix* extensions.
-
-It's recommended to turn on processing jobs in parallel processes: Administration > Jobs > Settings (in the top-right corner) > Jobs Run in Parallel. Note: Parallel processing is not supported on Windows environment.
+Daemon setup is available only in Unix-like operating systems. Requires *pcntl* and *posix* PHP extensions (usually available by default).
-Command to start daemon using nohup:
+Command to start the daemon using **nohup**:
```
nohup php /path/to/espocrm/daemon.php &
@@ -66,7 +70,6 @@ nohup php /path/to/espocrm/daemon.php &
Service configuration file: `/etc/systemd/system/espocrm-daemon.service`
-
Configuration (file content):
```
@@ -100,30 +103,83 @@ Command to start the service:
systemctl start espocrm-daemon.service
```
-
## Running jobs in parallel processes
-By default jobs are executed one by one, that may cause situations when one job blocks the execution of the next job for some time (usually it's not more than one minute). To avoid this, it's possible to run jobs in parallel processes. The parameter is available at Administration > Jobs > Settings (in the top-right corner).
+!!! note
+
+ It's **highly recommended** to enable running jobs in parallel processes.
+
+By default, jobs are executed one by one, which may cause situations when one job blocks the execution of the next job for some time (usually, it's not more than one minute). To avoid this, it's possible to configure the system to run jobs in parallel processes. The parameter enabling this behavior is available under: Administration > Job Settings.
+
+Requires *pcntl* and *posix* extensions. Some server configurations may restrict the ability to run child processes. Windows is not supported.
+
+## Parameters
+
+The administrator can configure job parameters under: Administration > Job Settings.
+
+#### Jobs Max Portion
+
+It may be reasonable to increase the **Jobs Max Portion** parameter when the number of users in your CRM is increased. It defines the maximum number of jobs that can be processed in a single cron (or daemon) run. By default, it's set to *15*.
-Requires *pcntl* and *posix* extensions. Some server configurations may restrict the ability to run child processes.
+#### Force UTC Time Zone
-Windows is not supported.
+If not checked, the default time zone (set in Administration > Settings) is used for job scheduling. It's highly recommended to have this parameter unchecked. This parameter was introduced to mitigate a migration burden when time zone support was introduced for jobs.
-## Running specific job manually in CLI
+## Running jobs in CLI
+To run a specific job manually in CLI
Command:
+
```
php command.php run-job JobName
```
-where JobName is an intrernal name of the job you want to run.
+where JobName is an internal name of the job you want to run.
+
+
+!!! example
+
+ ```
+ php command.php run-job Cleanup
+ php command.php run-job ProcessMassEmail
+ ```
+
+Jobs available out of the box:
+
+* CheckEmailAccounts – fetches emails for personal email accounts;
+* CheckInboundEmails – fetches emails for group email accounts;
+* Cleanup – performs cleanup, completely deletes removed records;
+* ProcessMassEmail – sends mass emails;
+* ProcessWebhookQueue – sends webhooks;
+* SendEmailNotifications
+* SendEmailReminders
+* SubmitPopupReminders
+* ControlKnowledgeBaseArticleStatus
+
+To print all available jobs run:
-Examples:
```
-php command.php run-job Cleanup
-php command.php run-job ProcessMassEmail
+bin/command app-info --jobs
```
+Some jobs (CheckEmailAccounts, CheckInboundEmails) require specifying `--target-id` and/or `--target-type` options.
+
+!!! example
+
+ ```
+ bin/command run-job CheckEmailAccounts --target-id={email_account_id}
+ ```
+
+## Tips
+
+### Jobs stuck in running state
+
+If a process that is running a job is terminated manually before completion, the job will remain in the *Running* status for some time until the system marks it as *Failed*. When such a situation occurs for a scheduled job, it will prevent next runs from being scheduled until the hanging job is resolved. You can manually remove that problem job to resolve the problem. Under Administration > Jobs, find the job with the status *Running* and remove it.
+
+Note that this situation is more common during development and testing, and rarely occurs in production.
+
+The period after the hanging running job changes its status to *Failed* is controlled by the [config parameter](https://docs.espocrm.com/administration/config-params/#jobs-daemon) *jobPeriod*.
+
## See also
-* [Creating custom job](../development/scheduled-job.md)
+* [Custom scheduled job](../development/scheduled-job.md)
diff --git a/docs/administration/layout-manager.md b/docs/administration/layout-manager.md
index d6f8e4015..8fd0ba4f3 100644
--- a/docs/administration/layout-manager.md
+++ b/docs/administration/layout-manager.md
@@ -1,9 +1,12 @@
# Layout Management
-Layout Manager is available at Administration panel. It provides the ability to customize the appearance of detail, edit, list views as well as search filters and fields for mass-update forms.
+The Layout Manager provides the ability to customize the appearance of detail, edit, list views as well as search filters and fields for mass-update forms. Layouts for a specific entity type can be accessed from Administration > Entity Manager.
+
+In this article:
* [Layouts](#layouts)
* [Different layouts for teams & portals](#different-layouts-for-teams-portals)
+* [Custom list layouts](#custom-list-layouts)
## Layouts
@@ -27,9 +30,13 @@ The main layout for the list view. It defines columns and their parameters.
Available parameters for columns are listed below.
-#### Width (%)
+#### Width
+
+A column width in percent or pixels. Empty means auto-width.
+
+!!! note
-Width of a column in percent, empty means auto-width.
+ It's recommended to have one column without width specified.
#### Link
@@ -37,7 +44,7 @@ If checked, then a field value will be displayed as a link pointing to the detai
#### Not Sortable
-Disables an ability to sort the column.
+Disables the ability to sort the column.
#### Align
@@ -45,13 +52,19 @@ Align the column to the left or to the right.
### Detail
-The main layout for the detail view and the edit view. It defines panels, rows and cells. Cells contain fields.
+The main layout for the detail and edit views. It defines panels, rows and cells. Cells contain fields.
The row can contain 1, 2, 3 or 4 cells. To add a row with single cell, you need to add a new row and click on a minus sign on any cell.

-For panels, it's possible to specify a label, color (style) and conditions making a panel visible (since version 5.2.6).
+Edit panel parameters by clicking a pencil icon on the panel. It's possible to specify a label, color (style), conditions making a panel visible, group panels in tabs (as of v7.2).
+
+To enable detail view tabs, you need to check the *Tab-break* for panels. Enable it for panels you want to be first in a tab. All following panels will be in the same tab till the next closest tab-break panel. Specify a *Tab Label* for tab-break panels.
+
+!!! note
+
+ The *Hidden* panel parameter is not fully compatible with tabs. It's not recommended to have both tab-breaks and hidden panels on the same layout.
### List (Small)
@@ -63,11 +76,9 @@ The detail view for quick create, quick view and quick edit forms.
### Bottom Panels
-Since 5.9.0 version.
-
-Relationship panels and Stream panel displayed on the detail view at the bottom. Panels can be re-ordered.
+Panels displayed in the bottom of the detail view. These are Relationship panels, the Stream panel and other panels defined for a concrete entity type. Panels can be re-ordered and grouped by tabs.
-Parameters are listed below.
+Available parameters are listed below.
#### Style
@@ -92,7 +103,7 @@ The list of fields available in the Mass Update form.
### Side Panels
-Side panels for Detail, Edit, Detail Small, Edit Small forms. Provides an ability to hide or re-order the list of panels: Activities, History, Tasks and others. Panels can be colorized by the Style parameter. You can define dynamic-logic conditions that will determine whether the panel is visible.
+Side panels for Detail, Edit, Detail Small, Edit Small forms. Provides the ability to hide or re-order panels. Panels can be colorized by the Style parameter. You can define dynamic-logic conditions that will determine whether the panel is visible.
Parameters are listed below.
@@ -114,7 +125,11 @@ Available for entity types with the enabled Kanban view.
### Side Panel Fields
-The list of fields displayed in the top side panel. By default, there are *Assinged User* and *Teams* fields.
+The list of fields displayed in the top side panel. By default, there are *Assigned User* and *Teams* fields.
+
+!!! warning
+
+ Avoid having the same field added in both the Side Panel Fields layout and the Detail layout. It won't function properly.
### Additional layouts
@@ -122,14 +137,24 @@ Some entity types contain additional layouts: Convert Lead, List for Account and
## Different layouts for teams & portals
-Available since version 5.9.0.
-
*Layout Sets* provide the ability to have different layouts for teams & portals.
-Admin can create Layout Set record, where they will define specific layouts that will differ from standard ones (defined in Layout Manager). Layout Sets are available at Administration > Layout Sets.
+An admin can create a Layout Set record where they will define specific layouts that will differ from standard ones (which are defined in the Entity Manager). Layout sets are available at Administration > Layout Sets.
+
+A Team and Portal have the *Layout Set* link fields.
+
+For internal users (*regular* & *admin*), a Layout Set is applied through the *Default Team* (User > Default Team > Layout Set). The Team should have the Layout Set specified. That team should be set as a *Default Team* for the User.
+
+For *portal* users, the Layout Set is applied through the *Portal* record.
+
+A Layout Set can also be specified for a specific User in the *Layout Set* field. Only *regular* and *admin* users have this field available.
+
+!!! note
+
+ You need to clear cache (Administration > Clear Cache) after configuring layout sets.
-*Team* & *Portal* have *Layout Set* link fields.
+## Custom list layouts
-For internal users (regular & admin), Layout Set is applied through *Default Team*. User > Default Team > Layout Set. The team should have Layout Set specified. That team should be set as a default team for the user.
+*As of v8.0.*
-For portal users, Layout Set is applied through *Portal* record.
+An admin can create custom list layouts. These layouts can then be selected for specific relationship panels (at Administration > Entity Manager > {Entity Type} > Relationships).
diff --git a/docs/administration/ldap-authorization-for-ad.md b/docs/administration/ldap-authorization-for-ad.md
index 4f925cac5..e7243768b 100644
--- a/docs/administration/ldap-authorization-for-ad.md
+++ b/docs/administration/ldap-authorization-for-ad.md
@@ -2,24 +2,23 @@
Example of configuration LDAP authorization for the Active Directory server. The full guide to configuring LDAP authorization is described [here](ldap-authorization.md).
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
+- Host: `espo.local`
+- Port: `389`
+- Full User DN: `cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local`
+- Password: `******`
+- Username Attribute: `sAMAccountName`
+- User ObjectClass: `person`
+- Account Canonical Form: `Principal` or `Username`
+- Bind Requires DN: `no`
+- Base DN: `cn=espo-users,ou=users,dc=espo,dc=local`
+- Account Domain Name: `espo.local`
+- Account Domain Name Short: `ESPO`
+- Create User in EspoCRM: `yes`
+- User First Name Attribute: `givenName`
+- User Last Name Attribute: `sn`
+- User Title Attribute: `title`
+- User Email Address Attribute: `mail`
+- User Phone Number Attribute: `telephoneNumber`
-
+
+
diff --git a/docs/administration/ldap-authorization-for-openldap.md b/docs/administration/ldap-authorization-for-openldap.md
index 27353b148..d9cb4e41e 100644
--- a/docs/administration/ldap-authorization-for-openldap.md
+++ b/docs/administration/ldap-authorization-for-openldap.md
@@ -2,22 +2,20 @@
Example of configuration LDAP authorization for OpenLDAP server. The full guide to configuring LDAP authorization is described [here](ldap-authorization.md).
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
+- Host: `espo.local`
+- Port: `389`
+- Full User DN: `cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local`
+- Password: `******`
+- Username Attribute: `uid`
+- User ObjectClass: `inetOrgPerson`
+- Account Canonical Form: `Dn`
+- Bind Requires DN: `yes`
+- Base DN: `cn=espo-users,ou=users,dc=espo,dc=local`
+- Create User in EspoCRM: `yes`
+- User First Name Attribute: `givenName`
+- User Last Name Attribute: `sn`
+- User Title Attribute: `title`
+- User Email Address Attribute: `mail`
+- User Phone Number Attribute: `telephoneNumber`
-
+
diff --git a/docs/administration/ldap-authorization.md b/docs/administration/ldap-authorization.md
index 08c30bce1..0dc88df12 100644
--- a/docs/administration/ldap-authorization.md
+++ b/docs/administration/ldap-authorization.md
@@ -1,57 +1,80 @@
# LDAP Authorization
-In this guide, we will show how to configure LDAP authorization for EspoCRM. Let’s go.
+* [LDAP configuration](#ldap-configuration)
+* [Active Directory configuration](ldap-authorization-for-ad.md)
+* [OpenLDAP configuration](ldap-authorization-for-openldap.md)
+* [Troubleshooting](#troubleshooting)
+
+## LDAP configuration
+
+In this guide, we will show how to configure LDAP authorization for EspoCRM.
Go to your LDAP server and create a base DN for the EspoCRM users like:
+
```
cn=espo-users,ou=users,dc=espo,dc=local
```
We have to create a system user that will have access to the users DN (“cn=espo-users,ou=users,dc=espo,dc=local”). So, the full DN for this system user will be:
+
```
cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
```
-Now, we can add LDAP user to access EspoCRM. E.g. Espo Tester with the username “tester” inside the “cn=espo-users,ou=users,dc=espo,dc=local” DN. Please note: to be able to use this login format for EspoCRM, you have to specify the “Username Attribute” and “Base DN” options.
-Then, go to EspoCRM Authentication settings in the Administrator panel, select the `LDAP` method and fill in the LDAP details:
+Now, we can add LDAP user to access EspoCRM. E.g. Espo Tester with the username “tester” inside the “cn=espo-users,ou=users,dc=espo,dc=local” DN. Note: to be able to use this login format for EspoCRM, you have to specify the “Username Attribute” and “Base DN” options.
-
+Then, go to EspoCRM Authentication settings in the Administrator panel, select the `LDAP` method and fill in the LDAP details:
+
+
* Host – LDAP IP or host name.
* Port – connection port.
* Auth – access credentials for the LDAP server:
- * Full User DN – the full system user DN which allows to search other users.
- * Password – the password to access the LDAP server.
-* Security – SSL or TSL protocol.
-* Username Attribute – the attribute to identify the user. For Active Directory, it can be “userPrincipalName” or “sAMAccountName”.
+* Full User DN – the full system user DN which allows searching other users.
+ * Password – the password to access the LDAP server.
+ * Security – SSL or TSL protocol.
+* Username Attribute – The attribute to identify the user.
+E.g. for Active Directory: "userPrincipalName" or "sAMAccountName",for OpenLDAP: "uid" .
* Account Canonical Form – the type of your account canonical form. There are 4 options:
- * Dn – the form in the format `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – the form `tester`.
- * Backslash – the form `COMPANY\tester`.
- * Principal – the form `tester@company.com`.
+ * `Dn` – the form in the format `CN=tester,CN=Espocrm,DC=company,DC=com`.
+ * `Username` – the form `tester`.
+ * `Backslash` – the form `COMPANY\tester`.
+ * `Principal` – the form `tester@company.com`.
+* User ObjectClass – ObjectClass attribute for searching users. E.g. for Active Directory: "person", for OpenLDAP: "inetOrgPerson".
* Bind Requires Dn – if there is a need to format the username in the DN form.
* Base Dn – the default base DN which is used for searching users.
-* User Login Filter – the filter which allows to restrict users who are able to use EspoCRM. E.g. `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – The domain which is used for authorization the LDAP server.
-* Account Domain Name Short – The short domain which is used for authorization the LDAP server.
+* User Login Filter – the filter which allows you to restrict users who are able to use EspoCRM. E.g. `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
* Try Username Split – the option to split a username with the domain.
* Opt Referrals – if referrals should be followed to the LDAP client.
* Create User in EspoCRM – this option allows EspoCRM to create a user from the LDAP.
- * User First Name Attribute – LDAP attribute which is used to determine the user’s first name.
- * User Last Name Attribute – LDAP attribute which is used to determine the user’s last name.
- * User Title Attribute – LDAP attribute which is used to determine the user title.
- * User Email Address Attribute – LDAP attribute which is used to determine the user’s email address.
- * User Phone Number Attribute – LDAP attribute which is used to determine the user’s phone number.
+* User First Name Attribute – LDAP attribute which is used to determine the user’s first name.
+* User Last Name Attribute – LDAP attribute which is used to determine the user’s last name.
+* User Title Attribute – LDAP attribute which is used to determine the user title.
+* User Email Address Attribute – LDAP attribute which is used to determine the user’s email address.
+* User Phone Number Attribute – LDAP attribute which is used to determine the user’s phone number.
+* User Teams – Teams for created user. For more, see user profile.
+* User Default Team – Default team for created user. For more, see user profile.
+* Use LDAP Authentication for Portal Users – Allow portal users to use LDAP authentication instead of Espo authentication.
+* Default Portals for a Portal User – Default Portals for created Portal User.
+* Default Roles for a Portal User – Default Roles for created Portal User.
+
+!!! note
+
+ For the **first** LDAP user login (both system and portal) the `Create User in EspoCRM` parameter should be checked. Otherwise it won't be able to login.
Now, go to the login page and enter user credentials.
-
+
User has been authenticated and automatically created in the EspoCRM.
-## Configuration instructions based on your server
+## Troubleshooting
+
+### Error: 0x31 (Invalid credentials; 80090308: LdapErr: DSID-0C09041C, comment: AcceptSecurityContext error, data 52e, v4563)
-* [Active Directory server](ldap-authorization-for-ad.md)
-* [OpenLDAP server](ldap-authorization-for-openldap.md)
+This error occurs when the wrong `Account Canonical Form` or `Username Attribute` are specified.
+The correct values are:
+- Account Canonical Form: `Principal` or `Username`.
+- Username Attribute: `sAMAccountName`
-You can read more information about configuring LDAP on the [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/) page, as EspoCRM uses this library.
+The full Active Directory configuration, see in the [documentation](ldap-authorization-for-ad.md).
diff --git a/docs/administration/log.md b/docs/administration/log.md
new file mode 100644
index 000000000..343ac3ae5
--- /dev/null
+++ b/docs/administration/log.md
@@ -0,0 +1,111 @@
+---
+search:
+ boost: 3
+---
+
+# Log
+
+## Default log
+
+By default, the application log files are automatically created in the directory `{ESPO_ROOT}/data/logs/`.
+
+## Parameters
+
+Log parameters are available in the file `data/config-internal.php`.
+
+Parameters example:
+
+```
+'logger' => [
+ 'level' => 'NOTICE', // DEBUG, INFO, NOTICE, WARNING, ERROR
+ 'maxFileNumber' => 30,
+ 'printTrace' => true, // to print an exception backtrace,
+ 'sql' => true, // log SQL queries
+ 'databaseHandler' => true, // the log will be available in the admin UI
+ 'databaseHandlerLevel' => 'NOTICE', // overrides the level for the database handler
+],
+```
+
+## Trace printing
+
+Parameter: `printTrace`.
+
+If enabled, the backtrace will be printed to the log when an exception is occurred. Note that in some cases an exception is caught and handled within the application, the trace won't be printed in this case.
+
+!!! warning
+
+ It is not recommended to enable trace printing on the production environment, as it may expose sensitive data to the log.
+
+## Admin UI
+
+Parameter: `databaseHandler`.
+
+*As of v8.3.*
+
+It may be convenient to check the logs right from the application UI. The log is available under: Administration > App Log. By default, this feature is disabled – log entries are not created in the database table.
+
+To make log records available in the admin UI, set the *databaseHandler* parameter to true.
+
+!!! note
+
+ Some log entries may be not available from the UI. For example, those that happened during upgrade or before database connection was established.
+
+## SQL queries
+
+Parameter: `sql`.
+
+*As of v7.4.*
+
+!!! note
+
+ Not to be enabled on production.
+
+If the parameter *sql* is set to true, all executed SQL queries will be printed to the log. Requires *INFO* or *DEBUG* level.
+
+If *sql* is set to true, and the log level is *NOTICE* or higher, than only failed queries will be logged. As of v8.2.
+
+## Handlers
+
+EspoCRM uses [Monolog](https://github.com/Seldaek/monolog) library for logging. The library is shipped with many handlers. Developer can also create custom handlers.
+
+It's possible to configure the list of handlers Espo should use for logging.
+
+In `data/config-internal.php`:
+
+```
+'logger' => [
+ 'level' => 'NOTICE',
+ 'handlerList' => [
+ [
+ 'className' => 'Espo\\Core\\Log\\Handler\\EspoRotatingFileHandler',
+ 'params' => [
+ 'filename' => 'data/logs/espo.log',
+ ],
+ 'level' => 'NOTICE',
+ 'formatter' => [
+ 'className' => 'Monolog\\Formatter\\LineFormatter',
+ 'params' => [
+ 'dateFormat' => 'Y-m-d H:i:s',
+ ],
+ ],
+ ],
+ [
+ 'loaderClassName' => 'Espo\\Core\\Log\\EspoRotatingFileHandlerLoader',
+ 'params' => [
+ 'filename' => 'data/logs/test-warning.log',
+ ],
+ 'level' => 'WARNING',
+ ],
+ ],
+],
+```
+
+Handlers can be defined with a handler class name or a loader class name. The loader class instantiates a handler class.
+This allows initializing constructor parameters for the handler. It can be helpful if you need to pass some parameters to the handler's constructor and these parameters cannot be resolved with the DI mechanism.
+The loader class must implement `Espo\Core\Log\HandlerLoader` interface. It's possible to pass dependencies to the loader via the DI mechanism.
+
+!!! note
+
+ By specifying `handlerList` in the config, the default handler stops from being used.
+
+You can find the list of handlers supported by Monolog [here](https://github.com/Seldaek/monolog/tree/main/src/Monolog/Handler).
diff --git a/docs/administration/maps.md b/docs/administration/maps.md
index 5e84b644c..096646a9f 100644
--- a/docs/administration/maps.md
+++ b/docs/administration/maps.md
@@ -4,38 +4,31 @@ EspoCRM supports Google Maps out of the box.
## Google Maps
-### Api Key
+### API Key
-You need to specify Api Key to use Google Maps (Administration > Integration > Google Maps).
+To use Google Maps, you need to specify the API Key (at Administration > Integration > Google Maps). Geocoding API, Maps JavaScript API, Maps Static API must be enabled in Google Maps Platform.
+### Map ID
-## Showing map for address field
-
-### As a field on detail view
-
-Every Address field has its corresponding Map field. All you need is to put it on Detail layout. It uses Google Maps service.
+Create a Map ID under Google Cloud Console > Map Management.
-Administration > Layout Manager > Select entity type > Detail > Drag & Drop Map field.
+## Showing map for address field
-Make the cell wide using the minus sign.
+### As a field in detail view
-You can also configure the height of your field.
+Every *Address* field has a corresponding *Map* field. You need to add it to the *Detail* layout. Administration > Entity Manager > {Entity Type} > Layouts > Detail > Drag & Drop Map field. You can make the cell wide using the minus sign.
-Administration > Entity Manager > Choose entity > Fields > find the map field and click on it > edit the height and save.
+You can also configure the height of your field. Administration > Entity Manager > {Entity Type} > Fields > find the map field and click on it > edit the height and save.
### In modal dialog
-Available since v 5.8.0.
-
-Administration > Entity Manager > Click on the needed entity type > Click on the needed address field (e.g. *Billing Address*) > Check *View Map Button* and save.
+Administration > Entity Manager > {Entity Type} > {needed address field} (e.g. *Billing Address*) > Check **View Map Button** and save.
*View Map* button should appear under the address field on the detail view. Note, that the address should contain either a city or postal code.
## Printing in PDF
-Available since v5.9.2.
-
-*googleMapsImage* helper is availabe for printing Google Maps in PDF.
+*googleMapsImage* helper is available for printing Google Maps in PDF.
Usage (in PDF Template):
@@ -43,13 +36,13 @@ Usage (in PDF Template):
{{googleMapsImage}}
```
-Printing specific address field:
+Printing a specific address field:
```
{{googleMapsImage field='shippingAddress'}}
```
-Printing specific address:
+Printing a specific address:
```
{{googleMapsImage city='New York' country='United States'}}
diff --git a/docs/administration/moving-to-another-server.md b/docs/administration/moving-to-another-server.md
index 7c954f8b3..cde42e265 100644
--- a/docs/administration/moving-to-another-server.md
+++ b/docs/administration/moving-to-another-server.md
@@ -1,14 +1,14 @@
# Moving EspoCRM to another server
-Follow these steps to move EspoCRM to another server:
+Follow these steps to move EspoCRM to another server.
### Step 1. Backup files
-Open a file manager or login via SSH to archive all available files from the EspoCRM directory. See [more details](backup-and-restore.md#step-1-backup-files).
+Open a file manager or log in via SSH to archive all available files from the EspoCRM directory. See [more details](backup-and-restore.md#step-1-back-up-files).
### Step 2. Backup your database
-The data stored in the database (MySQL, MariaDB) should be backed up. Please, follow this [recommendation](backup-and-restore.md#step-2-backup-database).
+The data stored in the database (MySQL, MariaDB or PostgreSQL) should be backed up. Follow this [recommendation](backup-and-restore.md#step-2-back-up-database).
### Step 3. Copy files and database backups to another server
@@ -19,23 +19,23 @@ Copy the backups of files and your database to a new server.
To unarchive the backup files, you can use Archive Manager or this [instruction](backup-and-restore.md#step-1-unarchive-backup-files).
Note: Files need to be placed in the web-server directory.
-### Step 5. Configure a server
+### Step 5. Configure the server
-Configure a new server based on the recommendations [here](server-configuration.md).
+Configure the new server based on the recommendations [here](server-configuration.md).
### Step 6. Correct permissions
-Set required permissions and files owner, see [here](server-configuration.md#required-permissions-for-unix-based-systems).
+Set proper permissions and file ownership, see [here](server-configuration.md#required-permissions-for-unix-based-systems).
### Step 7. Import your database backup
-First, you have to create a new database with a user in MySQL. To import your database from the backup, follow these [instructions](backup-and-restore.md#step-3-import-database-dump).
+First, you have to create a new database with a user in MySQL/MariaDB/PostgreSQL. To import your database from the backup, follow these [instructions](backup-and-restore.md#step-3-import-database-dump).
### Step 8. Correct EspoCRM configurations
-After successfully importing and configuring the server, please correct EspoCRM configurations in the file `ESPOCRM_DIRECTORY/data/config.php`:
+After successfully importing and configuring the server, correct EspoCRM config parameters in the files `data/config-internal.php` and `data/config.php`.
-database connection settings:
+Database connection settings:
```php
'database' => [
@@ -48,13 +48,13 @@ database connection settings:
],
```
-*siteUrl* - if your domain name (URL) is changed:
+Site URL, if your domain name (URL) has changed:
```php
'siteUrl' => 'https://new-link.com',
```
-default files owner (only if different):
+Default file owner (only if the new web server has a different user/group):
```php
'defaultPermissions' => [
@@ -69,6 +69,14 @@ where `www-data` is your web-server user.
Setup a [crontab](server-configuration.md#setting-up-crontab).
-Note: it should be configured under your web-server user.
+!!! note
-That's all. Now, your EspoCRM instance is running on a new server.
+ it should be configured under your web-server user.
+
+Now, your EspoCRM instance is running on the new server.
+
+## Misc
+
+### MariaDB to MySQL migration
+
+When migrating from MariaDB to MySQL, a database dump incompatibility arises. The problem is that MariaDB supports default values for TEXT column but MySQL does not. To solve this problem, you can manually remove default values for text columns in the dump file. Usually, there are not many.
diff --git a/docs/administration/multiple-assigned-users.md b/docs/administration/multiple-assigned-users.md
index a9186ff35..e660ac450 100644
--- a/docs/administration/multiple-assigned-users.md
+++ b/docs/administration/multiple-assigned-users.md
@@ -1,13 +1,13 @@
# Multiple Assigned Users
-Note: This is an experimental feature. Flawless work and compatibility with other features are not guaranteed.
+*As of v9.0.*
-Out-of-the-box EspoCRM allows to assign only one user to a certain record. It's possible to add the ability to assign multiple users for a specific entity type.
+Multiple assigned users can be enabled for custom entity types and for certain built-in entity types. Enable it at: Administration > Entity Manager > {Entity Type} > Edit > check *Multiple Assigned Users* and save.
-For this, you just need to create a many-to-many relationship between the needed entity type and the *User* entity type, with the name *assignedUsers*. Link Multiple Field must be checked.
+!!! important
-
+ Existing assigned users which are already set in the *Assigned User* field won't be transferred to the new *Assigned Users* field after enabling multiple assigned users.
-Make sure that you chose link names that do not already exist in the system.
+The maximum number of assigned users allowed per record can be set at: Administration > Entity Manager > {Entity Type} > Fields > Assigned Users > Max Item Count. By default, it's set to 10.
-Make sure that the old *Assigned User* field is not set as required (at Entity Manager > fields). Make it not required if it is.
+After enabling Multiple Assigned Users, you may need to replace the Assigned User field with the Assigned Users field in the following layouts: Mass Update, Search Filters, and List.
diff --git a/docs/administration/nginx-server-configuration.md b/docs/administration/nginx-server-configuration.md
index 8dc194595..5861b31be 100644
--- a/docs/administration/nginx-server-configuration.md
+++ b/docs/administration/nginx-server-configuration.md
@@ -1,6 +1,6 @@
# Nginx server configuration for EspoCRM
-These instructions are supplementary to the [server configuration](server-configuration.md) guidelines. Note that all configuration settings listed here are made on Ubuntu server.
+These instructions are supplementary to the [server configuration](server-configuration.md) guidelines. Note that all configuration settings listed here are made on an Ubuntu server.
## PHP requirements
@@ -8,29 +8,60 @@ To install all necessary libraries, run these commands in a terminal:
```
sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-zip php-imap php-mbstring php-curl
+sudo apt-get install php-mysql php-json php-gd php-zip php-imap php-mbstring php-curl php-exif php-ldap
sudo phpenmod imap mbstring
sudo service nginx restart
```
-## Fixing the issue 'API Error: EspoCRM API is unavailable'
+## Server configuration
-When you are trying to install EspoCRM via browser, you may encounter 'API Error: EspoCRM API is unavailable' error.
-
-To fix it, try the following steps **one by one**. After each step check if the issue is solved. If it works, then further steps are not needed.
-
-### 1. Enable rewrite rules in Nginx server
-
-Add this code to your Nginx server block config file (`/etc/nginx/sites-available/YOUR_SITE`) inside **server** block:
+Nginx config file example:
```
server {
- # ...
+ listen 80 default_server;
+ listen [::]:80 default_server;
+
+ server_name localhost; # domain name
+
+ charset utf-8;
+ index index.html index.php;
client_max_body_size 50M;
- location / {
- try_files $uri $uri/ /index.php?$query_string;
+ keepalive_timeout 300;
+ types_hash_max_size 2048;
+
+ server_tokens off;
+ fastcgi_send_timeout 300;
+ fastcgi_read_timeout 300;
+
+ gzip on;
+ gzip_types text/plain text/css text/javascript application/javascript application/json;
+ gzip_min_length 1000;
+ gzip_comp_level 9;
+
+ root /path-to-espo/public; # path to public dir
+
+ location /client {
+ root /path-to-espo; # path to espocrm root dir
+ autoindex off;
+
+ location ~* ^.+\.(js|css|png|jpg|svg|svgz|jpeg|gif|ico|tpl)$ {
+ access_log off;
+ expires max;
+ }
+ }
+
+ location = /favicon.ico { access_log off; log_not_found off; }
+ location = /robots.txt { access_log off; log_not_found off; }
+
+ location ~ \.php$ {
+ fastcgi_pass espocrm-php:9000;
+ include fastcgi_params;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param QUERY_STRING $query_string;
}
location /api/v1/ {
@@ -49,76 +80,40 @@ server {
}
}
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
+ location ~ /(\.htaccess|\web.config|\.git) {
deny all;
}
}
```
-If you don’t have this file, you have to create it. For this open a terminal and run the command:
+You need to change `/path-to-espo` to the absolute path of your EspoCRM instance.
+
+What this config does:
+
+* sets the document root to `/path-to-espo/public/`;
+* redirects `/client/` requests to `/path-to-espo/client/` (as the *client* dir is located outside of the *public* dir);
+* adds some rewrite rules.
+
+Config file path: `/etc/nginx/sites-available/YOUR_SITE`. If you don’t have this file, you have to create it. For this, open the terminal and run the command:
```
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
```
-And add the code listed above. For more information on how to configure a new Virtual Host on Nginx, please read this [guidelines](nginx-virtual-host.md).
+For more information on how to configure the new virtual host on Nginx, read this [guidelines](nginx-virtual-host.md).
-Run this command in a terminal to check if everything is fine:
+Run this command in the terminal to check if everything is fine:
```
sudo nginx -t
```
-If so, run the command to restart nginx server:
+If so, run the command to restart the nginx server:
```
sudo service nginx restart
```
-### 2. Add RewriteBase path
-
-Open a file /ESPOCRM_DIRECTORY/api/v1/.htaccess and replace the following line:
-
-```
-# RewriteBase /
-```
-with
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
+## See also
-where REQUEST_URI is a part of URL, e.g. for 'http://example.com/espocrm/', REQUEST_URI is 'espocrm'.
+To configure a new Virtual Host on Nginx, read this [guidelines](nginx-virtual-host.md).
diff --git a/docs/administration/nginx-virtual-host.md b/docs/administration/nginx-virtual-host.md
index db1b766d6..775b3a309 100644
--- a/docs/administration/nginx-virtual-host.md
+++ b/docs/administration/nginx-virtual-host.md
@@ -1,4 +1,4 @@
-# Configuring a Virtual Host on Nginx for EspoCRM
+# Configuring Virtual Host on Nginx
In this guide we will show how to configure a virtual host on Nginx for EspoCRM on Ubuntu server.
@@ -10,92 +10,86 @@ To create this file, open a terminal and run the command:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
```
-Now, open this file (/etc/nginx/sites-available/espocrm.conf) and modify the code following the format printed below (some settings may be different based on your configuration):
+Now, open this file (`/etc/nginx/sites-available/espocrm.conf`) and modify the code following the format printed below (some settings may be different depending on your configuration).
```
server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
+ listen 80 default_server;
+ listen [::]:80 default_server;
+
+ server_name localhost; # domain name
+
+ charset utf-8;
+ index index.html index.php;
+
+ client_max_body_size 50M;
+
+ keepalive_timeout 300;
+ types_hash_max_size 2048;
+
+ server_tokens off;
+ fastcgi_send_timeout 300;
+ fastcgi_read_timeout 300;
+
+ gzip on;
+ gzip_types text/plain text/css text/javascript application/javascript application/json;
+ gzip_min_length 1000;
+ gzip_comp_level 9;
+
+ root /path-to-espo/public; # path to public dir
+
+ location /client {
+ root /path-to-espo; # path to espocrm root dir
+ autoindex off;
+
+ location ~* ^.+\.(js|css|png|jpg|svg|svgz|jpeg|gif|ico|tpl)$ {
+ access_log off;
+ expires max;
+ }
+ }
+
+ location = /favicon.ico { access_log off; log_not_found off; }
+ location = /robots.txt { access_log off; log_not_found off; }
+
location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
+ fastcgi_pass espocrm-php:9000;
+ include fastcgi_params;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param QUERY_STRING $query_string;
}
-
+
location /api/v1/ {
if (!-e $request_filename){
rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
}
}
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
+
+ location /portal/ {
+ try_files $uri $uri/ /portal/index.php?$query_string;
}
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
+
+ location /api/v1/portal-access {
+ if (!-e $request_filename){
+ rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
}
}
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
+
+ location ~ /(\.htaccess|\web.config|\.git) {
deny all;
}
}
```
+You need to change `/path-to-espo` to the absolute path of your EspoCRM instance.
+
## Enable this server block
Create a symbolic link:
```
sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
+```
Run this command to check if everything is fine:
@@ -117,4 +111,4 @@ If you added a local domain, you have to configure it on your local computer (no
192.168.1.1 espocrm.local # specify the IP address of your Nginx server
```
-For Windows, please follow these [instructions](http://support.microsoft.com/kb/923947).
+For Windows, follow these [instructions](http://support.microsoft.com/kb/923947).
diff --git a/docs/administration/oidc.md b/docs/administration/oidc.md
new file mode 100644
index 000000000..e9da4b4ce
--- /dev/null
+++ b/docs/administration/oidc.md
@@ -0,0 +1,68 @@
+# OpenID Connect (OIDC) Authentication
+
+*As of v7.3.*
+
+EspoCRM supports authentication over the OIDC protocol. A user can log in to multiple systems (that your business uses) with a single account. In other words, users can authenticate to Espo using identity providers that support OpenID Connect.
+
+!!! note
+
+ EspoCRM cannot be used as an identity provider. This article is about configuring EspoCRM to use a 3rd party identity provider for authentication.
+
+Features:
+
+* User creation. Optional. If a user does not exist in Espo, it will be created upon the first login.
+* Team mapping. Espo teams are mapped against identity provider's groups. The Espo user is automatically associated with the corresponding teams.
+* User profile and user teams sync. Optional. On every login, the user profile data is automatically synced with the provider's data.
+* The ability to choose a claim that will be used as a username.
+* Fallback login method. The ability to use the default Espo method. Can be enabled for admins or for both regular users and admins.
+* For admins, the OIDC method can be disabled so that only the fallback method is allowed.
+* Logout redirect. When a user is logging out from Espo, the identity provider session is cleared.
+* Backchannel logout. The ability to forcibly log out a user from Espo. Available under `api/v1/backchannelLogout` API endpoint.
+
+Details:
+
+* Espo's 2-factor authentication does not work with OIDC. Consider using 2FA of your identity provider.
+* The *userName* field length may need to be increased up to 255 in some cases (by default, Espo has the limit 50).
+* Supported signing algorithms: RS256, RS384. RS512, HS256, HS384, HS512. Developers can add implementations of other algorithms in an upgrade-safe manner.
+* *client_secret_jwt* and *private_key_jwt* [methods](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication) are not supported. You might need to enable *client_secret_post* method for providers that apply a JWT method by default (e.g. Keycloak).
+
+## Setting up
+
+1. Create an application in your identity provider.
+2. In EspoCRM at Administration > Authentication, select the *OIDC* method. Below, on the same form, a *OIDC* panel will appear.
+ * Copy the *Client ID* and the *Client Secret* from the identity provider to Espo.
+ * Copy the *Authorization Redirect URI* from Espo and add it to a corresponding field on the identity provider.
+ * Copy required endpoints (URLs) from the identity provider to Espo.
+ * Save the form in Espo.
+
+## Team mapping
+
+If your identity provider users have groups, it's reasonable to map them against Espo teams. When an Espo user is created (upon signing in the first time) or synced, corresponding teams will be assigned to that user according to the configured team mapping.
+
+Note that instead of 'group', the provider may use terms like 'team', 'role', or another equivalent designation.
+
+You need to specify the *Group Claim*, the [claim](https://en.wikipedia.org/wiki/JSON_Web_Token) that will be carrying the information about user groups. Some identity providers don't include the group claim in the JWT payload by default and you need to do some settings to have it.
+
+## Setting up for portals
+
+*As of v7.4.*
+
+1. Create an application in your identity provider.
+2. In EspoCRM, at Administration > Authentication Providers, create a provider.
+3. In EspoCRM, edit the Portal record, select the Authentication Provider.
+
+## Auth0
+
+1. Set the *Group Claim* to `http://www.myexample.com/roles` in Espo.
+2. Create [a rule](https://auth0.com/docs/manage-users/access-control/sample-use-cases-actions-with-authorization?_ga=2.226983773.1572279349.1664444295-1913114833.1664024344&_gl=1*1y6ck81*rollup_ga*MTkxMzExNDgzMy4xNjY0MDI0MzQ0*rollup_ga_F1G3E656YZ*MTY2NDQ1ODY2Mi44LjEuMTY2NDQ2MzU5OS40OS4wLjA.#add-user-roles-to-tokens) to include the roles claim in the JWT.
+
+## Debugging
+
+Set the *DEBUG* or *INFO* mode for the [log](log.md). More information will be printed to the log. It can be useful to see what values is sent in JWT tokens (printed to the log), especially when configuring the team mapping.
+
+## Additional config parameters
+
+Can be set manually in `data/config.php`.
+
+* oidcAuthorizationMaxAge – integer;
+* oidcJwksCachePeriod – string (default: `'10 minutes'`);
diff --git a/docs/administration/passwords.md b/docs/administration/passwords.md
new file mode 100644
index 000000000..ce471e9a6
--- /dev/null
+++ b/docs/administration/passwords.md
@@ -0,0 +1,37 @@
+# Passwords
+
+## New users
+
+When an administrator creates a new user, there are two options for password generation:
+
+* Let the user set the password by leaving the password field empty. The user must have a valid email address. Upon creation, an email with a unique link will be sent to the user.
+* Specify the password for the user. In this case, checking 'Send Email with Access Info to User' will send the password in an email to the user. This method is not recommended due to security concerns.
+
+## Existing users
+
+An administrator can send a password change link to an existing user. The user will receive an email with a link where they can specify a new password. Note that this option is not available for users without an email address.
+
+
+
+The administrator can also generate a new password for the user from the menu. The new password will be sent in an email. This way is not recommended as it's not secure.
+
+## Password recovery
+
+Users can reset their password from the login form by clicking 'Forgot Password?' link. They will be promted to enter their username and email address. If the credentials are correct, they will receive an email with a unique link. By following the link, they will be able to specify a new password. Note that the link will be active only for 3 hours and the user is not permitted to send new password change requests during that period.
+
+
+
+An administrator can disable the ability to recover passwords at Administration > Authentications > Passwords. It can be disabled for all users, for admin users or for internal users.
+
+## Password strength
+
+An administrator can configure password strength settings at Administration > Authentications > Passwords. Available parameters:
+
+* Minimum password length;
+* Number of letters required in password;
+* Password must contain letters of both upper and lower case;
+* Number of digits required in password.
+
+## See also
+
+* [Password config parameters](config-params.md#passwords)
diff --git a/docs/administration/performance-tweaking.md b/docs/administration/performance-tweaking.md
index fd43640bc..2a4c81c50 100644
--- a/docs/administration/performance-tweaking.md
+++ b/docs/administration/performance-tweaking.md
@@ -1,27 +1,25 @@
# Performance Tweaking
-## Disabling total count on list view
-
-It is relevant if there are a lot of records of a specific entity type in the database. In this case, it's reasonable to disable displaying count on the list view of that entity type, since COUNT is a very slow operation in MySQL.
-
-To disable: Administration > Entity Manager > edit specific entity type > check *Disable record count*.
-
## Recommendations
-* SSD is preferred over HHD.
+* SSD is preferred over HDD.
* Dedicated server is preferred over shared.
* More RAM can be helpful if your database grows.
## Database indexes
-By default, EspoCRM has some pre-defined indexes. As your database gets bigger, it's reasonable to create new indexes. What exactly indexes are needed depends on how you use CRM and how you customized it: what custom fields are created, default record orders are set, reports are often run, searches are usually performed, etc.
+By default, EspoCRM has some pre-defined indexes. As your database gets bigger, it's reasonable to create new indexes. What exactly indexes are needed, depends on how you use CRM and how you customized it: what custom fields are created, default record orders are set, reports are often run, searches are usually performed, etc.
* You need indexes for fields that are used for a default order.
* You need indexes for fields that are often used in filters (reports & regular searches).
-See article about [how to create indexes](../development/db-indexes.md).
+See the article on [how to create indexes](../development/db-indexes.md).
-## MySQL params
+## Database choice
+
+Filters by teams, relations, multi-enums perform faster in MariaDB and PostgreSQL than in MySQL (as of the date we performed tests).
+
+## MySQL and MariaDB parameters
#### innodb_buffer_pool_size
@@ -29,7 +27,7 @@ It's recommended to set a value that is about 70% of your RAM.
#### sort_buffer_size
-You can consider increasing this param to speed up ORDER BY or GROUP BY. [See more](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_sort_buffer_size).
+You may consider increasing this param to speed up ORDER BY or GROUP BY. [See more](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_sort_buffer_size).
#### innodb_log_file_size
@@ -39,13 +37,26 @@ Should be large enough. [See more](https://dev.mysql.com/doc/refman/8.0/en/innod
We recommend to set it to `2`.
+## Misc
+
+### Disabling total count on list view
+
+It is relevant if there are a lot of records of a specific entity type in the database. In this case, it can be reasonable to disable displaying the record count in the list view for that entity type, since the COUNT function may perform very slow in MySQL and MariaDB.
+
+To disable: Administration > Entity Manager > {entity type} > Edit > check *Disable record count*.
+
+### Use full-text search
+
+Create [full-text search](../user-guide/text-search.md#full-text-search) indexes for large tables. It will improve record lookup.
+
## PHP configuration
### Preloading
-Since EspoCRM v6.0.0 you can use a [preloading](https://www.php.net/manual/en/opcache.preloading.php). The file `preload.php` is available at the root directory.
+You can use a [preloading](https://www.php.net/manual/en/opcache.preloading.php). The file `preload.php` is available at the root directory.
-Important: Preloading must be disabled before upgrading and extension installation.
+Using preloading is not likely to bring a significant performance boost. The database usually is the bottleneck in applications like CRM.
-Note: Using preloading is not likely to bring a significant performance boost. The database usually is a bottleneck in applications like CRM.
+!!! important
+ Preloading must be disabled before upgrading and extension installation.
diff --git a/docs/administration/phone-numbers.md b/docs/administration/phone-numbers.md
new file mode 100644
index 000000000..0d460d9e3
--- /dev/null
+++ b/docs/administration/phone-numbers.md
@@ -0,0 +1,17 @@
+# Phone Numbers
+
+## International phone numbers
+
+The international phone numbers functionality can be enabled or disabled at Administration > Settings. When enabled, all phone number values are stored in the international format, e.g. *+111111111111*.
+
+Features:
+
+* A user is able to select country code when entering a number in a phone number field.
+* Appropriate formatting is applied when a phone number is displayed.
+* Validation is applied when saving a phone number, not allowing to save a not valid number.
+
+It is possible to define preferred country codes at Administration > Settings. This will avoid the need to enter the same country code when operating in a specific region.
+
+When importing records, there is the ability to specify a regional telephone code, so that values in a regional format will be automatically converted to international. The same functionality exists for the Lead Capture feature.
+
+
diff --git a/docs/administration/portal.md b/docs/administration/portal.md
index 69c8332c8..76ec0f073 100644
--- a/docs/administration/portal.md
+++ b/docs/administration/portal.md
@@ -1,98 +1,83 @@
+---
+search:
+ boost: 2
+---
+
# Portal
-Portal provides the ability to access specific CRM data and functions for your customers and partners. Administrators can create multiple portals. Each portal can have its own settings, dashboard, user list, access control settings.
+The Portal feature provides the ability to access specific CRM data and functions for your customers and partners. An administrator can create multiple Portals. Each Portal can have its own settings, dashboard, user list and access control settings.
+
+To create a Portal, follow Administration > Portals > *Create Portal*.
-To create portal follow Administration > Portals, click Create Portal button.
+* *Is Active*. If not checked, the Portal won't be available for anybody.
+* *Is Default*. Means that the Portal will be available by shorter URL: `https://YOUR_ESPO_URL/portal`.
+* *Roles*. Specify one or multiple Portal Roles that will be applied to Users logged into the Portal. More information about the Portal Roles is below.
+* *Tab List*. Tabs which will be shown in the navigation bar in the Portal.
+* *Dashboard Layout*. Specify dashlets that will be displayed on the home page of the Portal. Note that Portal Users can't configure their dashboard.
+* *URL*. Read-only field that displays the link you can access the Portal with.
+* *Layout Set*. Provides the ability to use different layouts from the Portal. See [more](layout-manager.md#different-layouts-for-teams-portals).
-* *Is Active*. If not checked, the portal won't be available for anybody.
-* *Is Default*. Means that the portal will be available by shorter url: `https://YOUR_ESPO_URL/portal`.
-* *Roles*. Specify one or multiple portal roles that will be applied to users logged into the portal. More information about the portal roles is below.
-* *Tab List*. Tabs which will be shown in the navigation bar.
-* *Dashboard Layout*. Specify dashlets that will be displayed on the home page of the portal. Note that portal users can't configure their dashboard.
-* *URL*. Read-only field that displays the link you can access the portal with.
-* *Layout Set*. Provides the ability to use different layouts from the portal. See more [info](layout-manager.md#different-layouts-for-teams-portals).
+In this article:
-## Portal Users
+* [Portal users](#portal-users)
+* [Portal roles](#portal-roles)
+* [Access to portal](#access-to-portal)
+* [See also](#see-also)
+
+## Portal users
Administrators can create portal users.
1. Administration > Portal Users.
-2. Click *Create Portal User* button .
-3. Select Contact the portal user will be linked with or *Proceed w/o Contact*
+2. Click *Create Portal User* button.
+3. Select Contact the Portal User will be linked with or *Proceed w/o Contact*
4. Fill needed fields on the form and click *Save*.
-Portal user should be linked to Portal record to be able to access that portal.
+A Portal User should be linked to a Portal record in order to be able to access that Portal.
-Portal users can have one or multiple additional *Portal Roles*. These roles will be merged with roles specified for a portal.
+Portal Users can have one or multiple additional *Portal Roles*. These roles will be merged with roles specified for a Portal.
-Portal users can have a specific *Dashboard Layout*. It allows certain users to have a specific layout that differs from the default portal layout.
+Portal Users can have a specific *Dashboard Layout*. It allows certain users to have a specific layout that differs from the default Portal's layout.
-## Portal Roles
+## Portal roles
-Portal roles are similar to regular roles in EspoCRM but with a few distinctions.
+Portal Roles are similar to regular Roles in EspoCRM but with a few distinctions.
* not-set ‒ Denies access.
* own ‒ Records created by the user. E.g. a portal user created some case and this case is owned by this user.
-* account ‒ Records related to the account the portal user is related to. Relation (link) should be named `account` or `accounts`.
-* contact ‒ Records related to the contact the portal user is related to. Relation (link) should be named `contact` or `contacts`.
-
-*Assigned User* and *Teams* fields are read-only for portal users.
-
-Portal roles can be applied to:
-
-* Portal ‒ all users of the portal will receive this role (multiple roles are merged);
-* Portal User ‒ to grant certain users specific permissions.
+* account ‒ Records related to the account the portal user is related to.
+* contact ‒ Records related to the contact the portal user is related to.
-### Example
-
-*Portal users should be able to create cases, view cases related to their account; they should be able to view knowledge base.*
-
-1. Open Create Portal Role form (Administration > Portal Roles > Create Role).
-2. Enable access to Cases, set: *create - yes, read - account, edit - no, delete - no, stream - account*.
-3. Enable access to Knowledge Base, set: *create - no, read - account, edit - no, delete - no*.
-4. Edit your portal record (Administration > Portals). Select your portal role in Roles field and then save.
-
-## Access to Portal
+For custom entity types, to be able to use *account* and *contact* access levels, you need (as of v9.0):
-You can find the URL for your portal in the *URL* field of the portal record. It's also possible to use server configuration tools (such as mod_rewrite) to be able to access by different url. For this case, you need to fill in 'Custom URL' field.
+1. To have relationships between your entity type and Account/Contact.
+2. To select these relations in the *ACL Account Link* and *ACL Contact Link* parameters at Administration > Entity Manager > {Entity Type} > Edit.
-### Access portal by Custom URL for Apache server
+The *Assigned User* and *Teams* fields are read-only for portal users.
-Custom URL: 'portal-host-name.com'.
+Portal Roles can be applied to:
-#### crm.portal.conf
+* Portal ‒ all users of the portal will receive this role (multiple roles applied to one Portal are merged into one);
+* Portal User ‒ to grant certain users specific permissions.
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName portal-host-name.com
+### Example
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
+*Portal Users should be able to create Cases, view Cases related to their Account; they also should be able to view Knowledge Base.*
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-```
+1. Open the *Create Portal Role* form (Administration > Portal Roles > Create Role).
+2. Enable access to Cases, set: *create – yes, read – account, edit – no, delete – no, stream – account*.
+3. Enable access to Knowledge Base, set: *create – no, read – account, edit – no, delete – no*.
+4. Edit the Portal record (Administration > Portals). Select your portal role in Roles field and then save.
-#### Mod rewrite rules
+## Access to portal
-Specify portal record ID instead of `{PORTAL_ID}`. Portal record ID can be obtained from the address bar of your web browser when you open the detail view of the portal record. Like: `https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24`. *16b9hm41c069e6j24* is the portal record ID.
+You can find the URL for your Portal in the *URL* field of the Portal record.
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name\.com$
- RewriteRule ^client - [L]
+It's possible to use server configuration tools (such as mod_rewrite) to be able to access the portal by a different URL. For this case, you need to fill in the *Custom URL* field. Note that using a different subdomain is recommended way. Prefer it over accessing the portal through the */portal* directory. See the server configuration guidelines:
- RewriteCond %{HTTP_HOST} ^portal-host-name\.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
+* [Apache configuration](portal/apache-configuration.md)
+* [Nginx configuration](portal/nginx-configuration.md)
## See also
-* [Portal ACL customization](../development/acl.md#portal-acl)
-
+* [Quick tour](https://app.supademo.com/demo/cmgajngej3dxj2noml5li5gm3)
diff --git a/docs/administration/portal/apache-configuration.md b/docs/administration/portal/apache-configuration.md
new file mode 100644
index 000000000..3d57dfcf3
--- /dev/null
+++ b/docs/administration/portal/apache-configuration.md
@@ -0,0 +1,41 @@
+# Configuring Portal in Apache
+
+It's possible to be able to access to the Portal by a different URL. You need to set the *Custom URL* field in the Portal record. For example, you can use your domain name `portal.my-company.com` to access the Portal.
+
+
+Config example:
+
+```
+DocumentRoot /path_to_espo/public/portal/
+Alias /client/ /path_to_espo/client/
+Alias /api/v1/ /path_to_espo/public/api/v1/
+
+
+ AllowOverride None
+
+
+
+ AllowOverride All
+
+
+
+ RewriteEngine On
+
+ RewriteRule .* - [E=ESPO_PORTAL_ID:{PORTAL_ID}]
+
+```
+
+* Replace `/path_to_espo/` with the absolute path of your EspoCRM instance (e.g. it can be `/var/www/html/`).
+* Replace `{PORTAL_ID}` with the ID of your Portal. The ID can be obtained from the address bar in your web browser when you open the detail view of the Portal record. E.g. in the URL `https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24`, *16b9hm41c069e6j24* is the Portal record ID.
+
+What this configuration does:
+
+* Sets the *public/portal* directory as a root directory.
+* Creates an alias to redirect */client/* requests to the *client* directory which is located outside of our webserver root.
+* Creates an alias to redirect */api/v1/* requests to the respective directory.
+* Disables *.htaccess* in the Espo root directory (as it's not needed).
+* Enables *.htaccess* in the *public* directory (which defines rewrite rules for API requests).
+* Enables *mod_rewrite*.
+* Makes the portal ID to be passed in an environment variable to let Espo know what Portal to start (as there can be multiple Portals in Espo).
+
+Note that if you use [WebSocket](../websocket.md), you also need to setup a [proxy](../websocket.md#apache) for the portal URL.
diff --git a/docs/administration/portal/nginx-configuration.md b/docs/administration/portal/nginx-configuration.md
new file mode 100644
index 000000000..683e38a2c
--- /dev/null
+++ b/docs/administration/portal/nginx-configuration.md
@@ -0,0 +1,80 @@
+# Configuring Portal in Nginx
+
+It's possible to be able to access to the Portal by a different URL. You need to set the Custom URL field in the Portal record. For example, you can use your domain name `portal.my-company.com` to access the Portal.
+
+Config example:
+
+```
+server {
+ listen 80 default_server;
+ listen [::]:80 default_server;
+
+ server_name localhost; # domain name
+
+ charset utf-8;
+ index index.html index.php;
+
+ client_max_body_size 50M;
+
+ keepalive_timeout 300;
+ types_hash_max_size 2048;
+
+ server_tokens off;
+ fastcgi_send_timeout 300;
+ fastcgi_read_timeout 300;
+
+ gzip on;
+ gzip_types text/plain text/css text/javascript application/javascript application/json;
+ gzip_min_length 1000;
+ gzip_comp_level 9;
+
+ root /path-to-espo/public/portal; # path to `public/portal` dir
+
+ location /client {
+ root /path-to-espo; # no trailing slash needed
+ autoindex off;
+
+ location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico|tpl)$ {
+ access_log off;
+ expires max;
+ }
+ }
+
+ location /api {
+ root /path-to-espo/public; # path to `public` dir
+ autoindex off;
+
+ location ~ \.php$ {
+ fastcgi_pass espocrm-php:9000;
+ include fastcgi_params;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param QUERY_STRING $query_string;
+ }
+
+ location /api/v1/portal-access {
+ if (!-e $request_filename){
+ rewrite ^/api/v1/portal-access/(.*)$ /api/v1/portal-access/index.php last; break;
+ }
+ }
+ }
+
+ location ~ \.php$ {
+ fastcgi_pass espocrm-php:9000;
+ include fastcgi_params;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param QUERY_STRING $query_string;
+
+ fastcgi_param ESPO_PORTAL_ID {PORTAL_ID}; # portal ID
+ fastcgi_param ESPO_PORTAL_IS_CUSTOM_URL "true";
+ }
+
+ location ~ /(\.htaccess|\web.config|\.git) {
+ deny all;
+ }
+}
+```
+
+* Replace `path-to-espo` with the absolute path to your EspoCRM instance.
+* Replace `{PORTAL_ID}` with the ID of your Portal. The Portal record ID can be obtained from the address bar of your web browser when you open the detail view of the Portal record. For example, in `https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24`, 16b9hm41c069e6j24 is the Portal record ID.
diff --git a/docs/administration/roles-management.md b/docs/administration/roles-management.md
index 71a4f9bc0..10c622476 100644
--- a/docs/administration/roles-management.md
+++ b/docs/administration/roles-management.md
@@ -1,44 +1,77 @@
-# Roles Management
+---
+search:
+ boost: 2
+tags:
+ - roles
+---
+
+# Role Management
+
+In this article:
+
+* [Overview](#overview)
+* [Permissions by default](#permissions-by-default)
+* [Actions](#actions)
+* [Levels](#levels)
+* [Example](#example)
+* [Special Permissions](#special-permissions)
+* [Collaborators](#collaborators)
+* [See also](#see-also)
## Overview
-In order to restrict access for some users, you need to use Roles. Administrator can manage roles in Administration panel. Each role defines access to certain areas (scopes) which is applied to users who own that role.
+Roles are used to grant or restrict access for users. An administrator can manage Roles under Administration > Roles. Each Role defines access to specific areas (scopes).
-One user can have multiple roles. Those roles can be selected for a specific user (*Roles* field of User record) and/or be inherited from the teams that the user belongs to.
+One User can have multiple Roles applied. Roles can be set in the User record (the *Roles* field) and/or be inherited from the User's Teams.
-If a user has multiple roles, then they will be merged so that the permissive rule will have a higher priority. That allows administrator to manage access level control easily and flexibly.
+When a User has multiple Roles, these Roles will be merged in a way that a more permissive rule will have a higher priority over a less permissive. This enables the ability to flexibly manage access level control.
-It's possible to see what permissions are applied to a certain user by clicking *Access* button on the user's detail view.
+It's possible to see what permissions are applied to a certain User by clicking the *Access* button on the user's detail view.

-Note: By default, users can **delete self-assigned records** that they have created during a specific period of time. It is possible to disable this ability at Administration > Settings > Allow to remove created records.
+!!! note
+
+ By default, users can **delete self-assigned records** that they have created during a specific period of time. It is possible to disable this ability at Administration > Settings > Allow to remove created records.
## Permissions by default
-By default (since 5.6.10), users have minimal access. You need to assign roles to grant users specific access levels.
+By default, Users have minimal access levels restricting almost everything. You need to assign Roles to grant Users specific access levels.
-There is the ability to grant users with full access by default by disabling 'ACL Strict Mode' in `data/config.php`:
+### Baseline role
-```
-'aclStrictMode' => false,
-```
+*As of v9.2.*
+
+It's possible to designate one role as a baseline. This role will be applied for all internal users. Other roles assigned to a user will grant permissions on top of the baseline.
+
+The baseline role can be set under: Administration > Settings > Access.
## Actions
-* Create – the ability to create records
-* Read – the ability to view records (on the list and detail views)
-* Edit – the ability to update records
-* Delete – the ability to remove records
-* Stream – the ability to see a record's stream
+* Create – ability to create records;
+* Read – ability to view records (on the list and detail views);
+* Edit – ability to update records;
+* Delete – ability to remove records;
+* Stream – ability to see a record's stream.
+
+## Levels
+
+Listed from more permissive to less permissive.
+
+* yes
+* all
+* team
+* own
+* no
## Example
-For example, a user belongs to the team 'Sales'. That team has a single role 'Salesman'. So, all users from this team will obtain the 'Salesman' role.
+We have a Team 'Sales'. That Team has a single Role 'Salesperson' (the *Roles* field of the Team). All Users from this Team will obtain the 'Salesperson' Role (as all team roles are automatically applied to users of the team).
-The 'Salesman' role is defined in the following way:
+The 'Salesperson' Role is defined in the following way:
Lead:
+
```
create – yes
read – team
@@ -48,6 +81,7 @@ stream – team
```
Opportunity:
+
```
create – yes
read – team
@@ -56,15 +90,20 @@ delete – no
stream – team
```
-Users will be able to read only those leads and opportunities which belong to the 'Sales Department' team (*Teams* field).
-The users will be able to edit only those leads and opportunities which they are assigned to or those they have created.
-The users won't be able to remove any leads or opportunities.
+Users of the 'Sales' Team:
+
+* Can create new Leads/Opportunities.
+* Are able to read only those Leads/Opportunities that are related to the 'Sales' Team (through the *Teams* field of a record).
+* Are able to edit only those Leads/Opportunities that they are assigned to.
+* Can't remove any Lead/Opportunity.
+* Have access to the Stream of Leads/Opportunities that are related to the 'Sales' Team.
-We want to give more rights to a certain user who holds a sales manager position in the company. This employee must have the ability to read/edit/delete all records from the 'Sales' team. The user should belong to our 'Sales' team. But we need to create a new role 'Sales Manager' and select this role for that user in *Roles* field.
+We want to give more rights to a certain User who holds a Sales Manager position in the company. This employee needs to have the ability to read/edit/delete all records related to the 'Sales' Team. We need to add that user to the 'Sales' Team. We also need to create a new role 'Sales Manager' and select this Role for that User (the *Roles* field of the User).
The 'Sales Manager' role is defined in the following way:
Lead:
+
```
create - yes
read – team
@@ -74,6 +113,7 @@ stream - team
```
Opportunity:
+
```
create – yes
read – team
@@ -82,43 +122,115 @@ delete – team
stream – team
```
-Our user will be able to manage all leads and opportunities from the 'Sales' team.
+Our sales manager User will be able to manage all Leads/Opportunities related to the 'Sales' Team. Under the hood this User have two roles ('Salesperson' and 'Sales Manager') merged into one in a way that a more permissive level suppresses less permissive.
## Special Permissions
### Assignment Permission
-Set this parameter to restrict the ability to re-assign records to another user and/or teams. If you set `team` - then it will be possible to assign only to users from own team(s). If `no` - users won't be able to re-assign at all.
+Set this parameter to restrict the ability to re-assign records to another User and/or Teams. If you set the parameter to *team*, users will be able to assign record only to Users from their own Teams. If you set it to *no*, users won't be able to assign at all.
-It also defines whether a user is able to post to stream of other users/teams.
+This parameter also defines whether the User is able to post to the Stream of other Users and other Teams.
### User Permission
-Allows to restrict the ability for users to view activities, calendar and stream of other users.
+Allows to view:
+
+* Stream of other Users;
+* which access to a specific record other Users have.
+
+!!! note
+
+ Allow this permission only for privileged users.
+
+### User Calendar Permission
+
+*As of v9.0.*
+
+Allows to view Calendars of other users.
### Portal Permission
-Defines access to portal information, the ability to post messages to portal users.
+Defines access to portal information, the ability to post messages to Portal Users.
+
+Users with the Portal Permission can manage followers of a specific record. Only Portal Users can be managed.
### Group Email Account Permission
-Defines access to group email accounts, the ability to send emails from group SMTP.
+Defines access to Group Email Accounts, the ability to send emails from a group SMTP.
### Export Permission
-Defines whether user have the ability to export records. (since version 4.9.0)
+Defines whether a User have the ability to export records.
+
+### Mass Update Permission
+
+Defines whether users have the ability to mass-update records.
+
+### Data Privacy Permission
+
+Allows to erase personal data.
+
+### Follower Management Permission
+
+Allows to manage followers of specific records. Users will be able to add and remove followers. Can be restricted to Users of own Teams.
+
+### Message Permission
+
+Allows to send stream messages to other Users. (as of v8.0)
+
+### Audit Permission
+
+Allows to view the Audit Log. (as of v8.2)
+
+### Mention Permission
+
+Allows to mention other Users in the Stream. (as of v8.3)
+
+### Lock Permission
+
+Allows to lock and unlock records. (as of v9.4)
## Field Level Security
Allows to control access for specific fields.
-By default, user can read all fields if one can read the record. A user can edit any field if one can edit the record. You can restrict access to specific fields using Field Level Security.
+By default, a User can read all fields if they can read the record. A User can edit any field if one can edit the record. You can restrict access to specific fields using the Field Level Security.
-In the edit view of a role record in Field Level section, click plus icon next to the specific scope, then select the needed field. Then, you will be able to specify the access level for `read` and `edit` actions. There are two options: `yes` and `no`.
+In the edit view of a Role record in the Field Level section, click plus icon next to a specific scope, then select a needed field. Then, you will be able to specify the access level for *read* and *edit* actions. There are two options: *yes* and *no*.

+## Collaborators
+
+*As of v9.0.*
+
+The Collaborators feature can be enabled for an entity type in the Entity Manager. Once enabled:
+
+* A link-multiple field *Collaborators* will be automatically created.
+* A bool filter *Shared* will be added.
+
+The administrator needs to add the *Collaborators* to the layout: Administration > Entity Manager > {Entity Type} > Layouts > Side Panel Fields.
+
+Users added as collaborators to a record will have *read* and *stream* access, provided their access level, as defined by Roles, is other than *no*.
+
+Assignees are automatically added to collaborators. This ensures that when a record is reassigned to another user, the previous assignee remains a collaborator unless explicitly removed.
+
+A user who creates a record is automatically pre-filled as a collaborator. This ensures that a user with 'own' read access will still have access to a record after assigning it to another user.
+
+Access:
+
+* Assignment Permission is required to be able to add a user to collaborators.
+* Edit access to a record is required to be able to add collaborators.
+
+Limitations:
+
+* Portal users cannot be added as collaborators.
+
+The Collaborators parameter is available for custom entities created via the Entity Manager and for the standard following entity types: Task, Case, Account, Contact, Lead, Opportunity, Document, Knowledge Base Article and Target List.
+
## See also
+* [Roles quick tour](https://app.supademo.com/embed/cmls03z6a1dl01189pv9nrmb9)
* [Security roles management in EspoCRM](https://www.espocrm.com/tips/security-roles/)
* [Multiple assigned users](multiple-assigned-users.md)
diff --git a/docs/administration/security.md b/docs/administration/security.md
new file mode 100644
index 000000000..84a98ca35
--- /dev/null
+++ b/docs/administration/security.md
@@ -0,0 +1,33 @@
+# Security recommendations
+
+## Password strength
+
+❗ Important.
+
+Configure password strength parameters (at Administration > Authentication). The minimum recommended password length is at least 10 characters (or 8 if 2FA is mandatory). Require digits, and both upper case and lower case letters.
+
+## 2-factor authentication
+
+❗ Important.
+
+Enable 2FA for users. Require regular users to set up 2FA with the corresponding parameter. Can be enabled at Administration > Authentication.
+
+## Don't use admin user
+
+Don't use an admin user for everyday work. Use a regular user instead.
+
+## Disable password recovery for admins
+
+Can be done at Administration > Authentication. If you lost admin access and want to recover your password, set 'passwordRecoveryForAdminDisabled' to *false* in `data/config.php`.
+
+## Auth token expiration
+
+Consider decreasing *Auth Token Max Idle Time*. Additionally, you can also specify *Auth Token Lifetime*.
+
+## Restrict upgrade via UI
+
+Restrict the ability to upgrade and upload extensions via the UI. Set `'adminUpgradeDisabled' => true` in `data/config-internal.php`.
+
+## IP address whitelist
+
+Consider specifying an IP address whitelist. Parameters are available at: Administration > Authentication > Access.
diff --git a/docs/administration/server-configuration.md b/docs/administration/server-configuration.md
index 0a4c151a8..4a2582327 100644
--- a/docs/administration/server-configuration.md
+++ b/docs/administration/server-configuration.md
@@ -2,16 +2,22 @@
EspoCRM can be installed on:
-* Apache ([instructions](apache-server-configuration.md)), Nginx ([instructions](nginx-server-configuration.md)), or IIS server
-* with PHP version 7.2 and later
-* MySQL 5.7 (and later), or MariaDB 10.1 (and later)
+* Webserver
+ * [Apache](apache-server-configuration.md)
+ * [Nginx](nginx-server-configuration.md)
+ * [IIS](iis-server-configuration.md)
+* PHP 8.3 - 8.5
+* Database
+ * MySQL 8.0 - 8.4
+ * MariaDB 10.3 and greater
+ * PostgreSQL 15
In this article:
* [Recommendations & requirements](#recommendations-requirements)
* [Required permissions for Unix-based systems](#required-permissions-for-unix-based-systems)
* [Setting up crontab](#setting-up-crontab)
-* [Configuration instructions based on your server](#configuration-instructions-based-on-your-server)
+* [Configuration instructions based on your server](#configuration-instructions-for-specific-web-servers)
* [See also](#see-also)
@@ -19,21 +25,29 @@ In this article:
### PHP requirements
-EspoCRM requires PHP 7.2 or later, with the following extensions:
-
-* [pdo](http://php.net/manual/en/book.pdo.php) – for database access;
-* [json](http://php.net/manual/en/book.json.php);
-* [gd](http://php.net/manual/en/book.image.php) – to manipulate images;
-* [openssl](http://php.net/manual/en/book.openssl.php) – to ensure the highest protection;
-* [zip](http://php.net/manual/en/book.zip.php) – to be able to upgrade EspoCRM and install extensions;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [iconv](http://php.net/manual/en/book.iconv.php);
-* [curl](http://php.net/manual/en/book.curl.php) – for integrations;
-* [xml](http://php.net/manual/en/book.xml.php) – for excel export;
+EspoCRM requires PHP with the following extensions:
+
+* [pdo_mysql](https://php.net/manual/en/book.pdo.php) – for database access;
+* [gd](https://php.net/manual/en/book.image.php) (with enabled FreeType support) – to manipulate images and render avatars;
+* [openssl](https://php.net/manual/en/book.openssl.php) – to ensure the highest protection;
+* [zip](https://php.net/manual/en/book.zip.php) – to be able to upgrade EspoCRM and install extensions;
+* [mbstring](https://php.net/manual/en/book.mbstring.php);
+* [iconv](https://php.net/manual/en/book.iconv.php);
+* [curl](https://php.net/manual/en/book.curl.php) – for integrations;
+* [xml](https://php.net/manual/en/book.xml.php) – for excel export;
* [xmlwriter](http://php.net/manual/en/book.xmlwriter.php) – for excel export;
-* [exif](http://php.net/manual/en/book.exif.php) – for a proper oriantion of uploaded images.
+* [exif](https://php.net/manual/en/book.exif.php) – for a proper orientation of uploaded images;
+* [bcmath](https://www.php.net/manual/en/book.bc.php) – arbitrary precision mathematics;
+
+Optional PHP extensions that could be useful:
+
+* [zmq](http://php.net/manual/en/book.zmq.php) – for WebSocket;
+* [pcntl](http://php.net/manual/en/book.pcntl.php) – for parallel job processing and daemon (Unix-like systems only);
+* [posix](http://php.net/manual/en/book.posix.php) – for Unix-like systems;
+* [ldap](http://php.net/manual/en/book.ldap.php) – for LDAP authentication;
+* [ev](https://www.php.net/manual/en/book.ev.php) – for WebSocket, if a large number of connections is expected.
-php.ini settings:
+Recommended minimum values in php.ini:
```
max_execution_time = 180
@@ -43,37 +57,26 @@ post_max_size = 50M
upload_max_filesize = 50M
```
-Optional php extensions that may be needed:
-
-* [zmq](http://php.net/manual/en/book.zmq.php) – for websocket;
-* [pcntl](http://php.net/manual/en/book.pcntl.php) – for parallel job processing and daemon (Unix-like systems only);
-* [posix](http://php.net/manual/en/book.posix.php) – for Unix-like systems;
-* [ldap](http://php.net/manual/en/book.ldap.php) – for LDAP authentication.
-
-
### Database requirements
-EspoCRM supports MySQL 5.7 or greater and MariaDB 10.1 or greater. These are no special peculiarities. All default settings are fine for EspoCRM.
+EspoCRM supports MySQL, MariaDB and PostgreSQL. There are no special requirements – the default settings work fine for EspoCRM.
-### MySQL 8 support
+### Server recommendations
-MySQL 8.0.4 has changed a default authentication method to `caching_sha2_password` which is not supported by PHP (at the time of writing). For MySQL 8 it should be changed to `mysql_native_password` method. For a user it can be done with the query:
-
-```
-CREATE USER username@localhost identified with mysql_native_password by 'password';
-```
-where username is your MySQL user, password is your MySQL user password.
+Prefer using a VPS or a dedicated server for production EspoCRM instances. Shared hosting typically imposes some limitations. Nevertheless, Espo can run on shared hosting environments quite smoothly.
## Required permissions for Unix-based systems
-**Note**: In most cases permissions are set properly after extracting EspoCRM instance from a zip package. You need only to set ownership.
+!!! note
+
+ In most cases, permissions are set properly after extracting EspoCRM instance from the zip package. You may only need to set file ownership.
### Permissions
The files and directories should have the following permissions:
-* `/data`, `/custom`, `/client/custom` – should be writable all files, directories and subdirectories (664 for files, 775 for directories, including all subdirectories and files);
-* `/application/Espo/Modules`, `/client/modules` – should be writable the current directory (775 for the current directory, 644 for files, 755 for directories and subdirectories);
+* `data`, `custom`, `client/custom` – all files, directories and subdirectories should be writable (664 for files, 775 for directories, including all subdirectories and files);
+* `bin/command` – should be executable (754);
* all other files and directories should be readable (644 for files, 755 for directories).
To set the permissions, execute these commands in the terminal:
@@ -83,15 +86,17 @@ cd
find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
find data custom client/custom -type d -exec chmod 775 {} + && find data custom client/custom -type f -exec chmod 664 {} +;
chmod 775 application/Espo/Modules client/modules;
+chmod 754 bin/command;
```
### Ownership
All files should be owned and group-owned by the webserver process. It can be *www-data*, *daemon*, *apache*, *www*, etc.
-Note: On Bitnami Stack, files should be owned and group-owned by *daemon* user.
+!!! note
+
+ On shared hosts, files should be owned and group-owned by your user account.
-Note: On shared hosts, files should be owned and group-owned by your user account.
To set the owner and group-owner, execute these commands in the terminal:
@@ -102,7 +107,7 @@ chown -R : .;
## Setting up crontab
-Note: More information about jobs in EspoCRM is available [here](jobs.md).
+More information about jobs in EspoCRM is available [here](jobs.md).
### Unix-like systems
@@ -116,6 +121,8 @@ To setup crontab on Unix-like system, take the following steps:
* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
```
+You might need to replace `/var/www/html/espocrm/` with an actual path to your instance.
+
3\. Open a terminal and run this command:
```
@@ -124,19 +131,21 @@ crontab -e -u WEBSERVER_USER
WEBSERVER_USER can be one of the following “www”, “www-data”, “apache”, etc (depends on your webserver).
-4\. Paste the copied string (from step 2) and save the crontab file (Ctrl+O, then Ctrl+X for nano editor).
+4\. Paste the copied string (from step 2) and save the crontab file (Ctrl + O, then Ctrl + X for nano editor).
### Windows
-For Windows servers you can utilize Scheduled Tasks.
+See in a separate [article](cron-on-windows.md) how to set up Cron on Windows.
-## Configuration instructions based on your server
+## Configuration instructions for specific web servers
* [Apache server configuration](apache-server-configuration.md)
* [Nginx server configuration](nginx-server-configuration.md)
+* [IIS server configuration](iis-server-configuration.md)
## See also
* [Jobs](jobs.md)
* [WebSocket](websocket.md)
* [Performance tweaking](performance-tweaking.md)
+* [Installation by script](installation-by-script.md)
diff --git a/docs/administration/sms-sending.md b/docs/administration/sms-sending.md
new file mode 100644
index 000000000..98bf9d88f
--- /dev/null
+++ b/docs/administration/sms-sending.md
@@ -0,0 +1,91 @@
+# SMS Sending
+
+EspoCRM has the built-in functionality for sending SMS, but it's not shipped with any provider implementation. The official [SMS Providers](https://github.com/espocrm/ext-sms-providers/) extension includes implementations for the following SMS providers:
+
+* Twilio
+* Spryng
+* seven
+* smstools
+* SerwerSms
+* Verimor
+* GatewayAPI
+
+Out of the box, it's possible to send SMS from a Formula script or from a PHP code. The [VoIP Integration](https://www.espocrm.com/extensions/voip-integration/) provides also the ability to send SMS through the UI (only for the Twilio provider).
+
+In this article:
+
+* [Setting up](#setting-up)
+* [Sending with formula](#sending-with-formula)
+* [Two-Factor Authentication](#two-factor-authentication)
+* [VoIP integration for Twilio](#voip-integration-for-twilio)
+
+## Setting up
+
+Download the extension package from the [GitHub repository](https://github.com/espocrm/ext-sms-providers/releases) (under the Assets section). Then upload and install the package in Espo at Administration > Extensions.
+
+After the SMS Providers extension is installed, go to Administration > SMS and select the *SMS Provider* you want to use from the dropdown list. Also, in the *SMS From Number* field, enter the number with the country code (e.g. +11111111111) from which you will be sending SMS messages.
+
+Next, go to Administration > Integrations, select your provider, and set up needed credentials and parameters.
+
+## Sending with formula
+
+It's possible to send SMS from a formula-script with the [ext\sms\send](formula/ext.md#extsmssend) function.
+
+### With Workflow
+
+*Requires [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).*
+
+With the Workflow tool it's possible to set up Espo to SMS notification on a specific condition.
+
+Create a Workflow rule with the needed trigger type and conditions. Add the *Execute Formula Script* action and paste the following formula-script:
+
+```
+$body = 'Hi! This is an SMS notification from EspoCRM.';
+
+// Phone number is obtained from the entity.
+$phoneNumber = phoneNumber;
+
+$smsId = record\create(
+ 'Sms',
+ 'to', $phoneNumber,
+ 'body', $body
+);
+
+ext\sms\send($smsId);
+```
+
+## Two-Factor Authentication
+
+[SMS 2FA](2fa.md#authentication-via-sms) is supported out of the box, but you need to have an implementation for your SMS provider (see the SMS Providers extension).
+
+Note that the *Phone* field of the user, for whom you want to set up the Two-Factor Authentication, must be filled in with at least one number.
+
+1. At Administration > Authentication, check the box *Enable 2-Factor Authentication*. Add the *SMS* value in the field *Available 2FA methods*. Save changes.
+2. At Administration > Users, select the user for which the 2FA will be configured.
+3. On the detail view of the user, click on the *Access* button and check the box *Enable 2-Factor Authentication*. Also, choose *SMS* 2FA Method in the drop down list. Click the *Apply* button.
+4. Enter the Administrator password, select a phone number that will be used for 2FA in the *Phone* dropdown list, and click the *Send Code* button.
+5. Enter the code that will be sent to the selected phone number and click the *Apply* button.
+
+## VoIP integration for Twilio
+
+The [VoIP integration](https://www.espocrm.com/extensions/voip-integration/) allows sending and receiving Twilio SMS/MMS through the UI.
+
+!!! important
+
+ The VoIP integration does not support the SMS Providers extension. It implements Twilio SMS only.
+
+To use Twilio Integration for receiving and making calls, SMS and MMS, first configure it according to [these instructions](https://docs.espocrm.com/extensions/voip-integration/twilio-integration-setup/).
+
+At Administration > VoIP Routers > the phone number required for sending and receiving SMS, check the *SMS* and *MMS* boxes for those team users whom you need in the Team Users panel.
+
+Also, you need to enable Twilio messaging geographic permissions:
+
+1. Log in to your Twilio account.
+2. Navigate to Programmable SMS > Settings > [Geo Permissions](https://www.twilio.com/console/sms/settings/geo-permissions).
+3. Enable needed countries.
+
+Do not forget to set *[Grant access to Messages](https://docs.espocrm.com/extensions/voip-integration/customization/#grant-access-to-messages)* for the required users.
+
+Keep in mind that for the Twilio Trial account you will need to add a [*Verified Phone Numbers* or *Caller ID*](https://support.twilio.com/hc/en-us/articles/223180048-Adding-a-Verified-Phone-Number-or-Caller-ID-with-Twilio).
+
+After that, you can proceed to the installation and configuration of the SMS Providers extension.
diff --git a/docs/administration/terms-and-naming.md b/docs/administration/terms-and-naming.md
index f188d3eee..cca30b0ef 100644
--- a/docs/administration/terms-and-naming.md
+++ b/docs/administration/terms-and-naming.md
@@ -2,21 +2,23 @@
## Entity type
-It's a type of data. E.g. Account, Contact, Opportunity, Task, Knowledge Base.
+An *entity type* is a type of data, an object. For example, Account, Contact, Opportunity, Task, Knowledge Base.
Entity types are named in UpperCamelCase (start with a capital letter).
-**The list of available entity types** can be obtained at: Administration > Entity Manager > *Name* column.
+The list of available entity types can be obtained at: Administration > Entity Manager > *Name* column.
-Entities have their fields and links.
+Entity types contain fields and links in their definitions.
## Field
-A field is a unit of data. Entities have their own set of fields. E.g. name, status, createdAt, assignedUser.
+A *field* is a unit of data. An entity defines its own set of fields. For example, name, status, createdAt, assignedUser.
-Fields are named in lowerCamelCase (start with a lowercase letter).
+Fields are named in lowerCamelCase (starting with a lowercase letter).
-**The list of available fields** for a specific entity type can be obtained at: Administration > Entity Manager > needed entity type > Fields > *Name* column.
+!!! info
+
+ The list of available fields for a specific entity type can be obtained at: Administration > Entity Manager > {Entity Type} > Fields > *Name* column.
Each field can have one or few attributes (depending on the field type).
@@ -24,28 +26,38 @@ The list of available field types can be found [here](fields.md).
## Attribute
-Most fields have only one attribute named the same as its field. E.g. `createdAt` field has attribute `createdAt`. Some fields have multiple attributes.
+* An attribute usually corresponds to a database column, provided that the attribute is storable.
+* In the REST API, JSON object keys correspond to attributes.
+* Attributes are used for accessing entity values in Formula Script.
-Attributes are named in lowerCamelCase (start with a lowercase letter).
+!!! info
+
+ The list of available attributes for a specific field can be obtained at: Administration > Entity Manager > {Entity Type} > View Details from the dropdown of the field.
+
+Most fields have only one attribute named the same as the field. For example, the *createdAt* field has the attribute *createdAt*. Some fields have multiple attributes.
-Field types having multiple attributes:
+Field types that have multiple attributes and their attribute naming:
* Link: *fieldId*, *fieldName*
-* Link-Multiple: *fieldIds*, *fieldNames* (ids − array of ids, names − object of id=>name pairs)
-* Link-Parent: *fieldId*, *fieldType*, *fieldName* (type is entity type)
-* Currency: *field*, *fieldCurrency* (currency is currency code)
-* Person Name: *firstName*, *lastName*, *middleName*, *salutation*
+* Link-Multiple: *fieldIds*, *fieldNames* (ids − array of IDs, names − object of ID => name pairs)
+* Link-Parent: *fieldId*, *fieldType*, *fieldName* (type is an entity type)
+* Currency: *field*, *fieldCurrency* (currency is a currency code)
+* Person Name: *firstName*, *lastName*, *middleName*, *salutationName*
* Address: *fieldStreet*, *fieldCity*, *fieldPostalCode*, *fieldCountry*, *fieldState*
-where *field* is the name of the field.
+Where *field* is a name of the field.
+
+Attributes are named in lowerCamelCase (start with a lowercase letter).
## Link
-A link represents a relationship with another entity. Entities have their set of links.
+A *link* represents a relationship with another entity.
Links are named in lowerCamelCase (start with a lowercase letter).
-**The list of available links** for a specific entity type can be obtained at: Administration > Entity Manager > needed entity type > Links > 4th column.
+!!! info
+
+ The list of available links for a specific entity type can be obtained at: Administration > Entity Manager > {Entity Type} > Relationships.
Each relationship between two entity types is a pair of two links on both sides.
@@ -61,7 +73,7 @@ Relationship type & link types mapping:
* One-to-Many: hasMany + belongsTo
* Many-to-One: belongsTo + hasMany
-* Many-toMany: hasMany + hasMany
+* Many-to-Many: hasMany + hasMany
* One-to-One Right: belongsTo + hasOne
* One-to-One Left: hasOne + belongsTo
* Parent-to-Children: hasChildren + belongsToParent
diff --git a/docs/administration/troubleshooting.md b/docs/administration/troubleshooting.md
index 4ca8c26a6..b0fec0c91 100644
--- a/docs/administration/troubleshooting.md
+++ b/docs/administration/troubleshooting.md
@@ -3,32 +3,78 @@
In this article:
* [Check logs](#check-logs)
+ * [Debug mode](#debug-mode)
* [Check system requirements](#check-system-requirements)
-* [Scheduled Jobs are not working](#scheduled-jobs-are-not-working)
+* [File permissions](#file-permissions)
+* [Scheduled jobs are not working](#scheduled-jobs-are-not-working)
* [Running rebuild from CLI](#running-rebuild-from-cli)
* [EspoCRM is not loading after upgrade](#espocrm-is-not-loading-after-upgrade)
* [MySQL error: The server requested authentication method unknown to the client](#mysql-error-the-server-requested-authentication-method-unknown-to-the-client)
* [Emails are not being fetched](#emails-are-not-being-fetched)
-* [Enabling debug mode for a logger](#enabling-debug-mode-for-a-logger)
+* [Delay in fetching emails](#delay-in-fetching-emails)
* [Admin password is lost, can't log in](#admin-password-is-lost-cant-log-in)
+* [MySQL error: MySQL can only use 61 tables in a join](#mysql-error-mysql-can-only-use-61-tables-in-a-join)
+* [MySQL error: Row size too large](#mysql-error-row-size-too-large)
## Check logs
-To find out the problem, you have to check error log files.
+This is the most **important step** in diagnosing the problem. There are two main logs you need to check:
-#### EspoCRM error logs
+* EspoCRM [log](log.md);
+* Webserver error log.
-EspoCRM logs are located at `/data/logs/*.log` and contain some error information.
+#### EspoCRM log
-#### Apache error logs
+EspoCRM log files are located in `{ESPO_ROOT}/data/logs/` directory. Most errors are logger there.
-For Ubuntu server, an apache error log is located at `/var/log/apache2/error.log` and contains all error information. The location of log files can be different on other systems.
+#### Webserver error log
+
+
+##### Apache
+
+The Apache error log is usually located at `/var/log/apache2/error.log`. The location of the log file can vary in different systems.
+
+##### Nginx
+
+`/var/log/nginx/error.log`
+
+### Debug mode
+
+In some cases, it can be reasonable to enable debug mode for the Espo logger. It will print more information to the log.
+
+To enable debug mode for the logger, edit the file `data/config-internal.php` and set the value of the *logger.level* parameter to `DEBUG`:
+
+```
+'logger' => [
+ ...
+ 'level' => 'DEBUG',
+]
+```
+
+Don't forget to revert the mode back after the problem is solved (to `WARNING` or `ERROR`).
+
+### Backtrace printing
+
+Enabling trace printing will print a backtrace to the log for every thrown exception. Can be very useful for debugging occurred errors.
+
+In `data/config-internal.php` (or `data/config.php`):
+
+```
+'logger' => [
+ ...
+ 'printTrace' => true,
+]
+```
## Check system requirements
-At Admiistration > System Requirements. It's important to have all required extensions installed.
+At Administration > System Requirements. It's important that you have all required PHP extensions installed.
-## Scheduled Jobs are not working
+## File permissions
+
+It's the most common issue. Because of incorrect file permissions (or ownership), the instance might not be able to write certain files (for example, cache files). You can find how to configure file permissions [here](server-configuration.md#permissions).
+
+## Scheduled jobs are not working
#### Problem #1: Your crontab is not configured
@@ -42,7 +88,7 @@ Note: Crontab should be configured under web-server user, e.g. `crontab -e -u ww
#### Problem #2. Crontab is configured, but Scheduled Jobs are not working
-To make sure there are no errors when cron is running, try to run the cron command in a terminal:
+To make sure there are no errors when cron is running, try to run the cron command in the terminal:
1\. Login via SSH to your server.
@@ -70,7 +116,7 @@ where `www-data` is a web-server user.
## Running rebuild from CLI
-Sometimes you need to run rebuild from the command line interface when the application is not loading.
+Sometimes you need to run rebuild from the command-line interface, usually when the application fails to load or the log shows database-schema errors.
```bash
php rebuild.php
@@ -78,22 +124,34 @@ php rebuild.php
## EspoCRM is not loading after upgrade
-Sometimes it can happen on some shared hostings.
+[Check logs](#check-logs) for errors. Googling an error message may help figure out the cause of the problem.
+
+Often the problem is caused by the webserver PHP version being lower than the minimum required version.
+
+File permissions can be set to not proper values on some shared hostings after upgrade.
+
+Check permissions of these files:
-Check permissions of the files:
-/index.php
-/api/v1/index.php
+* `public/index.php`
+* `public/api/v1/index.php`
-They must be 644. If any of those files have permission 664, you need to change it to 644. Use your hosting's control panel or chmod command.
+They must be 644. If any of these files have permission 664, you need to change it to 644. Use your hosting's control panel or *chmod* command.
```
chmod 644 /path/to/file
```
+
More information about file permissions can be found [here](server-configuration.md#required-permissions-for-unix-based-systems).
## MySQL error: The server requested authentication method unknown to the client
-MySQL 8.0.4 has changed default authentication method to `caching_sha2_password` which is not supported by PHP. This issue can be solved by this [solution](server-configuration.md#mysql-8-support).
+MySQL 8.0.4 has changed a default authentication method to `caching_sha2_password` which is not supported by PHP (at the time of writing). For MySQL 8 it should be changed to `mysql_native_password` method. For a user it can be done with the query:
+
+```
+CREATE USER username@localhost identified with mysql_native_password by 'password';
+```
+
+where username is your MySQL user, password is your MySQL user password.
## Emails are not being fetched
@@ -102,30 +160,15 @@ MySQL 8.0.4 has changed default authentication method to `caching_sha2_password`
3. Check log at Administration > Scheduled Job > Check Personal Email Accounts. Make sure there are no records with failed status.
4. Check log at Administration > Scheduled Job > Check Group Email Accounts. Make sure there are no records with failed status.
-## Enabling debug mode for a logger
+## Delay in fetching emails
-To enable debug mode for log, edit the file `data/config.php` and change the value:
+The following configuration will speed up your email fetching (and other background processes):
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-to
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
+1. Cron should be configured to execute once a minute or more often. More details [here](jobs.md#setting-up).
+2. The *Jobs Run in Parallel* parameter should be enabled in Administration > Jobs > Settings (in the top-right corner). More details [here](jobs.md#running-jobs-in-parallel-processes).
## Admin password is lost, can't log in
-Available since EspoCRM 5.8.3.
-
Run the following command in CLI:
```
@@ -133,3 +176,67 @@ php command.php set-password [username]
```
where `[username]` is a user name, e.g. `admin`.
+
+## MySQL error: MySQL can only use 61 tables in a join
+
+Full error message: *General error: 1116 Too many tables; MySQL can only use 61 tables in a join*.
+
+Any of the following actions may solve the problem.
+
+1. Remove unused many-to-one and one-to-one relationships (if you have such).
+2. Disable link-multiple for some many-to-many relationships of the problem entity type.
+3. Set `noJoin` parameter (to `true`) for some *belongsTo* links. [Example](https://github.com/espocrm/espocrm/blob/7.2.7/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Campaign.json#L269).
+4. Set *currencyNoJoinMode* (`'currencyNoJoinMode' => true,` in `data/config.php`). With this mode enabled, you will need to clear Espo cache every time you change the system currency list. (as of v7.3)
+
+## MySQL error: Row size too large
+
+Full error messages (may be one of the following):
+
+1. *ERROR 1118 (42000): Row size too large. The maximum row size for the used table type,
+not counting BLOBs, is 65535. This includes storage overhead, check the manual. You
+have to change some columns to TEXT or BLOBs.*
+2. *ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to
+TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.*
+
+You can get this error if there are too many Varchar fields in an entity type. You cannot create new fields in this case.
+
+To fix this problem, you can try two solutions:
+
+### Solution 1. Decrease max length for some varchar fields
+
+#### Step 1. Change in definitions
+
+Edit the file `custom/Espo/Custom/Resources/metadata/entityDefs/{EntityType}.json`. Decrease *maxLength* parameter for some custom varchar fields. E.g. from 255 to 100.
+
+#### Step 2. Change columns length in database
+
+Then you need to amend the corresponding columns in your database by changing their length. You can do it manually (by running a query or via a database admin tool) or run a [hard rebuild](commands.md#hard-rebuild).
+
+#### Step 3. Rebuild
+
+*Not needed if you already run a hard rebuild.*
+
+Log in as an administrator in EspoCRM, go to Administration and click *Rebuild*. Alternatively, run rebuild via [CLI](commands.md/#rebuild).
+
+### Solution 2. Change type for some varchar fields from *Varchar* to *Text*
+
+#### Step 1. Change in definitions
+
+Edit the file `custom/Espo/Custom/Resources/metadata/entityDefs/{EntityType}.json` manually. Change definitions of some custom varchar fields from:
+
+```
+"type": "varchar",
+"maxLength": 150
+```
+
+to:
+
+```
+"type": "text"
+```
+
+Note that the *maxLength* value can be different for your field. You just need to remove it. Make sure that the resulting JSON is valid.
+
+#### Step 2. Rebuild
+
+Log in as administrator in EspoCRM, go to Administration and click the Rebuild link. Alternatively, rebuild via [CLI](commands.md/#rebuild).
diff --git a/docs/administration/upgrading-manually.md b/docs/administration/upgrading-manually.md
new file mode 100644
index 000000000..2fd4442a7
--- /dev/null
+++ b/docs/administration/upgrading-manually.md
@@ -0,0 +1,141 @@
+# Upgrading Manually
+
+## Option 1. Migration
+
+!!! note
+
+ The minimal version you can upgrade from using this method is 7.1.0.
+ The minimal version you can upgrade to using this method is 8.3.0.
+
+!!! note
+
+ This method assumes that all installed third party extensions have their files placed in the `custom` and `client/custom` directories.
+
+!!! important
+
+ This methods does not perform before-upgrade checks that the regular upgrade method does. After replacing the files manually, it's possible that your system won't work due to reasons like PHP version incompatibility or customization incompatibility. The method is preferred for more experienced users.
+
+Check all the [recommendations](https://docs.espocrm.com/administration/upgrading/#recommendations) before performing upgrade.
+
+### 1. Replace files.
+
+Replace all application files with files with files from a new version package. You need to delete all existing source files except the directories listed below.
+
+The directories you must NOT delete:
+
+* `data`
+* `custom`
+* `client/custom`
+
+Make sure [file permissions](server-configuration.md#required-permissions-for-unix-based-systems) are correct.
+
+### 2. Run migration.
+
+Run the command:
+
+```
+bin/command migrate
+```
+
+It will run needed prepare and after-upgrade scripts, run rebuild. The version parameter in config will be updated.
+
+## Option 2. Upgrade package
+
+Manually replicating upgrade with an upgrade package. This is another option to upgrade, not related to the section above.
+
+!!! important
+
+ Only for very experienced users. It's **not recommended** way to upgrade. We do not guarantee any success if you decide to upgrade this way.
+
+If your environment is configured properly, the regular upgrade process via CLI should work fine.
+
+In some cases it can be more reasonable to install a fresh instance, then copy your `custom` directory, `data/upload` directory, install all needed extensions.
+
+The following actions are the same as those that the automatic upgrade script performs when you run the *upgrade* command.
+
+## 0. Check system requirements of the new version.
+
+Whether your system suits for the new version. Sometimes we drop support of old PHP and MySQL versions.
+
+### 1. Run rebuild.
+
+Make sure no error occurred. If any error occurred it means your Espo instance is faulty and need to be fixed before upgrade.
+
+### 2. Download an upgrade package. Unzip it.
+
+Find a needed upgraded package at https://www.espocrm.com/download/upgrades/. If the needed package is not listed
+you can try to compose an URL `https://www.espocrm.com/downloads/upgrades/EspoCRM-upgrade-{FROM}-to-{TO}.zip` by substituting the *from* and *to* versions.
+Maybe the needed file exists but not listed on the page. Note that there are no packages that skip minor versions. *6.0.10* can be upgraded to *6.1.3* in one step but cannot to *6.2.0*.
+
+### 3. Copy files from copyBefore
+
+1. Check whether the directory `copyBefore` exists in the package. If it does not exist, then skip this step.
+2. Copy all files from there to the root directory of your instance.
+3. Run rebuild.
+
+### 4. Run before-upgrade script.
+
+Check whether the file `scripts/BeforeUpgrade.php` exists in the package. If it does not exist, then skip this step.
+
+Create a file `BeforeUpgradeRunner.php` in the root directory of your instance:
+
+```php
+run(
+ $app->getContainer()
+);
+
+```
+
+Copy `scripts/BeforeUpgrade.php` to the root directory.
+
+Run `BeforeUpgradeRunner.php`.
+
+Run rebuild.
+
+Remove created files.
+
+### 5. Apply vendor files.
+
+1. Check whether `vendorFiles` directory exists in the package. If it does not exist, then skip this step.
+2. Replace the existing `vendor/autoload.php` file (in your instance) with `vendorFiles/autoload.php` (from the package).
+3. Remove folders `vendor/*` (in your instance) that are presented in the upgrade packages in `vendorFiles` directory.
+4. Copy all folders from `vendorFiles` directory (upgrade package) to `vendor` directory of your instance.
+
+### 6. Remove unneeded files.
+
+1. Open `manifest.json` file in any text editor.
+2. Find the list of files under `delete` parameter.
+3. Remove all these files from your instance.
+
+### 7. Copy new and changed files.
+
+Copy all files from `files` directory (upgrade package) to your the root directory of your instance.
+
+### 8. Run rebuild.
+
+### 9. Copy files from copyAfter
+
+1. Check whether the directory `copyAfter` exists in the package. If it does not exist, then skip this step.
+2. Copy all files
+3. Run rebuild.
+
+### 10. Run after-upgrade script.
+
+Check whether the file `scripts/AfterUpgrade.php` exists in the package. If it does not exit, then skip this step.
+
+To the same actions as for *before-upgrade*.
+
+### 11. Change version in the config.
+
+1. Open the file `data/config.php`.
+2. Find the `version` parameter and change its value to the value of the version you upgraded to.
+
+You can download the fresh instance and compare files using some tool. To make sure files are the same (except *custom* directory and installed extensions).
+
+Make sure that file permissions are correct.
diff --git a/docs/administration/upgrading.md b/docs/administration/upgrading.md
index 2e08582d6..6afa64501 100644
--- a/docs/administration/upgrading.md
+++ b/docs/administration/upgrading.md
@@ -1,10 +1,13 @@
+---
+search:
+ boost: 3
+---
+
# How to upgrade EspoCRM
## Upgrade from CLI
-Available from version 5.6.0.
-
-This is **the most preferable** way to upgrade.
+This is the preferable way to upgrade.
Command to run:
@@ -12,24 +15,46 @@ Command to run:
php command.php upgrade
```
-This will check the next available version, download it and install. Once the upgrade is complete, it will prompt to run the command again, if a newer version is available.
+This command will check whether the next version is available, download it and install. Once the upgrade is complete, it will prompt to run the command again if a newer version is available.
+
+!!! note
+
+ Upgrading process may take a while. Do not close the terminal until it's finished.
+
+!!! note
+
+ If the next Espo version requires a higher PHP version, upgrade won't be processed, a message will be displayed.
+
+It's recommended to upgrade whenever the new version is out. If you skip a few minor or major versions before deciding to upgrade, it's more likely that the upgrade will run unsmoothly. For minor or major releases it may be reasonable to wait for a few days before upgrading, as a very fresh release is likely to have yet undiscovered bugs.
+
+!!! warning
+
+ Upgrading between minor or major versions is not always a hands-off process. Incompatibility issues are possible if you have extensions or manual customizations. It is recommended to make a backup before proceeding to upgrade.
-Note: Upgrading process may take a while. Do not close the terminal until it's finished.
+Versioning (X.Y.Z):
+
+* X – major – incompatibility issues are very likely, very important to backup before upgrading;
+* Y – minor – incompatibility issues are possible, recommended to backup before upgrading;
+* Z – patch – no-brainer to upgrade.
## Recommendations
1. Make a [backup](backup-and-restore.md) before upgrading.
-2. Disable cron (at Administration > Settings) before upgrading. Enable it back after the upgrade is finished.
-3. Enable *Maintenance Mode* (at Administration > Settings) before upgrading. Disable after the upgrade is finished.
-4. Make sure you have free disk space on the server.
+2. If the next Espo version requires a higher PHP version, upgrade your PHP (with all extensions). The PHP version you are upgrading to must be supported by your current Espo (usually you make a +2 minor version steps). After that, make sure your Espo is working, cron is running. Make sure that the new PHP version is applied to the CLI (command `php -v`) and to the web server (at Administration > System Requirements > PHP Version).
+3. Make sure you have enough free disk space on the server.
+4. Disable cron before upgrading (at Administration > Settings). Enable it back after upgrade is finished. This will prevent situations when a job started on the previous version and finished on the new version. In most cases this won't cause any issues though. The most significant problem it can cause is the job not being finished.
+5. Enable *Maintenance Mode* before upgrading (at Administration > Settings). Disable after upgrade is finished. This will prevent non-admin users accessing the application before you started upgrading.
+6. *opcache.enable_cli* parameter in PHP should be set to false (usually set to false by default).
+
+It's recommended to run upgrade either under the webserver user (usually *www-data*) or *root* user.
## Additional parameters
Available parameters (only for advanced users):
+- `--file="EspoCRM-upgrade.zip"` − install a specific [upgrade package](https://www.espocrm.com/download/upgrades/) (path to file);
- `-y` − run w/o user confirmation;
-- `-s` − run an upgrade in a single process;
-- `--file="EspoCRM-upgrade.zip"` − install a specific upgrade package (path to file).
+- `-s` − run an upgrade in a single process (dangerous, not recommended to use).
Example of using parameters:
@@ -37,19 +62,11 @@ Example of using parameters:
php command.php upgrade -y --file="EspoCRM-upgrade.zip"
```
-## Legacy way to upgrade
-
-Before 5.6.0 version.
-
-Execute the following command from EspoCRM root directory:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
-
## Upgrade from UI
-This is **not recommended** way to upgrade. It may cause problems.
+!!! warning
+
+ This is not a recommended way to upgrade. It may cause problems as the upgrade will be processed in a single web server process.
#### Step 1. Check your current version
@@ -57,8 +74,41 @@ To check your current version, go to Administration > Upgrade page.
#### Step 2. Download needed upgrade packages
-Go to the upgrade page https://www.espocrm.com/download/upgrades/ and based on your currect version download needed packages.
+Go to the [download upgrade page](https://www.espocrm.com/download/upgrades/) and download needed packages (based on your current version).
#### Step 3. Run upgrade from Administration panel
Go to Administration > Upgrade. Upload and install upgrade packages one by one.
+
+## Breaking changes
+
+Espo upgrades should not break customizations made via the UI. But customizations made via code may break. To review breaking changes before upgrading, check release notes or GitHub issues marked with the *change* tag.
+
+## Quick revert
+
+If after upgrade the system does not work properly and you want to quickly revert the previous version, you can use this method. Note that this method is not equivalent to a full backup recovery.
+
+1\. Download the previous version build from the [releases](https://github.com/espocrm/espocrm/releases) on GitHub.
+
+2\. Remove the following folders in your problem instance:
+
+- `application`
+- `html`
+- `public`
+- `vendor`
+
+3\. Copy all files from the downloaded build to the root directory of your instance. Existing files to be replaced.
+
+4\. Fix [file permissions](server-configuration.md#permissions) if needed.
+
+5\. Run rebuild:
+
+```
+php rebuild.php
+```
+
+## See also
+
+* [Upgrading manually](upgrading-manually.md)
+* [Troubleshooting](troubleshooting.md)
+
diff --git a/docs/administration/users-management.md b/docs/administration/users-management.md
new file mode 100644
index 000000000..aeeb0d089
--- /dev/null
+++ b/docs/administration/users-management.md
@@ -0,0 +1,103 @@
+# Users management
+
+In this article:
+
+* [User types](#user-types)
+* [Sending access info](#sending-access-info)
+* [Password recovery](#password-recovery)
+* [User inactivating](#user-inactivating)
+* [Logging in as another user](#logging-in-as-another-user)
+* [Teams](#teams)
+* [See also](#see-also)
+
+## User types
+
+Types of users:
+
+* Admin
+* Regular
+* Portal
+* API
+* System
+
+### Admin
+
+An *admin* user has full access to the system. Admin users can create and remove other users, manage access roles, teams, portals, etc.
+
+There can be multiple admin users in the system. An admin can create another admin users.
+
+### Regular
+
+A regular user has access only to scopes allowed by [Roles](roles-management.md) assigned to the user. A regular users can edit their own user record (if allowed by roles) except the following fields: User Name, Type, Emails, Teams, Roles, Is Active.
+
+An admin user can manage regular users at Administration > Users.
+
+### Portal
+
+Portal users have access only to the [portal](portal.md) (or multiple portals). A portal user is usually associated with a specific Contact and Account. Access permissions are defined by Portal Roles.
+
+Portal users can be managed at Administration > Portal Users.
+
+### API
+
+API users serve for accessing the system via the [API](../development/api.md). Access permissions are defined by [Roles](roles-management.md).
+
+API users can be managed at Administration > API Users.
+
+### System
+
+The system user serves for system purposes. It's not possible to log in under the system user.
+
+## Sending access info
+
+When a user (regular, admin or portal) is being created by an admin, it's possible to send an access info email to the user. On the create form, you need to fill in the *Email* field, then the checkbox 'Send access info' will show up. It will initiate the access email sending after user creation. The access info email contains the link to the system and the username.
+
+If the admin does not specify a **password** for a new user, it will prompt the user to specify their password once they follow the link in the access email. If the password is specified by the admin, it will be sent plain in the email. It's **not recommended** that the password is specified by the admin because of security reasons.
+
+The email template for access info emails can be changed at Administration > Template Manager > Access info.
+
+## Password recovery
+
+Users can recover their access if they forgot their password by clicking **Forgot Password?** on the login screen. The user needs to enter their username and email address. If the entered data is correct, an email with a unique link will be sent to the user. This link has an expiration period.
+
+Password recovery (for all, regular or admin users) can be disabled at Administration > Authentication.
+
+For security reasons, it's recommended to check **Prevent email address exposure on password recovery form** at Administration > Authentication.
+
+See the [config parameters](config-params.md#passwords) for password recovery.
+
+The email template for password recovery can be changed at Administration > Template Manager > Password Change Link.
+
+The admin can send a password change link for a specific user at the user detail view > the dropdown next to the Edit button > Send Password Change Link.
+
+See more in the [separate article](passwords.md).
+
+## User inactivating
+
+To disable access for a specific user w/o deleting the record, the admin needs to uncheck the field *Is Active*.
+
+## Logging in as another user
+
+*As of v7.3.*
+
+The admin can log in as another regular user. The user detail view > the dropdown next to the *Edit* > Log In.
+
+Limitations:
+
+* WebSocket is disabled when logged in as another user.
+* Requires re-entering admin password to log in as another user.
+* Recommended to open the login link in an incognito/private window to avoid losing a current login session.
+
+The functionality can be disabled in the config: `'authAnotherUserDisabled' => true`.
+
+## Teams
+
+A user can be related to one or multiple teams. Only the administrator can manage user's teams.
+
+Teams can provide additional access control capabilities. For example, a user added to a specific team, gets the ability to view records related to that team. Or, a user added to a team (e.g. called 'Managers') gets the ability to create and edit records of specific type and full read access.
+
+A user can have the Default Team. All records created by the user will be related to that team by default.
+
+## See also
+
+* [Teams quick tour](https://app.supademo.com/demo/cmm0qgpdz1q4p2rl72vtcqtx4)
diff --git a/docs/administration/web-to-lead.md b/docs/administration/web-to-lead.md
index fa2470940..cc6c00a00 100644
--- a/docs/administration/web-to-lead.md
+++ b/docs/administration/web-to-lead.md
@@ -1,65 +1,125 @@
+---
+search:
+ boost: 2
+---
+
# Web-to-Lead
-## Lead Capture
+In this article:
+
+* [Lead capture](#lead-capture)
+* [Web form](#web-form)
+* [API request](#api-request)
+* [Lead assignment distribution](#lead-assignment-distribution)
+* [Hooks](#hooks)
+* [Exposing entry point](#exposing-entry-point)
+* [See also](#see-also)
+
+## Lead capture
-Note: Available since 5.4.0 version.
+By utilizing the Lead Capture feature, an administrator can create entry points for capturing Leads through API and web forms. Follow Administration > Lead Capture to create a Lead Capture record.
-By utilizing Lead Capture feature administrator can create an entry point for capturing leads through API. Create an entry point at Administration > Lead Capture.
+Parameters:
-* Subscribe to Target List - a created lead will be added to a specified target list;
-* Subscribe Contact if exists - If a contact with the same email exists, then the contact will be added to the target list;
-* Target Team - A team to assign a created lead to;
-* Campaign - Statistics will be available in a campaign log;
-* Payload Fields - Select what fields need to be passed.
+* Subscribe to Target List – a created lead will be added to a specified target list;
+* Subscribe Contact if exists – if a contact with the same email exists, then the contact will be added to the target list;
+* Target Team – a team created leads will be assigned to;
+* Campaign – statistics will be available in the log of a selected campaign record;
+* Payload Fields – what fields need to be sent in payload (from the web form to the API entry point).
### Double Opt-in (confirmed opt-in)
-If double opt-in is enabled, then your subscribers will need to confirm their intention to opt-in by clicking on a link in an email. The email will be sent automatically once data is received through API.
+If double opt-in is enabled, then your subscribers will need to confirm their intention to opt-in by clicking on a link in an email. The email will be sent automatically once data is received through the API.
-Create Email Template that will be used for a double opt-in. You can use following placeholders in a template body:
+Create an Email Template that will be used for the double opt-in. You can use the following placeholders in a template body:
-* `{optInUrl}` - confirmation URL;
-* `{optInLink}` - confirmation link;
-* `{optInDate}` - date when a subscription request was submitted (since 5.6.10);
-* `{optInTime}` - time when a subscription request was submitted (since 5.6.10);
-* `{optInDateTime}` - date and time when a subscription request was submitted (since 5.6.10).
+* `{optInUrl}` – confirmation URL;
+* `{optInLink}` – confirmation link;
+* `{optInDate}` – date when a subscription request was submitted;
+* `{optInTime}` – time when a subscription request was submitted;
+* `{optInDateTime}` – date and time when a subscription request was submitted.
-A confirmation link will be added automatically if you haven’t inserted a placeholder in the email template.
+A confirmation link will be added automatically if you haven’t inserted the confirmation link placeholder in the email template.
-## Posting API request
+!!! note
-Your web site needs to make a POST request to send the form data to your CRM. A request **doesn't require any authorization**. You just need to use a specific URL with an API Key. The information about the request is available in the side panel on Lead Capture detail view.
+ When sending empty values, use *null* rather than an empty string.
-Required headers:
+## Web form
+
+*As of v9.0.*
+
+The Web Form can be enabled for a particular Lead Capture record. A form can be displayed either on a separate page or embedded in an IFRAME. When enabled, a form URL will be displayed in the panel on the right.
+
+Parameters:
+
+* Text to display on form
+* Text to display after form submission
+* URL to redirect to after form submission
+* Language used on form
+* Allowed hosts for form embedding (for IFRAME)
+* Use Captcha
+
+Captcha can be configured under Administration > Integrations. ReCAPTCHA v3 is implemented.
+
+Supported field types:
-* Content-Type: application/json
-* Accept: application/json
+* Varchar
+* Email
+* Phone
+* Text
+* Person Name
+* Enum
+* Multi-Enum
+* Array
+* Checklist
+* Integer
+* Float
+* Currency
+* Date
+* Date-Time
+* Boolean
+* URL
+* URL-Multiple
+* Address
+## API request
+
+You can use API requests to send Leads directly without using the built-in web-form.
+
+Your web site needs to make a POST request to send form data to your Espo. The request doesn't require any authorization. You just need to use a specific URL with an API Key in it. The information about the request is available in the side panel on the Lead Capture detail view.
+
+Required headers:
+
+* `Content-Type: application/json`
+* `Accept: application/json`
### PHP
-You can use [API client for PHP](../development/api-client-php.md).
+You can use the [API client](https://github.com/espocrm/php-espo-api-client).
-Example:
+!!! example
-```php
-setApiKey($apiKey);
+ $client->setSecretKey($secretKey); // if you use HMAC method
-$apiKey = 'f1b04885f28ee1a6d55dd203daed68f9'; // specify your API key here
+ $apiKey = 'f1b04885f28ee1a6d55dd203daed68f9'; // specify your API key here
-$formData = [
- 'firstName' => $_POST['firstName'],
- 'lastName' => $_POST['lastName'],
- 'emailAddress' => $_POST['emailAddress']
-];
+ $formData = [
+ 'firstName' => $_POST['firstName'] ?: null,
+ 'lastName' => $_POST['lastName'] ?: null,
+ 'emailAddress' => $_POST['emailAddress'] ?: null,
+ ];
-$client->request('POST', 'LeadCapture/' . $apiKey, $formData);
+ $client->request(Client::METHOD_POST, 'LeadCapture/' . $apiKey, $formData);
-```
+ ```
### Python
@@ -67,76 +127,110 @@ $client->request('POST', 'LeadCapture/' . $apiKey, $formData);
### Directly by a web browser
-Example:
-
-```html
-
-
-
-
-```
-'Access-Control-Allow-Origin' header can be set in `data/config.php` with the parameter `leadCaptureAllowOrigin`. By default, `*` value is used.
+ webToLeadFormIsSubmitted = true;
+ webToLeadFormElement.submit.setAttribute('disabled', 'disabled');
+
+ const payloadData = {
+ firstName: webToLeadFormElement.firstName.value || null,
+ lastName: webToLeadFormElement.lastName.value || null,
+ emailAddress: webToLeadFormElement.emailAddress.value || null,
+ };
+
+ // The URL can be found on the Lead Capture detail view.
+ const url = 'https://URL_OF_YOUR_CRM/api/v1/LeadCapture/API_KEY';
+
+ const xhr = new XMLHttpRequest();
+
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/json');
+ xhr.setRequestHeader('Accept', 'application/json');
+
+ xhr.onreadystatechange = () => {
+ if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
+ const containerElement = document.getElementById('web-to-lead-form-container');
+
+ containerElement.innerHTML = 'Sent';
+ }
+ };
+
+ xhr.onerror = () => {
+ webToLeadFormElement.submit.removeAttribute('disabled');
+ webToLeadFormIsSubmitted = false;
+ };
+
+ xhr.send(JSON.stringify(payloadData));
+ });
+
+ ```
+
+The `Access-Control-Allow-Origin` header (see [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)) can be set in the `data/config.php` with the parameter `leadCaptureAllowOrigin`. The default value is `*`.
+
+```
+'leadCaptureAllowOrigin' => '*',
+```
## Lead assignment distribution
-By utilizing [Workflows](workflows.md) or [BPM tool](bpm.md), you can create an assignment rule that will distribute leads among team users. There are Round-Robin and Least-Busy rules available.
+By utilizing the [Workflow](workflows.md) or the [BPM](bpm.md) tools, you can create an assignment rule that will distribute leads among team users. *Round-Robin* and *Least-Busy* rules are available.
-To apply the rule for only leads coming through the entry point, you can use a condition checking Campaign field.
+To apply the rule only for leads that are coming through the lead capture form, you can use a condition that checks the *Campaign* field (assuming that you have created a separate campaign record for the lead capture form).
+You can also utilize a Formula script (Administration > Entity Manager > Lead > Formula) to set some additional fields.
## Hooks
It's possible to catch a lead capture event with built-in [hooks](../development/hooks.md#additional-default-hooks). Requires coding.
+## Exposing entry point
+
+*As of v9.2.*
+
+If there's no access to your CRM from the internet, you need to configure your server to handle requests to specific entry points to have the lead capture functioning.
+
+Set the config parameter `leadCaptureSiteUrl` with the base URL that will be exposed.
+
+You need to handle the following requests:
+
+- GET `{siteUrl}?entryPoint=leadCaptureForm&id={id}`
+- GET `{siteUrl}?entryPoint=confirmOptIn&id={id}`
+- POST `{siteUrl}/api/v1/LeadCapture/{apiKey}`
+- OPTIONS `{siteUrl}/api/v1/LeadCapture/{apiKey}`
+- POST `{siteUrl}/api/v1/LeadCapture/form/{id}`
+
## See also
-* [Drip Email Campaign with BPM](bpm-drip-email-campaign.md)
+* [Quick tour](https://app.supademo.com/demo/cme8qhb2r3w9lh3pyo4d2hh6k)
+* [Drip email campaign with BPM](bpm-drip-email-campaign.md)
+
+
diff --git a/docs/administration/webhooks.md b/docs/administration/webhooks.md
index df707d8e0..5b1a67d48 100644
--- a/docs/administration/webhooks.md
+++ b/docs/administration/webhooks.md
@@ -2,7 +2,7 @@
Webhooks allow other applications to subscribe to specific events happening in EspoCRM and receive data related to those events. Webhooks are supposed to be created via API by other applications. The webhook has a specific *Event* and *URL*. Every time the event occurs, the system will send POST request with some payload to the specified URL.
-Webhooks can be created only by API Users (via API request) and Administrators. API User has to have *Webhooks* scope enabled in *Roles*. API User has also to have access to all entity types for which webhooks are planned to be created.
+Webhooks can be created only by API Users (via an API request) and Administrators. An API User has to have *Webhooks* scope enabled in Roles. An API User has also to have access to all entity types for which webhooks are intended to be created.
* [Subscription](#subscription)
* [Events](#events)
@@ -10,6 +10,7 @@ Webhooks can be created only by API Users (via API request) and Administrators.
* [Error handling](#error-handling)
* [Signature checking](#signature-checking)
* [Config parameters](#config-parameters)
+* [Debugging](#debugging)
## Subscription
@@ -24,37 +25,40 @@ Webhooks can be created only by API Users (via API request) and Administrators.
}
```
-Webhook ID (*id*), secret key (*secretKey*) will be sent back in a response.
+Parameters:
+
+* `URL` – string – an endpoint;
+* `skipOwn` – boolean – to skip if the event was initiated by the user owning the webhook (as of v9.2).
+
+A Webhook ID and a secret key will be sent back in the response:
+
+* `id` – an ID of created webhook,
+* `secretKey` – a generated secret key,
### Deleting request
`DELETE api/v1/Webhook/WEBHOOK_ID`
-```json
-{
- "event": "EVENT",
- "url": "URL"
-}
-```
-
### Administration
-Administrator can manage webhooks at Administration > Webhooks. It's possible to remove, edit or create webhooks there.
+An administrator can manage webhooks at Administration > Webhooks. It's possible to remove, edit or create webhooks there.
## Events
-Note: The list of available entity types can be obtained at Administration > Entity Manager.
+!!! note
+
+ The list of available entity types can be obtained at Administration > Entity Manager.
### ENTITY_TYPE.create
-Triggered when a record is created. All record attributes will be sent in payload.
+Triggered when a record is created. All record attributes will be sent in a payload.
Example: `Account.create`
### ENTITY_TYPE.update
-Triggered when a record is updated. Only updated record attributes will be sent in payload.
+Triggered when a record is updated. Only updated record attributes will be sent in a payload.
Example: `Account.update`
@@ -64,20 +68,22 @@ Triggered when a record is removed.
Example: `Account.delete`
-### *ENTITY_TYPE.fieldUpdate.FIELD*
+### ENTITY_TYPE.fieldUpdate.FIELD
-Triggered when a specific field is updated. New field attributes will be sent in payload.
+Triggered when a specific field is updated. New field attributes will be sent in a payload.
Example: `Account.fieldUpdate.assignedUserId`
-Note: The list of available fields can be obtained at Administration > Entity Manager > fields.
+!!! note
+
+ The list of available fields can be obtained at Administration > Entity Manager > fields.
## Webhook requests
Every webhook request (sent by EspoCRM to a specified URL) is of POST type. A content type is *application/json*.
-Events related to the same hook are sent in batches. Request payload is always an array (even if only one record is sent).
+Events related to the same hook are sent in batches. The request payload is always an array (even if only one record is sent).
One event occurred:
@@ -105,47 +111,49 @@ Multiple events occurred:
]
```
-Request sending is processed by a scheduled job *Process Webhook Queue* (Administration > Scheduled Jobs). By default, it runs every 5 minutes. You can change the scheduling.
+Request sending is processed by the scheduled job *Process Webhook Queue* (Administration > Scheduled Jobs). By default, it runs every 5 minutes. You can change the scheduling.
## Error handling
-When EspoCRM is trying to send a webhook request and an error occurs, EspoCRM will process it in the following ways:
+When EspoCRM is trying to send a webhook request and an error occurs, EspoCRM will process it the following ways:
* errors 400, 401, 403, 404, 405, 408, connection timed out, or connection failed - will try to make another attempt;
* error 410 - hook will be removed immediately.
## Signature checking
-It's possible to check the authenticity of a webhook request by comparing a signature passed in *X-Signature* header with a value calculated on a server that receives the request.
+It's possible to check the authenticity of a webhook request by comparing the signature passed in the *Signature* header with a value calculated on the server that receives the request.
Example for PHP:
```php
-$signature = base64_encode($webhookId . ':' . hash_hmac('sha256', $payload, $secretKey, true));
+$signature = base64_encode($webhookId . ':' . hash_hmac('sha256', $payload, $secretKey));
```
-* *webhookId* can be obtained from a response upon a webhook creation or at Admninistration > Webhooks;
-* *secretKey* can be obtained from a response upon a webhook creation or at Admninistration > Webhooks;
-* *payload* is a payload of a request
-
+* *webhookId* can be obtained from the response upon webhook creation or at Administration > Webhooks;
+* *secretKey* can be obtained from the response upon webhook creation or at Administration > Webhooks;
+* *payload* is a payload of the request.
-## Config parameters
-
-Can be set manually in `data/config.php`
+!!! important
-*webhookMaxCountPerUse*r = 50
+ Prior to v9.0, the signature was passed in the *X-Signature* header and constructed in a slightly different manner. *X-Signature* will still be passed after v9.0 and will be available until v11.0. If your script checks *X-Signature*, you need to fix it to *Signature*.
-*webhookQueueEventPortionSize* = 20
-*webhookQueuePortionSize* = 20
-
-*webhookBatchSize* = 50
+## Config parameters
-*webhookMaxAttemptNumber* = 4
+Can be set manually in `data/config.php`.
-*webhookFailAttemptPeriod* = '10 minutes'
+* *webhookMaxCountPerUser* = 50
+* *webhookQueueEventPortionSize* = 20
+* *webhookQueuePortionSize* = 20
+* *webhookBatchSize* = 50
+* *webhookMaxAttemptNumber* = 4
+* *webhookFailAttemptPeriod* = '10 minutes'
+* *webhookConnectTimeout* = 5 (seconds)
+* *webhookTimeout* = 10 (seconds)
-*webhookConnectTimeout* = 5 (seconds)
+## Debugging
-*webhookTimeout* = 10 (seconds)
+Queues are stored in two database tables: `webhook_queue_item` and `webhook_event_queue_item`. Webhook Queue Items are available from the UI at Administration > Webhooks > menu in the top-right corner > Webhook Queue Items.
+You can enable [debug mode](troubleshooting.md#debug-mode) to see more details in the log.
diff --git a/docs/administration/websocket.md b/docs/administration/websocket.md
index 3a2da4242..6b82706e1 100644
--- a/docs/administration/websocket.md
+++ b/docs/administration/websocket.md
@@ -1,19 +1,19 @@
# WebSocket
-Available from version 5.6.0.
+The WebSocket enables interaction between a server and a client (browser) without the latter making polling requests. Example: When a new notification is received, the server sends the information to the browser in real time.
-WebSocket enables interaction between a server and a client (browser) w/o the latter making polling requests. Example: When a new notification is received, the server sends the information to the browser in real time.
-
-Out-of-the-box WebSocket covers the following features:
+Out-of-the-box the WebSocket covers the following features:
* New in-app notifications;
* New event reminders;
* Updates in stream on the record detail view;
-* Updates of the detail view (since 5.9.0).
+* Updates of the detail view.
+
+!!! important
-Enable *Use WebSocket* parameter at Administation > Settings.
+ You need to have *zmq* php extension installed.
-You need to have *zmq* php extension installed.
+Enable **Use WebSocket** parameter at Administration > Settings.
## Daemon
@@ -53,32 +53,32 @@ Command to start the service:
## SSL support
-You need to set up a proxy that will forward SSL request to our websocket server and vice-versa.
+You need to set up a proxy that will forward SSL requests to our websocket server and vice-versa.
### Apache
-You need to have proxy and proxy_wstunnel modules installed.
+You need to have *proxy* and *proxy_wstunnel* modules installed.
```
sudo a2enmod proxy
sudo a2enmod proxy_wstunnel
```
-In your apache config inside VirtualHost section for SSL (``) add the following:
+In your Apache config inside the *VirtualHost* section for SSL (``), add the following:
```
-
- ProxyRequests Off
-
- ProxyPass ws://your-domain:8080
- ProxyPassReverse ws://your-domain:8080
-
-
+
+ ProxyRequests Off
+
+ ProxyPass ws://your-domain:8080
+ ProxyPassReverse ws://your-domain:8080
+
+
```
-### Ngnix
+### Nginx
-Add to server.conf:
+Add to *server.conf*:
```
map $http_upgrade $connection_upgrade {
@@ -91,7 +91,7 @@ upstream websocket {
}
```
-Add to section `server`:
+Add to the section `server`:
```
location /wss {
@@ -103,5 +103,73 @@ location /wss {
}
```
-Note: By default, Nginix has *proxy_read_timeout* parameter set to 60 (seconds). You need to increase the value to avoid the connection being terminated too soon. In the example, we set it to 14h.
+!!! note
+
+ By default, Nginx has *proxy_read_timeout* parameter set to 60 (seconds). You need to increase the value to avoid the connection being terminated too soon. In the example, we set it to 12h.
+
+## Checking whether it works
+
+Click F12 to open the browser console. See whether there's any error related to the WebSocket. If you enabled the WebSocket in the settings, the frontend client will try to connect to the WebSocket once the page is loaded. If something went wrong, an error will be displayed in the browser console.
+
+## Config params
+
+* webSocketDebugMode – bool – `false` – if you run a server (`php websocket.php`) manually from CLI, you will be able to see debug messages in the terminal; changing requires WebSocket process restart;
+* webSocketUrl – string – a custom URL for websocket; used only by the client (frontend);
+* webSocketUseSecureServer – bool – `false` – to use SSL w/o a proxy;
+* webSocketZeroMQSubscriberDsn – string – `tcp://127.0.0.1:5555` – an endpoint to bind to for message listening; to be changed when used inside a container;
+* webSocketZeroMQSubmissionDsn – string – `tcp://localhost:5555'` – an endpoint to connect to for message sending; to be changed when used inside a container;
+* webSocketPort – string – by default '8443' (ssl) or '8080';
+* webSocketSslCertificateFile
+* webSocketSslCertificateLocalPrivateKey
+* webSocketSslCertificatePassphrase
+* webSocketSslAllowSelfSigned
+* webSocketUseSecureServer
+
+## Installing ZMQ
+
+### Option 1
+
+```
+sudo apt install php-zmq
+```
+
+### Option 2
+
+If the previous won't work, try compiling.
+
+You need to have `libzmq3-dev` installed:
+
+```
+apt install libzmq3-dev
+```
+
+You need to have `php-dev` installed:
+
+```
+apt install php-dev
+```
+
+Then execute the following commands (from the *root* user):
+
+```
+cd /usr
+curl -fSL https://github.com/zeromq/php-zmq/archive/e0db82c3286da81fa8945894dd10125a528299e4.tar.gz -o php-zmq.tar.gz
+tar -zxf php-zmq.tar.gz
+cd php-zmq-e0db82c3286da81fa8945894dd10125a528299e4
+phpize && ./configure
+make
+make install
+cd .. && rm -rf php-zmq-e0db82c3286da81fa8945894dd10125a528299e4 && rm php-zmq.tar.gz
+```
+
+Then edit *php.ini* (both for the CLI and webserver), add:
+
+```
+extension=zmq
+```
+
+## Event loop implementations
+
+The default [event loop](https://github.com/reactphp/event-loop?tab=readme-ov-file#loop-implementations) implementation of the WebSocket server relies on file descriptors. By default, the maximum number of file descriptors per process may be set relatively low (commonly 1024).
+For production, it's reasonable to install [ext-ev](https://pecl.php.net/package/ev) extension, or any other recommended by ReactPHP. With the extension installed, it will automatically choose the appropriate event loop implementation.
diff --git a/docs/administration/workflows-telegram-message.md b/docs/administration/workflows-telegram-message.md
new file mode 100644
index 000000000..286cc78e1
--- /dev/null
+++ b/docs/administration/workflows-telegram-message.md
@@ -0,0 +1,49 @@
+# Sending telegram message with Workflow
+
+Since Advanced Pack version 2.4.0 it’s possible to send HTTP requests with Workflows and BPM tools.
+
+* [Workflow configuration](#workflow-configuration)
+* [Telegram configuration](#telegram-configuration)
+
+
+### Workflow configuration
+
+Create a workflow rule. Specify needed conditions and then add action Send HTTP Request.
+
+Set:
+
+**Request Type:** POST
+
+**Content-type:** None
+
+**URL:** `https://api.telegram.org/bot/sendMessage`
+
+Example: `https://api.telegram.org/bot3457233623:AAGKRIhcGSJ7bKFFh6DJMRWhyRbVBSRS53c/sendMessage`
+
+**Payload:**
+
+```
+{
+ "chat_id": "CHAT_ID",
+ "text": "Created new Contact:\n {$name}/n *Phone number:* {$phoneNumber}",
+ "parse_mode": "Markdown"
+}
+```
+
+* chat_id supports 2 formats:
+ - -1003332162016
+ - @chat-name
+* text supports:
+ - plain text.
+ - Target Entity variables (e.g. {$description}, {$name}, {$phoneNumber}, etc.).
+ - Markdown text.
+* "parse_mode" is optional parameter. Can send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption.
+
+You can read more about bot request methods and payloads [here](https://core.telegram.org/bots/api).
+
+### Telegram configuration
+
+1. Create a new Telegram channel.
+2. Create a new [Telegram bot](https://core.telegram.org/bots#3-how-do-i-create-a-bot).
+3. Add the bot to your Telegram channel.
+4. Add the bot to the channel admins group.
\ No newline at end of file
diff --git a/docs/administration/workflows.md b/docs/administration/workflows.md
index 1ceb2a941..d5bbed3f7 100644
--- a/docs/administration/workflows.md
+++ b/docs/administration/workflows.md
@@ -1,13 +1,30 @@
+---
+search:
+ boost: 2
+tags:
+ - automation
+---
+
# Workflows
-Workflows feature is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
+The Workflows tool is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
+
+The Workflows tool automates your business processes in an easy way. Possible use cases of what can be achieved:
+
+* Automatically modify records when specific conditions are met.
+* Define assignment rules for efficient task distribution.
+* Add buttons on the record detail view to trigger business logic actions.
+* Integrate Espo with external systems through an API for data exchange.
+* And many more.
-Workflows automate your business process in an easy way. You can access workflows from Administration panel. To create a workflow rule you need to define:
+You can access Workflows from the Administration panel. Only administrators can view or configure workflows.
-* Target Entity – what entity type a workflow is applied to;
-* Trigger Type – when a workflow will be triggered;
-* Conditions – conditions need to be met to trigger a workflow;
-* Actions – what to do if a workflow is triggered.
+When creating a Workflow rule, you need to set:
+
+* Target entity type – the entity type the rule is applied to;
+* Trigger type – how the rule will be triggered;
+* Conditions – conditions need to be met to trigger the rule;
+* Actions – what actions to perform when the rule is triggered.
In this article:
@@ -15,9 +32,20 @@ In this article:
* [Conditions](#conditions)
* [Actions](#actions)
* [Using formula in actions](#using-formula-in-actions)
+* [Formula functions](#formula-functions)
+* [Config parameters](#config-parameters)
+* [See also](#see-also)
## Trigger types
+* [After record created](#after-record-created)
+* [After record updated](#after-record-updated)
+* [After record create or updated](#after-record-created-or-updated)
+* [Manual](#manual)
+* [Scheduled](#scheduled)
+* [Sequential](#sequential)
+* [Signal](#signal)
+
### After record created
Triggered only when a new record is created. If specified conditions are met, then actions will be executed.
@@ -26,15 +54,39 @@ Triggered only when a new record is created. If specified conditions are met, th
Triggered only when an existing record is updated. If specified conditions are met, then actions will be executed.
-### After record saved
+!!! important
+
+ Be aware of potential loops. A built-in safeguard prevents looping in basic cases. However, loops can still occur – for example, when using a formula to update records.
+
+### After record created or updated
Triggered when a new record is created or an existing record is updated. If specified conditions are met, then actions will be executed.
-For workflow rules with this trigger type, it's a common practice to have a condition that checks whether some field was 'changed'. E.g. If Case's status is changed, then execute some actions.
+For Workflow rules with this trigger type, it's a common practice to have a condition that checks whether some field was changed. For example, if a Case's status is changed, then do some actions.
+
+### Manual
+
+*As of v2.12.*
+
+Triggered manually by a user by clicking a button (or a dropdown menu item) on the record detail view.
+
+The ability to define:
+
+* an element type (a button or a dropdown item);
+* a label text;
+* teams allowed to run the Workflow;
+* dynamic-logic conditions that make a button/menu-item available;
+* access to the record required to be able to run the Workflow (read, edit, admin).
+
+Limitations:
+
+* Portal Users are not allowed to run *Manual* Workflows.
+
+To show a custom result message use the function [workflow\alert](workflows.md#workflowalert) in an Execute Formula Script action.
### Scheduled
-Triggered according to the defined scheduling. You can setup it to run every day, every week, etc. Actions will be applied for records returned by a specified list report. So, you need also to create a list report.
+Triggered according to a defined scheduling. You can set up it to run every day, every week, etc. Actions will be applied for records returned by a specified *List* Report. Hence, you need also to create a *List* Report.
Scheduling is specified in a crontab notation.
@@ -51,51 +103,67 @@ Scheduling is specified in a crontab notation.
How it works:
-1. You need to create a list report showing records that met specific criteria. You can specify any columns for the report, it doesn't matter.
-2. Then create a workflow rule with *Scheduled* trigger type, select the report. Specify the scheduling.
-3. Specify one or multiple actions in the workflow.
+1. You need to create a *List* Report showing records that met specific criteria. You can specify any columns for the Report, it doesn't matter in this context.
+2. Then, create a Workflow rule with the *Scheduled* trigger type, select the Report you created before. Specify the needed scheduling.
+3. Specify one or multiple actions in the Workflow rule.
+
+The Workflow rule will be running in idle according to the specified scheduling. On each run, it will run the Report and obtain all records from the Report result. Then, it will apply the action (or multiple actions) for every record.
-Workflow rule will be running (in idle) according to the specified scheduling. On each run, it will execute the report and take all records from the report result. Then, it will apply the action (or multiple actions) for every record.
+!!! example "Example, a use case"
-The usage example: Send a notification email to customers who have their license expiring in 1 week. You will need a report showing contacts who have their license expiring exactly in 7 days. Setup a workflow to run once a day.
+ Send a notification email to customers who have their license expiring in 1 week. You will need a report listing contacts who have their license expiring exactly in 7 days. Set up a Workflow to run once a day.
### Sequential
-Supposed to be run by another workflow. Provides the ability to make a complex logic.
+Is supposed to be run by another Workflow. Provides the ability to create complex logic.
+
+1. Create a Workflow rule with the *Sequential* trigger type.
+2. Create another Workflow rule with another trigger type. Add an action *Trigger another Workflow* and select the Workflow rule from the step 1.
-1. Create a workflow with sequential trigger type.
-2. Create another workflow with another trigger type. Add action *Trigger another Workflow* and select the workflow from the step 1.
+!!! note
-Note: It can be reasonable to utilize [BPM tool](bpm.md) rather than Workflows if you need more complex logic.
+ It can be reasonable to utilize [BPM tool](bpm.md) rather than Workflows if you need more complex logic.
### Signal
-Triggered when a specified signal is escalated in the system. Only object signals can be used. See [more info](bpm-signals.md) about signals.
+Triggered when a specified signal is broadcast in the system. Only object signals can be used here. See [more info](bpm-signals.md) about signals.
----
## Conditions
-You can specify conditions that must be met to trigger the workflow. There are two ways how conditions can be specified: with the UI condition builder and with formula.
+You can specify conditions that must be met to trigger a Workflow rule. There are two ways how conditions can be specified: with the UI condition builder and with a Formula script.
+
+In formula, it's possible to have multiple expressions separated by a semicolon. The evaluation of the last expression will be returned as the result.
### UI condition builder
Some available condition types:
-* _equals_ - the field equals to a specific value or a value of another field;
-* _was equal_ - the field was equal to a specific value before the workflow was triggered;
-* _not equals_ - the field does not equal to a specific value or a value of another field;
-* _was not equal_ - the field was not equal to specific value before the workflow was triggered;
-* _empty_ - the field value is empty;
-* _not empty_ - the field value is not empty;
-* _changed_ - the field was changed;
-* _not changed_ - the field was not changed.
+* _equals_ – the field equals to a specific value or a value of another field;
+* _was equal_ – the field was equal to a specific value before the Workflow was triggered;
+* _not equals_ – the field does not equal to a specific value or a value of another field;
+* _was not equal_ – the field was not equal to specific value before the Workflow was triggered;
+* _empty_ – the field value is empty;
+* _not empty_ – the field value is not empty;
+* _changed_ – the field was changed;
+* _not changed_ – the field was not changed.
### Formula conditions
Formula provides the ability to define conditions of any complexity. To read about formula syntax, follow [this article](formula.md).
-Note: There should not be any `;` delimiter used in formula code when it determines a condition. It should be one expression that returns a value (TRUE of FALSE).
+!!! note
+
+ There should not be any `;` delimiter used in formula code when it determines a condition. It should be one expression that returns a value (TRUE or FALSE).
+
+!!! example
+
+ Expression with the logical AND:
+
+ ```
+ status == 'New' && assignedUserId == null
+ ```
----
@@ -113,72 +181,99 @@ Note: There should not be any `;` delimiter used in formula code when it determi
* [Make Followed](#make-followed)
* [Trigger another Workflow](#trigger-another-workflow)
* [Run Service Action](#run-service-action)
-* [Start BPM Process](#start-BPM-process)
+* [Start BPM Process](#start-bpm-process)
* [Send HTTP Request](#send-http-request)
+* [Execute Formula Script](#execute-formula-script)
### Send Email
-System will send an email using a specified email template. A recipient’s email address can be taken from the target record, any related record, the current user, followers, team users or specified. The email can be sent immediately or delayed for a specific interval.
+System will send an email using a specified Email Template. A recipient’s email address can be taken from the target record, any related record, the current user, followers, team users or specified explicitly. The email can be sent immediately or delayed for a specific interval.
-If you specify *From* address with the address of an existing Group Email Account, then SMTP parameters of that account will be used for sending.
+If you specify the *From* address with an address of an existing Group Email Account, then SMTP parameters of that account will be used for sending.
-It's possible to use the **opt-out** link in an email body.
+It's possible to add an **opt-out** link to an email body.
+
+It's possible to specify multiple email addresses by separating them with a semicolon.
+
+It's possible to use a formula variable when specifying an email address. Example: `{$$variable}`. As of v3.6.
+
+Additional attachments can be added to an email using the *Attachments Variable* parameter. Specify a Formula variable name that contains an attachment ID or an array of attachment IDs. You can generate needed attachments in a Formula script in a previous action. As of v3.6.
### Create Record
-The system will create a new record of any entity type. If there is a relationship between the target record and creating record, it's possible to relate the records.
+The system will create a new record of any entity type. If there is a relationship between the target entity type and the entity type of records being created, it's possible to relate them.
-There is an ability to define **formula** to calculate field values.
+There is the ability to define a Formula script to calculate field values.
+
+!!! note
+
+ Variables defined within the Formula script won't be available in following actions (or the BPM process). They are only available within the current script.
### Create Related Record
-System will create the record related to the target record. It's possible to define formula to calculate field values.
+The system will create the record related to a target record.
+
+It's possible to define a Formula script to calculate field values. Note: Variables defined within the Formula script will be only available within the current script.
### Update Target Record
-Allows changing of specific fields of the target record.
+Allows to change specific fields of a target record.
-It's possible to define **formula** to calculate field values. You can utilize *Update Target Record* action for executing formula script without actually updating any fields.
+It's possible to define a Formula script to calculate field values. Note: Variables defined within the Formula script will be only available within the current script.
-If you need to add new items to the Link-Multiple field w/o loosing existing data (e.g. Teams), you need to utilize formula function *entity\addLinkMultipleId*. Example: `entity\addLinkMultipleId('teams', 'teamId')`.
+!!! note
-There is the ability to **delete** the record with the following formula code: `deleted = 1`;
+ It's not recommended to rely on an *Update Target Record* action triggering another after-update Workflow. In some cases it won't work. It's better to define additional actions in the same Workflow or trigger a *Sequential* Workflow.
+
+!!! warning "Important"
+
+ Formula within an *Update Target Record* action must be utilized only for field updating. Use the *Execute Formula Script* action for any other need.
+
+For Link-Multiple, Array, Multi-Enum, and Checklist fields it's possible to add or remove items without loosing set items. For example, adding a specific Team while preserving existing Teams.
+
+There is the ability to **delete** the record with the following formula code: `deleted = true`;
### Update Related Record
-Allows changing of specific fields of the related record or records. It's possible to define formula to calculate field values.
+Allows to change specific fields of a related record (or records).
+
+It's possible to define Formula script to calculate field values. Note: Variables defined within formula won't be passed back.
-There is the ability to delete the record with the following formula code: `deleted = 1`;
+There is the ability to delete the record with the following formula code: `deleted = true`;
+
+!!! tip
+
+ If there can be many related records, it's reasonable to process updating these records in idle. For this, utilize the *Trigger Another Workflow* action with a small or zero delay. Define an *Update Related Record* action in a *Sequential* Workflow rule.
### Link with another Record
-Relates the target record with another specific record. E.g. add specific team to the record.
+Relates the target record with another specific record. For example, add specific team to the record.
### Unlink from another Record
-Unrelates the target record from another specific record. E.g. remove a specific team from the record.
+Unrelates the target record from another specific record. For example, remove a specific team from the record.
### Apply Assignment Rule
-Assigns the target record to user by distribution rule. There are two available rules: Round-Robin and Least-Busy.
+Assigns the target record to a User using a specific distribution rule. There are two available rules: *Round-Robin* and *Least-Busy*.
-* Round-Robin - users are chosen from the top to the bottom of a list (team) and then starting again.
-* Least-Busy - the user who has fewer assigned records will be chosen for assignment.
+* Round-Robin – Users are chosen from the top to the bottom of a list and then starting again.
+* Least-Busy – the User who has fewer assigned records will be chosen for assignment.
-*List Report* - determines what records will be taken into account to calculate the number of assigned records for Least-Busy distribution. E.g. we need to take only records with active status for Cases.
+*List Report* – determines what records will be taken into account to calculate the number of assigned records for *Least-Busy* distribution. For example, we need to take into account only active Cases.
-*Target Team* - Users of the selected team will take part in the assignment process.
+*Target Team* – Users of the selected team will take part in the assignment process.
-*Target User Position* - Allows to restrict the list of users that will take part in the assignment process. Users that have the selected position (in team) will take part. If the field is set to *All*, then all team members will take part.
+*Target User Position* – Allows to restrict the list of users that will take part in the assignment process. Users that have the selected position (in team) will take part. If the field is set to *All*, then all team members will take part.
### Create Notification
-Notify specific users with the message.
+Notify specific users with a message.
It's possible to use placeholders in the message template:
-* `{entity}` - a target record;
-* `{user}` - a current user.
+* `{entity}` – a target record;
+* `{user}` – a current user.
### Make Followed
@@ -186,15 +281,19 @@ Forces specific users to follow the target record or a specified related record.
### Trigger another Workflow
-Allows to make sequential workflows. It's possible to diverge workflows by condition: you can setup the workflow to trigger two workflows with different conditions defined in those workflows.
+Allows to make *Sequential* Workflows. It's possible to diverge Workflows by condition: you can set up a Workflow to trigger two Workflows with different conditions defined in those Workflows.
+
+It's possible to delay executing of a *Sequential* Workflow. In a *Sequential* Workflow, you can define the condition that checks whether specific fields were changed since the parent Workflow was triggered by using _Changed_ and _Was Equal_ condition types.
-It's possible to delay executing of a sequential workflow. In the sequential workflow, you can define the condition that checks whether specific fields were changed since the parent workflow was triggered by using _Changed_ and _Was Equal_ condition types.
+A *Target* for a triggered Workflow can be substituted with a related record.
-Target for a triggered workflow can be substituted with a related record.
+!!! note
-Note: For complex logic, it can be more reasonable to utilize [BPM tool](bpm.md) rather than Workflows.
+ For complex logic, it can be more reasonable to utilize [BPM tool](bpm.md) rather than Workflows.
-Note: It's possible to trigger only workflow rules of 'Sequential' type.
+!!! note
+
+ It's possible to trigger only Workflow rules of *Sequential* type.
### Run Service Action
@@ -209,12 +308,12 @@ Meetings/Calls:
Quotes/Sales Orders/Invoices:
* *Add Items*
-* *Convery Currency* – converts all currency values based on current rates (since version 5.7.0)
+* *Convert Currency* – converts all currency values based on current rates (since version 5.7.0)
* *Send in Email*
Opportunities:
-* *Convery Currency* (since version 5.7.0)
+* *Convert Currency*
Contacts/Leads/Accounts:
@@ -222,40 +321,156 @@ Contacts/Leads/Accounts:
Users:
-* *Generate Password* – generates a new password for a user and sends it to their email address (since version 5.7.0)
+* *Generate Password* – generates a new password for a user and sends it to their email address
Developers can write their own service actions. See [more detail](../development/workflow-service-actions.md).
### Start BPM Process
-Starts BPM process. You can specify which target will be used for a process.
+Starts a BPM process. You can specify what target record will be used for the process.
### Send HTTP Request
-Provides the ability to call external API. POST and PUT requests are suppored.
+Provides the ability to call an external API. Can be utilized to integrate Espo with other systems.
+
+Supported request methods:
-Payload should be specified in JSON format (event if *Content type* is not *application/json*). It's possible to use placeholders in payload json.
+* GET
+* POST
+* PUT
+* PATCH
+* DELETE
-Additional headers can be specified. Placeholders can be used in headers.
+Additional headers can be specified.
+
+Placeholders can be used in:
+
+* Headers
+* Request URL
+* Payload JSON
Available placeholders:
-* *{$attribute}* – a value of an attribute (field) of a target record; e.g. `{$description}`, `{$assignedUserId}` (see [info](formula.md#attribute) about attributes);
-* *{$$variable}* – a value of a variable (available only in BPM process); e.g. `{$$myVariableName}`.
+* *{$attribute}* – a value of an [attribute](terms-and-naming.md#attribute) of a target record;
+* *{$$variable}* – a value of a formula variable;
+* *{#secrets.name}* – an App Secret; available only in headers; as of v3.4.7.
-## Using formula in actions
+#### Payload
+
+A payload can be specified in a JSON format or taken from a formula variable.
+
+When specified in JSON, it's possible to use placeholders.
-It's possible to define formula to calculate fields for Create Record, Update Target Record, Create Related Record, Update Related Record. For the last two, to access attributes of target entity, you should use function `targetEntity\attribute`. To access attributes of target entity that was set before the workflow was triggered, use function `targetEntity\attributeFetched`.
+Example of payload with placeholders:
-Example:
```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
+{
+ "espoRecordId": "{$id}",
+ "name": "{$name}",
+ "userId": "{$assignedUserId}",
+ "intValue": {$$myIntegerVariable},
+ "boolValue": {$$myBooleanVariable},
+ "stringValue": "{$$myStringVariable}"
+}
```
+Alternatively, you can craft a payload in formula script, store it in a variable and then use this variable as a payload. The variable value can be an object, array, string or a scalar.
+
+#### Handling HTTP response
+
+A response body of an HTTP request will be available in formula with the function `workflow\lastHttpResponseBody()`. It can be accessed in the following workflow actions within the workflow rule. For example, in an Execute Formula Script action.
+
+JSON attributes can be retrieved with the function `json\retrieve`.
+
+!!! example
+
+ A POST request returns a JSON body `{"id": "SOME_ID"}`. We need to store that ID. Add a *Update Target Record* action in the same Workflow rule with the formula script:
+
+ ```
+ $id = json\retrieve(workflow\lastHttpResponseBody(), 'id');
+ entity\setAttribute('someIdField', $id);
+ ```
+
+!!! note
+
+ In the context of a BPM process, the last response body is available only within the Task that contains the Send HTTP Request action. The response won't be passed further along the process flow. But if you assign the response value to a variable, the variable will be passed further.
+
+In the context of a BPM process, it's possible to catch response errors with an Error Boundary Event. The error code can be obtained by using `bpm\caughtErrorCode` function.
+
+### Execute Formula Script
+
+Executes a [formula](formula.md) script.
+
+Variables defined within the script will be passed back. They will be available in the following Workflow actions within the rule. When used in a BPM process, the defined variables will be available further in the flow.
+
+## Using formula in actions
+
+It's possible to define formula to calculate fields in the following actions:
+
+* Execute Formula Script,
+* Create Record,
+* Update Target Record,
+* Create Related Record,
+* Update Related Record.
+
+## Formula functions
+
+#### workflow\targetEntity\attribute
+
+`workflow\targetEntity\attribute(ATTRIBUTE_NAME)`
+
+Returns an attribute value of the target entity. Useful when the scope is switched to a related record.
+
+#### workflow\targetEntity\attributeFetched
+
+`workflow\targetEntity\attributeFetched(ATTRIBUTE_NAME)`
+
+Returns a previous attribute value of the target entity (before the Workflow was triggered).
+
+#### workflow\trigger
+
+`workflow\trigger(ENTITY_TYPE, ID, WORKFLOW_ID)`
+
+Triggers another Workflow rule.
+
+#### workflow\signalParam
+
+`workflow\signalParam(PARAM)`
+
+Get a signal param.
+
+#### workflow\lastCreatedEntityId
+
+`workflow\lastCreatedEntityId()`
+
+*As of v3.9.*
+
+Returns the ID of the last record that has been created within the workflow rule by a *Create Record* or *Created Related Record* action. Available only within a workflow rule and within a BPM's Task activity.
+
+#### workflow\alert
+
+`workflow\alert(MESSAGE, [AUTO_CLOSE], [TYPE])`
+
+*As of v3.9.*
+
+Sets an alert message to show for the user after a manual workflow in run. AUTO_CLOSE is boolean. TYPE can be `"warning"`, `"danger"`, `"success"`, `"info"`.
+
+Markdown is supported. It enables the ability to display a link for the user.
+
+!!! note
+
+ The alert function only works in the context of the manual workflow. It won't work if called from a BPM processes started by the manual workflow. It won't work if called from another workflow initiated by the manual workflow.
+
+## Config parameters
+
+* `workflowSendRequestTimeout` – `7` – a timeout for the Send HTTP Request action;
+* `workflowEmailSiteUrl` – to override the default site URL (can be helpful if there's no access to your CRM from the internet, but you need to handle opting out & tracking URLs; you will need to configure your server to handle requests to the specified URL); the parameter is applied for emails sent using workflows and BPM;
+
## See also
+* [Quick tour](https://app.supademo.com/demo/cmf4988mv261h39ozgxi1un4e)
* [Birthday notifications in EspoCRM](https://www.espocrm.com/blog/birthday-notifications-in-espocrm/)
* [Adding custom service action for Workflows](../development/workflow-service-actions.md)
* [Automated Email-to-Lead with Workflows](https://www.espocrm.com/blog/automated-email-to-lead-with-workflows/)
* [Automatic posting to stream with Workflows](https://www.espocrm.com/blog/automatic-posting-to-stream-with-workflow/)
-* [Sending Telegram message with Workflows](https://www.espocrm.com/blog/sending-telegram-message-with-workflows/)
+* [Sending Telegram message with Workflows](workflows-telegram-message.md)
diff --git a/docs/api/index.html b/docs/api/index.html
new file mode 100644
index 000000000..0ba54f5b8
--- /dev/null
+++ b/docs/api/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ EspoCRM API Docs
+
+
+
+
+
+
+
+
diff --git a/docs/api/spec.json b/docs/api/spec.json
new file mode 100644
index 000000000..86dc215ef
--- /dev/null
+++ b/docs/api/spec.json
@@ -0,0 +1,36048 @@
+{
+ "openapi": "3.1.1",
+ "info": {
+ "title": "EspoCRM API",
+ "version": "1.0.0"
+ },
+ "paths": {
+ "\/Account": {
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Account_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Account",
+ "description": "Create a new 'Account' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Account"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "customers",
+ "resellers",
+ "partners",
+ "recentlyCreated"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "website",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "type",
+ "industry",
+ "sicCode",
+ "contactRole",
+ "contactIsInactive",
+ "billingAddressStreet",
+ "billingAddressCity",
+ "billingAddressState",
+ "billingAddressCountry",
+ "billingAddressPostalCode",
+ "shippingAddressStreet",
+ "shippingAddressCity",
+ "shippingAddressState",
+ "shippingAddressCountry",
+ "shippingAddressPostalCode",
+ "description",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "billingAddressMap",
+ "shippingAddressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account",
+ "description": "List Account records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Account"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "summary": "Read Account",
+ "description": "Read an existing 'Account' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Account"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Account"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Version-Number",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A version number for optimistic concurrency control. Obtained from the 'versionNumber' field."
+ }
+ ],
+ "summary": "Update Account",
+ "description": "Update an existing 'Account' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Account"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "summary": "Remove Account",
+ "description": "Remove an existing 'Account' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/calls": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . calls",
+ "description": "List 'Call' records related through the 'calls' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . calls",
+ "description": "Relate 'Call' record though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . calls",
+ "description": "Unrelate 'Call' record related though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/callsPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . callsPrimary",
+ "description": "List 'Call' records related through the 'callsPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . callsPrimary",
+ "description": "Relate 'Call' record though the 'callsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . callsPrimary",
+ "description": "Unrelate 'Call' record related though the 'callsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/cases": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "closed"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "number",
+ "status",
+ "priority",
+ "type",
+ "description",
+ "accountId",
+ "accountName",
+ "leadId",
+ "leadName",
+ "contactId",
+ "contactName",
+ "contactsIds",
+ "contactsNames",
+ "inboundEmailId",
+ "inboundEmailName",
+ "originalEmailId",
+ "originalEmailName",
+ "isInternal",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . cases",
+ "description": "List 'Case' records related through the 'cases' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Case"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . cases",
+ "description": "Relate 'Case' record though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . cases",
+ "description": "Unrelate 'Case' record related though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/contactsPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . contactsPrimary",
+ "description": "List 'Contact' records related through the 'contactsPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . contactsPrimary",
+ "description": "Relate 'Contact' record though the 'contactsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . contactsPrimary",
+ "description": "Unrelate 'Contact' record related though the 'contactsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/documents": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "draft"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "fileId",
+ "fileName",
+ "status",
+ "type",
+ "publishDate",
+ "expirationDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "accountsIds",
+ "accountsNames",
+ "folderId",
+ "folderName"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . documents",
+ "description": "List 'Document' records related through the 'documents' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Document"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . documents",
+ "description": "Relate 'Document' record though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . documents",
+ "description": "Unrelate 'Document' record related though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/emails": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . emails",
+ "description": "List 'Email' records related through the 'emails' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . emails",
+ "description": "Relate 'Email' record though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . emails",
+ "description": "Unrelate 'Email' record related though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/emailsPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . emailsPrimary",
+ "description": "List 'Email' records related through the 'emailsPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . emailsPrimary",
+ "description": "Relate 'Email' record though the 'emailsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . emailsPrimary",
+ "description": "Unrelate 'Email' record related though the 'emailsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/meetings": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . meetings",
+ "description": "List 'Meeting' records related through the 'meetings' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . meetings",
+ "description": "Relate 'Meeting' record though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . meetings",
+ "description": "Unrelate 'Meeting' record related though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/meetingsPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . meetingsPrimary",
+ "description": "List 'Meeting' records related through the 'meetingsPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . meetingsPrimary",
+ "description": "Relate 'Meeting' record though the 'meetingsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . meetingsPrimary",
+ "description": "Unrelate 'Meeting' record related though the 'meetingsPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/opportunities": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "won",
+ "lost"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "amountCurrency",
+ "amount",
+ "amountConverted",
+ "amountWeightedConverted",
+ "accountId",
+ "accountName",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "contactId",
+ "contactName",
+ "stage",
+ "lastStage",
+ "probability",
+ "leadSource",
+ "closeDate",
+ "description",
+ "campaignId",
+ "campaignName",
+ "originalLeadId",
+ "originalLeadName",
+ "contactRole",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . opportunities",
+ "description": "List 'Opportunity' records related through the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . opportunities",
+ "description": "Relate 'Opportunity' record though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . opportunities",
+ "description": "Unrelate 'Opportunity' record related though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/portalUsers": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . portalUsers",
+ "description": "List 'User' records related through the 'portalUsers' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . portalUsers",
+ "description": "Relate 'User' record though the 'portalUsers' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . portalUsers",
+ "description": "Unrelate 'User' record related though the 'portalUsers' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/targetLists": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "categoryId",
+ "categoryName",
+ "entryCount",
+ "optedOutCount",
+ "description",
+ "sourceCampaignId",
+ "sourceCampaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "includingActionList",
+ "excludingActionList",
+ "targetStatus",
+ "isOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . targetLists",
+ "description": "List 'TargetList' records related through the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . targetLists",
+ "description": "Relate 'TargetList' record though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . targetLists",
+ "description": "Unrelate 'TargetList' record related though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/tasks": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . tasks",
+ "description": "List 'Task' records related through the 'tasks' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . tasks",
+ "description": "Relate 'Task' record though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . tasks",
+ "description": "Unrelate 'Task' record related though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/tasksPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . tasksPrimary",
+ "description": "List 'Task' records related through the 'tasksPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . tasksPrimary",
+ "description": "Relate 'Task' record though the 'tasksPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . tasksPrimary",
+ "description": "Unrelate 'Task' record related though the 'tasksPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Account\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Account"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Account . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Account . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Account"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Account . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Call": {
+ "post": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Call_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Call",
+ "description": "Create a new 'Call' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Call"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Call"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Call",
+ "description": "List Call records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Call\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Call"
+ ],
+ "summary": "Read Call",
+ "description": "Read an existing 'Call' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Call"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Call"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update Call",
+ "description": "Update an existing 'Call' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Call"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Call"
+ ],
+ "summary": "Remove Call",
+ "description": "Remove an existing 'Call' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Call\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Call"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Call . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Call . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Call . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Call\/{id}\/leads": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Call"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "active",
+ "converted"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "title",
+ "status",
+ "source",
+ "industry",
+ "opportunityAmountCurrency",
+ "opportunityAmount",
+ "opportunityAmountConverted",
+ "website",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "description",
+ "convertedAt",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "accountName",
+ "assignedUserId",
+ "assignedUserName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamsIds",
+ "teamsNames",
+ "campaignId",
+ "campaignName",
+ "createdAccountId",
+ "createdAccountName",
+ "createdContactId",
+ "createdContactName",
+ "createdOpportunityId",
+ "createdOpportunityName",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Call . leads",
+ "description": "List 'Lead' records related through the 'leads' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Lead"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Call . leads",
+ "description": "Relate 'Lead' record though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Call . leads",
+ "description": "Unrelate 'Lead' record related though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Call\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Call"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Call . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Call . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Call . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Call\/{id}\/users": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Call"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Call . users",
+ "description": "List 'User' records related through the 'users' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Call . users",
+ "description": "Relate 'User' record though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Call"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Call . users",
+ "description": "Unrelate 'User' record related though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign": {
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Campaign_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Campaign",
+ "description": "Create a new 'Campaign' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Campaign"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "type",
+ "startDate",
+ "endDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "excludingTargetListsIds",
+ "excludingTargetListsNames",
+ "sentCount",
+ "openedCount",
+ "clickedCount",
+ "optedInCount",
+ "optedOutCount",
+ "bouncedCount",
+ "hardBouncedCount",
+ "softBouncedCount",
+ "leadCreatedCount",
+ "openedPercentage",
+ "clickedPercentage",
+ "optedOutPercentage",
+ "bouncedPercentage",
+ "revenueCurrency",
+ "revenue",
+ "budgetCurrency",
+ "budget",
+ "contactsTemplateId",
+ "contactsTemplateName",
+ "leadsTemplateId",
+ "leadsTemplateName",
+ "accountsTemplateId",
+ "accountsTemplateName",
+ "usersTemplateId",
+ "usersTemplateName",
+ "mailMergeOnlyWithAddress",
+ "revenueConverted",
+ "budgetConverted"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign",
+ "description": "List Campaign records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Campaign"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "summary": "Read Campaign",
+ "description": "Read an existing 'Campaign' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Campaign"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Campaign"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update Campaign",
+ "description": "Update an existing 'Campaign' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Campaign"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "summary": "Remove Campaign",
+ "description": "Remove an existing 'Campaign' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}\/accounts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "customers",
+ "resellers",
+ "partners",
+ "recentlyCreated"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "website",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "type",
+ "industry",
+ "sicCode",
+ "contactRole",
+ "contactIsInactive",
+ "billingAddressStreet",
+ "billingAddressCity",
+ "billingAddressState",
+ "billingAddressCountry",
+ "billingAddressPostalCode",
+ "shippingAddressStreet",
+ "shippingAddressCity",
+ "shippingAddressState",
+ "shippingAddressCountry",
+ "shippingAddressPostalCode",
+ "description",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "billingAddressMap",
+ "shippingAddressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign . accounts",
+ "description": "List 'Account' records related through the 'accounts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Account"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Campaign . accounts",
+ "description": "Relate 'Account' record though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Campaign . accounts",
+ "description": "Unrelate 'Account' record related though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Campaign . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Campaign . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}\/excludingTargetLists": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "categoryId",
+ "categoryName",
+ "entryCount",
+ "optedOutCount",
+ "description",
+ "sourceCampaignId",
+ "sourceCampaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "includingActionList",
+ "excludingActionList",
+ "targetStatus",
+ "isOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign . excludingTargetLists",
+ "description": "List 'TargetList' records related through the 'excludingTargetLists' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Campaign . excludingTargetLists",
+ "description": "Relate 'TargetList' record though the 'excludingTargetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Campaign . excludingTargetLists",
+ "description": "Unrelate 'TargetList' record related though the 'excludingTargetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}\/leads": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "active",
+ "converted"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "title",
+ "status",
+ "source",
+ "industry",
+ "opportunityAmountCurrency",
+ "opportunityAmount",
+ "opportunityAmountConverted",
+ "website",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "description",
+ "convertedAt",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "accountName",
+ "assignedUserId",
+ "assignedUserName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamsIds",
+ "teamsNames",
+ "campaignId",
+ "campaignName",
+ "createdAccountId",
+ "createdAccountName",
+ "createdContactId",
+ "createdContactName",
+ "createdOpportunityId",
+ "createdOpportunityName",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign . leads",
+ "description": "List 'Lead' records related through the 'leads' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Lead"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Campaign . leads",
+ "description": "Relate 'Lead' record though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Campaign . leads",
+ "description": "Unrelate 'Lead' record related though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}\/opportunities": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "won",
+ "lost"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "amountCurrency",
+ "amount",
+ "amountConverted",
+ "amountWeightedConverted",
+ "accountId",
+ "accountName",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "contactId",
+ "contactName",
+ "stage",
+ "lastStage",
+ "probability",
+ "leadSource",
+ "closeDate",
+ "description",
+ "campaignId",
+ "campaignName",
+ "originalLeadId",
+ "originalLeadName",
+ "contactRole",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign . opportunities",
+ "description": "List 'Opportunity' records related through the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Campaign . opportunities",
+ "description": "Relate 'Opportunity' record though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Campaign . opportunities",
+ "description": "Unrelate 'Opportunity' record related though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}\/targetLists": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "categoryId",
+ "categoryName",
+ "entryCount",
+ "optedOutCount",
+ "description",
+ "sourceCampaignId",
+ "sourceCampaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "includingActionList",
+ "excludingActionList",
+ "targetStatus",
+ "isOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign . targetLists",
+ "description": "List 'TargetList' records related through the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Campaign . targetLists",
+ "description": "Relate 'TargetList' record though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Campaign . targetLists",
+ "description": "Unrelate 'TargetList' record related though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Campaign\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Campaign"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Campaign . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Campaign . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Campaign"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Campaign . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case": {
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Case_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Case",
+ "description": "Create a new 'Case' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Case"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "closed"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "number",
+ "status",
+ "priority",
+ "type",
+ "description",
+ "accountId",
+ "accountName",
+ "leadId",
+ "leadName",
+ "contactId",
+ "contactName",
+ "contactsIds",
+ "contactsNames",
+ "inboundEmailId",
+ "inboundEmailName",
+ "originalEmailId",
+ "originalEmailName",
+ "isInternal",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case",
+ "description": "List Case records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Case"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "summary": "Read Case",
+ "description": "Read an existing 'Case' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Case"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Case"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Version-Number",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A version number for optimistic concurrency control. Obtained from the 'versionNumber' field."
+ }
+ ],
+ "summary": "Update Case",
+ "description": "Update an existing 'Case' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Case"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "summary": "Remove Case",
+ "description": "Remove an existing 'Case' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/articles": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "published"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "language",
+ "type",
+ "portalsIds",
+ "portalsNames",
+ "publishDate",
+ "expirationDate",
+ "order",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "categoriesIds",
+ "categoriesNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "body",
+ "bodyPlain"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . articles",
+ "description": "List 'KnowledgeBaseArticle' records related through the 'articles' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of KnowledgeBaseArticle record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . articles",
+ "description": "Relate 'KnowledgeBaseArticle' record though the 'articles' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of KnowledgeBaseArticle record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . articles",
+ "description": "Unrelate 'KnowledgeBaseArticle' record related though the 'articles' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/calls": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . calls",
+ "description": "List 'Call' records related through the 'calls' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . calls",
+ "description": "Relate 'Call' record though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . calls",
+ "description": "Unrelate 'Call' record related though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/collaborators": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . collaborators",
+ "description": "List 'User' records related through the 'collaborators' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . collaborators",
+ "description": "Relate 'User' record though the 'collaborators' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . collaborators",
+ "description": "Unrelate 'User' record related though the 'collaborators' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/emails": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . emails",
+ "description": "List 'Email' records related through the 'emails' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . emails",
+ "description": "Relate 'Email' record though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . emails",
+ "description": "Unrelate 'Email' record related though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/meetings": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . meetings",
+ "description": "List 'Meeting' records related through the 'meetings' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . meetings",
+ "description": "Relate 'Meeting' record though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . meetings",
+ "description": "Unrelate 'Meeting' record related though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/tasks": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . tasks",
+ "description": "List 'Task' records related through the 'tasks' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . tasks",
+ "description": "Relate 'Task' record though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . tasks",
+ "description": "Unrelate 'Task' record related though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Case\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Case"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Case . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Case . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Case"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Case . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact": {
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Contact_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Contact",
+ "description": "Create a new 'Contact' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Contact"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact",
+ "description": "List Contact records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "summary": "Read Contact",
+ "description": "Read an existing 'Contact' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Contact"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Contact"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update Contact",
+ "description": "Update an existing 'Contact' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Contact"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "summary": "Remove Contact",
+ "description": "Remove an existing 'Contact' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/accounts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "customers",
+ "resellers",
+ "partners",
+ "recentlyCreated"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "website",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "type",
+ "industry",
+ "sicCode",
+ "contactRole",
+ "contactIsInactive",
+ "billingAddressStreet",
+ "billingAddressCity",
+ "billingAddressState",
+ "billingAddressCountry",
+ "billingAddressPostalCode",
+ "shippingAddressStreet",
+ "shippingAddressCity",
+ "shippingAddressState",
+ "shippingAddressCountry",
+ "shippingAddressPostalCode",
+ "description",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "billingAddressMap",
+ "shippingAddressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . accounts",
+ "description": "List 'Account' records related through the 'accounts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Account"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . accounts",
+ "description": "Relate 'Account' record though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . accounts",
+ "description": "Unrelate 'Account' record related though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/calls": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . calls",
+ "description": "List 'Call' records related through the 'calls' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . calls",
+ "description": "Relate 'Call' record though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . calls",
+ "description": "Unrelate 'Call' record related though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/cases": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "closed"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "number",
+ "status",
+ "priority",
+ "type",
+ "description",
+ "accountId",
+ "accountName",
+ "leadId",
+ "leadName",
+ "contactId",
+ "contactName",
+ "contactsIds",
+ "contactsNames",
+ "inboundEmailId",
+ "inboundEmailName",
+ "originalEmailId",
+ "originalEmailName",
+ "isInternal",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . cases",
+ "description": "List 'Case' records related through the 'cases' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Case"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . cases",
+ "description": "Relate 'Case' record though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . cases",
+ "description": "Unrelate 'Case' record related though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/casesPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "closed"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "number",
+ "status",
+ "priority",
+ "type",
+ "description",
+ "accountId",
+ "accountName",
+ "leadId",
+ "leadName",
+ "contactId",
+ "contactName",
+ "contactsIds",
+ "contactsNames",
+ "inboundEmailId",
+ "inboundEmailName",
+ "originalEmailId",
+ "originalEmailName",
+ "isInternal",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . casesPrimary",
+ "description": "List 'Case' records related through the 'casesPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Case"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . casesPrimary",
+ "description": "Relate 'Case' record though the 'casesPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . casesPrimary",
+ "description": "Unrelate 'Case' record related though the 'casesPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/documents": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "draft"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "fileId",
+ "fileName",
+ "status",
+ "type",
+ "publishDate",
+ "expirationDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "accountsIds",
+ "accountsNames",
+ "folderId",
+ "folderName"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . documents",
+ "description": "List 'Document' records related through the 'documents' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Document"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . documents",
+ "description": "Relate 'Document' record though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . documents",
+ "description": "Unrelate 'Document' record related though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/emails": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . emails",
+ "description": "List 'Email' records related through the 'emails' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . emails",
+ "description": "Relate 'Email' record though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . emails",
+ "description": "Unrelate 'Email' record related though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/meetings": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . meetings",
+ "description": "List 'Meeting' records related through the 'meetings' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . meetings",
+ "description": "Relate 'Meeting' record though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . meetings",
+ "description": "Unrelate 'Meeting' record related though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/opportunities": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "won",
+ "lost"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "amountCurrency",
+ "amount",
+ "amountConverted",
+ "amountWeightedConverted",
+ "accountId",
+ "accountName",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "contactId",
+ "contactName",
+ "stage",
+ "lastStage",
+ "probability",
+ "leadSource",
+ "closeDate",
+ "description",
+ "campaignId",
+ "campaignName",
+ "originalLeadId",
+ "originalLeadName",
+ "contactRole",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . opportunities",
+ "description": "List 'Opportunity' records related through the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . opportunities",
+ "description": "Relate 'Opportunity' record though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . opportunities",
+ "description": "Unrelate 'Opportunity' record related though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/opportunitiesPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "won",
+ "lost"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "amountCurrency",
+ "amount",
+ "amountConverted",
+ "amountWeightedConverted",
+ "accountId",
+ "accountName",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "contactId",
+ "contactName",
+ "stage",
+ "lastStage",
+ "probability",
+ "leadSource",
+ "closeDate",
+ "description",
+ "campaignId",
+ "campaignName",
+ "originalLeadId",
+ "originalLeadName",
+ "contactRole",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . opportunitiesPrimary",
+ "description": "List 'Opportunity' records related through the 'opportunitiesPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . opportunitiesPrimary",
+ "description": "Relate 'Opportunity' record though the 'opportunitiesPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . opportunitiesPrimary",
+ "description": "Unrelate 'Opportunity' record related though the 'opportunitiesPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/targetLists": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "categoryId",
+ "categoryName",
+ "entryCount",
+ "optedOutCount",
+ "description",
+ "sourceCampaignId",
+ "sourceCampaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "includingActionList",
+ "excludingActionList",
+ "targetStatus",
+ "isOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . targetLists",
+ "description": "List 'TargetList' records related through the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . targetLists",
+ "description": "Relate 'TargetList' record though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . targetLists",
+ "description": "Unrelate 'TargetList' record related though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/tasks": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . tasks",
+ "description": "List 'Task' records related through the 'tasks' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . tasks",
+ "description": "Relate 'Task' record though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . tasks",
+ "description": "Unrelate 'Task' record related though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/tasksPrimary": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . tasksPrimary",
+ "description": "List 'Task' records related through the 'tasksPrimary' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . tasksPrimary",
+ "description": "Relate 'Task' record though the 'tasksPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . tasksPrimary",
+ "description": "Unrelate 'Task' record related though the 'tasksPrimary' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Contact\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Contact"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Contact . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Contact . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Contact"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Contact . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Document": {
+ "post": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Document_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Document",
+ "description": "Create a new 'Document' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Document"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Document"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "draft"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "fileId",
+ "fileName",
+ "status",
+ "type",
+ "publishDate",
+ "expirationDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "accountsIds",
+ "accountsNames",
+ "folderId",
+ "folderName"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Document",
+ "description": "List Document records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Document"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Document\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Document"
+ ],
+ "summary": "Read Document",
+ "description": "Read an existing 'Document' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Document"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Document"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update Document",
+ "description": "Update an existing 'Document' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Document"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Document"
+ ],
+ "summary": "Remove Document",
+ "description": "Remove an existing 'Document' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Document\/{id}\/accounts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Document"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "customers",
+ "resellers",
+ "partners",
+ "recentlyCreated"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "website",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "type",
+ "industry",
+ "sicCode",
+ "contactRole",
+ "contactIsInactive",
+ "billingAddressStreet",
+ "billingAddressCity",
+ "billingAddressState",
+ "billingAddressCountry",
+ "billingAddressPostalCode",
+ "shippingAddressStreet",
+ "shippingAddressCity",
+ "shippingAddressState",
+ "shippingAddressCountry",
+ "shippingAddressPostalCode",
+ "description",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "billingAddressMap",
+ "shippingAddressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Document . accounts",
+ "description": "List 'Account' records related through the 'accounts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Account"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Document . accounts",
+ "description": "Relate 'Account' record though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Document . accounts",
+ "description": "Unrelate 'Account' record related though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Document\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Document"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Document . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Document . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Document . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Document\/{id}\/leads": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Document"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "active",
+ "converted"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "title",
+ "status",
+ "source",
+ "industry",
+ "opportunityAmountCurrency",
+ "opportunityAmount",
+ "opportunityAmountConverted",
+ "website",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "description",
+ "convertedAt",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "accountName",
+ "assignedUserId",
+ "assignedUserName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamsIds",
+ "teamsNames",
+ "campaignId",
+ "campaignName",
+ "createdAccountId",
+ "createdAccountName",
+ "createdContactId",
+ "createdContactName",
+ "createdOpportunityId",
+ "createdOpportunityName",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Document . leads",
+ "description": "List 'Lead' records related through the 'leads' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Lead"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Document . leads",
+ "description": "Relate 'Lead' record though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Document . leads",
+ "description": "Unrelate 'Lead' record related though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Document\/{id}\/opportunities": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Document"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "won",
+ "lost"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "amountCurrency",
+ "amount",
+ "amountConverted",
+ "amountWeightedConverted",
+ "accountId",
+ "accountName",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "contactId",
+ "contactName",
+ "stage",
+ "lastStage",
+ "probability",
+ "leadSource",
+ "closeDate",
+ "description",
+ "campaignId",
+ "campaignName",
+ "originalLeadId",
+ "originalLeadName",
+ "contactRole",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Document . opportunities",
+ "description": "List 'Opportunity' records related through the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Document . opportunities",
+ "description": "Relate 'Opportunity' record though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Opportunity record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Document . opportunities",
+ "description": "Unrelate 'Opportunity' record related though the 'opportunities' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Document\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Document"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Document . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Document . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Document"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Document . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Email": {
+ "post": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Email_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Email",
+ "description": "Create a new 'Email' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Email"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Email"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Email",
+ "description": "List Email records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Email\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Email"
+ ],
+ "summary": "Read Email",
+ "description": "Read an existing 'Email' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Email"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Email"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update Email",
+ "description": "Update an existing 'Email' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Email"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Email"
+ ],
+ "summary": "Remove Email",
+ "description": "Remove an existing 'Email' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Email\/{id}\/assignedUsers": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Email"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Email . assignedUsers",
+ "description": "List 'User' records related through the 'assignedUsers' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Email . assignedUsers",
+ "description": "Relate 'User' record though the 'assignedUsers' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Email . assignedUsers",
+ "description": "Unrelate 'User' record related though the 'assignedUsers' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Email\/{id}\/replies": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Email"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Email . replies",
+ "description": "List 'Email' records related through the 'replies' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Email . replies",
+ "description": "Relate 'Email' record though the 'replies' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Email . replies",
+ "description": "Unrelate 'Email' record related though the 'replies' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Email\/{id}\/tasks": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Email"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Email . tasks",
+ "description": "List 'Task' records related through the 'tasks' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Email . tasks",
+ "description": "Relate 'Task' record though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Email . tasks",
+ "description": "Unrelate 'Task' record related though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Email\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Email"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Email . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Email . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Email . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Email\/{id}\/users": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Email"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Email . users",
+ "description": "List 'User' records related through the 'users' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Email . users",
+ "description": "Relate 'User' record though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Email"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Email . users",
+ "description": "Unrelate 'User' record related though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/KnowledgeBaseArticle": {
+ "post": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create KnowledgeBaseArticle",
+ "description": "Create a new 'KnowledgeBaseArticle' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "published"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "language",
+ "type",
+ "portalsIds",
+ "portalsNames",
+ "publishDate",
+ "expirationDate",
+ "order",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "categoriesIds",
+ "categoriesNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "body",
+ "bodyPlain"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List KnowledgeBaseArticle",
+ "description": "List KnowledgeBaseArticle records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/KnowledgeBaseArticle\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "summary": "Read KnowledgeBaseArticle",
+ "description": "Read an existing 'KnowledgeBaseArticle' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Version-Number",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A version number for optimistic concurrency control. Obtained from the 'versionNumber' field."
+ }
+ ],
+ "summary": "Update KnowledgeBaseArticle",
+ "description": "Update an existing 'KnowledgeBaseArticle' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "summary": "Remove KnowledgeBaseArticle",
+ "description": "Remove an existing 'KnowledgeBaseArticle' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/KnowledgeBaseArticle\/{id}\/cases": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "closed"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "number",
+ "status",
+ "priority",
+ "type",
+ "description",
+ "accountId",
+ "accountName",
+ "leadId",
+ "leadName",
+ "contactId",
+ "contactName",
+ "contactsIds",
+ "contactsNames",
+ "inboundEmailId",
+ "inboundEmailName",
+ "originalEmailId",
+ "originalEmailName",
+ "isInternal",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List KnowledgeBaseArticle . cases",
+ "description": "List 'Case' records related through the 'cases' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Case"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate KnowledgeBaseArticle . cases",
+ "description": "Relate 'Case' record though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate KnowledgeBaseArticle . cases",
+ "description": "Unrelate 'Case' record related though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/KnowledgeBaseArticle\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List KnowledgeBaseArticle . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate KnowledgeBaseArticle . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "KnowledgeBaseArticle"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate KnowledgeBaseArticle . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead": {
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Lead_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Lead",
+ "description": "Create a new 'Lead' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Lead"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "active",
+ "converted"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "title",
+ "status",
+ "source",
+ "industry",
+ "opportunityAmountCurrency",
+ "opportunityAmount",
+ "opportunityAmountConverted",
+ "website",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "description",
+ "convertedAt",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "accountName",
+ "assignedUserId",
+ "assignedUserName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamsIds",
+ "teamsNames",
+ "campaignId",
+ "campaignName",
+ "createdAccountId",
+ "createdAccountName",
+ "createdContactId",
+ "createdContactName",
+ "createdOpportunityId",
+ "createdOpportunityName",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead",
+ "description": "List Lead records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Lead"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "summary": "Read Lead",
+ "description": "Read an existing 'Lead' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Lead"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Lead"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update Lead",
+ "description": "Update an existing 'Lead' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Lead"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "summary": "Remove Lead",
+ "description": "Remove an existing 'Lead' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/calls": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . calls",
+ "description": "List 'Call' records related through the 'calls' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . calls",
+ "description": "Relate 'Call' record though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . calls",
+ "description": "Unrelate 'Call' record related though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/cases": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "closed"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "number",
+ "status",
+ "priority",
+ "type",
+ "description",
+ "accountId",
+ "accountName",
+ "leadId",
+ "leadName",
+ "contactId",
+ "contactName",
+ "contactsIds",
+ "contactsNames",
+ "inboundEmailId",
+ "inboundEmailName",
+ "originalEmailId",
+ "originalEmailName",
+ "isInternal",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . cases",
+ "description": "List 'Case' records related through the 'cases' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Case"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . cases",
+ "description": "Relate 'Case' record though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Case record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . cases",
+ "description": "Unrelate 'Case' record related though the 'cases' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/documents": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "draft"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "fileId",
+ "fileName",
+ "status",
+ "type",
+ "publishDate",
+ "expirationDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "accountsIds",
+ "accountsNames",
+ "folderId",
+ "folderName"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . documents",
+ "description": "List 'Document' records related through the 'documents' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Document"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . documents",
+ "description": "Relate 'Document' record though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . documents",
+ "description": "Unrelate 'Document' record related though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/emails": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . emails",
+ "description": "List 'Email' records related through the 'emails' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . emails",
+ "description": "Relate 'Email' record though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . emails",
+ "description": "Unrelate 'Email' record related though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/meetings": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . meetings",
+ "description": "List 'Meeting' records related through the 'meetings' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . meetings",
+ "description": "Relate 'Meeting' record though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . meetings",
+ "description": "Unrelate 'Meeting' record related though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/targetLists": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "categoryId",
+ "categoryName",
+ "entryCount",
+ "optedOutCount",
+ "description",
+ "sourceCampaignId",
+ "sourceCampaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "includingActionList",
+ "excludingActionList",
+ "targetStatus",
+ "isOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . targetLists",
+ "description": "List 'TargetList' records related through the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . targetLists",
+ "description": "Relate 'TargetList' record though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . targetLists",
+ "description": "Unrelate 'TargetList' record related though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/tasks": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . tasks",
+ "description": "List 'Task' records related through the 'tasks' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . tasks",
+ "description": "Relate 'Task' record though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . tasks",
+ "description": "Unrelate 'Task' record related though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Lead\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Lead"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Lead . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Lead . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Lead"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Lead . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Meeting": {
+ "post": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Meeting_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Meeting",
+ "description": "Create a new 'Meeting' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Meeting"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Meeting",
+ "description": "List Meeting records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Meeting\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Meeting"
+ ],
+ "summary": "Read Meeting",
+ "description": "Read an existing 'Meeting' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update Meeting",
+ "description": "Update an existing 'Meeting' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Meeting"
+ ],
+ "summary": "Remove Meeting",
+ "description": "Remove an existing 'Meeting' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Meeting\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Meeting"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Meeting . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Meeting . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Meeting . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Meeting\/{id}\/leads": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Meeting"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "active",
+ "converted"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "title",
+ "status",
+ "source",
+ "industry",
+ "opportunityAmountCurrency",
+ "opportunityAmount",
+ "opportunityAmountConverted",
+ "website",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "description",
+ "convertedAt",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "accountName",
+ "assignedUserId",
+ "assignedUserName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamsIds",
+ "teamsNames",
+ "campaignId",
+ "campaignName",
+ "createdAccountId",
+ "createdAccountName",
+ "createdContactId",
+ "createdContactName",
+ "createdOpportunityId",
+ "createdOpportunityName",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Meeting . leads",
+ "description": "List 'Lead' records related through the 'leads' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Lead"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Meeting . leads",
+ "description": "Relate 'Lead' record though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Meeting . leads",
+ "description": "Unrelate 'Lead' record related though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Meeting\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Meeting"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Meeting . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Meeting . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Meeting . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Meeting\/{id}\/users": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Meeting"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Meeting . users",
+ "description": "List 'User' records related through the 'users' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Meeting . users",
+ "description": "Relate 'User' record though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Meeting"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Meeting . users",
+ "description": "Unrelate 'User' record related though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity": {
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Opportunity_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Opportunity",
+ "description": "Create a new 'Opportunity' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "open",
+ "won",
+ "lost"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "amountCurrency",
+ "amount",
+ "amountConverted",
+ "amountWeightedConverted",
+ "accountId",
+ "accountName",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "contactId",
+ "contactName",
+ "stage",
+ "lastStage",
+ "probability",
+ "leadSource",
+ "closeDate",
+ "description",
+ "campaignId",
+ "campaignName",
+ "originalLeadId",
+ "originalLeadName",
+ "contactRole",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity",
+ "description": "List Opportunity records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "summary": "Read Opportunity",
+ "description": "Read an existing 'Opportunity' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Version-Number",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A version number for optimistic concurrency control. Obtained from the 'versionNumber' field."
+ }
+ ],
+ "summary": "Update Opportunity",
+ "description": "Update an existing 'Opportunity' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Opportunity"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "summary": "Remove Opportunity",
+ "description": "Remove an existing 'Opportunity' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}\/calls": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity . calls",
+ "description": "List 'Call' records related through the 'calls' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Opportunity . calls",
+ "description": "Relate 'Call' record though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Opportunity . calls",
+ "description": "Unrelate 'Call' record related though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Opportunity . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Opportunity . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}\/documents": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "draft"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "fileId",
+ "fileName",
+ "status",
+ "type",
+ "publishDate",
+ "expirationDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "accountsIds",
+ "accountsNames",
+ "folderId",
+ "folderName"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity . documents",
+ "description": "List 'Document' records related through the 'documents' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Document"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Opportunity . documents",
+ "description": "Relate 'Document' record though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Document record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Opportunity . documents",
+ "description": "Unrelate 'Document' record related though the 'documents' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}\/emails": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity . emails",
+ "description": "List 'Email' records related through the 'emails' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Opportunity . emails",
+ "description": "Relate 'Email' record though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Opportunity . emails",
+ "description": "Unrelate 'Email' record related though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}\/meetings": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity . meetings",
+ "description": "List 'Meeting' records related through the 'meetings' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Opportunity . meetings",
+ "description": "Relate 'Meeting' record though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Opportunity . meetings",
+ "description": "Unrelate 'Meeting' record related though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}\/tasks": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity . tasks",
+ "description": "List 'Task' records related through the 'tasks' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Opportunity . tasks",
+ "description": "Relate 'Task' record though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Opportunity . tasks",
+ "description": "Unrelate 'Task' record related though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Opportunity\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Opportunity"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Opportunity . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Opportunity . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Opportunity"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Opportunity . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList": {
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/TargetList_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create TargetList",
+ "description": "Create a new 'TargetList' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "categoryId",
+ "categoryName",
+ "entryCount",
+ "optedOutCount",
+ "description",
+ "sourceCampaignId",
+ "sourceCampaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "includingActionList",
+ "excludingActionList",
+ "targetStatus",
+ "isOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList",
+ "description": "List TargetList records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "summary": "Read TargetList",
+ "description": "Read an existing 'TargetList' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update TargetList",
+ "description": "Update an existing 'TargetList' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "summary": "Remove TargetList",
+ "description": "Remove an existing 'TargetList' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}\/accounts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "customers",
+ "resellers",
+ "partners",
+ "recentlyCreated"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "website",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "type",
+ "industry",
+ "sicCode",
+ "contactRole",
+ "contactIsInactive",
+ "billingAddressStreet",
+ "billingAddressCity",
+ "billingAddressState",
+ "billingAddressCountry",
+ "billingAddressPostalCode",
+ "shippingAddressStreet",
+ "shippingAddressCity",
+ "shippingAddressState",
+ "shippingAddressCountry",
+ "shippingAddressPostalCode",
+ "description",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "billingAddressMap",
+ "shippingAddressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList . accounts",
+ "description": "List 'Account' records related through the 'accounts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Account"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate TargetList . accounts",
+ "description": "Relate 'Account' record though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate TargetList . accounts",
+ "description": "Unrelate 'Account' record related though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}\/campaigns": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "type",
+ "startDate",
+ "endDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "excludingTargetListsIds",
+ "excludingTargetListsNames",
+ "sentCount",
+ "openedCount",
+ "clickedCount",
+ "optedInCount",
+ "optedOutCount",
+ "bouncedCount",
+ "hardBouncedCount",
+ "softBouncedCount",
+ "leadCreatedCount",
+ "openedPercentage",
+ "clickedPercentage",
+ "optedOutPercentage",
+ "bouncedPercentage",
+ "revenueCurrency",
+ "revenue",
+ "budgetCurrency",
+ "budget",
+ "contactsTemplateId",
+ "contactsTemplateName",
+ "leadsTemplateId",
+ "leadsTemplateName",
+ "accountsTemplateId",
+ "accountsTemplateName",
+ "usersTemplateId",
+ "usersTemplateName",
+ "mailMergeOnlyWithAddress",
+ "revenueConverted",
+ "budgetConverted"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList . campaigns",
+ "description": "List 'Campaign' records related through the 'campaigns' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Campaign"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Campaign record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate TargetList . campaigns",
+ "description": "Relate 'Campaign' record though the 'campaigns' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Campaign record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate TargetList . campaigns",
+ "description": "Unrelate 'Campaign' record related though the 'campaigns' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}\/campaignsExcluding": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "type",
+ "startDate",
+ "endDate",
+ "description",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "excludingTargetListsIds",
+ "excludingTargetListsNames",
+ "sentCount",
+ "openedCount",
+ "clickedCount",
+ "optedInCount",
+ "optedOutCount",
+ "bouncedCount",
+ "hardBouncedCount",
+ "softBouncedCount",
+ "leadCreatedCount",
+ "openedPercentage",
+ "clickedPercentage",
+ "optedOutPercentage",
+ "bouncedPercentage",
+ "revenueCurrency",
+ "revenue",
+ "budgetCurrency",
+ "budget",
+ "contactsTemplateId",
+ "contactsTemplateName",
+ "leadsTemplateId",
+ "leadsTemplateName",
+ "accountsTemplateId",
+ "accountsTemplateName",
+ "usersTemplateId",
+ "usersTemplateName",
+ "mailMergeOnlyWithAddress",
+ "revenueConverted",
+ "budgetConverted"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList . campaignsExcluding",
+ "description": "List 'Campaign' records related through the 'campaignsExcluding' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Campaign"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Campaign record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate TargetList . campaignsExcluding",
+ "description": "Relate 'Campaign' record though the 'campaignsExcluding' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Campaign record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate TargetList . campaignsExcluding",
+ "description": "Unrelate 'Campaign' record related though the 'campaignsExcluding' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}\/contacts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "portalUsers",
+ "notPortalUsers",
+ "accountActive"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "accountAnyId",
+ "title",
+ "description",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "accountId",
+ "accountName",
+ "accountsIds",
+ "accountsColumns",
+ "accountsNames",
+ "accountRole",
+ "accountIsInactive",
+ "accountType",
+ "opportunityRole",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "portalUserId",
+ "portalUserName",
+ "hasPortalUser",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList . contacts",
+ "description": "List 'Contact' records related through the 'contacts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Contact"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate TargetList . contacts",
+ "description": "Relate 'Contact' record though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Contact record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate TargetList . contacts",
+ "description": "Unrelate 'Contact' record related though the 'contacts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}\/leads": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "active",
+ "converted"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "title",
+ "status",
+ "source",
+ "industry",
+ "opportunityAmountCurrency",
+ "opportunityAmount",
+ "opportunityAmountConverted",
+ "website",
+ "addressStreet",
+ "addressCity",
+ "addressState",
+ "addressCountry",
+ "addressPostalCode",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "doNotCall",
+ "description",
+ "convertedAt",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "accountName",
+ "assignedUserId",
+ "assignedUserName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamsIds",
+ "teamsNames",
+ "campaignId",
+ "campaignName",
+ "createdAccountId",
+ "createdAccountName",
+ "createdContactId",
+ "createdContactName",
+ "createdOpportunityId",
+ "createdOpportunityName",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "targetListIsOptedOut",
+ "originalEmailId",
+ "originalEmailName",
+ "addressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList . leads",
+ "description": "List 'Lead' records related through the 'leads' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Lead"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate TargetList . leads",
+ "description": "Relate 'Lead' record though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Lead record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate TargetList . leads",
+ "description": "Unrelate 'Lead' record related though the 'leads' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate TargetList . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate TargetList . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/TargetList\/{id}\/users": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "TargetList"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List TargetList . users",
+ "description": "List 'User' records related through the 'users' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate TargetList . users",
+ "description": "Relate 'User' record though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "TargetList"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate TargetList . users",
+ "description": "Unrelate 'User' record related though the 'users' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Task": {
+ "post": {
+ "tags": [
+ "Task"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Task_create"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Skip-Duplicate-Check",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Skip duplicate check."
+ },
+ {
+ "in": "header",
+ "name": "X-Duplicate-Source-Id",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID of the entity that is being duplicated."
+ }
+ ],
+ "summary": "Create Task",
+ "description": "Create a new 'Task' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Task"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict. May be a possible duplicate. Use X-Skip-Duplicate-Check to skip check."
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Task"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Task",
+ "description": "List Task records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Task\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Task"
+ ],
+ "summary": "Read Task",
+ "description": "Read an existing 'Task' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Task"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "Task"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Task"
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-Version-Number",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A version number for optimistic concurrency control. Obtained from the 'versionNumber' field."
+ }
+ ],
+ "summary": "Update Task",
+ "description": "Update an existing 'Task' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Task"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Task"
+ ],
+ "summary": "Remove Task",
+ "description": "Remove an existing 'Task' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "boolean",
+ "description": "Always true. Do not check the value."
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Task\/{id}\/collaborators": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Task"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Task . collaborators",
+ "description": "List 'User' records related through the 'collaborators' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Task"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Task . collaborators",
+ "description": "Relate 'User' record though the 'collaborators' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Task"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of User record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Task . collaborators",
+ "description": "Unrelate 'User' record related though the 'collaborators' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Task\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Task"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Task . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "Task"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate Task . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "Task"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate Task . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Team": {
+ "get": {
+ "tags": [
+ "Team"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List Team",
+ "description": "List Team records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/Team\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "Team"
+ ],
+ "summary": "Read Team",
+ "description": "Read an existing 'Team' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/Team"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User": {
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "in": "header",
+ "name": "X-No-Total",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "true",
+ "false"
+ ]
+ },
+ "description": "Disable calculation of the total number of records."
+ },
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "active",
+ "activePortal",
+ "activeApi",
+ "portal",
+ "api",
+ "internal"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMyTeam"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "userName",
+ "salutationName",
+ "firstName",
+ "lastName",
+ "middleName",
+ "name",
+ "type",
+ "authMethod",
+ "apiKey",
+ "secretKey",
+ "isActive",
+ "title",
+ "position",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "token",
+ "authTokenId",
+ "ipAddress",
+ "defaultTeamId",
+ "defaultTeamName",
+ "acceptanceStatus",
+ "acceptanceStatusMeetings",
+ "acceptanceStatusCalls",
+ "teamRole",
+ "teamsIds",
+ "teamsColumns",
+ "teamsNames",
+ "rolesIds",
+ "rolesNames",
+ "portalsIds",
+ "portalsNames",
+ "portalRolesIds",
+ "portalRolesNames",
+ "contactId",
+ "contactName",
+ "accountsIds",
+ "accountsNames",
+ "accountId",
+ "accountName",
+ "portalId",
+ "portalName",
+ "avatarId",
+ "avatarName",
+ "avatarColor",
+ "sendAccessInfo",
+ "gender",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "dashboardTemplateId",
+ "dashboardTemplateName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "layoutSetId",
+ "layoutSetName",
+ "auth2FA",
+ "lastAccess",
+ "emailAddressList",
+ "userEmailAddressList",
+ "excludeFromReplyEmailAddressList",
+ "recordAccessLevels",
+ "targetListIsOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User",
+ "description": "List User records.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/User"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User\/{id}": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "summary": "Read User",
+ "description": "Read an existing 'User' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/User"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "patch": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/User"
+ }
+ }
+ }
+ },
+ "parameters": [],
+ "summary": "Update User",
+ "description": "Update an existing 'User' record.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "$ref": "#\/components\/schemas\/User"
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ },
+ "409": {
+ "description": "Conflict."
+ }
+ }
+ }
+ },
+ "\/User\/{id}\/accounts": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "customers",
+ "resellers",
+ "partners",
+ "recentlyCreated"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "website",
+ "emailAddressIsOptedOut",
+ "emailAddressIsInvalid",
+ "emailAddress",
+ "emailAddressData",
+ "phoneNumberIsOptedOut",
+ "phoneNumberIsInvalid",
+ "phoneNumber",
+ "phoneNumberData",
+ "type",
+ "industry",
+ "sicCode",
+ "contactRole",
+ "contactIsInactive",
+ "billingAddressStreet",
+ "billingAddressCity",
+ "billingAddressState",
+ "billingAddressCountry",
+ "billingAddressPostalCode",
+ "shippingAddressStreet",
+ "shippingAddressCity",
+ "shippingAddressState",
+ "shippingAddressCountry",
+ "shippingAddressPostalCode",
+ "description",
+ "campaignId",
+ "campaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "targetListsIds",
+ "targetListsNames",
+ "targetListId",
+ "targetListName",
+ "originalLeadId",
+ "originalLeadName",
+ "targetListIsOptedOut",
+ "billingAddressMap",
+ "shippingAddressMap",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User . accounts",
+ "description": "List 'Account' records related through the 'accounts' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Account"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate User . accounts",
+ "description": "Relate 'Account' record though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Account record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate User . accounts",
+ "description": "Unrelate 'Account' record related though the 'accounts' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User\/{id}\/calls": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateEnd",
+ "duration",
+ "reminders",
+ "direction",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "phoneNumbersMap",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User . calls",
+ "description": "List 'Call' records related through the 'calls' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Call"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate User . calls",
+ "description": "Relate 'Call' record though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Call record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate User . calls",
+ "description": "Unrelate 'Call' record related though the 'calls' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User\/{id}\/emails": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "subject",
+ "fromName",
+ "fromAddress",
+ "fromString",
+ "replyToString",
+ "replyToName",
+ "replyToAddress",
+ "addressNameMap",
+ "from",
+ "to",
+ "cc",
+ "bcc",
+ "replyTo",
+ "personStringData",
+ "isRead",
+ "isNotRead",
+ "isReplied",
+ "isNotReplied",
+ "isImportant",
+ "inTrash",
+ "inArchive",
+ "folderId",
+ "isUsers",
+ "isUsersSent",
+ "folderName",
+ "folderStringId",
+ "folderStringName",
+ "nameHash",
+ "typeHash",
+ "idHash",
+ "messageId",
+ "messageIdInternal",
+ "emailAddress",
+ "fromEmailAddressId",
+ "fromEmailAddressName",
+ "toEmailAddressesIds",
+ "toEmailAddressesNames",
+ "ccEmailAddressesIds",
+ "ccEmailAddressesNames",
+ "bccEmailAddressesIds",
+ "bccEmailAddressesNames",
+ "replyToEmailAddressesIds",
+ "replyToEmailAddressesNames",
+ "bodyPlain",
+ "body",
+ "isHtml",
+ "status",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "hasAttachment",
+ "parentId",
+ "parentType",
+ "parentName",
+ "dateSent",
+ "deliveryDate",
+ "sendAt",
+ "isAutoReply",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "sentById",
+ "sentByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "repliedId",
+ "repliedName",
+ "repliesIds",
+ "repliesNames",
+ "isSystem",
+ "isJustSent",
+ "isBeingImported",
+ "skipNotificationMap",
+ "teamsIds",
+ "teamsNames",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "assignedUsersIds",
+ "assignedUsersNames",
+ "inboundEmailsIds",
+ "inboundEmailsNames",
+ "emailAccountsIds",
+ "emailAccountsNames",
+ "icsContents",
+ "icsEventData",
+ "icsEventUid",
+ "icsEventDateStart",
+ "icsEventDateStartDate",
+ "createEvent",
+ "createdEventId",
+ "createdEventType",
+ "createdEventName",
+ "groupFolderId",
+ "groupFolderName",
+ "groupStatusFolder",
+ "accountId",
+ "accountName",
+ "tasksIds",
+ "tasksNames"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User . emails",
+ "description": "List 'Email' records related through the 'emails' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Email"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate User . emails",
+ "description": "Relate 'Email' record though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Email record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate User . emails",
+ "description": "Unrelate 'Email' record related though the 'emails' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User\/{id}\/meetings": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "planned",
+ "held",
+ "todays"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "isAllDay",
+ "duration",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "uid",
+ "joinUrl",
+ "acceptanceStatus",
+ "usersIds",
+ "usersColumns",
+ "usersNames",
+ "contactsIds",
+ "contactsColumns",
+ "contactsNames",
+ "leadsIds",
+ "leadsColumns",
+ "leadsNames",
+ "sourceEmailId",
+ "sourceEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User . meetings",
+ "description": "List 'Meeting' records related through the 'meetings' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Meeting"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate User . meetings",
+ "description": "Relate 'Meeting' record though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Meeting record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate User . meetings",
+ "description": "Unrelate 'Meeting' record related though the 'meetings' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User\/{id}\/targetLists": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "categoryId",
+ "categoryName",
+ "entryCount",
+ "optedOutCount",
+ "description",
+ "sourceCampaignId",
+ "sourceCampaignName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "includingActionList",
+ "excludingActionList",
+ "targetStatus",
+ "isOptedOut"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User . targetLists",
+ "description": "List 'TargetList' records related through the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/TargetList"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate User . targetLists",
+ "description": "Relate 'TargetList' record though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of TargetList record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate User . targetLists",
+ "description": "Unrelate 'TargetList' record related though the 'targetLists' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User\/{id}\/tasks": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "primaryFilter",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "actual",
+ "completed",
+ "deferred",
+ "todays",
+ "actualStartingNotInFuture",
+ "overdue"
+ ]
+ },
+ "description": "A primary filter."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "status",
+ "priority",
+ "dateStart",
+ "dateStartDate",
+ "dateEnd",
+ "dateEndDate",
+ "dateCompleted",
+ "isOverdue",
+ "reminders",
+ "description",
+ "parentId",
+ "parentType",
+ "parentName",
+ "accountId",
+ "accountName",
+ "contactId",
+ "contactName",
+ "originalEmailId",
+ "originalEmailName",
+ "createdAt",
+ "modifiedAt",
+ "createdById",
+ "createdByName",
+ "modifiedById",
+ "modifiedByName",
+ "assignedUserId",
+ "assignedUserName",
+ "teamsIds",
+ "teamsNames",
+ "attachmentsIds",
+ "attachmentsNames",
+ "attachmentsTypes",
+ "collaboratorsIds",
+ "collaboratorsNames",
+ "streamUpdatedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User . tasks",
+ "description": "List 'Task' records related through the 'tasks' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Task"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate User . tasks",
+ "description": "Relate 'Task' record though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Task record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate User . tasks",
+ "description": "Unrelate 'Task' record related though the 'tasks' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ },
+ "\/User\/{id}\/teams": {
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "string"
+ },
+ "description": "A record ID."
+ }
+ ],
+ "get": {
+ "tags": [
+ "User"
+ ],
+ "parameters": [
+ {
+ "name": "offset",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "description": "A pagination offset."
+ },
+ {
+ "name": "maxSize",
+ "in": "query",
+ "schema": {
+ "type": "integer",
+ "minimum": 0,
+ "maximum": 200
+ },
+ "description": "The maximum number of records to return."
+ },
+ {
+ "name": "orderBy",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "An attribute (field) to order by."
+ },
+ {
+ "name": "order",
+ "in": "query",
+ "schema": {
+ "type": "string",
+ "enum": [
+ "asc",
+ "desc"
+ ]
+ },
+ "description": "An order direction."
+ },
+ {
+ "name": "textFilter",
+ "in": "query",
+ "schema": {
+ "type": "string"
+ },
+ "description": "A text filter query. Wildcard (*) is supported."
+ },
+ {
+ "name": "boolFilterList",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "onlyMy"
+ ]
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Bool filters."
+ },
+ {
+ "name": "attributeSelect",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "name",
+ "rolesIds",
+ "rolesNames",
+ "positionList",
+ "userRole",
+ "layoutSetId",
+ "layoutSetName",
+ "workingTimeCalendarId",
+ "workingTimeCalendarName",
+ "createdAt",
+ "modifiedAt"
+ ]
+ }
+ },
+ "style": "form",
+ "explode": false,
+ "description": "Attributes to return. Select only the necessary ones to improve performance."
+ },
+ {
+ "name": "whereGroup",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ "style": "deepObject",
+ "explode": true,
+ "description": "Where items."
+ }
+ ],
+ "summary": "List User . teams",
+ "description": "List 'Team' records related through the 'teams' link.",
+ "responses": {
+ "200": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "list": {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/Team"
+ },
+ "description": "Records."
+ },
+ "total": {
+ "type": "number",
+ "description": "The total number of records. If the total number is disabled, special values are returned: -1 – there are more records to paginate, -2 – there are no more records."
+ }
+ }
+ }
+ }
+ },
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "post": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Relate User . teams",
+ "description": "Relate 'Team' record though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "User"
+ ],
+ "requestBody": {
+ "content": {
+ "application\/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "An ID of Team record."
+ }
+ }
+ }
+ }
+ }
+ },
+ "summary": "Unrelate User . teams",
+ "description": "Unrelate 'Team' record related though the 'teams' link.",
+ "responses": {
+ "200": {
+ "description": "Success."
+ },
+ "400": {
+ "description": "Bad request. Might be a validation error. Check logs for details."
+ },
+ "403": {
+ "description": "Forbidden. Might be an access control error. Check logs for details."
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Account": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 249,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "website": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "emailAddress": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A primary email address."
+ },
+ "emailAddressData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "emailAddress": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "lower": {
+ "type": "string",
+ "readOnly": true
+ }
+ },
+ "required": [
+ "emailAddress",
+ "primary"
+ ]
+ },
+ "description": "Multiple email addresses"
+ },
+ "phoneNumber": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 36,
+ "readOnly": false,
+ "description": "A primary phone number."
+ },
+ "phoneNumberData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "phoneNumber": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "Office",
+ "Mobile",
+ "Fax",
+ "Other"
+ ]
+ }
+ },
+ "required": [
+ "phoneNumber",
+ "primary"
+ ]
+ },
+ "description": "Multiple phone numbers."
+ },
+ "type": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Customer",
+ "Investor",
+ "Partner",
+ "Reseller"
+ ]
+ },
+ "industry": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Advertising",
+ "Aerospace",
+ "Agriculture",
+ "Apparel & Accessories",
+ "Architecture",
+ "Automotive",
+ "Banking",
+ "Biotechnology",
+ "Building Materials & Equipment",
+ "Chemical",
+ "Construction",
+ "Consulting",
+ "Computer",
+ "Culture",
+ "Creative",
+ "Defense",
+ "Education",
+ "Electronics",
+ "Electric Power",
+ "Energy",
+ "Entertainment & Leisure",
+ "Finance",
+ "Food & Beverage",
+ "Grocery",
+ "Healthcare",
+ "Hospitality",
+ "Insurance",
+ "Legal",
+ "Manufacturing",
+ "Mass Media",
+ "Marketing",
+ "Mining",
+ "Music",
+ "Publishing",
+ "Petroleum",
+ "Real Estate",
+ "Retail",
+ "Service",
+ "Sports",
+ "Software",
+ "Support",
+ "Shipping",
+ "Travel",
+ "Technology",
+ "Telecommunications",
+ "Television",
+ "Transportation",
+ "Testing, Inspection & Certification",
+ "Venture Capital",
+ "Wholesale",
+ "Water"
+ ]
+ },
+ "sicCode": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 40,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "billingAddressStreet": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "billingAddressCity": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "billingAddressState": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "billingAddressCountry": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "billingAddressPostalCode": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 40,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "shippingAddressStreet": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "shippingAddressCity": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "shippingAddressState": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "shippingAddressCountry": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "shippingAddressPostalCode": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 40,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "campaignId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Campaign type."
+ },
+ "campaignName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "targetListsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the TargetList type."
+ },
+ "targetListsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "targetListId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "targetListName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "originalLeadId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Lead type."
+ },
+ "originalLeadName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "emailAddressIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "emailAddressIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "streamUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Account_create": {
+ "$ref": "#\/components\/schemas\/Account",
+ "type": "object",
+ "required": [
+ "name"
+ ]
+ },
+ "Call": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Planned",
+ "Held",
+ "Not Held"
+ ]
+ },
+ "dateStart": {
+ "type": "string",
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "dateEnd": {
+ "type": "string",
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "direction": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Outbound",
+ "Inbound"
+ ]
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "parentId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A foreign record ID."
+ },
+ "parentType": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Account",
+ "Lead",
+ "Contact",
+ "Opportunity",
+ "Case",
+ "CCompany"
+ ],
+ "description": "An entity type."
+ },
+ "parentName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Account type."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "uid": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "acceptanceStatus": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "None",
+ "Accepted",
+ "Tentative",
+ "Declined"
+ ]
+ },
+ "usersIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the User type."
+ },
+ "usersNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "usersColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "contactsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Contact type."
+ },
+ "contactsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "contactsColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "leadsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Lead type."
+ },
+ "leadsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "leadsColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": "string",
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ }
+ }
+ },
+ "Call_create": {
+ "$ref": "#\/components\/schemas\/Call",
+ "type": "object",
+ "required": [
+ "name",
+ "dateStart",
+ "dateEnd",
+ "assignedUserId"
+ ]
+ },
+ "Campaign": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Planning",
+ "Active",
+ "Inactive",
+ "Complete"
+ ]
+ },
+ "type": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Email",
+ "Newsletter",
+ "Informational Email",
+ "Web",
+ "Television",
+ "Radio",
+ "Mail"
+ ]
+ },
+ "startDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "format": "date",
+ "description": "A date."
+ },
+ "endDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "format": "date",
+ "description": "A date."
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "targetListsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the TargetList type."
+ },
+ "targetListsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "excludingTargetListsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the TargetList type."
+ },
+ "excludingTargetListsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "sentCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "openedCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "clickedCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "optedInCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "optedOutCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "bouncedCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "hardBouncedCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "softBouncedCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "leadCreatedCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "revenue": {
+ "readOnly": true,
+ "type": [
+ "number",
+ "null"
+ ],
+ "description": "A currency amount."
+ },
+ "revenueCurrency": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "enum": [
+ "USD",
+ "EUR"
+ ],
+ "readOnly": true,
+ "description": "A code."
+ },
+ "budget": {
+ "readOnly": false,
+ "type": [
+ "number",
+ "null"
+ ],
+ "description": "A currency amount."
+ },
+ "budgetCurrency": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "enum": [
+ "USD",
+ "EUR"
+ ],
+ "readOnly": false,
+ "description": "A code."
+ },
+ "contactsTemplateId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Template type."
+ },
+ "contactsTemplateName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "leadsTemplateId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Template type."
+ },
+ "leadsTemplateName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "accountsTemplateId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Template type."
+ },
+ "accountsTemplateName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "usersTemplateId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Template type."
+ },
+ "usersTemplateName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "mailMergeOnlyWithAddress": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "revenueConverted": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A currency amount converted to the default currency."
+ },
+ "budgetConverted": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A currency amount converted to the default currency."
+ }
+ }
+ },
+ "Campaign_create": {
+ "$ref": "#\/components\/schemas\/Campaign",
+ "type": "object",
+ "required": [
+ "name"
+ ]
+ },
+ "Case": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "number": {
+ "type": "integer",
+ "readOnly": true,
+ "description": "An auto-increment number."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "New",
+ "Assigned",
+ "Pending",
+ "Closed",
+ "Rejected",
+ "Duplicate"
+ ]
+ },
+ "priority": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Low",
+ "Normal",
+ "High",
+ "Urgent"
+ ]
+ },
+ "type": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Question",
+ "Incident",
+ "Problem"
+ ]
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Account type."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "leadId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Lead type."
+ },
+ "leadName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "contactId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Contact type."
+ },
+ "contactName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "contactsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Contact type."
+ },
+ "contactsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "inboundEmailId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the InboundEmail type."
+ },
+ "inboundEmailName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "originalEmailId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "originalEmailName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "isInternal": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "collaboratorsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the User type."
+ },
+ "collaboratorsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "streamUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Case_create": {
+ "$ref": "#\/components\/schemas\/Case",
+ "type": "object",
+ "required": [
+ "name"
+ ]
+ },
+ "Contact": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "salutationName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Mr.",
+ "Ms.",
+ "Mrs.",
+ "Dr."
+ ]
+ },
+ "firstName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "lastName": {
+ "type": "string",
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "title": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "emailAddress": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A primary email address."
+ },
+ "emailAddressData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "emailAddress": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "lower": {
+ "type": "string",
+ "readOnly": true
+ }
+ },
+ "required": [
+ "emailAddress",
+ "primary"
+ ]
+ },
+ "description": "Multiple email addresses"
+ },
+ "phoneNumber": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 36,
+ "readOnly": false,
+ "description": "A primary phone number."
+ },
+ "phoneNumberData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "phoneNumber": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "Mobile",
+ "Office",
+ "Home",
+ "Fax",
+ "Other"
+ ]
+ }
+ },
+ "required": [
+ "phoneNumber",
+ "primary"
+ ]
+ },
+ "description": "Multiple phone numbers."
+ },
+ "doNotCall": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "addressStreet": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "addressCity": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "addressState": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "addressCountry": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "addressPostalCode": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 40,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Account type."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "accountsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Account type."
+ },
+ "accountsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "accountsColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "role": {
+ "type": "string",
+ "maxLength": 100
+ },
+ "isInactive": {
+ "type": "boolean"
+ }
+ }
+ }
+ },
+ "accountRole": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "accountIsInactive": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "accountType": {
+ "readOnly": true,
+ "type": [
+ "string",
+ "null"
+ ]
+ },
+ "opportunityRole": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Decision Maker",
+ "Evaluator",
+ "Influencer"
+ ]
+ },
+ "acceptanceStatusMeetings": {
+ "type": "string",
+ "readOnly": false
+ },
+ "acceptanceStatusCalls": {
+ "type": "string",
+ "readOnly": false
+ },
+ "campaignId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Campaign type."
+ },
+ "campaignName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "targetListsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the TargetList type."
+ },
+ "targetListsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "targetListId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "targetListName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "portalUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "portalUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "hasPortalUser": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "originalLeadId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Lead type."
+ },
+ "originalLeadName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "originalEmailId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "originalEmailName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "middleName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "emailAddressIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "emailAddressIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "streamUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Contact_create": {
+ "$ref": "#\/components\/schemas\/Contact",
+ "type": "object",
+ "required": [
+ "lastName"
+ ]
+ },
+ "Document": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "fileId": {
+ "type": "string",
+ "readOnly": false,
+ "description": "An ID of the record of the Attachment type."
+ },
+ "fileName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Draft",
+ "Active",
+ "Canceled",
+ "Expired"
+ ]
+ },
+ "type": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Contract",
+ "NDA",
+ "EULA",
+ "License Agreement"
+ ]
+ },
+ "publishDate": {
+ "type": "string",
+ "readOnly": false,
+ "format": "date",
+ "description": "A date."
+ },
+ "expirationDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "format": "date",
+ "description": "A date."
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "accountsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Account type."
+ },
+ "accountsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "folderId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the DocumentFolder type."
+ },
+ "folderName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ }
+ }
+ },
+ "Document_create": {
+ "$ref": "#\/components\/schemas\/Document",
+ "type": "object",
+ "required": [
+ "name",
+ "fileId",
+ "publishDate"
+ ]
+ },
+ "Email": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "subject": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "fromName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "fromAddress": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "fromString": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "replyToString": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "replyToName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "replyToAddress": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "from": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "to": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "cc": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "bcc": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "replyTo": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "personStringData": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "isRead": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "isNotRead": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "isReplied": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "isNotReplied": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "isImportant": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "inTrash": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "inArchive": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "folderId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "isUsers": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "folderName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "folderStringId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "folderStringName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "messageId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "messageIdInternal": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 300,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "emailAddress": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "fromEmailAddressId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the EmailAddress type."
+ },
+ "fromEmailAddressName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "toEmailAddressesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the EmailAddress type."
+ },
+ "toEmailAddressesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "ccEmailAddressesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the EmailAddress type."
+ },
+ "ccEmailAddressesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "bccEmailAddressesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the EmailAddress type."
+ },
+ "bccEmailAddressesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "replyToEmailAddressesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the EmailAddress type."
+ },
+ "replyToEmailAddressesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "bodyPlain": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A multi-line text."
+ },
+ "body": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "isHtml": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Draft",
+ "Sending",
+ "Sent",
+ "Archived",
+ "Failed"
+ ]
+ },
+ "hasAttachment": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "parentId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A foreign record ID."
+ },
+ "parentType": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Account",
+ "Lead",
+ "Contact",
+ "Opportunity",
+ "Case",
+ "CCompany"
+ ],
+ "description": "An entity type."
+ },
+ "parentName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "dateSent": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "deliveryDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "sendAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "isAutoReply": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "sentById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "sentByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "repliedId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Email type."
+ },
+ "repliedName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "repliesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the Email type."
+ },
+ "repliesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "repliesColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "enum": [
+ "Draft",
+ "Sending",
+ "Sent",
+ "Archived",
+ "Failed"
+ ]
+ }
+ }
+ }
+ },
+ "isSystem": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "usersIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the User type."
+ },
+ "usersNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "usersColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "inTrash": {
+ "type": "boolean"
+ },
+ "folderId": {
+ "type": "string"
+ },
+ "inArchive": {
+ "type": "boolean"
+ },
+ "isRead": {
+ "type": "boolean"
+ }
+ }
+ }
+ },
+ "assignedUsersIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the User type."
+ },
+ "assignedUsersNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "inboundEmailsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the InboundEmail type."
+ },
+ "inboundEmailsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "emailAccountsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the EmailAccount type."
+ },
+ "emailAccountsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "icsContents": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A multi-line text."
+ },
+ "icsEventUid": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "icsEventDateStart": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "Specified if the 'icsEventDateStart' field is all-day."
+ },
+ "icsEventDateStartDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date",
+ "readOnly": true
+ },
+ "createdEventId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record ID."
+ },
+ "createdEventType": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An entity type."
+ },
+ "createdEventName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "groupFolderId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the GroupEmailFolder type."
+ },
+ "groupFolderName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "groupStatusFolder": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "enum": [
+ "Archive",
+ "Trash"
+ ]
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Account type."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "tasksIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the Task type."
+ },
+ "tasksNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "tasksColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "enum": [
+ "Not Started",
+ "Started",
+ "Completed",
+ "Canceled",
+ "Deferred"
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "Email_create": {
+ "$ref": "#\/components\/schemas\/Email",
+ "type": "object",
+ "required": [
+ "name",
+ "subject",
+ "from",
+ "to"
+ ]
+ },
+ "KnowledgeBaseArticle": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Draft",
+ "In Review",
+ "Published",
+ "Archived"
+ ]
+ },
+ "language": {
+ "type": "string",
+ "readOnly": false
+ },
+ "type": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Article"
+ ]
+ },
+ "portalsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Portal type."
+ },
+ "portalsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "publishDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "format": "date",
+ "description": "A date."
+ },
+ "expirationDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "format": "date",
+ "description": "A date."
+ },
+ "order": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "categoriesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the KnowledgeBaseCategory type."
+ },
+ "categoriesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "body": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "bodyPlain": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A multi-line text."
+ }
+ }
+ },
+ "KnowledgeBaseArticle_create": {
+ "$ref": "#\/components\/schemas\/KnowledgeBaseArticle",
+ "type": "object",
+ "required": [
+ "name"
+ ]
+ },
+ "Lead": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "salutationName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Mr.",
+ "Ms.",
+ "Mrs.",
+ "Dr."
+ ]
+ },
+ "firstName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "lastName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "title": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "New",
+ "Assigned",
+ "In Process",
+ "Converted",
+ "Recycled",
+ "Dead"
+ ]
+ },
+ "source": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Call",
+ "Email",
+ "Existing Customer",
+ "Partner",
+ "Public Relations",
+ "Web Site",
+ "Campaign",
+ "Other"
+ ]
+ },
+ "industry": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Advertising",
+ "Aerospace",
+ "Agriculture",
+ "Apparel & Accessories",
+ "Architecture",
+ "Automotive",
+ "Banking",
+ "Biotechnology",
+ "Building Materials & Equipment",
+ "Chemical",
+ "Construction",
+ "Consulting",
+ "Computer",
+ "Culture",
+ "Creative",
+ "Defense",
+ "Education",
+ "Electronics",
+ "Electric Power",
+ "Energy",
+ "Entertainment & Leisure",
+ "Finance",
+ "Food & Beverage",
+ "Grocery",
+ "Healthcare",
+ "Hospitality",
+ "Insurance",
+ "Legal",
+ "Manufacturing",
+ "Mass Media",
+ "Marketing",
+ "Mining",
+ "Music",
+ "Publishing",
+ "Petroleum",
+ "Real Estate",
+ "Retail",
+ "Service",
+ "Sports",
+ "Software",
+ "Support",
+ "Shipping",
+ "Travel",
+ "Technology",
+ "Telecommunications",
+ "Television",
+ "Transportation",
+ "Testing, Inspection & Certification",
+ "Venture Capital",
+ "Wholesale",
+ "Water"
+ ]
+ },
+ "opportunityAmount": {
+ "readOnly": false,
+ "type": [
+ "number",
+ "null"
+ ],
+ "minimum": 0,
+ "description": "A currency amount."
+ },
+ "opportunityAmountCurrency": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "enum": [
+ "USD",
+ "EUR"
+ ],
+ "readOnly": false,
+ "description": "A code."
+ },
+ "opportunityAmountConverted": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A currency amount converted to the default currency."
+ },
+ "website": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "addressStreet": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "addressCity": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "addressState": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "addressCountry": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "addressPostalCode": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 40,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "emailAddress": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A primary email address."
+ },
+ "emailAddressData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "emailAddress": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "lower": {
+ "type": "string",
+ "readOnly": true
+ }
+ },
+ "required": [
+ "emailAddress",
+ "primary"
+ ]
+ },
+ "description": "Multiple email addresses"
+ },
+ "phoneNumber": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 36,
+ "readOnly": false,
+ "description": "A primary phone number."
+ },
+ "phoneNumberData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "phoneNumber": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "Mobile",
+ "Office",
+ "Home",
+ "Fax",
+ "Other"
+ ]
+ }
+ },
+ "required": [
+ "phoneNumber",
+ "primary"
+ ]
+ },
+ "description": "Multiple phone numbers."
+ },
+ "doNotCall": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "convertedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "acceptanceStatusMeetings": {
+ "type": "string",
+ "readOnly": false
+ },
+ "acceptanceStatusCalls": {
+ "type": "string",
+ "readOnly": false
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "campaignId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Campaign type."
+ },
+ "campaignName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdAccountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Account type."
+ },
+ "createdAccountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdContactId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Contact type."
+ },
+ "createdContactName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdOpportunityId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Opportunity type."
+ },
+ "createdOpportunityName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "targetListsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the TargetList type."
+ },
+ "targetListsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "targetListId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "targetListName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "originalEmailId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "originalEmailName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "middleName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "emailAddressIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "emailAddressIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "streamUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Lead_create": {
+ "$ref": "#\/components\/schemas\/Lead",
+ "type": "object"
+ },
+ "Meeting": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Planned",
+ "Held",
+ "Not Held"
+ ]
+ },
+ "dateStart": {
+ "type": "string",
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "Specified if the 'dateStart' field is all-day."
+ },
+ "dateStartDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date",
+ "readOnly": false
+ },
+ "dateEnd": {
+ "type": "string",
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "Specified if the 'dateEnd' field is all-day."
+ },
+ "dateEndDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date",
+ "readOnly": false
+ },
+ "isAllDay": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "parentId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A foreign record ID."
+ },
+ "parentType": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Account",
+ "Lead",
+ "Contact",
+ "Opportunity",
+ "Case",
+ "CCompany"
+ ],
+ "description": "An entity type."
+ },
+ "parentName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Account type."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "uid": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "joinUrl": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 320,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "acceptanceStatus": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "None",
+ "Accepted",
+ "Tentative",
+ "Declined"
+ ]
+ },
+ "usersIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the User type."
+ },
+ "usersNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "usersColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "contactsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Contact type."
+ },
+ "contactsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "contactsColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "leadsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Lead type."
+ },
+ "leadsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "leadsColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "sourceEmailId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "sourceEmailName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": "string",
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "streamUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Meeting_create": {
+ "$ref": "#\/components\/schemas\/Meeting",
+ "type": "object",
+ "required": [
+ "name",
+ "dateStart",
+ "dateEnd",
+ "assignedUserId"
+ ]
+ },
+ "Opportunity": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "amount": {
+ "readOnly": false,
+ "type": "number",
+ "minimum": 0,
+ "description": "A currency amount."
+ },
+ "amountCurrency": {
+ "type": "string",
+ "enum": [
+ "USD",
+ "EUR"
+ ],
+ "readOnly": false,
+ "description": "A code."
+ },
+ "amountConverted": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A currency amount converted to the default currency."
+ },
+ "amountWeightedConverted": {
+ "type": [
+ "number",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Account type."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "contactsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Contact type."
+ },
+ "contactsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "contactsColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "role": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "enum": [
+ "Decision Maker",
+ "Evaluator",
+ "Influencer"
+ ]
+ }
+ }
+ }
+ },
+ "contactId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Contact type."
+ },
+ "contactName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "stage": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Prospecting",
+ "Qualification",
+ "Proposal",
+ "Negotiation",
+ "Closed Won",
+ "Closed Lost"
+ ]
+ },
+ "lastStage": {
+ "type": "string",
+ "readOnly": false
+ },
+ "probability": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": false,
+ "minimum": 0,
+ "maximum": 100
+ },
+ "leadSource": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Call",
+ "Email",
+ "Existing Customer",
+ "Partner",
+ "Public Relations",
+ "Web Site",
+ "Campaign",
+ "Other"
+ ]
+ },
+ "closeDate": {
+ "type": "string",
+ "readOnly": false,
+ "format": "date",
+ "description": "A date."
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "campaignId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Campaign type."
+ },
+ "campaignName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "originalLeadId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Lead type."
+ },
+ "originalLeadName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "contactRole": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Decision Maker",
+ "Evaluator",
+ "Influencer"
+ ]
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "streamUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Opportunity_create": {
+ "$ref": "#\/components\/schemas\/Opportunity",
+ "type": "object",
+ "required": [
+ "name",
+ "amount",
+ "amountCurrency",
+ "closeDate"
+ ]
+ },
+ "TargetList": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "categoryId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the TargetListCategory type."
+ },
+ "categoryName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "entryCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "optedOutCount": {
+ "type": [
+ "integer",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "sourceCampaignId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false
+ },
+ "sourceCampaignName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "targetStatus": {
+ "type": "string",
+ "readOnly": true,
+ "enum": [
+ "Listed",
+ "Opted Out"
+ ]
+ },
+ "isOptedOut": {
+ "type": "boolean",
+ "readOnly": true
+ }
+ }
+ },
+ "TargetList_create": {
+ "$ref": "#\/components\/schemas\/TargetList",
+ "type": "object",
+ "required": [
+ "name"
+ ]
+ },
+ "Task": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": "string",
+ "maxLength": 255,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "status": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Not Started",
+ "Started",
+ "Completed",
+ "Canceled",
+ "Deferred"
+ ]
+ },
+ "priority": {
+ "type": "string",
+ "readOnly": false,
+ "enum": [
+ "Low",
+ "Normal",
+ "High",
+ "Urgent"
+ ]
+ },
+ "dateStart": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "Specified if the 'dateStart' field is all-day."
+ },
+ "dateStartDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date",
+ "readOnly": false
+ },
+ "dateEnd": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "Specified if the 'dateEnd' field is all-day."
+ },
+ "dateEndDate": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date",
+ "readOnly": false
+ },
+ "dateCompleted": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "description": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A multi-line text."
+ },
+ "parentId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "A foreign record ID."
+ },
+ "parentType": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Account",
+ "Contact",
+ "Lead",
+ "Opportunity",
+ "Case",
+ "CCompany"
+ ],
+ "description": "An entity type."
+ },
+ "parentName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Account type."
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "contactId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Contact type."
+ },
+ "contactName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "modifiedById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "modifiedByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "assignedUserId": {
+ "type": "string",
+ "readOnly": false,
+ "description": "An ID of the record of the User type."
+ },
+ "assignedUserName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "collaboratorsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the User type."
+ },
+ "collaboratorsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "streamUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Task_create": {
+ "$ref": "#\/components\/schemas\/Task",
+ "type": "object",
+ "required": [
+ "name",
+ "assignedUserId"
+ ]
+ },
+ "Team": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "name": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "rolesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": false,
+ "description": "IDs of records of the Role type."
+ },
+ "rolesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "positionList": {
+ "type": "array",
+ "readOnly": false,
+ "items": {
+ "type": "string"
+ },
+ "description": "A multi-enum."
+ },
+ "layoutSetId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the LayoutSet type."
+ },
+ "layoutSetName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "workingTimeCalendarId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the WorkingTimeCalendar type."
+ },
+ "workingTimeCalendarName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ }
+ }
+ },
+ "Team_create": {
+ "$ref": "#\/components\/schemas\/Team",
+ "type": "object"
+ },
+ "User": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "readOnly": true,
+ "description": "An ID."
+ },
+ "userName": {
+ "type": "string",
+ "maxLength": 50,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "type": {
+ "type": "string",
+ "readOnly": true,
+ "enum": [
+ "regular",
+ "admin",
+ "portal",
+ "system",
+ "super-admin",
+ "api"
+ ]
+ },
+ "authMethod": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "enum": [
+ "ApiKey",
+ "Hmac"
+ ]
+ },
+ "apiKey": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "secretKey": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "salutationName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Mr.",
+ "Ms.",
+ "Mrs.",
+ "Dr."
+ ]
+ },
+ "firstName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "lastName": {
+ "type": "string",
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "isActive": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "title": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "position": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": true,
+ "description": "A one-line string."
+ },
+ "emailAddress": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 255,
+ "readOnly": true,
+ "description": "A primary email address."
+ },
+ "emailAddressData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "emailAddress": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "lower": {
+ "type": "string",
+ "readOnly": true
+ }
+ },
+ "required": [
+ "emailAddress",
+ "primary"
+ ]
+ },
+ "description": "Multiple email addresses",
+ "readOnly": true
+ },
+ "phoneNumber": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 36,
+ "readOnly": false,
+ "description": "A primary phone number."
+ },
+ "phoneNumberData": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "phoneNumber": {
+ "type": "string"
+ },
+ "primary": {
+ "type": "boolean"
+ },
+ "optOut": {
+ "type": "boolean"
+ },
+ "invalid": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string",
+ "enum": [
+ "Mobile",
+ "Office",
+ "Home",
+ "Fax",
+ "Other"
+ ]
+ }
+ },
+ "required": [
+ "phoneNumber",
+ "primary"
+ ]
+ },
+ "description": "Multiple phone numbers."
+ },
+ "defaultTeamId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Team type."
+ },
+ "defaultTeamName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "acceptanceStatusMeetings": {
+ "type": "string",
+ "readOnly": false
+ },
+ "acceptanceStatusCalls": {
+ "type": "string",
+ "readOnly": false
+ },
+ "teamsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the Team type."
+ },
+ "teamsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "teamsColumns": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An {ID => object} map. Relationship column values.",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "role": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "rolesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the Role type."
+ },
+ "rolesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "portalsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the Portal type."
+ },
+ "portalsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "portalRolesIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the PortalRole type."
+ },
+ "portalRolesNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "contactId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the Contact type."
+ },
+ "contactName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "accountsIds": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "IDs of records of the Account type."
+ },
+ "accountsNames": {
+ "type": [
+ "object",
+ "null"
+ ],
+ "additionalProperties": {
+ "type": "string"
+ },
+ "readOnly": true,
+ "description": "An {ID => record name} map."
+ },
+ "accountId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true
+ },
+ "accountName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "avatarId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the Attachment type."
+ },
+ "avatarName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "gender": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "enum": [
+ "Male",
+ "Female",
+ "Neutral"
+ ]
+ },
+ "createdAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "modifiedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "createdById": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the User type."
+ },
+ "createdByName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "dashboardTemplateId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": false,
+ "description": "An ID of the record of the DashboardTemplate type."
+ },
+ "dashboardTemplateName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "workingTimeCalendarId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the WorkingTimeCalendar type."
+ },
+ "workingTimeCalendarName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "layoutSetId": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "An ID of the record of the LayoutSet type."
+ },
+ "layoutSetName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "description": "A foreign record name."
+ },
+ "lastAccess": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "readOnly": true,
+ "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
+ "examples": [
+ "2026-11-29 12:34:56"
+ ],
+ "description": "A timestamp in UTC."
+ },
+ "middleName": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "maxLength": 100,
+ "readOnly": false,
+ "description": "A one-line string."
+ },
+ "emailAddressIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "emailAddressIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsOptedOut": {
+ "type": "boolean",
+ "readOnly": false
+ },
+ "phoneNumberIsInvalid": {
+ "type": "boolean",
+ "readOnly": false
+ }
+ }
+ },
+ "User_create": {
+ "$ref": "#\/components\/schemas\/User",
+ "type": "object",
+ "required": [
+ "userName",
+ "lastName"
+ ]
+ },
+ "whereItem": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "and",
+ "or",
+ "not",
+ "subQueryNotIn",
+ "subQueryIn",
+ "expression",
+ "in",
+ "notIn",
+ "equals",
+ "notEquals",
+ "on",
+ "notOn",
+ "like",
+ "notLike",
+ "startsWith",
+ "endsWith",
+ "contains",
+ "notContains",
+ "greaterThan",
+ "lessThan",
+ "greaterThanOrEquals",
+ "lessThanOrEquals",
+ "after",
+ "before",
+ "between",
+ "ever",
+ "any",
+ "none",
+ "isNull",
+ "isNotNull",
+ "isTrue",
+ "isFalse",
+ "today",
+ "past",
+ "future",
+ "lastSevenDays",
+ "lastXDays",
+ "nextXDays",
+ "olderThanXDays",
+ "afterXDays",
+ "currentMonth",
+ "nextMonth",
+ "lastMonth",
+ "currentQuarter",
+ "lastQuarter",
+ "currentYear",
+ "lastYear",
+ "currentFiscalYear",
+ "lastFiscalYear",
+ "currentFiscalQuarter",
+ "lastFiscalQuarter",
+ "arrayAnyOf",
+ "arrayNoneOf",
+ "arrayAllOf",
+ "arrayIsEmpty",
+ "arrayIsNotEmpty",
+ "linkedWith",
+ "notLinkedWith",
+ "linkedWithAll",
+ "isLinked",
+ "isNotLinked"
+ ],
+ "description": "An operator."
+ },
+ "attribute": {
+ "type": "string",
+ "description": "An attribute or field."
+ },
+ "value": {
+ "oneOf": [
+ {
+ "type": [
+ "string",
+ "integer",
+ "number",
+ "boolean",
+ "null"
+ ]
+ },
+ {
+ "type": "array",
+ "items": {
+ "$ref": "#\/components\/schemas\/whereItem"
+ }
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ],
+ "description": "A value. A scalar, or an array of strings."
+ },
+ "dateTime": {
+ "type": "boolean",
+ "description": "Set true for date-time fields."
+ },
+ "timeZone": {
+ "type": "string",
+ "description": "A time zone. For date-time fields."
+ }
+ },
+ "required": [
+ "type"
+ ],
+ "description": "A where item."
+ }
+ },
+ "securitySchemes": {
+ "ApiKeyAuth": {
+ "type": "apiKey",
+ "in": "header",
+ "name": "X-Api-Key"
+ }
+ }
+ },
+ "security": [
+ {
+ "ApiKeyAuth": []
+ }
+ ],
+ "servers": [
+ {
+ "url": "{siteUrl}\/api\/v1",
+ "variables": {
+ "siteUrl": {
+ "default": "http:\/\/localhost",
+ "description": "An URL of you Espo instance."
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/docs/css/extra.css b/docs/css/extra.css
index 66286d542..68b0e026a 100644
--- a/docs/css/extra.css
+++ b/docs/css/extra.css
@@ -1,9 +1,48 @@
:root {
- --md-link-color: #537898;
+ //--md-link-color: #537898;
--md-accent-fg-color: #af4d73;
--md-accent-fg-color-light: #cc95aa;
}
+* {
+ animation: none !important;
+ transition: none !important;
+}
+
+.md-grid {
+ max-width: 62rem;
+}
+
+.md-typeset .admonition {
+ border-style: none;
+}
+
+.md-typeset > p > img {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+
+ border-radius: 5px;
+ box-shadow: var(--md-shadow-z1);
+}
+
+label.md-nav__link:not(.md-nav__container):focus,
+label.md-nav__link:not(.md-nav__container):hover {
+ color: var(--md-typeset-color);
+}
+
+label.md-nav__link:not(.md-nav__container):hover {
+ text-decoration: underline;
+}
+
+a.md-nav__link:not(.md-nav__container):hover {
+ color: var(--md-typeset-a-color);
+}
+
+.md-nav--secondary a.md-nav__link:not(.md-nav__container):hover {
+ color: var(--md-typeset-color)
+}
+
.md-typeset h1 {
font-weight: 400 !important;
color: var(--md-default-fg-color);
@@ -25,13 +64,13 @@
.md-main a:hover,
.md-main a:visited,
.md-main a {
- color: var(--md-link-color);
+ color: var(--md-typeset-a-color);
}
.md-main a:focus,
.md-main a:hover {
text-decoration: underline !important;
- color: var(--md-link-color);
+ color: var(--md-typeset-a-color);
}
.md-nav--secondary a:focus,
@@ -59,5 +98,31 @@
}
.md-nav--secondary > .md-nav__list > .md-nav__item > .md-nav {
- display: none;
-}
\ No newline at end of file
+ font-size: 0.65rem;
+ //display: none;
+}
+
+.md-nav__list {
+ user-select: none;
+}
+
+.md-typeset table {
+ table-layout: fixed;
+ width: 100%;
+ font-size: .8rem;
+
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.md-typeset table:not([class]) {
+ display: table;
+ font-size: .8rem;
+
+ tr {
+ td, th {
+ border: .05rem solid var(--md-typeset-table-color);
+ padding: 0.6em 0.8em;
+ }
+ }
+}
diff --git a/docs/development/acl.md b/docs/development/acl.md
index 2ea83bbad..8d7c1bd35 100644
--- a/docs/development/acl.md
+++ b/docs/development/acl.md
@@ -1,285 +1,68 @@
-# ACL (access control level)
+# ACL · Access control level
-## Checking access
+## Access checking
-There are two objects that allow to check access:
+There are two [container services](di.md/#container-services) that provide the ability to check access to records, scopes and fields:
-* AclManager - `\Espo\Core\AclManager`
-* Acl - `\Espo\Core\Acl`
+* AclManager – `Espo\Core\AclManager` – to check access for any user; the user is passed as a method parameter;
+* Acl – `Espo\Core\Acl` – an *AclManager* wrapper to check access for the current user.
-With *AclManager* you can check access for any user. *Acl* is a wrapper for *AclManager* for a current user.
-
-You can obtain both objects form the *Container*.
-
-```php
-// available actions: create, read, edit, delete, stream
-
-// check read access to entity for specific user
-$hasAccess = $aclManager->check($user, $entity, 'read');
-
-// check read access to entity for current user
-$hasAccess = $acl->check($entity, 'read');
-
-// check access to scope for specific user
-$hasAccess = $aclManager->check($user, 'Account');
-
-// check create access to scope for current user
-$hasAccess = $acl->check('Account', 'create');
-
-// get access level
-$level = $aclManager->check($user, 'Account', 'edit');
-$level = $acl->check('Account', 'edit');
-
-// get permission (e.g. assignmentPermission, portalPermission)
-$assignmentPermission = $aclManager->get($user, 'assignmentPermission');
-$assignmentPermission = $acl->get('assignmentPermission');
-
-// check user is owned of record (by assigned user)
-$isOwner = $aclManager->checkIsOwner($user, $entity);
-$isOwner = $acl->checkIsOwner($entity);
-
-// check user teams set intersects with record teams
-$inTeam = $aclManager->checkInTeam($user, $entity);
-$inTeam = $acl->inTeam($entity);
-
-// attributes user doesn't have access to
-$attributeList = $aclManager->getScopeForbiddenAttributeList($user, 'Account', 'read');
-$attributeList = $acl->getScopeForbiddenAttributeList('Account', 'edit');
-
-$fieldList = $acl->getScopeForbiddenFieldList('Account', 'read');
-$linkList = $acl->getScopeForbiddenLinkList('Account', 'read');
-```
-
-## Custom ACL for entity type
-
-How to customize ACL rules for a specific entity type. In this example, we will customize Task entity type.
-
-1\. Create a file `custom/Espo/Custom/Acl/Task.php`:
+AclManager usage examples:
```php
get('assignedUserId') === $user->id ||
- $entity->get('createdById') === $user->id;
- }
-
- // checks whether entity is 'in team' for user
- // used for 'team' access level
- // omit if you don't need a custom logic for this
- public function checkInTeam(User $user, Entity $entity)
- {
- // it's a copy of the original method
- $userTeamIdList = $user->getLinkMultipleIdList('teams');
- if (!$entity->hasRelation('teams') || !$entity->hasAttribute('teamsIds')) {
- return false;
- }
- $entityTeamIdList = $entity->getLinkMultipleIdList('teams');
- if (empty($entityTeamIdList)) {
- return false;
- }
- foreach ($userTeamIdList as $id) {
- if (in_array($id, $entityTeamIdList)) {
- return true;
- }
- }
- return false;
- }
+use Espo\Core\Acl\Table;
- // checks whether entity can be deleted by user
- // omit if you don't need a custom logic for this
- public function checkEntityDelete(User $user, Entity $entity, $data)
- {
- if ($user->isAdmin())
- return true;
+// Available actions: create, read, edit, delete, stream.
- // here we call a default logic checking 'delete' access
- if ($this->checkEntity($user, $entity, $data, 'delete'))
- return true;
+// Check read access.
+$hasAccess = $aclManager->check($user, $entity, Table::ACTION_READ);
- if (is_object($data)) {
- // here we allow to delete records created by user, if the user has 'create' access and specific 'edit' access
- if ($data->create === 'yes' && $data->edit === 'all') {
- if ($entity->get('createdById') == $user->id) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- // checks whether entity can be edited by user
- // omit if you don't need a custom logic for this
- public function checkEntityEdit(User $user, Entity $entity, $data)
- {
- // custom logic here
-
- if ($this->checkEntity($user, $entity, $data, 'edit'))
- return true;
-
- // custom logic here
- }
-
- // checks whether entity can be read by user
- // omit if you don't need a custom logic for this
- public function checkEntityRead(User $user, Entity $entity, $data)
- {
- // custom logic here
+// Check access to a scope.
+$hasAccess = $aclManager->check($user, 'Account');
- if ($this->checkEntity($user, $entity, $data, 'read'))
- return true;
+// Get an access level.
+$level = $aclManager->check($user, 'Account', Table::ACTION_EDIT);
- // custom logic here
+// Get a permission level (e.g. assignment, portal).
+$assignmentPermission = $aclManager->getPermissionLevel($user, 'assignmentPermission');
- return false;
- }
+// Check the user is owned of a record (through assigned user).
+$isOwner = $aclManager->checkOwnershipOwn($user, $entity);
- // checks whether entity can be created by user
- // omit if you don't need a custom logic for this
- public function checkEntityCreate(User $user, Entity $entity, $data)
- {
- // custom logic here
+// Check a user teams set intersects with record's teams.
+$inTeam = $aclManager->checkOwnershipTeam($user, $entity);
- if ($this->checkEntity($user, $entity, $data, 'create'))
- return true;
+// Attributes/fields/links the user does not have access to.
+$attributeList = $aclManager->getScopeForbiddenAttributeList($user, 'Account', Table::ACTION_READ);
+$fieldList = $aclManager->getScopeForbiddenFieldList($user, 'Account', Table::ACTION_READ);
+$linkList = $aclManager->getScopeForbiddenLinkList($user, 'Account', Table::ACTION_READ);
- // custom logic here
- }
-}
+// Check access to a specific field.
+$hasAccess = $aclManager->checkField($user, $scope, $field, Table::ACTION_EDIT);
```
+The methods of the *Acl* service class are mostly the same as in *AclManager* but without the *$user* parameter, as the current user is used.
-2\. Create a file `custom/Espo/Custom/SelectManagers/Task.php`:
+## Custom ACL
-```php
- [
- 'assignedUserId' => $this->getUser()->id,
- 'createdById' => $this->getUser()->id,
- ]
- ];
- }
+An access checker implements access checking against an entity instance and/or a scope name for a giver user. The *data* object is passed to checking method – this object contain role table data for the user.
- // apply coditions for select query when 'read' access is set to 'team'
- protected function accessOnlyTeam(&$result)
- {
- $this->setDistinct(true, $result);
- $this->addLeftJoin(['teams', 'teamsAccess'], $result);
+For example, it check whether a user: has access to the Account, can edit Accounts, or has access to a specific Account record.
- $orGroup = [
- 'teamsAccess.id' => $this->getUser()->getLinkMultipleIdList('teams'),
- 'assignedUserId' => $this->getUser()->id,
- 'createdById' => $this->getUser()->id,
- ];
+You can define a custom [access checker](metadata/acl-defs.md#accesscheckerclassname) class for a specific scope. Note that portals use a separate access checker.
- $result['whereClause'][] = [
- 'OR' => $orGroup
- ];
- }
-}
+### Ownership checker
-```
+An ownership checker checks how the given user is related to the given entity – whether the user is an owner, the user is in the same team the record is related to, or the portal user belongs to the account the record is related to.
+You can define a custom [ownership checker](metadata/acl-defs.md#ownershipcheckerclassname) class for a specific scope. Note that portals use a separate ownership access checker.
-## Portal ACL
+### Access control filters
-1\. Create a file `custom/Espo/Custom/AclPortal/Task.php`:
+You may also need to define custom [access control filters](metadata/select-defs.md#accesscontrolfilterclassnamemap). These filters belong to the [Select framework](select-builder.md), not to the ACL framework.
-```php
-hasAttribute('createdById')) {
- if ($entity->has('createdById')) {
- if ($user->id === $entity->get('createdById')) {
- return true;
- }
- }
- }
- return false;
- }
-
- public function checkInAccount(User $user, Entity $entity)
- {
- return in_array($entity->get('accountId'), $user->getLinkMultipleIdList('accounts'));
- }
-
- public function checkIsOwnContact(User $user, Entity $entity)
- {
- if ($contactId = $user->get('contactId')) {
- $repository = $this->getEntityManager()->getRepository('Task');
- if ($repository->isRelated($entity, 'contacts', $contactId)) {
- return true;
- }
- }
- return false;
- }
-}
-```
-
-2\. Create a file `custom/Espo/Custom/SelectManagers/Task.php`:
+When the framework build a database query in order to display a record list for the user, it applies an access control filter to the query. Which exactly filter is applied – depends on the user's roles. It's also possible to customize the filter application rules with a custom [resolver](metadata/select-defs.md#accesscontrolfilterresolverclassname).
-```php
-getSeed()->hasAttribute('createdById')) {
- $result['whereClause'][] = [
- 'createdById' => $this->getUser()->id
- ];
- } else {
- $result['whereClause'][] = [
- 'id' => null
- ];
- }
- }
-
- protected function accessPortalOnlyAccount(&$result)
- {
- $result['whereClause'] = [
- 'accountId' => $this->getUser()->getLinkMultipleIdList('accounts'),
- ];
- }
-
- protected function accessPortalOnlyContact(&$result)
- {
- $this->setDistinct(true, $result);
- $this->addLeftJoin(['contacts', 'contactsAccess'], $result);
- $result['whereClause'] = [
- 'contactsAccess.id' => $this->getUser()->get('contactId'),
- ];
- }
-}
-```
diff --git a/docs/development/api-action.md b/docs/development/api-action.md
index c4e60780e..2e55ab3cf 100644
--- a/docs/development/api-action.md
+++ b/docs/development/api-action.md
@@ -1,107 +1,164 @@
-# Custom API action
+# API actions
-## Extending existing controller
+This article would be useful for those who needs to create a custom [API](api.md) action.
-Example for Account scope.
+## Routing
-Create a file (or modify if it already exists) `custom/Espo/Custom/Controllers/Account.php`.
+You can define a specific route to access your API action (endpoint).
-```php
-someKey ?? null;
+* `custom/Espo/Modules/{ModuleName}/Resources/routes.json`
+* `custom/Espo/Custom/Resources/routes.json`
- $response->setStatus(201); // this is optional, example how to set custom response status code
-
- // $someData = $this->getContainer()->get('serviceFactory')->create('MyService')
- // ->doSomething($data);
+### Example
- return $someData; // can be true, false, array or object.
- }
+`routes.json`:
- /**
- * GET api/v1/Account/action/test
- */
- public function getActionTest($params, $data, $request)
+```json
+[
{
- $myUriParam = $request->get('myUriParam');
-
- return $someData; // can be true, false, array or object.
+ "route": "/MyAction",
+ "method": "get",
+ "actionClassName": "Espo\\Modules\\MyModule\\Api\\GetMyAction"
+ },
+ {
+ "route": "/MyScope/:id/something",
+ "method": "post",
+ "actionClassName": "Espo\\Modules\\MyModule\\Api\\PostMyScopeSomething"
+ },
+ {
+ "route": "/TestNoAuth",
+ "method": "get",
+ "params": {
+ "myParam1": "MyValue1",
+ "myParam2": "MyValue2"
+ },
+ "noAuth": true
}
-}
+]
```
-Note: For Account entity type we extend `\Espo\Modules\Crm\Controllers\Account`. Some entity types might not have controllers in `\Espo\Modules\Crm\Controllers` namespace. They are defined in `\Espo\Controllers` namespace.
+Route parameters:
-## Custom controller
+* *noAuth* makes the endpoint accessible without authentication.
+* *method* specifies an HTTP method. The most used methods are: *get*, *post*, *put*, *delete*.
+* *actionClassName* defines an action class name – the entry point of the route.
+* *params* – parameters passed to the action implementation, rarely used.
-### In Custom folder
+A route can contain placeholders (for example, `:id`). The value will be passed to the Action in the Request object.
-Create a file `custom/Espo/Custom/Controllers/MyController.php`.
+A route can be processed either by an Action class or by a Controller.
+
+The API endpoint for a particular route: `https://your-site/api/v1/{route}`.
+
+Clearing cache is required after changes in routing files.
+
+## Action
+
+*As of v7.4.*
+
+!!! note
+
+ This is the preferable method.
+
+The *actionClassName* parameter in a route definition defines the action class. The action class is an entry point. Action classes should implement the `Espo\Core\Api\Action` interface.
+
+Example:
```php
getRouteParam('id') ?? throw new RuntimeException();
+
+ // Read payload.
+ $someInputValue = $request->getParsedBody()->someKey ??
+ throw new BadRequest("Key is not passed in payload.");
+
+ // Delegate the logic to some class.
+ $data = $this->service->get($id, $someInputValue);
+
+ // Output the result as JSON.
+ return ResponseComposer::json([
+ 'someKey' => $data->someKey,
+ ]);
+ }
}
```
-Clear cache (Administration > Clear Cache).
+## Route parameters
-### In Module folder
+You can define arbitrary route parameters in route definitions. The defined parameters will be available in the action class. It may be useful if you want to use the same action class for different routes but don't want to use a placeholder parameter.
-Create a file `custom/Espo/Modules/MyModule/Resources/metadata/scopes/MyController.json`.
+ `route.json`:
```json
-{
- "module": "MyModule"
-}
+[
+ {
+ "route": "Account/:id/myItems",
+ "method": "get",
+ "actionClassName": "Espo\\Modules\\MyModules\\Api\\GetItems",
+ "params": {
+ "entityType": "Account"
+ }
+ },
+ {
+ "route": "Contact/:id/myItems",
+ "method": "get",
+ "actionClassName": "Espo\\Modules\\MyModules\\Api\\GetItems",
+ "params": {
+ "entityType": "Contact"
+ }
+ }
+]
```
-Create a file `custom/Espo/Modules/MyModule/Controllers/MyController.php`.
+In the action method:
```php
getRouteParam('entityType') ?? throw new RuntimeException();
```
-Clear cache (Administration > Clear Cache).
+Instead of defining a generic route `:entityType/:id/myItems`, we defined two separate routes for specific record types.
-## Routing
+---
-You can define a specific route to access your api action.
+For most cases, the sections below won't be relevant and can be skipped.
-Default routes are defined here `application/Espo/Resources/routes.json`.
+## Controller
-Custom routes can be defined in following places:
+!!! note
-* `application/Espo/Modules/{moduleName}/Resources/routes.json`
-* `custom/Espo/Custom/Resources/routes.json`
+ Using controllers is not advisable. Prefer actions instead.
-### Example
+A Controller is an alternative to an Action class. A Controller can contain multiple methods for different actions.
-`routes.json`
+Example of `route.json` with routes mapped to controller actions:
```json
[
@@ -126,35 +183,159 @@ Custom routes can be defined in following places:
]
```
-Controller:
+### Custom controller
+
+
+#### In Custom folder
+
+Create a file `custom/Espo/Custom/Controllers/MyController.php`.
+
+```php
+ Clear Cache).
+
+#### In Module folder
+
+Create a file `custom/Espo/Modules/MyModule/Resources/metadata/scopes/MyController.json`.
+
+```json
+{
+ "module": "MyModule"
+}
+```
+
+Create a file `custom/Espo/Modules/MyModule/Controllers/MyController.php`.
```php
Clear Cache).
+
+Example:
+
+```php
+getRouteParam('id');
+ $data = $request->getParsedBody();
+
+ $result = $this->someDependency->doSomething($id, $data);
+
+ // Response can be returned or written with `Response::writeBody`.
+ return $result->toStdClass();
+ }
+}
+```
+
+### Extending existing controller
+
+!!! note
+
+ Not recommended.
+
+Example for the *Account* scope.
+Create a file (or modify if it already exists) `custom/Espo/Custom/Controllers/Account.php`.
+
+```php
+getQueryParam('someParam'); // GET parameter
+ $data = $request->getParsedBody(); // payload
- // ...
+ $someValue = $data->someKey ?? null;
+
+ $response->setStatus(201); // example how to set custom response status code
+
+ // call some service class here
+
+ return $someData; // can be true, false, array or object.
}
-
+
/**
- * POST api/v1/HelloWorld/someName
+ * GET api/v1/Account/action/test
*/
- public function postActionHelloWrold($params, $data, $request)
+ public function getActionTest(Request $request, Response $response): void
{
- $name = $params['name']; // 'someName'
+ $someParam = $request->getQueryParam('someParam'); // GET parameter
- // ...
+ // call some service class here
+
+ $response->writeBody('true');
}
}
```
-You need to clear cache after changes.
+!!! note
+
+ For the *Account* entity type, we extend `Espo\Modules\Crm\Controllers\Account`.
+ Some entity types might not have controllers in `Espo\Modules\Crm\Controllers` namespace. They are defined in `Espo\Controllers` namespace.
+
+## CRUD actions
+
+If a controller is used, the CRUD operations for a record are implemented using the methods shown below.
+
+```php
+
+ dev.array21
+ espocrm-api-client
+ VERSION
+
+```
+
+Gradle:
+```groovy
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation 'dev.array21:espocrm-api-client:VERSION'
+}
+```
+
+## Usage
+```java
+import java.io.IOException;
+import java.security.InvalidKeyException;
+
+import dev.array21.espocrm.client.ClientBuilder;
+import dev.array21.espocrm.client.EspoApiClient;
+import dev.array21.espocrm.client.RequestException;
+import dev.array21.espocrm.types.Where;
+import dev.array21.espocrm.types.FilterType;
+import dev.array21.espocrm.types.Method;
+import dev.array21.espocrm.types.Params;
+
+public class ExampleClass {
+ public static void main(String[] args) {
+ EspoApiClient client = new ClientBuilder()
+ .setHost("YOUR ESPOCRM HOST")
+ .setApiKey("YOUR ESPOCRM API KEY")
+ .setSecretKey("YOUR ESPOCRM SECRET KEY") // for HMAC method
+ .build();
+
+ Where[] whereFilter = new Where[] {
+ new Where(FilterType.EQUALS, "SomeEspoCrmField").setValue("itMustBeEqualToThis")
+ }
+
+ Params requestParams = new Params()
+ .setOffset(0)
+ .setMaxSize(50)
+ .setSelect("id")
+ .setOrderBy("id")
+ .setOrder(Order.DESC)
+ .setWhere(whereFilter);
+
+ try {
+ String jsonResponse = client.requestGet("Account", requestParams);
+ } catch(InvalidKeyException e) {
+ e.printStackTrace();
+ } catch(IOException e) {
+ e.printStackTrace();
+ } catch(RequestException e) {
+ e.printStackTrace();
+ }
+ }
+}
+```
+
+
diff --git a/docs/development/api-client-js.md b/docs/development/api-client-js.md
index 93367d135..94207a4e9 100644
--- a/docs/development/api-client-js.md
+++ b/docs/development/api-client-js.md
@@ -17,44 +17,44 @@ const client = new Client(
// POST example
-var payload = {
- name: 'some name'
+const payload = {
+ name: 'Some name',
};
-client.request('POST', 'Account', payload)
- .then(
- (response) => {
- // success
- console.log(response);
- }
- )
- .catch(
- (res) => {
- // error
- console.log(res.statusCode, res.statusMessage);
- }
- );
+client
+ .request('POST', 'Account', payload)
+ .then(response => {
+ // success
+ console.log(response);
+ })
+ .catch(response => {
+ // error
+ console.log(response.statusCode, response.statusMessage);
+ });
// GET example
-var params = {
+const params = {
maxSize: 5,
where: [
{
type: 'equals',
attribute: 'type',
- value: 'Customer'
- }
+ value: 'Customer',
+ },
],
- select: 'id,name',
+ select: ['id', name'],
};
-client.request('GET', 'Account', params)
- .then(
- (response) => {
- console.log(response);
- }
- )
+client
+ .request('GET', 'Account', params)
+ .then(response => {
+ console.log(response);
+ })
+ .catch(response => {
+ // error
+ console.log(response.statusCode, response.statusMessage);
+ });
```
## Module
@@ -62,44 +62,59 @@ client.request('GET', 'Account', params)
File `espocrm-api-client.js`:
```js
-
class Client {
- constructor (url, apiKey, secretKey, options) {
+ /**
+ *
+ * @param {string} url
+ * @param {string} apiKey
+ * @param {string|null} [secretKey]
+ * @param {{
+ * port?: number,
+ * timeout?: number,
+ * }} [options]
+ */
+ constructor(url, apiKey, secretKey = null, options = {}) {
this.url = url;
this.apiKey = apiKey;
this.secretKey = secretKey;
- if (this.url.substr(-1) == '/') {
+
+ if (this.url.substr(-1) === '/') {
this.url = this.url.substr(0, this.url.length -1);
}
+
+ this.options = options;
+
this.urlPath = '/api/v1/';
- this.options = options || {};
this.isHttps = url.toLowerCase().indexOf('https') === 0;
}
- request (method, action, data) {
+ /**
+ *
+ * @param {'GET'|'POST'|'PUT'|'DELETE'|'PATCH'|'OPTIONS'} method
+ * @param {string} action
+ * @param {Record} [data]
+ * @return {Promise}
+ */
+ request(method, action, data) {
method = method || 'GET';
method = method.toUpperCase();
let url = this._buildUrl(action);
- let headers = {};
- if (this.apiKey && this.secretKey) {
- let string = method + ' /' + action;
+ const headers = {};
+ if (this.apiKey && this.secretKey) {
const crypto = require('crypto');
- let b2 = crypto
- .createHmac('sha256', this.secretKey)
- .update(string)
- .digest();
+ const string = method + ' /' + action;
- let b1 = Buffer.from(this.apiKey + ':');
+ const authString = this.apiKey + ':' +
+ crypto.createHmac('sha256', this.secretKey).update(string).digest('hex');
- let authPart = Buffer.concat([b1, b2]).toString('base64');
+ const authPart = Buffer.from(authString).toString('base64');
headers['X-Hmac-Authorization'] = authPart;
-
} else if (this.apiKey) {
headers['X-Api-Key'] = this.apiKey;
} else {
@@ -109,74 +124,81 @@ class Client {
let postData;
if (data) {
- if (method == 'GET') {
+ if (method === 'GET') {
const querystring = require('querystring');
- url += '?' + querystring.stringify(data);
+
+ url += '?' + querystring.stringify({searchParams: JSON.stringify(data)});
} else {
postData = JSON.stringify(data);
+
headers['Content-Type'] = 'application/json';
headers['Content-Length'] = Buffer.byteLength(postData);
}
}
- return new Promise(
- function (resolve, reject) {
- let o = {
- headers: headers,
- method: method,
- };
-
- if (this.options.port) o.port = this.options.port;
- if (this.options.timeout) o.timeout = this.options.timeout;
-
- let h;
- if (this.isHttps) {
- h = require('https');
- } else {
- h = require('http');
- }
-
- const req = h.request(url, o, (res) => {
- let data = '';
- res.on('data', (chunk) => {
- data += chunk;
- });
- res.on('end', () => {
- if (res.statusCode < 200 || res.statusCode > 299) {
- reject(res);
- return;
- }
- try {
- data = JSON.parse(data);
- } catch (e) {
- console.error(`Error: Could not parse response`);
-
- reject({});
- return;
- }
- resolve(data, res);
- });
+ return new Promise((resolve, reject) => {
+ const o = {
+ headers: headers,
+ method: method,
+ };
+
+ if (this.options.port) {
+ o.port = this.options.port;
+ }
+
+ if (this.options.timeout) {
+ o.timeout = this.options.timeout;
+ }
+
+ const h = this.isHttps ? require('https') : require('http');
+
+ const req = h.request(url, o, res => {
+ let data = '';
+
+ res.on('data', chunk => {
+ data += chunk;
});
- req.on('error', (e) => {
- console.error(`Error: ${e.message}`);
- reject(e);
+ res.on('end', () => {
+ if (res.statusCode < 200 || res.statusCode > 299) {
+ reject(res);
+
+ return;
+ }
+
+ try {
+ data = JSON.parse(data);
+ } catch (e) {
+ console.error(`Error: Could not parse response`);
+ reject({});
+
+ return;
+ }
+
+ resolve(data, res);
});
+ });
- if (data && method != 'GET') {
- req.write(postData);
- }
- req.end();
+ req.on('error', e => {
+ console.error(`Error: ${e.message}`);
- }.bind(this)
- );
+ reject(e);
+ });
+
+ if (data && method !== 'GET') {
+ req.write(postData);
+ }
+
+ req.end();
+ });
}
- _buildUrl (action) {
+ _buildUrl(action) {
return this.url + this.urlPath + action;
}
}
-if (module && module.exports) module.exports = Client;
-
+if (module && module.exports) {
+ module.exports = Client;
+}
```
diff --git a/docs/development/api-client-php.md b/docs/development/api-client-php.md
index 1ceddf5f7..c584b691c 100644
--- a/docs/development/api-client-php.md
+++ b/docs/development/api-client-php.md
@@ -1,260 +1,51 @@
# API Client Implementation in PHP
-* [Usage](#usage)
-* [Class](#class)
+Require [Espo Api Client](https://github.com/espocrm/php-espo-api-client) with Composer:
-## Usage
+```
+composer require espocrm/php-espo-api-client
+```
+Before executing this script, create an API user with the needed permissions.
+
+### Usage
```php
-$client = new EspoApiClient('https://your-espocrm-site');
+use Espo\ApiClient\Client;
+
+$client = new Client('https://your-espocrm-site');
$client->setApiKey('API_KEY');
-$response = $client->request('POST', 'Lead', [
+// The second parameter is the path.
+$response = $client->request(Client::METHOD_POST, 'Lead', [
'firstName' => 'Test',
'lastName' => 'Hello',
]);
-$response = $client->request('GET', 'Opportunity', [
+$response = $client->request(Client::METHOD_GET, 'Opportunity', [
'maxSize' => 10,
'select' => 'id,name,assignedUserId',
'orderBy' => 'createdAt',
'order' => 'desc',
'primaryFilter' => 'open',
]);
+
+$parsedBody = $response->getParsedBody();
+
+$fileContents = $client->request(Client::METHOD_GET, "Attachment/file/$attachmentId")
+ ->getBodyPart();
```
### Api Key Authentication
```php
-$client = new EspoApiClient('https://your-espocrm-site');
+$client = new Client('https://your-espocrm-site');
$client->setApiKey('API_KEY');
```
### HMAC Authentication
```php
-$client = new EspoApiClient('https://your-espocrm-site');
+$client = new Client('https://your-espocrm-site');
$client->setApiKey('API_KEY');
$client->setSecretKey('SECRET_KEY');
```
-
-### Authentication with username and password
-
-Note: Not recommended.
-
-```php
-$client = new EspoApiClient('https://your-espocrm-site', 'USERNAME', 'PASSWORD');
-```
-
-
-## Class
-
-Copy this class into a separate PHP file and then include that file in your code.
-
-```php
-url = $url;
- }
- if (isset($userName)) {
- $this->userName = $userName;
- }
- if (isset($password)) {
- $this->password = $password;
- }
- }
-
- public function setUrl($url)
- {
- $this->url = $url;
- }
-
- public function setUserName($userName)
- {
- $this->userName = $userName;
- }
-
- public function setPassword($password)
- {
- $this->password = $password;
- }
-
- public function setApiKey($apiKey)
- {
- $this->apiKey = $apiKey;
- }
-
- public function setSecretKey($secretKey)
- {
- $this->secretKey = $secretKey;
- }
-
- /**
- * Send request to EspoCRM
- *
- * @param string $method
- * @param string $action
- * @param array|null $data
- *
- * @return array | \Exception
- */
- public function request($method, $action, array $data = null)
- {
- $method = strtoupper($method);
-
- $this->checkParams();
-
- $this->lastResponse = null;
- $this->lastCh = null;
-
- $url = $this->normalizeUrl($action);
-
- $ch = curl_init($url);
-
- $headerList = [];
-
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- if ($this->userName && $this->password) {
- curl_setopt($ch, CURLOPT_USERPWD, $this->userName.':'.$this->password);
- curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
- } else if ($this->apiKey && $this->secretKey) {
- $string = $method . ' /' . $action;
- $authPart = base64_encode($this->apiKey . ':' . hash_hmac('sha256', $string, $this->secretKey, true));
- $authHeader = 'X-Hmac-Authorization: ' . $authPart;
- $headerList[] = $authHeader;
- } else if ($this->apiKey) {
- $authHeader = 'X-Api-Key: ' . $this->apiKey;
- $headerList[] = $authHeader;
- }
-
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_HEADER, true);
-
- if ($method != 'GET') {
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- }
-
- if (isset($data)) {
- if ($method == 'GET') {
- curl_setopt($ch, CURLOPT_URL, $url. '?' . http_build_query($data));
- } else {
- $payload = json_encode($data);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
- $headerList[] = 'Content-Type: application/json';
- $headerList[] = 'Content-Length: ' . strlen($payload);
- }
- }
-
- if (!empty($headerList)) {
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headerList);
- }
-
- $this->lastResponse = curl_exec($ch);
- $this->lastCh = $ch;
-
- $parsedResponse = $this->parseResponce($this->lastResponse);
- $responseCode = $this->getResponseHttpCode();
-
- if ($responseCode == 200 && !empty($parsedResponse['body'])) {
- curl_close($ch);
- return json_decode($parsedResponse['body'], true);
- }
-
- $header = $this->normalizeHeader($parsedResponse['header']);
- $errorMessage = !empty($header['X-Status-Reason']) ? $header['X-Status-Reason'] : 'EspoClient: Unknown Error';
-
- curl_close($ch);
- throw new \Exception($errorMessage, $responseCode);
- }
-
- public function getResponseContentType()
- {
- return $this->getInfo(CURLINFO_CONTENT_TYPE);
- }
-
- public function getResponseTotalTime()
- {
- return $this->getInfo(CURLINFO_TOTAL_TIME);
- }
-
- public function getResponseHttpCode()
- {
- return $this->getInfo(CURLINFO_HTTP_CODE);
- }
-
- protected function normalizeUrl($action)
- {
- return $this->url . $this->urlPath . $action;
- }
-
- protected function checkParams()
- {
- $paramList = [
- 'url'
- ];
-
- foreach ($paramList as $name) {
- if (empty($this->$name)) {
- throw new \Exception('EspoClient: Parameter "'.$name.'" is not defined.');
- }
- }
-
- return true;
- }
-
- protected function getInfo($option)
- {
- if (isset($this->lastCh)) {
- return curl_getinfo($this->lastCh, $option);
- }
- }
-
- protected function parseResponce($response)
- {
- $headerSize = $this->getInfo(CURLINFO_HEADER_SIZE);
-
- return [
- 'header' => trim( substr($response, 0, $headerSize) ),
- 'body' => substr($response, $headerSize),
- ];
- }
-
- protected function normalizeHeader($header)
- {
- preg_match_all('/(.*): (.*)\r\n/', $header, $matches);
-
- $headerArray = array();
- foreach ($matches[1] as $index => $name) {
- if (isset($matches[2][$index])) {
- $headerArray[$name] = trim($matches[2][$index]);
- }
- }
-
- return $headerArray;
- }
-}
-
-
-```
diff --git a/docs/development/api-client-python.md b/docs/development/api-client-python.md
index d474802f6..019c67b1a 100644
--- a/docs/development/api-client-python.md
+++ b/docs/development/api-client-python.md
@@ -1,6 +1,8 @@
# API Client Implementation in Python
-Note: You need to have *requests* package installed with: `pip install requests`.
+!!! note
+
+ You need to have *requests* package installed with: `pip install requests`.
## Class
@@ -76,7 +78,7 @@ class EspoAPI:
if self.status_code != 200:
reason = self.parse_reason(response.headers)
- raise EspoAPIError('Wrong request, status code is {response.status_code}, reason is {reason}')
+ raise EspoAPIError(f'Wrong request, status code is {response.status_code}, reason is {reason}')
data = response.content
if not data:
diff --git a/docs/development/api-client-rust.md b/docs/development/api-client-rust.md
new file mode 100644
index 000000000..d9284d094
--- /dev/null
+++ b/docs/development/api-client-rust.md
@@ -0,0 +1,120 @@
+# API Client implementation in Rust
+
+* [Installation](#installation)
+* [HMAC authorization](#hmac-authorization)
+* [API Key authorization](#api-key-authorization)
+* [Basic authorization](#basic-authorization)
+* [Making a request](#making-a-request)
+
+!!! note
+
+ This is an unofficial (3rd party) client.
+
+For the full documentation, refer to [docs.rs](https://docs.rs/espocrm-rs/latest/espocrm_rs/).
+For the source code, refer to [GitHub](https://github.com/TobiasDeBruijn/espocrm-rs).
+
+## Installation
+[](https://crates.io/crates/espocrm-rs)
+The crate is on crates.io, so you can add it by adding it to your `[dependencies]` in your Cargo.toml:
+```toml
+[dependencies]
+espocrm-rs = "0.2.0"
+```
+
+For the latest version, refer to [crates.io](https://crates.io/crates/espocrm-rs).
+
+## HMAC authorization
+
+```rust
+use espocrm_rs::EspoApiClient;
+
+let client = EspoApiClient::new("https://espocrm.example.com")
+ .set_api_key("Your API Key here")
+ .set_secret_key("Your API Secret")
+ .build();
+```
+## API Key authorization
+
+```rust
+use espocrm_rs::EspoApiClient;
+let client = EspoApiClient::new("https://espocrm.example.com")
+ .set_api_key("Your API Key here")
+ .build();
+```
+
+## Basic authorization
+
+```rust
+use espocrm_rs::EspoApiClient;
+let client = EspoApiClient::new("https://espocrm.example.com")
+ .set_username("Your Username here")
+ .set_password("Your Password here")
+ .build();
+```
+
+## Making a request
+
+To make a GET request, you need to know a couple things:
+
+- the request method to use;
+- on what to perform the request;
+- optionally, any data needed for the request.
+
+```rust
+use espocrm_rs::{EspoApiClient, Params, Where, FilterType, Value, NoGeneric};
+use reqwest::Method;
+
+let params = Params::default()
+ .set_offset(0)
+ .set_where(vec![
+ Where {
+ r#type: FilterType::IsTrue,
+ attribute: "exampleField".to_string(),
+ value: None
+ },
+ Where {
+ r#type: FilterType::ArrayAnyOf,
+ attribute: "exampleField2".to_string(),
+ value: Some(Value::array(vec![
+ Value::str("a"),
+ Value::str("b"),
+ Value::str("c")
+ ]))
+ }
+ ])
+ .build();
+
+let client = EspoApiClient::new("https://espocrm.example.com")
+ .set_secret_key("Your Secret Key")
+ .set_api_key("Your api key")
+ .build();
+
+let result = client.request::(Method::GET, "Contact".to_string(), Some(params), None);
+```
+
+A POST, PUT, etc request is very similar:
+```rust
+use espocrm::EspoApiClient;
+use reqwest::Method;
+use serde::Serialize;
+
+#[derive(Serialize)]
+struct MyData {
+ some_value: String,
+ some_other_value: i64
+}
+
+let client = EspoApiClient::new("https://espocrm.example.com")
+ .set_secret_key("Your Secret Key")
+ .set_api_key("Your api key")
+ .build();
+
+let data = MyData {
+ some_value: "value".to_string(),
+ some_other_value: 10
+}
+
+let result = client.request(Method::POST, "Contact".to_string(), None, Some(data));
+```
+
+The MyData struct here will be serialized into JSON data using Serde's Serialize trait.
diff --git a/docs/development/api-client-zig.md b/docs/development/api-client-zig.md
new file mode 100644
index 000000000..b311bd806
--- /dev/null
+++ b/docs/development/api-client-zig.md
@@ -0,0 +1,141 @@
+# API Client implementation in Zig
+
+- [Installation](#installation)
+- [API Key authentication](#using-api-key-authentication)
+- [Making a read GET request](#making-a-read-request)
+- [Making a list GET request](#making-a-list-request)
+- [Making a create POST request](#making-a-create-request)
+- [Making an update PUT request](#making-an-update-request)
+- [Making a delete DELETE request](#making-a-delete-request)
+
+!!! note
+
+ This is an unofficial (3rd party) client.
+
+For the source code, refer to [GitHub](https://github.com/definitepotato/espocrmz).
+
+# Getting Started
+
+This Zig `espocrm` library provides an API client for EspoCRM. To get started you'll have to provide the URL where EspoCRM is located and your method of authentication. Read more from the [official documentation](https://docs.espocrm.com/development/api/#authentication).
+
+## Installation
+
+Add this to your build.zig.zon
+
+```zig
+.dependencies = .{
+ .espocrmz = .{
+ .url = "https://github.com/definitepotato/espocrmz/archive/refs/heads/master.tar.gz",
+ .hash = "the correct hash will be suggested by zig at build time",
+ }
+}
+```
+
+Add this to your build.zig
+
+```zig
+const espocrmz = b.dependency("espocrmz", .{
+ .target = target,
+ .optimize = optimize,
+});
+exe.root_module.addImport("espocrmz", espocrmz.module("espocrmz"));
+```
+
+You can then import the library into your code like this
+
+```zig
+const espocrm = @import("espocrmz");
+```
+
+## Basic Usage
+
+### Using API Key Authentication:
+
+```zig
+const allocator = std.heap.page_allocator;
+
+const client: espocrm.Client = .init(
+ "https://espocrm.example.com",
+ .{ .api_key = "Your API Key here" },
+);
+```
+
+### Making a Read request:
+
+```zig
+const allocator = std.heap.page_allocator;
+
+const result = try client.readEntity(
+ allocator,
+ "Contact",
+ "78abc123def456",
+);
+defer result.deinit();
+```
+
+### Making a List request:
+
+```zig
+var params = espocrm.Parameters.init();
+_ = params.setMaxSize(10).setOrder(espocrm.Parameters.Order.Asc);
+const params_encoded = try params.encode(allocator);
+
+const allocator = std.heap.page_allocator;
+
+const result = try client.listEntities(allocator, "Contact", params, &[_]espocrm.Where{
+ .{ .filter_type = espocrm.FilterOption.Equals, .filter_attribute = "name", .filter_value = "Alice" },
+ .{ .filter_type = espocrm.FilterOption.GreaterThan, .filter_attribute = "age", .filter_value = "42" },
+});
+defer result.deinit();
+```
+
+### Making a Create request:
+
+```zig
+const allocator = std.heap.page_allocator;
+
+const new_contact =
+ \\{
+ \\ "name": "Alice",
+ \\ "age": 69
+ \\}
+;
+
+const result = try espocrm.createEntity(
+ allocator,
+ "Contact",
+ new_contact,
+);
+defer result.deinit();
+```
+
+### Making an Update request:
+
+```zig
+const allocator = std.heap.page_allocator;
+
+const update_info =
+ \\{
+ \\ "name": "Bob"
+ \\}
+;
+
+const result = try client.updateEntity(
+ allocator,
+ "Contact",
+ "67abe33f5883bd9e",
+ update_info
+);
+defer result.deinit();
+```
+
+### Making a Delete request:
+
+```zig
+const result = try client.deleteEntity(
+ allocator,
+ "Contact",
+ "67abe33f5883bd9e"
+);
+defer result.deinit();
+```
diff --git a/docs/development/api-search-params.md b/docs/development/api-search-params.md
index 8705122ec..8ff6d7bcf 100644
--- a/docs/development/api-search-params.md
+++ b/docs/development/api-search-params.md
@@ -4,7 +4,7 @@ Filters and other search parameters can be used with API functions that returns
* [Examples](#examples)
* [PHP](#php)
- * [Javacript](#javascript-nodejs)
+ * [Javascript](#javascript-nodejs)
* [Python](#python)
* [Params](#params)
* [Where items](#where-items)
@@ -15,6 +15,8 @@ Filters and other search parameters can be used with API functions that returns
### PHP
```php
+request('GET', $url, $params);
```js
// every param is optional
-var params = {
+const params = {
maxSize: 5,
primaryFilter: 'open',
where: [
@@ -80,11 +82,7 @@ var params = {
};
client.request('GET', 'Case', params)
- .then(
- (response) => {
- console.log(response);
- }
- )
+ .then(response => console.log(response))
```
### Python
@@ -100,11 +98,20 @@ params = {
},
],
}
+
result = client.request('GET', 'Account', params)
```
## Params
+Parameters are passed as query parameters (in GET request).
+
+It's also possible to pass all search parameters in JSON format in a single query parameter `searchParams`:
+
+```
+?searchParams={JSON_ENCODED_SEARCH_PARAMETERS}
+```
+
### offset
*Integer*
@@ -115,27 +122,37 @@ An offset for pagination.
*Integer*
-How much records to return.
+How many records to return.
### select
-*String*
+*String* (or *Array* of strings if search params passed in JSON)
What record [attributes](../administration/terms-and-naming.md#attribute) to return. Separated by comma. Whitespaces are not allowed. Specify only attributes that you need, it can improve performance.
Example: `id,name,status,assignedUserId`.
+Example in JSON: `["id", "name"]`.
+
+!!! note
+
+ An alias GET parameter `attributeSelect` can be used instead to prevent false positive firewall blocking. As of v9.0.
+
### where
*Array*
Search criteria. Can contain nested arrays and objects. See more [below](#where-items) more detail.
+!!! note
+
+ An alias GET parameter `whereGroup` can be used instead to prevent false positive firewall blocking. As of v9.0.
+
### primaryFilter
*String*
-A primiry filter. Primary filters are usualy defined in *Select Manager* class.
+A primary filter. Primary filters are usually defined in *Select Manager* class.
### boolFilterList
@@ -158,9 +175,9 @@ A direction of order: 'desc' or 'asc'.
## Where items
-*Where* parameter is an array if items, that can contain nested items. The data should be URL-encoded. API clients provided in the documentation handle encoding.
+A *Where* parameter is an array if items. Items can contain nested items.
-Examples below are given in JSON format for readability.
+Examples below are given in JSON format.
### equals, notEquals
@@ -273,6 +290,17 @@ For link-multiple fields. Whether is linked or not linked with any record.
}
```
+For date-time fields:
+
+```json
+{
+ "type": "today",
+ "attribute": "someDateTimeField",
+ "dateTime": true,
+ "timeZone": "Europe/Kyiv"
+}
+```
+
### lastXDays, nextXDays, olderThanXDays, afterXDays,
```json
diff --git a/docs/development/api-tutorial.md b/docs/development/api-tutorial.md
index 87303c39b..185af83a7 100644
--- a/docs/development/api-tutorial.md
+++ b/docs/development/api-tutorial.md
@@ -2,8 +2,7 @@
## In EspoCRM
-1. Go to Admninistration > Roles and create a **new role** with permissions you want to grand for the API user.
- * Note: For versions below 5.9.0 it's recommended to set *Assignment Permission* to `all`.
+1. Go to Administration > Roles and create a **new role** with permissions you want to grand for the API user.
2. Go to Administration > API Users and create a new API User. Select the created role. An **API Key** will be generated, you will need to use it in your API requests further.
## In external application
@@ -14,32 +13,9 @@
### PHP
-1. Create a new PHP file: `EspoApiClient.php` with the code copied from [here](api-client-php.md#class).
-2. Include this file in the place where you want to call EspoCRM API and use it. See the code below.
+Install [PHP API client](api-client-php.md) via composer. See usage examples in the same article.
-```php
-setApiKey($apiKey);
-
-// example creating a new lead
-try {
- $response = $client->request('POST', 'Lead', [
- 'firstName' => 'Test',
- 'lastName' => 'Hello',
- ]);
-} catch (\Exception $e) {
- $errorCode = $e->getCode();
-}
-```
-
-Check `data/logs` in your EspoCRM if something went wrong. See [error codes](api.md#error-codes).
+If something went wrong, check `data/logs` in your EspoCRM. See [error codes](api.md#error-codes).
### Javascript (Nodejs)
@@ -55,11 +31,13 @@ const client = new Client(
);
// POST request example
-var payload = {
+const payload = {
name: 'some name',
type: 'Customer',
};
-client.request('POST', 'Account', payload)
+
+client
+ .request('POST', 'Account', payload)
.then(
(response) => {
// success
@@ -74,8 +52,7 @@ client.request('POST', 'Account', payload)
);
```
-
-Check `data/logs` in your EspoCRM if something went wrong. See [error codes](api.md#error-codes).
+If something went wrong, check `data/logs` in your EspoCRM. See [error codes](api.md#error-codes).
### Python
diff --git a/docs/development/api.md b/docs/development/api.md
index 5b93c4a03..b4bf04170 100644
--- a/docs/development/api.md
+++ b/docs/development/api.md
@@ -1,75 +1,92 @@
-# REST API
+# API Overview
-EspoCRM is a single page application so a frontend uses REST API to connect with a backend.
-All operations you perform using UI, you can implement via API calls using your programing language.
-You can learn how API works if you trace what's going in the network tab in your **browser console** (press F12 key to open the console).
+EspoCRM is a single page application so the frontend uses REST API to connect with the backend.
+All operations you perform using the UI, you can implement via API calls using your programming language.
+You can learn how the API works if you trace what's going in the network tab in your browser console (press F12 key to open the console).
-Most of API functions return JSON. POST and PUT requests usually need some data passed in the payload in JSON format.
+Most of API functions return JSON. POST and PUT requests usually need some data passed in the payload in JSON format. Whenever you send a JSON payload, add the header: `Content-Type: application/json`.
-Requests needs to have the header: `Content-Type: application/json`.
+The root API path is: `api/v1/`.
-The path to the API in EspoCRM is: `api/v1/`.
+!!! example "Example of GET API request"
-Example of GET API request:
+ ```
+ GET https://address_of_your_crm/api/v1/Contact/55643ca033f7ab4c5
+ ```
-```
-GET https://address_of_your_crm/api/v1/Contact/55643ca033f7ab4c5
-```
-
-In this documentation we omit the site URL and `api/v1/` path when we show examples of API functions. If you utilize any our client implementation, it will prepend these parts automatically.
-
-Note: API client implementations (available below) do most of work for you: add needed headers, handle autentication, parameters, etc.
+In this documentation we omit the site URL and `api/v1/` path when we show examples of API endpoints. If you utilize any of our client implementations, they prepend these URL parts automatically.
-It's recommended to create a **separate API user** with specific rights (roles) and use this user for API calls.
+!!! note
-See in [tutorial](api-tutorial.md) **how to get started**.
+ The API client implementations (available below) automatically adds needed headers and handles authentication.
In this article:
+* [API reference](#api-reference)
+* [Setting up](#setting-up)
* [Client implementations](#client-implementations)
* [Authentication](#authentication)
* [Error codes](#error-codes)
-
-API functions:
-
-* [CRUD operations](api/crud.md) - create, read, update, delete
-* [Related records](api/relationships.md)
-* [Stream](api/stream.md)
-* [CurrencyRate](api/currency-rate.md)
-* [Attachment](api/attachment.md)
-* [I18n](api/i18n.md)
-* [Account](api/account.md)
+* [Date and time values](#date-and-time-values)
See also:
* [Search parameters](api-search-params.md)
* [Usage tutorial](api-tutorial.md)
+## API reference
+
+* [API docs](../api/index.html) – a separate API reference documentation covering CRUD operations for main entity types;
+* [CRUD operations](api/crud.md) – an article on create, read, update, delete operations;
+* [Related records](api/relationships.md) – working with links;
+* [Stream](api/stream.md) – working with the Stream;
+* [CurrencyRate](api/currency-rate.md) – currency conversion rates;
+* [Attachment](api/attachment.md) – working with file attachments;
+* [I18n](api/i18n.md) – internationalization;
+* [Metadata](api/metadata.md) – working with application metadata;
+* [Account](api/account.md) – (to be removed in favor of the API reference)
+
+### OpenAPI specification
+
+*As of v9.3.*
+
+The OpenAPI specification for your Espo instance (including custom entity types and fields) covering the main CRUD operations can be obtained from the `/api/v1/OpenApi` endpoint. The endpoint is available for admin users and API users with the *OpenAPI* scope enabled in roles.
+
+You can also obtain the OpenAPI specification under: Administration > API Users > top-right menu > OpenAPI spec.
+
## Client implementations
* [PHP](api-client-php.md)
* [Javascript (Nodejs)](api-client-js.md)
* [Python](api-client-python.md)
+* [Rust](api-client-rust.md)
+* [Java](api-client-java.md)
+* [Go](api-client-go.md)
+* [Zig](api-client-zig.md)
+## Setting up
-## Authentication
+It's recommended to create a separate **API User** with specific permissions (defined by Roles) and use this user for API calls. You can have multiple API Users for different purposes, give each user specific permissions.
-### Authentication by Api Key
+See in the [tutorial](api-tutorial.md) **how to get started**.
-Available since 5.5.0 version.
+Client implementations require specifying the Site URL. It's an URL that you open in the browser to use EspoCRM.
-The easiest method of authentication. You need to create API User (Administration > API Users) with Api Key authentication method. Apply the needed role to the user to grant needed access.
+## Authentication
-Authentication header:
+### Authentication by API Key
-`X-Api-Key: API_KEY_COPIED_FROM_THE_USER_DETAIL_VIEW`
+The simplest method of authentication. You need to create an API User (Administration > API Users) with the *API Key* authentication method. Apply a needed role to the user to grant access to specific scopes.
+Authentication header:
-### HMAC Authentication
+```
+X-Api-Key: API_KEY_COPIED_FROM_THE_USER_DETAIL_VIEW
+```
-Available since 5.5.0 version.
+### HMAC Authentication
-The most secure method. You need to create API User (Administration > API Users) with HMAC authentication method. Apply needed role to the user to grant needed access.
+The most secure method. You need to create an API User (Administration > API Users) with the *HMAC authentication* method. Apply a needed role to the user to grant access to specific scopes.
Authentication header:
@@ -78,26 +95,29 @@ Authentication header:
```
where
-* `method` - GET, POST, PUT, DELETE;
-* `uri` - request path, e.g. `Lead/action/convert`.
+* `method` – GET, POST, PUT, DELETE;
+* `uri` – a request path, e.g. `Lead/action/convert`.
### Basic Authentication
-Note: This method is not recommended.
+!!! warning
-For regular users EspoCRM uses [Basic Authentication](http://en.wikipedia.org/wiki/Basic_access_authentication). Username and password (or token) are passed through `Authorization` header encoded in base64.
+ This method is not recommended.
-`"Authorization: Basic " + base64Encode(username + ':' + password)`
+For regular users, the EspoCRM front-end uses the [Basic Authentication](http://en.wikipedia.org/wiki/Basic_access_authentication). A username and password (or token) are passed through the `Authorization` header encoded with Base64.
+```
+"Authorization: Basic " + base64Encode(username + ':' + password)
+```
-It's better to use auth token instead of password when you work with API. In this case you will need to provide username and password/token in `Espo-Authorization` header.
+It's better to use an auth token instead of a password. In this case, you need to provide the username and the password/token in the `Espo-Authorization` header.
```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
+"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
```
-1. Obtain an access token by `GET App/user` request with the username and password passed in `Espo-Authorization` header.
-2. Use this token instead of password in `Espo-Authorization` header for all further request.
-3. If the request returns 401 error that means either username/password is wrong or token is not valid anymore.
+1. Obtain an access token with `GET App/user` request with the username and password passed in `Espo-Authorization` header.
+2. Use this token instead of the password in `Espo-Authorization` header for all further requests.
+3. If the request returns 401 error, that means either the username or password are wrong, or the token is not valid anymore.
#### Authentication Token / User Specific Data
@@ -107,21 +127,31 @@ Make this request to retrieve an access token.
Returns:
-* `token` - access token to use
-* `acl` - information about user access
-* `preferences` - user preferences
-* `user` - user record attributes
+* `token` – access token to use
+* `acl` – information about user access
+* `preferences` – user preferences
+* `user` – user record attributes
## Error codes
### 400 Bad request
-When you create or update a recod, this error can mean that you didn't pass a **required field** or it has an empty value. Check the response message or see `data/log` for more details.
+When you create or update a record, this error can mean that you didn't pass a **required field** or it has an empty value. Check the response message or see `data/log` for more details.
### 403 Forbidden
-Usually occurs when you **don't have an access** to a specific record or action. See `data/log` for more details.
+Usually occurs when you **don't have access** to a specific record or action. See `data/log` for more details.
### 404 Not found
Usually occurs when a requested **record doesn't exist**.
+
+### 409 Conflict
+
+An operation cannot be performed becase of a conflict error. For example, cannot edit a locked record, cannot create a duplicate record.
+
+## Date and time values
+
+Date format: *YYYY-MM-DD*. Datetime format: *YYYY-MM-DD HH:mm:ss*.
+
+All datetime values are represented in UTC timezone, regardless of the settings.
diff --git a/docs/development/api/account.md b/docs/development/api/account.md
index d7aca774b..4f1fe3405 100644
--- a/docs/development/api/account.md
+++ b/docs/development/api/account.md
@@ -1,4 +1,4 @@
-# API :: Account
+# API · Account
* [List](#list)
* [Create](#create)
@@ -150,7 +150,7 @@ Requires *stream* access to Account record.
## Relationships
-Note: [link](../../administration/terms-and-naming.md#link) names can be obtained at Administration > Enity Manager > click *relationsips* on *Account* row > 4th column. Actual types: parent-to-children, one-to-many, many-to-many.
+Note: [link](../../administration/terms-and-naming.md#link) names can be obtained at Administration > Entity Manager > click *relationships* on *Account* row > 4th column. Actual types: parent-to-children, one-to-many, many-to-many.
The list of links available out-of-the-box:
@@ -179,7 +179,7 @@ Requires *read* access to Account record and *read* access to the scope of the r
### POST Account/{id}/{link}
-Relate an existing account with a specific record (or multiple records) throuh a specific *link*.
+Relate an existing account with a specific record (or multiple records) through a specific *link*.
Requires *edit* access to Account record and *edit* access to the scope of the related entity type.
@@ -188,7 +188,7 @@ Payload parameters are available [here](relationships.md#link).
### DELETE Account/{id}/{link}
-Unlinks a specific record, linked throgh a specific link, from an account.
+Unlinks a specific record, linked through a specific link, from an account.
Requires *edit* access to Account record and *edit* access to the scope of the related entity type.
diff --git a/docs/development/api/attachment.md b/docs/development/api/attachment.md
index 1f72f4fd5..2c1434c8d 100644
--- a/docs/development/api/attachment.md
+++ b/docs/development/api/attachment.md
@@ -1,28 +1,30 @@
-# API :: Attachment
+# API · Attachment
* [Uploading](#uploading)
* [Downloading](#downloading)
### Uploading
+!!! note
+
+ There's also the ability to upload files in chunks. This method is not covered in this article.
+
`POST Attachment`
* Method: *POST*
-* Action: `Attachment`
+* Endpoint: `Attachment`
* Headers: `Content-Type: application/json`
Payload attributes:
-* name - file name;
-* type - mime type;
-* role - specify value `Attachment`;
-* relatedType - entity type attachment is related to (only for fields of *File* type);
-* relatedId - record ID attachment is related to (only for fields of *File* type);
-* parentType - entity type attachment is related to (only for fields of *Attachment Multiple* type);
-* field - field name of related record attachment is related through;
-* file - file contents.
-
-Note: *parentId* attribute is available when uploading and will be ignored.
+* name – file name;
+* type – mime type;
+* role – specify value `Attachment`;
+* relatedType – entity type attachment is related to (only for fields of *File* type);
+* relatedId – record ID attachment is related to (only for fields of *File* type);
+* parentType – entity type attachment is related to (only for fields of *Attachment Multiple* type);
+* field – field name of related record attachment is related through;
+* file – file contents.
#### Example (File field)
@@ -109,7 +111,7 @@ Create:
{
"post": "Some text",
"type": "Post",
- "attachmnetsIds": ["{id-of-attachment}"]
+ "attachmentsIds": ["{id-of-attachment}"]
}
```
@@ -119,18 +121,15 @@ Update:
```json
{
- "attachmnetsIds": ["{id-of-attachment}"]
+ "attachmentsIds": ["{id-of-attachment}"]
}
```
Note: If you are attaching to an existing record, you need also to add current attachments, otherwise they will be unlinked from the record.
-
### Downloading
-Available since version 5.9.0.
-
`GET Attachment/file/{id}`
Where `{id}` is an ID of the attachment record.
diff --git a/docs/development/api/crud.md b/docs/development/api/crud.md
index f9bdc50c4..a397cee3c 100644
--- a/docs/development/api/crud.md
+++ b/docs/development/api/crud.md
@@ -1,8 +1,12 @@
-# API :: CRUD Operations
+# API · CRUD Operations
CRUD stands for create, read, update, delete.
-Note: You can obtain the list of [entity types](../../administration/terms-and-naming.md#entity-type) at Administration > Entity Manager > the left column.
+!!! note
+
+ You can obtain the list of [entity types](../../administration/terms-and-naming.md#entity-type) under: Administration > Entity Manager > the left column.
+
+ Available entity attributes and their details can be obtained under: Administration > Entity Manager > {Entity Type} > Fields. You can *View Details* of a particular field to explore its attributes.
* [List](#list)
* [Read](#read)
@@ -19,12 +23,12 @@ Returns a list of records of a specific entity type.
GET parameters:
-* `maxSize` - (int) max size
-* `offset` - (int) offset
-* `where` - (array) filters
-* `orderBy` - (string) attribute to sort by
-* `order` - (string: 'asc' | 'desc') sort direction
-* `select` - (string) list of [attributes](../../administration/terms-and-naming.md#attribute) to be returned, sepratated by comma; if not specified, then all attributes will be returned; whitespaces are not allowed
+* `maxSize` – *int* – max size.
+* `offset` – *int* – offset.
+* `where` – *array* – filters. An alias `whereGroup` can be used instead to prevent false positive firewall blocking.
+* `orderBy` – *string* – attribute to sort by.
+* `order` – *"asc"|"desc"* – sort direction.
+* `select` – *string* – list of [attributes](../../administration/terms-and-naming.md#attribute) to be returned, separated by comma; if not specified, then all attributes will be returned; whitespaces are not allowed. An alias `attributeSelect` can be used instead to prevent false positive firewall blocking.
Example:
@@ -38,8 +42,14 @@ Returns:
}
```
+Note that if the record count is disabled for the entity type, -1 or -2 will be returned instead of the actual total number of records. -1 means that there are more records – pagination can be used to retrieve the next portion.
+
See [more info](../api-search-params.md) about search parameters.
+Additional headers:
+
+* `X-No-Total: true` – won't return a total number of records (can be reasonable for big tables, the request will be processed faster).
+
### Read
`GET {entityType}/{id}`
@@ -60,6 +70,10 @@ Payload: Object of entity [attributes](../../administration/terms-and-naming.md#
Returns attributes of the created record.
+Headers:
+
+* `Content-Type: application/json`
+
Example:
`POST Account`
@@ -72,6 +86,10 @@ Payload:
}
```
+Additional headers:
+
+* `X-Skip-Duplicate-Check: true` – skips checking for duplicates (won't return 409 Error if a duplicate record is found).
+
### Update
`PUT {entityType}/{id}`
@@ -82,6 +100,10 @@ Payload: Object of entity [attributes](../../administration/terms-and-naming.md#
Returns attributes of the updated record.
+Headers:
+
+* `Content-Type: application/json`
+
Example:
`PUT Account/5564764442a6d024c`
@@ -100,9 +122,8 @@ Payload:
Deletes an existing record.
-Returns TRUE if success.
+Returns `true`.
Example:
`DELETE Account/5564764442a6d024c`
-
diff --git a/docs/development/api/currency-rate.md b/docs/development/api/currency-rate.md
index ff68690f3..46c8075b6 100644
--- a/docs/development/api/currency-rate.md
+++ b/docs/development/api/currency-rate.md
@@ -1,4 +1,4 @@
-# API :: CurrencyRate
+# API · CurrencyRate
### Getting rates
diff --git a/docs/development/api/i18n.md b/docs/development/api/i18n.md
index 1abf88917..69245aa37 100644
--- a/docs/development/api/i18n.md
+++ b/docs/development/api/i18n.md
@@ -1,10 +1,10 @@
-# API :: I18n (Internalization)
+# API · I18n (Internalization)
## Getting all labels
`GET I18n`
-Returns all application labels. If authorized as an API User, labels will be translated to the default language (set in Administration > System). If authorized as a regular user (via Basic Authentication), then labels will be translated to the language set in preferences of that user. By passign GET parameter `default=true` it will force to return in the default language.
+Returns all application labels. If authorized as an API User, labels will be translated to the default language (set in Administration > System). If authorized as a regular user (via Basic Authentication), then labels will be translated to the language set in preferences of that user. By passing GET parameter `default=true` it will force to return in the default language.
Response data:
diff --git a/docs/development/api/metadata.md b/docs/development/api/metadata.md
new file mode 100644
index 000000000..c46c884cc
--- /dev/null
+++ b/docs/development/api/metadata.md
@@ -0,0 +1,11 @@
+# API · Metadata
+
+## Getting metadata
+
+`GET Metadata`
+
+Returns application metadata. Note that not all metadata is available for reading from the outside – some data is stripped from the result.
+
+Query params:
+
+* key – a specific path to return; e.g. `entityDefs.Lead.fields.status.options`; as of v8.2.
diff --git a/docs/development/api/relationships.md b/docs/development/api/relationships.md
index 19b43e8cb..bbf1c62aa 100644
--- a/docs/development/api/relationships.md
+++ b/docs/development/api/relationships.md
@@ -1,6 +1,7 @@
-# API :: Related records
+# API · Related records
-Note: You can obtain the list of [link](../../administration/terms-and-naming.md#link) names at Administration > Entity Manager > click relationships on a specific entity type > 4th column. Actual types: parent-to-children, one-to-many, many-to-many.
+!!! note
+ You can obtain the list of [link](../../administration/terms-and-naming.md#link) names at Administration > Entity Manager > click relationships on a specific entity type > 4th column. Actual types: parent-to-children, one-to-many, many-to-many.
* [List related records](#list-related-records)
* [Link](#link)
@@ -17,7 +18,7 @@ GET parameters:
* `where` - (array) filters
* `orderBy` - (string) attribute to sort by
* `order` - (string: 'asc' | 'desc') sort direction
-* `select` - (string) list of attributes to be returned, sepratated by comma; if not specified, then all fields will be returned
+* `select` - (string) list of attributes to be returned, separated by comma; if not specified, then all fields will be returned
You can find more info about search params [here](../api-search-params.md).
@@ -49,6 +50,10 @@ Payload:
* `massRelate` - optional, false or true, whether to use search criteria that will be used instead of specific ids
* `where` - optional [search criteria](../api-search-params.md#where)
+Headers:
+
+* `Content-Type: application/json`
+
Example:
`POST Account/5564764442a6d024c/opportunities`
@@ -71,6 +76,10 @@ Payload fields:
* `id` - ID of related record to remove
* `ids` - array of IDs of related records to remove
+Headers:
+
+* `Content-Type: application/json`
+
Example:
`DELETE Account/5564764442a6d024c/opportunities`
diff --git a/docs/development/api/stream.md b/docs/development/api/stream.md
index ba4431314..8bd99b326 100644
--- a/docs/development/api/stream.md
+++ b/docs/development/api/stream.md
@@ -1,4 +1,4 @@
-# API :: Stream
+# API · Stream
### List stream records for the current user
@@ -6,8 +6,8 @@
Get parameters:
-* `offset` - (int) offset
-* `maxSize` - (int) max size
+* `offset` – (int) offset
+* `maxSize` – (int) max size
### List stream notes of a specific record
@@ -15,8 +15,8 @@ Get parameters:
Get parameters:
-* `offset` - (int) offset
-* `maxSize` - (int) max size
+* `offset` – (int) offset
+* `maxSize` – (int) max size
### Follow record
@@ -32,11 +32,11 @@ Get parameters:
Payload attributes:
-* `type` - should be the string value `Post`
-* `parentId` - ID of the record to post to
-* `parentType` - entity type of the record to post to
-* `post` - text to post
-* `attachmentsIds` - optional, array of IDs of attachments (should be uploaded in separate request beforehand)
+* `type` – should be the string value `Post`
+* `parentId` – ID of the record to post to
+* `parentType` – entity type of the record to post to
+* `post` – text to post
+* `attachmentsIds` – optional, array of IDs of attachments (should be uploaded in separate request beforehand)
Payload example:
diff --git a/docs/development/app-params.md b/docs/development/app-params.md
index f48da852c..e094a051a 100644
--- a/docs/development/app-params.md
+++ b/docs/development/app-params.md
@@ -1,56 +1,48 @@
# App Params
-Since EspoCRM 5.8.0.
-
-App params are returned by backend once a user logged in. You can use this params in frontend. For example, the list of entity types available for printing to PDF.
+App params are returned by the back-end once a user logged in. You can use these params in the front-end. For example, Espo has a build-in app-param containing a list of entity types that can be printed to PDF for a current user.
## Custom app params
You can make the system to return custom parameters. This params can be unique for a current user (different user have different values in params).
-Create a file: `custom/Espo/Custom/Resources/metadata/app/appParams.json`
+Create a file: `custom/Espo/Custom/Resources/metadata/app/appParams.json`:
```json
{
"myParam": {
- "className": "\\Espo\\Custom\\Core\\AppParams\\MyParam"
+ "className": "Espo\\Custom\\Core\\AppParams\\MyParam"
}
}
```
-Create a file `custom/Espo/Custom/Core/AppParams/MyParam.php`
+Create a file `custom/Espo/Custom/Core/AppParams/MyParam.php`:
```php
addDependency('acl');
- $this->addDependency('entityManager');
- }
+ public function __construct(
+ // Pass needed dependencies.
+ ) {}
- public function get()
+ public function get(): mixed
{
- $acl = $this->getInjection('acl');
- $em = $this->getInjection('entityManager');
-
- $value = null;
-
- // here some logic
-
- return $value;
+ // Value fetching logic.
+ // Your value can be a scalar, array or stdClass.
+
+ return $someValue;
}
```
Clear cache.
-In frontend in *view* you can access your parameter the following way:
+In the front-end (in a [View](view.md)) you can access your parameter the following way:
```js
- this.getHelper().getAppParam('myParam');
-
+this.getHelper().getAppParam('myParam');
```
diff --git a/docs/development/attachments.md b/docs/development/attachments.md
new file mode 100644
index 000000000..7a26aea5d
--- /dev/null
+++ b/docs/development/attachments.md
@@ -0,0 +1,114 @@
+# Attachments
+
+## Attachment entity
+
+Attachments are records that represent stored files. These files can be attachments in a stream notes, email attachments, documents, etc.
+
+Example:
+
+```php
+entityManager
+ ->getRDBRepositoryByClass(Attachment::class)
+ ->getById($id);
+
+ if (!$attachment) {
+ throw new NotFound();
+ }
+
+ $name = $attachment->getName();
+ $size = $attachment->getSize();
+ $type = $attachment->getType();
+ }
+}
+```
+
+### Fields
+
+* name – a file name;
+* size – a size;
+* type – a mime type;
+* parent – a linked record an attachment is related to; used for Attachment-Multiple fields;
+* related – a linked record an attachment is related to; used for File, Image fields, for inline attachments;
+* field – a field an attachment is related through;
+* role – a role, e.g. Attachment, Inline Attachment, Export File.
+* sourceId – an original attachment reference; multiple attachments can refer to one file.
+
+## File storage manager
+
+The class: `Espo\Core\FileStorage\Manager`.
+
+An access point for file storing and fetching. Files are represented as Attachment entities. Note that different attachments can be stored in different storages (for example, in local folder, AWS S3). The Manager abstracts away
+how the file is stored.
+
+Usage example:
+
+```php
+entityManager
+ ->getRDBRepositoryByClass(Attachment::class)
+ ->getById($id);
+
+ if (!$attachment) {
+ throw new NotFound();
+ }
+
+ return $this->fileStorageManager->getContents($attachment);
+ }
+
+ public function store(string $contents): string
+ {
+ $attachment = $this->entityManager
+ ->getRDBRepositoryByClass(Attachment::class)
+ ->getNew();
+
+ $attachment->setName('file.txt');
+ $attachment->setType('text/plain');
+
+ $this->entityManager->saveEntity($attachment);
+ $this->fileStorageManager->putContents($attachment, $contents);
+
+ return $attachment->getId();
+ }
+}
+```
+
+Available methods:
+
+* exists – check whether a file exists;
+* getSize – get a file size;
+* getContents – get a string;
+* getStream – get a PSR-7 stream;
+* putContents – put a PSR-7 stream;
+* putStream – put a string;
+* unlink – remove from a storage.
diff --git a/docs/development/autoload.md b/docs/development/autoload.md
new file mode 100644
index 000000000..7c18c4ed0
--- /dev/null
+++ b/docs/development/autoload.md
@@ -0,0 +1,26 @@
+# Autoload
+
+Sometimes when developing a module for Espo, you need to include 3rd party libraries via composer.
+As Espo extensions are not installed via composer and even don't require CLI access to be installed, we needed a mechanism to let Espo know about additional libraries.
+
+You need to create an *autoload* configuration file `custom/Espo/Modules/{Module}/Resources/autoload.json`:
+
+Example:
+
+```json
+{
+ "psr-4": {
+ "SomeLib\\": "custom/Espo/Modules/MyModule/vendor/some-lib/src"
+ },
+ "psr-0": {},
+ "autoloadFileList": [
+ "custom/Espo/Modules/MyModule/vendor/some-lib/src/functions.php"
+ ],
+ "classmap": {
+ "SomeClass": "custom/Espo/Modules/MyModule/vendor/some-lib/src/SomeClass.php"
+ }
+}
+```
+
+
+This assumes that you installed composer dependencies in your extension's repository. When using an [ext-template](https://github.com/espocrm/ext-template), it will be the directory `src/files/custom/Espo/Modules/MyModule`.
diff --git a/docs/development/calculated-fields.md b/docs/development/calculated-fields.md
new file mode 100644
index 000000000..defca681a
--- /dev/null
+++ b/docs/development/calculated-fields.md
@@ -0,0 +1,26 @@
+# Calculated Fields
+
+It's possible to create a custom not-storable read-only field a value of which will be calculated dynamically upon fetching from the database.
+
+Create a file `custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`:
+
+```json
+{
+ "fields": {
+ "yourCustomField": {
+ "type": "float",
+ "notStorable": true,
+ "readOnly": true,
+ "select": {
+ "select": "SUB:(field1, field2)"
+ }
+ }
+ }
+}
+```
+
+`SUB:(field1, field2)` is a [complex expression](../user-guide/complex-expressions.md). In this example the expression subtracts one field from another.
+
+Clear cache.
+
+You will be able to set a label for your new field at Administration > Label Manager or manually in i18n files.
diff --git a/docs/development/campaign-unsubscribe-template.md b/docs/development/campaign-unsubscribe-template.md
index 81b18b274..79de144b4 100644
--- a/docs/development/campaign-unsubscribe-template.md
+++ b/docs/development/campaign-unsubscribe-template.md
@@ -1,7 +1,5 @@
# Custom template for mass email unsubscribe page
-Available since the version 5.6.4.
-
1. Create a file `custom/Espo/Custom/Resources/metadata/clientDefs/Campaign.json`
```json
@@ -12,7 +10,7 @@ Available since the version 5.6.4.
2. Create a file `client/custom/res/templates/campaign/unsubscribe.tpl`
-```
+```html
@@ -24,7 +22,10 @@ Available since the version 5.6.4.
{{translate 'unsubscribed' category='messages' scope='Campaign'}}
@@ -35,4 +36,4 @@ Available since the version 5.6.4.
Original content can be copied from the file `client/modules/crm/res/templates/campaign/unsubscribe.tpl`.
-The same logic is available for Subsrive Again template. Use `subscribeTemplate` parameter to define a custom template.
+The same logic is available for Subscribe Again template. Use `subscribeTemplate` parameter to define a custom template.
diff --git a/docs/development/coding-rules.md b/docs/development/coding-rules.md
index 1fa82b8af..60c05eea9 100644
--- a/docs/development/coding-rules.md
+++ b/docs/development/coding-rules.md
@@ -2,70 +2,121 @@
### 1\. Never pass Container into class constructors. Pass all dependencies separately.
+❗ Bad:
+
```php
entityManager = $entityManager;
- $this->metadata = $metadata;
- }
+```
+
+✔️ Good:
+
+```php
+entityManager->getRepository('Account')
+$account = $this->entityManager
+ ->getRDBRepositoryByClass(Account::class)
->select(['id', 'name'])
- ->where([
- 'type' => 'Customer',
- ])
+ ->where(['type' => Account::TYPE_CUSTOMER])
->order('createdAt')
->findOne();
```
-### 3\. Specify type hinting for method parameters. Also specify a method return type unless it's supposed to be void.
+✔️ Good:
+
+```php
+select(['id', 'name'])
+ ->from(Account::ENTITY_TYPE)
+ ->order('createdAt')
+ ->limit(0, 10)
+ ->build();
-Parameter types:
+$sth = $this->entityManager->getQueryExecutor()->execute($query);
+$rows = $sth->fetchAll();
+```
+
+### 3\. Specify types for method parameters. Also specify the method return type.
+
+❗ Bad:
```php
isSomethingWrong()) {
throw new Error("Something is wrong.");
}
-
+
if ($this->hasNoData()) {
return null;
}
-
+
return $this->value;
}
}
@@ -91,45 +142,406 @@ class MyClass
### 5\. Don't write comments, write self explanatory code.
-In addition:
+In addition: Do not write *phpdoc* for non-public methods and properties. It's OK if you don't write *phpdoc* at all (unless needed for static analysis).
-* Do not write *phpdoc* for non-public methods and properties. It's OK if you don't write *phpdoc* at all.
-* Do not comment out a code. Remove it. It will still be available in *git*.
+Exception: Adding comments may be reasonable in some rare cases.
-Bad:
+❗ Bad (excessive documenting and commenting):
```php
+sanitizeString($string);
```
+
+✔️ Good (explaining some non-obvious cases):
+
+```php
+platform === self::SOME) {
+ return;
+}
+```
+
+### 6\. Import classes in the beginning of the file.
+
+❗ Bad:
+
+```php
+isCached()) {
+ foreach ($this->itemList as $item) {
+ if (!$this->hasItem($item)) {
+ $this->loadItem($item);
+ }
+ }
+ }
+ }
+```
+
+✔️ Better:
+
+```php
+isCached()) {
+ foreach ($this->itemList as $item) {
+ $this->processLoadItem($item);
+ }
+ }
+ }
+```
+
+✔️ Good:
+
+```php
+isCached()) {
+ $this->processLoadItems();
+ }
+ }
+```
+
+### 8\. Use early returns.
+
+❗ Not good:
+
+```php
+config->get('emailMessageMaxSize');
+
+ if ($maxSize) {
+ $size = $storage->getSize($id);
+
+ if ($size > $maxSize) {
+ $fetchOnlyHeader = true;
+ }
+ }
+
+ return $fetchOnlyHeader;
+ }
+```
+
+✔️ Good:
+
+```php
+config->get('emailMessageMaxSize');
+
+ if (!$maxSize) {
+ return false;
+ }
+
+ $size = $storage->getSize($id);
+
+ return $size > $maxSize;
+ }
+```
+
+### 8\. Avoid too many parameters in methods.
+
+Less is better. Four is too much.
+
+❗ Bad:
+
+```php
+createBuilder()
+ ->where($where)
+ ->offset($offset)
+ ->limit($limit)
+ ->withAclApplied()
+ ->find();
+```
+
+### 9\. Methods that return values should not change state. Methods that change state should not return values.
+
+Not a strict rule but in most cases should be followed.
+
+❗ Bad:
+
+```php
+isProcessed = true;
+
+ // do something
+
+ return true;
+ }
+}
+```
+
+✔️ Good:
+
+```php
+baseChecker->check($entity);
+
+ // some additional logic
+
+ return $result;
+ }
+}
+```
+
+The *protected* visibility should be used very sparsely.
+
+### 11\. Use DTOs rather than associative arrays or stdClass objects.
+
+Use immutable data transfer objects.
+
+❗ Bad:
+
+```php
+ $attribute,
+ 'value' => $value,
+ 'entityType' => $entityType,
+];
+
+$someObject->process($data);
+```
+
+✔️ Good (cloning):
+
+```php
+withAttribute($attribute)
+ ->withValue($value)
+ ->withEntityType($entityType);
+
+$someObject->process($data);
+```
+
+✔️ Good (building):
+
+```php
+setAttribute($attribute)
+ ->setValue($value)
+ ->setEntityType($entityType)
+ ->build();
+
+$someObject->process($data);
+```
+
+✔️ Good (constructor named parameters):
+
+```php
+process($data);
+```
diff --git a/docs/development/collection.md b/docs/development/collection.md
new file mode 100644
index 000000000..8f6ace402
--- /dev/null
+++ b/docs/development/collection.md
@@ -0,0 +1,222 @@
+# Collection
+
+A collection is a list of models. See the [class](https://github.com/espocrm/espocrm/blob/stable/client/src/collection.js).
+
+## Methods
+
+### fetch
+
+Fetches a collection (from the back-end). Returns a promise.
+
+```js
+collection.fetch();
+
+collection.fetch({
+ remove: false,
+ more: true,
+});
+```
+
+Options:
+
+* remove – false will prevent removing current models;
+* more – load next portion of records (show-more).
+
+You can pass custom options and check them in 'change' event listeners.
+
+### clone
+
+Clone a collection. Models are kept identical. Returns a collection instance.
+
+### get
+
+Get a model from a collection by an id.
+
+```js
+const model = collection.get(id);
+```
+
+### at
+
+Get a model by its position in a collection.
+
+```js
+const model = collection.at(index);
+```
+
+### forEach
+
+Iterates through a collection.
+
+```js
+collection.forEach(model => {});
+```
+
+### add
+
+Add a model or multiple models to a collection. Firing an 'add' event for each model, and an 'update' event afterwards.
+
+```js
+collection.add(model);
+collection.add([model]);
+```
+
+### remove
+
+Remove a model from a collection. Fires a 'remove' event for a model, and an 'update' event afterwards.
+
+```js
+collection.remove(id);
+collection.remove(model, {
+ // Suppresses events.
+ silent: true,
+});
+```
+
+### reset
+
+Empties a collection.
+
+### push
+
+Add a model to the end.
+
+### pop
+
+Remove and return the last model.
+
+### unshift
+
+Add a model at the beginning.
+
+### shift
+
+Remove and return the first model.
+
+### resetOrderToDefault
+
+Resets order parameters to default.
+
+### setOrder
+
+Sets order parameters.
+
+```
+@param {string|null} orderBy
+@param {boolean|'asc'|'desc'|null} [order]
+@param {boolean} [setDefault]
+```
+
+### abortLastFetch
+
+Abort the last fetch.
+
+### hasMore
+
+Whether more records can be fetched.
+
+### setOffset
+
+Set an offset.
+
+```js
+collection.setOffset(offset);
+```
+
+### getWhere
+
+Get a where-clause.
+
+## Properties
+
+### entityType
+
+*string*
+
+An entity type.
+
+### length
+
+*number*
+
+A current length of a collection.
+
+### total
+
+*number*
+
+A total number of records in the backend.
+
+### offset
+
+*number*
+
+A current offset (for pagination).
+
+### maxSize
+
+*number*
+
+A max size to fetch (for pagination).
+
+### where
+
+*Object*
+
+A where clause.
+
+## Instantiating
+
+With a factory:
+
+```js
+
+export default class extends View {
+
+ setup() {
+ this.wait(this.loadCollection());
+ }
+
+ async loadCollection() {
+ this.collection = await this.getCollectionFactory().create('Account');
+
+ await this.collection.fetch();
+ }
+}
+```
+
+Without factory:
+
+```js
+import View from 'view';
+import Collection from 'collection';
+
+export default class extends View {
+
+ setup() {
+ const collection = new Collection();
+ // The URL will be used when fetching from the backend.
+ collection.url = 'MyEntityType/someEndPoint';
+
+ this.wait(
+ collection.fetch()
+ );
+ }
+}
+```
+
+## Events
+
+Note: `listenTo` and `listenToOnce` are methods of the *view* class.
+
+### sync
+
+Once a collection is fetched.
+
+```js
+this.listenTo(collection, 'sync', (collection, response, options) => {});
+```
+
+### update
+
+Once a collection is updated.
diff --git a/docs/development/confirm-dialog.md b/docs/development/confirm-dialog.md
index 97b909de1..aca981978 100644
--- a/docs/development/confirm-dialog.md
+++ b/docs/development/confirm-dialog.md
@@ -8,9 +8,7 @@ Available in views.
this.confirm({
message: this.translate('someMessageName', 'messages'),
confirmText: this.translate('Confirm'), // text of the confirmation button
- }).then(
- function () {
- // here do some actions
- }.bind(this)
- );
+ }).then(() => {
+ // here do some actions
+ });
```
diff --git a/docs/development/container-services.md b/docs/development/container-services.md
new file mode 100644
index 000000000..679884f24
--- /dev/null
+++ b/docs/development/container-services.md
@@ -0,0 +1,147 @@
+# Container Services
+
+Console command that prints all available container services with their implementing classes:
+
+```
+bin/command app-info --container
+```
+
+Most often used services are listed below.
+
+## entityManager
+
+Class: `Espo\ORM\EntityManager`
+
+A central access point to [ORM](orm.md) functionality.
+
+## metadata
+
+Class: `Espo\Core\Utils\Metadata`
+
+Application [metadata](metadata.md).
+
+## config
+
+Class: `Espo\Core\Utils\Config`
+
+A main application config.
+
+## ormDefs
+
+*As of v7.0.*
+
+Class: `Espo\ORM\Defs\Defs`
+
+Entity definitions (fields, attributes, relations).
+
+## fileManager
+
+Class: `Espo\Core\Utils\File\Manager`
+
+Provides functions for reading and storing files.
+
+## applicationState
+
+Class: `Espo\Core\ApplicationState`
+
+Provides information about an application, current user, portal.
+
+## log
+
+Class: `Espo\Core\Utils\Log`
+
+A logger. Messages are written into `data/log`.
+
+## user
+
+Class: `Espo\Entities\User`
+
+A current user. If an application does not require an authentication, then the *system* user is substituted.
+
+## preferences
+
+Class: `Espo\Entities\Preferences`
+
+Preferences of a current user.
+
+## aclManager
+
+Class: `Espo\Core\AclManager`
+
+Provides access checking functions for any user.
+
+## acl
+
+Class: `Espo\Core\Acl`
+
+Provides access checking functions for a current user. A wrapper for *aclManager*.
+
+## fieldUtil
+
+Class: `Espo\Core\Utils\FieldUtil`
+
+An utility class for obtaining information about fields.
+
+## dateTime
+
+Class: `Espo\Core\Utils\DateTime`
+
+Date-time utility functions.
+
+## number
+
+Class: `Espo\Core\Utils\NumberUtil`
+
+Number utility functions.
+
+## fileStorageManager
+
+Class: `Espo\Core\FileStorage\Manager`
+
+Stores and reads attachment entities.
+
+## language
+
+Class: `Espo\Core\Utils\Language`
+
+Language util of a current user.
+
+## defaultLanguage
+
+Class: `Espo\Core\Utils\Language`
+
+A util for a default language of the system.
+
+## baseLanguage
+
+Class: `Espo\Core\Utils\Language`
+
+A util for *en_US* language.
+
+## formulaManager
+
+Class: `Espo\Core\Formula\Manager`
+
+To run Formula scripts.
+
+## streamService
+
+Class: `Espo\Tools\Stream\Service`
+
+## applicationConfig
+
+*As of v9.1.*
+
+Class: `Espo\Core\Utils\Config\ApplicationConfig`
+
+## systemConfig
+
+*As of v9.1.*
+
+Class: `Espo\Core\Utils\Config\SystemConfig`
+
+## session
+
+*As of v9.4.*
+
+Interface: `Espo\Core\Session\Session`
diff --git a/docs/development/custom-buttons.md b/docs/development/custom-buttons.md
index f169f690f..7bad7bc16 100644
--- a/docs/development/custom-buttons.md
+++ b/docs/development/custom-buttons.md
@@ -4,7 +4,9 @@
How to add buttons (or dropdown actions) that will appear in the top-right corner.
-An example for the detail view of *Lead* entity type.
+An example for the detail view of the *Lead* entity type.
+
+### Definition
Create a file (if it doesn't exist) `custom/Espo/Custom/Resources/metadata/clientDefs/Lead.json`:
@@ -15,16 +17,15 @@ Create a file (if it doesn't exist) `custom/Espo/Custom/Resources/metadata/clien
"buttons": [
"__APPEND__",
{
- "label": "Some Label",
- "name": "someName",
- "action": "someName",
+ "label": "My Action",
+ "name": "myAction",
"style": "default",
"acl": "edit",
"aclScope": "Lead",
- "data": {
- "handler": "custom:my-action-handler"
- },
- "initFunction": "initSomeName"
+ "handler": "custom:my-action-handler",
+ "initFunction": "initMyAction",
+ "actionFunction": "myAction",
+ "checkVisibilityFunction": "isMyActionVisible"
}
]
}
@@ -32,48 +33,80 @@ Create a file (if it doesn't exist) `custom/Espo/Custom/Resources/metadata/clien
}
```
-`acl` parameter defines that a user needs 'edit' access level to see the button. You can omit this parameter.
+Parameters:
+
+* `name` – A name. Mandatory if a handler is used.
+* `handler` – A handler.
+* `initFunction` – A handler method to run on initialization. Omit if not needed.
+* `acl` – Defines what access level is required to see the button. You can omit this parameter.
+* `aclScope` – What scope to check access to. If omitted, the current scope is used.
+* `checkVisibilityFunction` – A handler method that will be used to determine whether an item is visible. The method should return a boolean value. As of v8.1.
+* `actionFunction` – An action method in the handler. As of v8.1.
+
+In order to add dropdown action, you need to use the `dropdown` key instead of *buttons*.
+
+Available `style` values:
+
+* default
+* success
+* danger
+* warning
+
+In the parameter `accessDataList`, it's possible to define rules that determine whether an action item is visible to a user. See the `module:utils~AccessDefs` JSDoc type in the [source file](https://github.com/espocrm/espocrm/blob/master/client/src/utils.js).
+
+The parameter `labelTranslation` defines a label translation path. Useful if you don't want to incorporate a new label but use an existing one. Example: `Global.scopeNamesPlural.Opportunity`.
+
+Menu items defined in the `Global.json` file will be applied for all entity types.
+
+Available views (object keys in definitions):
+
+* detail
+* edit
+* list
-In order to add dropdown action, you need to use `dropdown` key instead of *buttons*.
+### Handler class
Create a file `client/custom/src/my-action-handler.js`:
```js
-define('custom:my-action-handler', ['action-handler'], function (Dep) {
-
- return Dep.extend({
-
- actionSomeName: function (data, e) {
- Espo.Ajax.getRequest('Lead/' + this.view.model.id).then(function (response) {
- console.log(response);
- });
- },
-
- initSomeName: function () {
- this.controlButtonVisibility();
- this.view.listenTo(
- this.view.model, 'change:status', this.controlButtonVisibility.bind(this)
- );
- },
-
- controlButtonVisibility: function () {
- if (~['Converted', 'Dead', 'Recycled'].indexOf(this.view.model.get('status'))) {
- this.view.hideHeaderActionItem('someName');
- } else {
- this.view.showHeaderActionItem('someName');
+define(['action-handler'], (Dep) => {
+
+ return class extends Dep {
+
+ initMyAction() {}
+
+ async myAction() {
+ this.view.disableMenuItem('myAction');
+
+ let response;
+
+ try {
+ response = await Espo.Ajax.getRequest('Lead/' + this.view.model.id);
+ } catch (e) {
+ this.view.enableMenuItem('myAction');
+
+ return;
}
- },
- });
+
+ console.log(response);
+
+ this.view.enableMenuItem('myAction');
+ }
+
+ isMyActionVisible() {
+ return !['Converted', 'Dead', 'Recycled'].includes(this.view.model.attributes.status);
+ }
+ }
});
```
-## Dropdown action in detail view
+## Dropdown action in detail view
An action item next to the edit button.
-Available since version 5.6.14.
+An example for the *Lead* entity type. Menu items defined in the `Global.json` file will be applied for all entity types.
-An example for *Lead* entity type.
+### Definition
Create a file (if it doesn't exist) `custom/Espo/Custom/Resources/metadata/clientDefs/Lead.json`:
@@ -85,45 +118,132 @@ Create a file (if it doesn't exist) `custom/Espo/Custom/Resources/metadata/clien
"label": "Test Action",
"name": "test",
"acl": "edit",
- "data": {
- "handler": "custom:my-action-handler"
- },
- "initFunction": "initTest"
+ "handler": "custom:my-action-handler",
+ "initFunction": "initTest",
+ "checkVisibilityFunction": "isTestVisible",
+ "actionFunction": "test"
}
]
}
```
-Paremeter *acl* set to *edit* means that a user need *edit* access level to see the action. You can omit it.
+Parameters:
+
+* `name` ~ A name. Important if a handler is used.
+* `handler` – A handler.
+* `initFunction` – A handler method to run on initialization. Omit if not needed.
+* `acl` – Defines what access level is required to see the button. You can omit this parameter.
+* `checkVisibilityFunction` – A handler method that will be used to determine whether an item is visible. The method should return a boolean value. As of v8.1.
+* `actionFunction` – An action method in the handler. As of v8.1.
+### Handler class
Create a file `client/custom/src/my-action-handler.js`:
```js
-define('custom:my-action-handler', ['action-handler'], function (Dep) {
-
- return Dep.extend({
-
- actionTest: function (data, e) {
- Espo.Ajax.getRequest('Lead/' + this.view.model.id).then(function (response) {
- console.log(response);
- });
- },
-
- initTest: function () {
- this.controlActionVisibility();
- this.view.listenTo(
- this.view.model, 'change:status', this.controlActionVisibility.bind(this)
- );
- },
-
- controlActionVisibility: function () {
- if (~['Converted', 'Dead', 'Recycled'].indexOf(this.view.model.get('status'))) {
- this.view.hideActionItem('test');
- } else {
- this.view.showActionItem('test');
- }
- },
- });
+define(['action-handler'], (Dep) => {
+
+ return class extends Dep {
+
+ initTest() {}
+
+ async test() {
+ const response = await Espo.Ajax.getRequest('Lead/' + this.view.model.id);
+
+ console.log(response);
+ }
+
+ isTestVisible() {
+ return !['Converted', 'Dead', 'Recycled'].includes(this.view.model.attributes.status);
+ }
+ }
});
```
+
+## Dropdown action in detail modal view
+
+*As of v7.2.*
+
+Everything is the same as for the detail view. The only difference is that the metadata parameter name is `modalDetailActionList`.
+
+## Mass action in list view
+
+An action will available in the *Actions* dropdown when you select records on the list view.
+
+*As of v7.0.*
+
+An example for *Meeting* entity type.
+
+Create a file (if it doesn't exist) `custom/Espo/Custom/Resources/metadata/clientDefs/Meeting.json`:
+
+```json
+{
+ "massActionList": [
+ "__APPEND__",
+ "test"
+ ],
+ "checkAllResultMassActionList": [
+ "__APPEND__",
+ "test"
+ ],
+ "massActionDefs": {
+ "test": {
+ "handler": "custom:test-handler",
+ "initFunction": "initTest",
+ "actionFunction": "test"
+ }
+ }
+}
+```
+
+Create a handler `client/custom/src/test-handler.js`:
+
+```js
+define('custom:test-handler', [], () => {
+
+ return class {
+
+ constructor(view) {
+ this.view = view;
+ }
+
+ initTest() {
+ // called when the list view is loaded
+
+ // here you can remove the action on a specific condition
+ // this.view.removeMassAction('test');
+
+ // const acl = this.view.getAcl();
+ // const currentUser = this.view.getUser();
+ }
+
+ /**
+ * @param {{entityType: string, action: string, params: Record}} data
+ */
+ test(data) {
+ // Here you can show a modal or send an ajax request.
+ // this.view.createView( ... )
+ // Espo.Ajax.postRequest( ...)
+ }
+ }
+});
+
+```
+
+Create a language file `custom/Espo/Custom/Resources/i18n/en_US/Meeting.json`:
+
+```json
+{
+ "massActions": {
+ "test": "Test"
+ }
+}
+```
+
+Clear cache.
+
+You can use *Mass Action* framework to handle mass actions in the back-end. Available as of v7.0. Send a POST request to the `MassAction` endpoint with data passed to the action method.
+
+## See more
+
+In Advanced Pack it's possible to create detail view buttons and dropdown items that run workflow actions. A button can be configured to be visible only if specific conditions are met.
diff --git a/docs/development/custom-config-parameters.md b/docs/development/custom-config-parameters.md
new file mode 100644
index 000000000..44f48b478
--- /dev/null
+++ b/docs/development/custom-config-parameters.md
@@ -0,0 +1,153 @@
+# Custom config parameters
+
+In this article it will be shown how to add custom config parameters and how to make them available on the administration panel.
+
+In the example it's supposed that your module is named `MyModule`. Replace `MyModule` and `my-module` with your real module name.
+
+### 1. Metadata entityDefs > settings
+
+Create a file `custom/Espo/Modules/MyModule/Resources/metadata/entityDefs/Settings.json`:
+
+```json
+{
+ "fields": {
+ "myParameter": {
+ "type": "enum",
+ "options": ["Option 1", "Option 2"],
+ "tooltip": true
+ }
+ }
+}
+```
+
+### 2. Metadata app > config
+
+Create a file `custom/Espo/Modules/MyModule/Resources/metadata/app/config.json`:
+
+```json
+{
+ "params": {
+ "myParameter": {
+ "level": "admin"
+ }
+ }
+}
+```
+
+The *level* parameter defines availability of the config parameter in the front-end.
+
+* `default` – available for logged-in users (applied by default);
+* `global` – available even before logging in;
+* `system` – never available;
+* `internal` – never available for read, admin can write (useful for passwords, secrets; recommended to use the *password* field type) (as of v7.3);
+* `admin` – available only for admin (read and write);
+* `superAdmin` – available only for super-admin (read and write).
+
+The *readOnly* [parameter](metadata/app-config.md#readonly) disables the ability to change a parameter value for admin users.
+
+### 3. Metadata app > adminPanel
+
+Create a file `custom/Espo/Modules/MyModule/Resources/metadata/app/adminPanel.json`:
+
+```json
+{
+ "myPanel": {
+ "label": "My Panel",
+ "itemList": [
+ {
+ "url": "#Admin/mySettings",
+ "label": "My Settings",
+ "iconClass": "fas fa-cog",
+ "description": "myDescription",
+ "recordView": "my-module:views/admin/my-settings"
+ }
+ ],
+ "order": 101
+ }
+}
+```
+
+### 4. Language files
+
+Create a file `custom/Espo/Modules/MyModule/Resources/i18n/en_US/Admin.json`:
+
+```json
+{
+ "keywords": {
+ "myPanel": "some search keyword,another search keyword"
+ },
+ "descriptions": {
+ "myDescription": "Description text."
+ },
+ "labels": {
+ "My Settings": "My Settings",
+ "My Panel": "My Panel"
+ }
+}
+```
+
+
+Create a file `custom/Espo/Modules/MyModule/Resources/i18n/en_US/Settings.json`:
+
+```json
+{
+ "fields": {
+ "myParameter": "My Parameter"
+ },
+ "tooltips": {
+ "myParameter": "My parameter tooltip text. Markdown supported."
+ },
+ "options": {
+ "myParameter": {
+ "Option 1": "Option 1",
+ "Option 2": "Option 2"
+ }
+ }
+}
+```
+
+### 5. View
+
+Create a file `client/custom/modules/my-module/src/views/admin/my-settings.js`:
+
+```js
+define('my-module:views/admin/my-settings', ['views/settings/record/edit'], function (Dep) {
+
+ return Dep.extend({
+
+ detailLayout: [
+ {
+ rows: [
+ [
+ {
+ name: 'myParameter'
+ },
+ false
+ ]
+ ]
+ }
+ ],
+
+ // Dynamic logic can de defined.
+ dynamicLogicDefs: {},
+
+ setup: function () {
+ Dep.prototype.setup.call(this);
+
+ // Some custom logic can be written here.
+ },
+ });
+});
+```
+
+### 6. Final step
+
+Clear cache.
+
+The parameter value now can be read in the back-end:
+
+```php
+get('myParameter');
+```
diff --git a/docs/development/custom-css.md b/docs/development/custom-css.md
index 9da5a3faf..8cda4dfd5 100644
--- a/docs/development/custom-css.md
+++ b/docs/development/custom-css.md
@@ -5,11 +5,12 @@ Create a file `custom/Espo/Custom/Resources/metadata/app/client.json`.
```json
{
"cssList": [
+ "__APPEND__",
"path/to/your/file.css"
]
}
```
-Make sure the css file is readable by a webserver. It's recommended to put it in `client/custom/css/` or `client/modules/{module_name}/css/` directory.
+Make sure the CSS file is readable by the webserver. It's recommended to put it in `client/custom/css` or `client/custom/modules/{module-name}/css` directory.
Then clear cache.
diff --git a/docs/development/custom-entity-type.md b/docs/development/custom-entity-type.md
new file mode 100644
index 000000000..5e24971df
--- /dev/null
+++ b/docs/development/custom-entity-type.md
@@ -0,0 +1,327 @@
+# Custom Entity Type
+
+This article gives information about how to create custom entity types manually (without using the UI).
+
+In the example, the entity type will be defined in the `custom/Espo/Modules/MyModule` directory which corresponds to the `Espo\Modules\MyModule` namespace. You can also define in `custom/Espo/Custom` directory which corresponds to the `Espo\Custom` namespace.
+
+The entity type name created in the example is `MyEntity`.
+
+After all needed files are created, you need to run rebuild (Administration > Rebuild). It will clear cache and create the database table.
+
+## Metadata
+
+### entityDefs
+
+[Reference](metadata/entity-defs.md)
+
+File: `custom/Espo/Modules/MyModule/Resources/metadata/entityDefs/MyEntity.json`
+
+Defines entity definitions: fields, links, indexes and parameters.
+
+Example:
+
+```json
+{
+ "fields": {
+ "name": {
+ "type": "varchar",
+ "maxLength": 100,
+ "required": true
+ },
+ "status": {
+ "type": "enum",
+ "maxLength": 9,
+ "options": [
+ "Draft",
+ "Started",
+ "Completed",
+ "Canceled"
+ ],
+ "default": "Draft",
+ "style": {
+ "Started": "primary",
+ "Completed": "success",
+ "Canceled": "info"
+ }
+ },
+ "assignedUser": {
+ "type": "link"
+ },
+ "teams": {
+ "type": "linkMultiple"
+ },
+ "createdAt": {
+ "type": "datetime",
+ "readOnly": true
+ }
+ },
+ "links": {
+ "assignedUser": {
+ "type": "belongsTo",
+ "entity": "User"
+ },
+ "teams": {
+ "type": "hasMany",
+ "entity": "Team",
+ "relationName": "entityTeam"
+ }
+ },
+ "indexes": {
+ "name": {
+ "columns": ["name"]
+ }
+ },
+ "collection": {
+ "textFilterFields": ["name"],
+ "orderBy": "createdAt",
+ "order": "desc"
+ }
+}
+```
+
+### scopes
+
+[Reference](metadata/scopes.md)
+
+File: `custom/Espo/Modules/MyModule/Resources/metadata/scopes/MyEntity.json`
+
+Defines scope parameters.
+
+Example:
+
+```json
+{
+ "module": "MyModule",
+ "entity": true,
+ "object": true,
+ "acl": true,
+ "tab": true,
+ "importable": true
+}
+```
+
+### clientDefs
+
+[Reference](metadata/client-defs.md)
+
+File: `custom/Espo/Modules/MyModule/Resources/metadata/clientDefs/MyEntity.json`
+
+Defines entity type parameters for the frontend.
+
+Example:
+
+```json
+{
+ "controller": "controllers/record"
+}
+```
+
+Without the *controller* parameter the entity type won't be available in the frontend. *controllers/record* is a build-in standard CRUD controller in the frontend.
+
+## Entity class
+
+File: `custom/Espo/Modules/MyModule/Entities/MyEntity.php`
+
+Example:
+
+```php
+get('name');
+ }
+
+ public function setName(string $name): self
+ {
+ $this->set('name', $name);
+
+ return $this;
+ }
+
+ public function getStatus(): string
+ {
+ return $this->get('status');
+ }
+
+ public function setStatus(string $status): self
+ {
+ $this->set('status', $status);
+
+ return $this;
+ }
+
+ public function getAssignedUserId(): ?string
+ {
+ $this->get('assignedUserId');
+
+ return $this;
+ }
+
+ public function setAssignedUserId(?string $assignedUserId): self
+ {
+ $this->set('assignedUserId', $assignedUserId);
+
+ return $this;
+ }
+
+ public function getTeams(): LinkMultiple
+ {
+ /** @var LinkMultiple */
+ return $this->getValueObject('teams');
+ }
+
+ public function setTeams(LinkMultiple $teams): self
+ {
+ $this->setValueObject('teams', $teams);
+
+ return $this;
+ }
+
+ public function getCreatedAt(): DateTime
+ {
+ /** @var DateTime */
+ return $this->getValueObject('createdAt');
+ }
+}
+```
+
+## Controller class
+
+File: `custom/Espo/Modules/MyModule/Controllers/MyEntity.php`
+
+A Controller class is needed if you need to have CRUD operations available via the API. That includes the frontend, as the frontend communicates with the backend via the API.
+
+Example:
+
+```php
+ {
- detailTemplate: 'custom:fields/{field-type}/detail',
- listTemplate: 'custom:fields/{field-type}/list',
- editTemplate: 'custom:fields/{field-type}/edit',
- searchTemplate: 'custom:fields/{field-type}/search',
-
- setup: function () {
-
- },
-
- afterRender: function () {
+ return class extends BaseFieldView {
+
+ // Templates for all view modes.
+ detailTemplateContent = ` ... `
+ listTemplateContent = ` ... `
+ editTemplateContent = ` ... `
+ searchTemplateContent = ` ... `
- },
- });
+ setup() {}
+ }
});
```
-Create detail/list/edit/search templates (*.tpl extension) in `client/custom/res/templates/fields/{field-type}/` directory.
+See out-of-the-box field types for examples:
-Use out-of-the-box field types as examples:
-- `/client/src/views/fields/` - views
-- `/client/res/templates/fields/` - templates
+* `client/src/views/fields/` — views
### Translation
-The label is used in Entity Manager can be set in `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` in section `fieldTypes`.
-If you need to add translation to other language, use needed language [language code](https://en.wikipedia.org/wiki/ISO_639-1)_[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) instead of `en_US`. In `data/config.php` in section `languageList` you can find the list of included languages.
+The label is used in Entity Manager can be set in `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` in the section `fieldTypes`.
+If you need to add translation to other language, use [language code](https://en.wikipedia.org/wiki/ISO_639-1)_[Country Code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) instead of `en_US`.
Then you need to clear cache at the administration panel.
+
+### Backend validator
+
+You can define a validator class in a field metadata file in the `validatorClassName` parameter. See the [barcode field](https://github.com/espocrm/espocrm/blob/stable/application/Espo/Resources/metadata/fields/barcode.json) as an example.
diff --git a/docs/development/custom-views.md b/docs/development/custom-views.md
index fafeb0537..ce609255e 100644
--- a/docs/development/custom-views.md
+++ b/docs/development/custom-views.md
@@ -2,7 +2,7 @@
## Record views
-EspoCRM framework provides flexible abilities to define custom views for certain entity types. They must be defined in `clientDefs` category of metadata.
+EspoCRM framework provides abilities to define custom views for certain entity types. They must be defined in `clientDefs` category of metadata.
`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
@@ -21,37 +21,37 @@ EspoCRM framework provides flexible abilities to define custom views for certain
}
```
-#### Detail view
+### Detail view
`client/custom/src/views/your-entity-type/record/detail.js`
The view 'views/record/detail' contains all panels with fields, relations and other data you can see on detail view. It doesn't contain header and buttons in the top-right corner.
```javascript
-define('custom:views/your-entity-type/record/detail', ['views/record/detail'], function (Dep) {
+define('custom:views/your-entity-type/record/detail', ['views/record/detail'], (DetailRecordView) => {
- return Dep.extend({
+ return class extends DetailRecordView {
// custom template, omit if you don't need it
- template: 'custom:your-entity-type/record/detail',
+ // template = 'custom:your-entity-type/record/detail'
// custom central view, omit if you don't need it
- middleView: 'custom:views/your-entity-type/record/detail-middle',
+ // middleView = 'custom:views/your-entity-type/record/detail-middle'
// custom side column view, omit if you don't need it
- sideView: 'custom:views/your-entity-type/record/detail-side',
+ // sideView = 'custom:views/your-entity-type/record/detail-side'
// custom bottom view, omit if you don't need it
- bottomView: 'custom:views/your-entity-type/record/detail-bottom',
+ // bottomView = 'custom:views/your-entity-type/record/detail-bottom'
- setup: function() {
- Dep.prototype.setup.call(this);
+ setup() {
+ super.setup();
this.hideField('someField');
this.showField('someField');
// custom initialization logic, like binding listening to model changes
- this.listenTo(this.model, 'change:myField', function () {
+ this.listenTo(this.model, 'change:myField', () => {
this.model.set('anotherField', this.model.get('myField') + ' Hello');
this.hideField('someField');
@@ -64,16 +64,13 @@ define('custom:views/your-entity-type/record/detail', ['views/record/detail'], f
this.hidePanel('activities');
this.showPanel('history');
- }, this);
- },
+ });
+ }
- afterRender: function() {
- Dep.prototype.afterRender.call(this);
-
- // Custom code to be invoked right after rendering, when DOM is available.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- },
- });
+ afterRender() {
+ super.afterRender();
+ }
+ }
});
```
@@ -84,14 +81,14 @@ You are able to create a custom template with the following path: `client/custom
Detail view contains a record view and header view.
-#### Edit view
+### Edit view
`client/custom/src/views/your-entity-type/edit.js`
`client/custom/src/views/your-entity-type/record/edit.js`
The same as detail but it is used when record is being created or edited not in inline-edit mode.
-#### List view
+### List view
`client/custom/src/views/your-entity-type/list.js`
@@ -101,13 +98,13 @@ List view contains Record/List view, Header and Search Form View.
The views 'views/list/record' contains rows of records.
-####
+### Extending from specific view
-It is worth to mention that you need to inherit your view class from specific class for your entity if one already exists.
+It's worth to mention that you need to inherit your view class from specific class for your entity if one already exists.
```javascript
-define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
+define('custom:views/email/record/detail', ['views/email/record/detail'], (EmailDetailRecordView) => {
+ return class extends EmailDetailRecordView {}
});
```
@@ -133,19 +130,23 @@ Example for Address field of Account entity type.
`client/custom/src/views/account/fields/address.js`
```js
-define('custom:views/fields/address', 'views/fields/address', function (Dep) {
+define('custom:views/fields/address', ['views/fields/address'], (AddressFieldView) => {
- return Dep.extend({
+ return class extends AddressFieldView {
- setup: function () {
- Dep.prototype.setup.call(this);
+ setup() {
+ super.setup();
// some initialization
- },
+ }
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
+ afterRender() {
+ super.afterRender();
// your customizations executed after the field is rendered
- },
- });
+ }
+ }
});
```
+
+## See also
+
+* [View setup handlers](frontend/view-setup-handlers.md)
diff --git a/docs/development/customize-standard-fields.md b/docs/development/customize-standard-fields.md
index 12c9908cf..4870efefd 100644
--- a/docs/development/customize-standard-fields.md
+++ b/docs/development/customize-standard-fields.md
@@ -2,7 +2,7 @@
## Customizing field type
-An example for *Address* field type.
+An example for the *Address* field type.
Create a file `custom/Espo/Custom/Resources/metadata/fields/address.json`.
@@ -15,24 +15,24 @@ Create a file `custom/Espo/Custom/Resources/metadata/fields/address.json`.
Create a file `client/custom/src/views/fields/address.js`.
```js
-define('custom:views/fields/address', 'views/fields/address', function (Dep) {
+define(['views/fields/address'], (AddressFieldView) => {
- return Dep.extend({
-
- detailTemplate: 'custom:fields/address/detail', // omit if you don't need custom template
- editTemplate: 'custom:fields/address/edit', // omit if you don't need custom template
- listTemplate: 'custom:fields/address/list', // omit if you don't need custom template
+ return class extends AddressFieldView {
+
+ //detailTemplateContent = ' ... '
+ //editTemplateContent = ' ... '
+ //listTemplateContent = ' ... '
+ //listLinkTemplateContent = ' .. '
- setup: function () {
- Dep.prototype.setup.call(this);
- // some initialization
- },
+ setup() {
+ super.setup();
+ }
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
+ afterRender() {
+ super.afterRender();
// your customizations executed after the field is rendered
- },
- });
+ }
+ }
});
```
@@ -42,7 +42,7 @@ Create a template file (if needed) `client/custom/res/templates/fields/address/d
### Changing field type of existing field
-An example for meeting's Name field.
+An example for the *Meeting*'s *Name* field.
Create (or edit if exists) a file `custom/Espo/Custom/Resources/metadata/entityDefs/Meeting.json`.
@@ -58,7 +58,7 @@ Create (or edit if exists) a file `custom/Espo/Custom/Resources/metadata/entityD
### Custom view for specific field
-An example for *Meeting*'s *Name* field.
+An example for the *Meeting*'s *Name* field.
Create (or edit if exists) a file `custom/Espo/Custom/Resources/metadata/entityDefs/Meeting.json`.
@@ -75,20 +75,19 @@ Create (or edit if exists) a file `custom/Espo/Custom/Resources/metadata/entityD
File `client/custom/src/views/meeting/fields/name.js`:
```js
-define('custom:views/meeting/fields/name', 'views/fields/varchar', function (Dep) {
+define(['views/fields/varchar'], (VarcharFieldView) => {
- return Dep.extend({
+ return class extends VarcharFieldView {
- setup: function () {
- Dep.prototype.setup.call(this);
+ setup() {
+ super.setup();
// some initialization
- },
+ }
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
+ afterRender() {
+ super.afterRender();
// your customizations executed after the field is rendered
- },
- });
+ }
+ }
});
```
-
diff --git a/docs/development/db-indexes.md b/docs/development/db-indexes.md
index 8e9224515..ffc8f7839 100644
--- a/docs/development/db-indexes.md
+++ b/docs/development/db-indexes.md
@@ -4,7 +4,7 @@ Proper database indexes can drastically improve a performance of list view loadi
After changes you need to rebuild database. It's better to do from CLI to avoid timeout issue.
-Command to run rebuld:
+Command to run rebuild:
```
php rebuild.php
@@ -23,7 +23,6 @@ For *Lead* entity type.
```json
{
-
"indexes": {
"myIndexNameOne": {
"columns": ["columnName"]
@@ -48,15 +47,38 @@ You need to run rebuild after changes.
You need to specify an index name in *useIndex* param.
```php
-$repository->where($whereClause)->find([
- 'useIndex' => 'myIndexNameOne',
-]);
-
+getQueryBuilder()
+ ->select()
+ ->from($entityType)
+ ->where($whereClause)
+ ->useIndex('myIndexNameOne')
+ ->build();
+
+$collection = $entityManager->getRDBRepository($entityType)
+ ->clone($query)
+ ->find();
```
-Multiple indexes:
+## Relationship table indexes
-```php
-$repository->where($whereClause)->find([
- 'useIndex' => ['myIndexNameOne', 'myIndexNameTwo'],
-]);
+In entityDefs:
+
+```json
+{
+ "links": {
+ "linkName": {
+ "additionalColumns": {
+ "role": {
+ "type": "varchar"
+ }
+ },
+ "indexes": {
+ "role": {
+ "columns": ["role"]
+ }
+ }
+ }
+ }
+}
+```
diff --git a/docs/development/di.md b/docs/development/di.md
index 64091e533..186446c29 100644
--- a/docs/development/di.md
+++ b/docs/development/di.md
@@ -1,188 +1,403 @@
# Dependency Injection
-Note: This article is actual for v6.0.0 and greater.
+The Dependency Injection framework provides needed dependencies to classes (usually via a constructor). For example, if your hook needs the EntityManager service, you just define it as a constructor parameter.
-There are two types of classes, that utilize dependency injection.
+For example, your controller has a dependency on some service class. That service class has other dependencies (e.g. the entity manager, some utility classes), these dependencies can have their own dependencies and so on. You don't need to instantiate dependencies, you just define them in class constructors and the framework provides them automatically.
-* Container services
-* Classes created by *injectableFactory*
+```
+- MyController
+ - MyService
+ - EntityManager (container service)
+ - MyUtilityClass1
+ - EntityManager (container service)
+ - FileStorageManager (container service)
+ - MyUtilityClass2
+```
+
+In this article:
+
+* [Container services](#container-services)
+* [Injectable factory](#injectable-factory)
+* [Binding](#binding)
+* [See also](#see-also)
+
+There are two classes responsible for the dependency injection in EspoCRM:
+
+* Container – `Espo\Core\Container` [class](https://github.com/espocrm/espocrm/blob/master/application/Espo/Core/Container.php);
+* InjectableFactory – `Espo\Core\InjectableFactory` [class](https://github.com/espocrm/espocrm/blob/master/application/Espo/Core/InjectableFactory.php).
## Container services
-Note: Don't confuse with *Service* classes.
+The Container contains services. These services are supposed to be used in multiple places throughout the system. **Lazy initialization** is used, meaning that a service is not loaded until it's asked (as a dependency).
-Contaner services are instantiated by *Container* object (instance of `Espo\Core\Container`). **Lazy initialization** is used.
+Container services are defined:
-Container services are defined in:
+* in [metadata](metadata.md) (app > containerServices);
+* by loader classes (in `Espo\Core\Loaders` namespace);
-* container class `Espo\Core\Container` (most critical functinalities that are not supposed to be extended);
-* loader classes in `Espo\Core\Loaders` namespace (can be customized in `Espo\Custom\Core\Loaders`);
-* metadata (app > containerServices).
+!!! note
-Note: The best practice is not to require *container* in your classes, and never use it directly.
+ The best practice is not to require the *container* in your classes, and never use it directly. A specific service can be required in a constructor or with Aware interface.
-Console command that prints all available container services with their implementing classes:
+Console command that prints all available container services with their implementation classes:
```
-php command.php app-info --container
+bin/command app-info --container
```
-### Defining in metadata
+Most used container services are listed [here](container-services.md).
+
+### Defining
+
+If you need to define your custom container services, do it in metadata. In your module or in the custom folder:
+
+* `custom/Espo/Modules/{YourModule}/Resources/metadata/app/containerServices.json`;
+* `custom/Espo/Custom/Resources/metadata/app/containerServices.json`.
-If you need to define your custom container services, do it in metadata:
+When defining in metadata there are 2 options:
-* `custom/Espo/Custom/Resources/metadata/app/containserServices.json`;
-* or in your module folder.
+* specify a class for a service;
+* specify a loader that loads a service (the loader should implement `Espo\Core\Container\Loader` interface).
A definition example:
```json
{
- "notificatorFactory": {
- "className": "Espo\\Core\\NotificatorFactory"
+ "myService1": {
+ "className": "Espo\\Modules\\MyModule\\MyService1"
},
- "clientManager": {
- "className": "Espo\\Core\\Utils\\ClientManager"
+ "myService2": {
+ "loaderClassName": "Espo\\Modules\\MyModule\\MyService2Loader"
}
}
```
-Needed dependencies will be passed to a class constructor. Class constructor parameter names will be used to detect dependencies.
+Then you need to bind a class name to the service.
-For example, if a parameter name is `$entityManager`, then *entityMaanger* container service will be passed.
+File `custom/Espo/Modules/MyModule/Binding.php`:
```php
entityManager = $entityManager;
+ $binder->bindService('Espo\\Modules\\MyModule\\MyService1', 'myService1');
}
}
```
-## Injectable Factory
+Needed dependencies will be passed to a class constructor upon instantiation. Parameter type hinting and binding (processed on application start) will be used (via reflection) to detect dependencies.
+
+Example:
+
+```php
+injectableFactory = $injectableFactory;
- }
-
- public function createSomething() : Something
+ public function __construct(
+ private InjectableFactory $injectableFactory,
+ ) {}
+
+ public function create(): Something
{
- $this->injectableFactory->create(Something::class);
+ // Here can be logic that choose a specific class upon some criteria.
+ return $this->injectableFactory->create(Something::class);
}
}
```
### Constructor injection
-Constructor parameter names will be used to detect dependencies.
+*A recommended way.*
+
+Binding and constructor parameter names are used to detect service dependencies.
-For example, if the parameter name is `$entityManager`, then *entityManager* service will be passed.
+Resolving process:
-Class:
+* Tries to resolve by binding (see below about binding); exits if success;
+* Tries to resolve by a parameter name, assuming that the parameter name matches the service name and the type hint matches the service class; exits if success;
+* Creates a new instance if the type hint is a class.
+
+If a dependency is not a service, a new instance will be created every time the dependency is requested. See below.
```php
entityManager = $entityManager;
+ // $this->entityManager;
+ // $this->metadata;
}
}
```
-Instantiating:
+Using setter injections may be reasonable when you are extending from an existing class and want to add additional dependencies.
+
+Limitation: Only container services can be injected via setters.
+
+!!! note
+
+ It's not a recommended way to inject dependencies. Use it as a last resort if you don't want to modify an existing constructor signature.
+
+### Manual instantiating
+
+This way is supposed to be utilized in factory classes.
```php
-$injectableFactory->create('Espo\\Custom\\SomeClass');
+create(SomeClass::class);
```
-Only container services can be used as dependencies at the moment.
You can specify constructor injections explicitly using *createdWith* method. Those that are not specified, will be tried to be resolved using *ReflectionClass*.
```php
+createWith($className, [
'parameterName1' => $value1,
'parameterName2' => $value2,
]);
```
-### Setter method injection
+Factory example:
-Can be used along with the constructor injection. If a class implements *Aware* interface, the factory will use a corresponding setter function to inject a dependency. Setter traits can be utilized for adding setter functions into your class.
+```php
+injectableFactory->createWith(SomeType::class, [
+ 'userId' => $userId,
+ ]);
+ }
+}
+```
+
+It's also possible to pass a binding container when creating with the injectable factory. More info below.
+
+## Binding
+
+There is the ability to bind interfaces to implementations and bind parameter names to specific values. Binding is used for resolving dependencies passed through a constructor.
+
+Custom binding can be set up in a `Binding` class of a module:
+
+* `Espo\Modules\{ModuleName}\Binding`
+* `Espo\Custom\Binding`
+
+!!! note
+
+ The module order parameter is used when binding is processed. Meaning that modules with a lower order value will be processed first.
+
+CLI command to print all bindings:
+
+```
+bin/command app-info --binding
+```
+
+The default binding is set up in `Espo\Binding`.
+
+### Example
+
+File `custom/Espo/Modules/MyModule/Binding.php`:
```php
entityManager;
- $metadata = $this->metadata;
+ $binder
+ ->bindService('Espo\\SomeServiceName', 'someServiceName')
+ ->bindImplementation('Espo\\SomeInterface', 'Espo\\SomeImplementation');
+
+ $binder
+ ->bindService('Espo\\SomeServiceName $name', 'anotherServiceName');
+
+ $binder
+ ->for('Espo\\SomeClass')
+ ->bindImplementation('Espo\\SomeInterface', 'Espo\\SomeImplementation')
+ ->bindValue('$paramName', 'Some Value')
+ ->bindCallback(
+ 'Espo\\AnotherClass',
+ // Callback arguments are resolved automatically.
+ function (SomeDependency $dependency) {
+ return $dependency->getSomething();
+ }
+ );
}
}
```
-### Classes created by injectableFactory
+Explanation:
+
+* If any class requires `Espo\SomeServiceName`, give the container service `someServiceName`.
+* If any class requires `Espo\SomeInterface`, give an instance of `Espo\SomeImplementation`.
+* If any class requires `Espo\SomeServiceName ` and a parameter name is `$name`, then give `anotherServiceName` service.
+* When `Espo\SomeClass` requires `Espo\SomeInterface`, give an instance of `Espo\SomeImplementation`.
+* When `Espo\SomeClass` is instantiated, pass the value 'Same Value' for the parameter `$paramName`.
+* When `Espo\SomeClass` is instantiated, use the callback to resolve a value of the parameter with the type `Espo\AnotherClass`.
-The following classes are created by *injectableFactory*:
+### Binding to implementation
-* ApplicationRunners - `Espo\Core\ApplicationRunners`
-* Controllers - `Espo\Controllers`
-* Services - `Espo\Services`
-* Hooks - `Espo\Hooks`
-* Jobs - `Espo\Jobs`
-* EntryPoints - `Espo\EntryPoints`
-* Repositories - `Espo\Repositories`
-* SelectManagers - `Espo\SelectManagers`
-* Notificators - `Espo\Notificators`
-* Acl - `Espo\Acl`
-* Formula Functions
-* Cleanup - defined in metadata: app > cleanup
-* AppParams - defined in metadata: app > appParams
+Bind an interface to a specific implementation.
+
+```php
+bindImplementation(SomeInterface::class, SomeImplementation::class);
+```
+
+### Binding to service
+
+Bind an interface to a specific [service](container-services.md).
+
+```php
+$binder->bindService(SomeInterface::class, 'someServiceName');
+```
+
+### Binding to factory
+
+*As of v7.0.*
+
+Bind an interface to a specific factory so that a specific dependency will be created by a specific factory. The factory should implement `Espo\Core\Binding\Factory` interface.
+
+```php
+bindFactory(SomeInterface::class, SomeFactory::class);
+```
+
+### Binding to callback
+
+A callback will be used for creating a specific instance. The callback can have its own dependencies.
+
+```php
+bindCallback(SomeInterface::class, function (SomeDependency $dependency) {
+ // Create an instance here.
+ return $instance;
+});
+```
+
+### Using with Injectable Factory
+
+*As of v7.0.*
+
+It's possible to override default binding when creating instances with the injectable factory (usually this will be processed in your factory classes).
+
+The binding will be applied to all dependencies of the class, including dependencies of dependencies and so on.
+
+Example:
+
+```php
+bindInstance(SomeInterface::class, $someInstance)
+ ->inContext(SomeClass::class, function (ContextualBinder $binder): void {
+ // Bind dependencies of `SomeClass`.
+ $binder->bindValue('$parameterName', 'some value');
+ })
+ ->build();
+
+$instance = $injectableFactory->createWithBinding(SomeClass::class, $bindingContainer);
+```
-And many others. You can use `grep -R 'injectableFactory'` to find where it's used in Espo.
+The passed binding has a higher priority than the default binding (the default binding is applied globally to all objects resolved via DI).
-### Injectable interace
+## See also
-Using *Injectable* interface is deprecated. It's left for backward compatibility.
+* [Container services](container-services.md)
diff --git a/docs/development/duplicate-check.md b/docs/development/duplicate-check.md
index 76303e647..6d1e31ee6 100644
--- a/docs/development/duplicate-check.md
+++ b/docs/development/duplicate-check.md
@@ -1,96 +1,78 @@
# Custom duplicate check
-Duplicate check is performed upon record creation. It's also possible to enable it for a record update.
+Duplicate check is performed upon record creation. Optionally, it can be enabled for record update.
-You can customize (or enable if it's not by default) a duplicate checking for a specific entity type in the service class.
+*As of v7.0.*
-An example for Lead entity type.
+You need to define a class name in metadata: recordDefs > {entityType} > duplicateWhereBuilderClassName. The class should implement `Espo\Core\Duplicate\WhereBuilder` interface.
-Create a file `custom/Espo/Custom/Services/Lead.php`:
+### Example
+
+Create `custom/Espo/Custom/Resources/metadata/recordDefs/Lead.json`:
+
+```json
+{
+ "duplicateWhereBuilderClassName": "Espo\\Custom\\Classes\\DuplicateWhereBuilders\\Lead"
+}
+```
+
+Create a file `custom/Espo/Custom/Classes/DuplicateWhereBuilders/Lead.php`:
```php
[]
- ];
+ $orBuilder = OrGroup::createBuilder();
+
$toCheck = false;
+
if ($entity->get('firstName') || $entity->get('lastName')) {
- $part = [];
- $part['firstName'] = $entity->get('firstName');
- $part['lastName'] = $entity->get('lastName');
- $whereClause['OR'][] = $part;
+ $orBuilder->add(
+ Cond::and(
+ Cond::equal(
+ Cond::column('firstName'),
+ $entity->get('firstName')
+ ),
+ Cond::equal(
+ Cond::column('lastName'),
+ $entity->get('lastName')
+ )
+ )
+ );
+
$toCheck = true;
}
- if (
- ($entity->get('emailAddress') || $entity->get('emailAddressData'))
- &&
- (
- $entity->isNew() ||
- $entity->isAttributeChanged('emailAddress') ||
- $entity->isAttributeChanged('emailAddressData')
- )
- ) {
- if ($entity->get('emailAddress')) {
- $list = [$entity->get('emailAddress')];
- }
- if ($entity->get('emailAddressData')) {
- foreach ($entity->get('emailAddressData') as $row) {
- if (!in_array($row->emailAddress, $list)) {
- $list[] = $row->emailAddress;
- }
- }
- }
- foreach ($list as $emailAddress) {
- $whereClause['OR'][] = [
- 'emailAddress' => $emailAddress
- ];
- $toCheck = true;
- }
- }
+
+ // Here you can add more conditions.
+
if (!$toCheck) {
- return false;
+ return null;
}
- return $whereClause;
+
+ return $orBuilder->build();
}
}
-
```
-More simple example:
+You can find built-in duplicate where-builders [here](https://github.com/espocrm/espocrm/tree/master/application/Espo/Classes/DuplicateWhereBuilders). You can reuse them for your entity.
-```php
- protected function getDuplicateWhereClause(Entity $entity, $data)
- {
- $whereClause = [
- 'OR' => []
- ];
-
- $toCheck = false;
-
- if ($entity->get('name')) {
- $toCheck = true;
- $whereClause['OR']['name'] = $entity->get('name');
- }
+## Checking for duplicates when update
- if ($entity->get('emailAddress')) {
- $toCheck = true;
- $whereClause['OR']['emailAddress'] = $entity->get('emailAddress');
- }
-
- if (!$toCheck) return null;
+Disabled by default. Can be enabled in metadata: recordDefs > {entityType} > updateDuplicateCheck.
- return $whereClause;
- }
+```json
+{
+ "updateDuplicateCheck": true
+}
```
diff --git a/docs/development/dynamic-forms.md b/docs/development/dynamic-forms.md
deleted file mode 100644
index 961079b9c..000000000
--- a/docs/development/dynamic-forms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Dynamic Forms
-
-Note: Since version 4.3.0 it's possible to define dynamic form through admin's UI in Entity Manager.
-
-There is an ability to define a form behavior in EspoCRM.
-
-## Example
-
-> Need to show _nextStep_ field on an Opportunity detail view only if stage is 'Closed Won'.
->
-
-Create file `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-That means that _nextStep_ field will be hidden by default and shown if stage equals to 'Closed Won'.
-
-The list of available actions: `show`, `hide`, `setRequired`, `setNotRequired`.
-
-There is also ability to hide/show panels. Specify panel names in `panels`, attribute the same way as `fields`.
diff --git a/docs/development/dynamic-handler.md b/docs/development/dynamic-handler.md
index b2a7b0a67..7821b0d1e 100644
--- a/docs/development/dynamic-handler.md
+++ b/docs/development/dynamic-handler.md
@@ -2,9 +2,9 @@
Dynamic Handler provides the ability to manipulate the form (detail/edit views) appearance.
-Note, that you can make forms dynamic with [Dynamic Logic](../administration/dynamic-logic.md) feature. Dynamic Handler is intended for more complex tasks where Dynamic Logic can be useless.
+Note that you can make forms dynamic with [Dynamic Logic](../administration/dynamic-logic.md) feature. Dynamic Handler is intended for more complex tasks where Dynamic Logic can be useless.
-An example for Account entity type.
+An example for the *Account* entity type.
Create a file `custom/Espo/Custom/Resources/metadata/clientDefs/Account.json`:
@@ -18,55 +18,69 @@ Create a file `client/custom/src/account-dynamic-handler.js`:
```js
-define('custom:account-dynamic-handler', ['dynamic-handler'], function (Dep) {
-
- return Dep.extend({
-
- init: function () {
- this.controlFields();
-
- // invoke controlFields method every time assignedUserId gets changed
- this.recordView.listenTo(
- this.model, 'change:assignedUserId', this.controlFields.bind(this)
- );
- },
-
- controlFields: function () {
- if (this.model.get('assignedUserId')) {
+define('custom:account-dynamic-handler', ['dynamic-handler'], (Dep) => {
+
+ return class extends Dep {
+
+ // Called on initialization.
+ init() {
+ this.control();
+
+ // Invoke 'control' method every time assignedUserId gets changed.
+ this.recordView.listenTo(this.model, 'change:assignedUserId', () => this.control());
+
+ // Changing another attribute on status change.
+ this.recordView.listenTo(this.model, 'change:status', (model, value, options) => {
+ if (!options.ui) {
+ // Skip if the change was initiated not by a user interaction.
+ // Important.
+ return;
+ }
+
+ if (value === 'Some Status') {
+ setTimeout(() => this.model.set('someField', 'someValue'), 1);
+ }
+ });
+ }
+
+ control() {
+ // if assigned user is not empty
+ if (this.model.get('assignedUserId')) {
this.recordView.showField('sicCode');
+
this.recordView.setFieldRequired('type');
this.recordView.setFieldReadOnly('teams');
- // set options for enum/array/multi-enum/checklist fields
- this.recordView.setFieldOptionList('type', [
- 'Test',
- 'Hello',
- ]);
+ // set options
+ // actual for enum/array/multi-enum/checklist/varchar fields types
+ this.recordView.setFieldOptionList('type', ['Test', 'Hello']);
this.recordView.showPanel('activities');
- } else {
- this.recordView.hideField('sicCode');
- this.recordView.setFieldNotRequired('type');
- this.recordView.setFieldNotReadOnly('teams');
- this.recordView.setFieldOptionList('type', [
- 'Test',
- ]);
- this.recordView.hidePanel('activities');
+
+ return;
}
- },
- });
-});
+ this.recordView.hideField('sicCode');
+ this.recordView.setFieldNotRequired('type');
+ this.recordView.setFieldNotReadOnly('teams');
+ this.recordView.setFieldOptionList('type', ['Test']);
+ this.recordView.hidePanel('activities');
+ }
+ }
+});
```
-Clear cache after all.
+Then, clear cache.
+!!! note
+
+ If you set model attributes from a model-change listener callback, you might need to use *setTimeout* with a zero or a small interval value. It will prevent some side effects.
## Multiple dynamic handlers
-Since version 5.8.0 it's possible to add multiple dynamic handlers to for one entity type. This allows different extensions to have their own dynamic handler.
+It's possible to add multiple dynamic handlers to for one entity type. This allows different extensions to have their own dynamic handler.
-In metadata > clientDefs:
+In metadata > YourEntityType > clientDefs:
```json
{
@@ -76,3 +90,24 @@ In metadata > clientDefs:
]
}
```
+
+## Record view methods
+
+The list of record view methods that may be useful in a dynamic handler.
+
+* hideField
+* showField
+* setFieldReadOnly
+* setFieldNotReadOnly
+* setFieldRequired
+* setFieldNotRequired
+* setFieldOptionList
+* resetFieldOptionList
+* showPanel
+* hidePanel
+* stylePanel
+* unstylePanel
+
+## See also
+
+* [Example for multi-enum fields](examples/dynamic-logic-multi-enum.md)
diff --git a/docs/development/email-sending.md b/docs/development/email-sending.md
new file mode 100644
index 000000000..63972ef55
--- /dev/null
+++ b/docs/development/email-sending.md
@@ -0,0 +1,38 @@
+# Email Sending
+
+Example:
+
+```php
+emailFactory->create();
+
+ $email->setSubject('Subject');
+ $email->setBody('Email Body');
+ $email->addToAddress('some@address.com');
+ $email->setFromAddress('some@address.com'); // optional; if not specified, the system address will be used
+ $email->setIsPlain(); // Html is by default
+
+ $smtpParams = SmtpParams::create(); // build SMTP params (optionally)
+
+ $this->emailSender
+ ->withSmtpParams($smtpParams) // optional
+ ->withAttachments([$attachment]) // optional, to send with attachments
+ ->send($email);
+ }
+}
+```
diff --git a/docs/development/entry-points.md b/docs/development/entry-points.md
new file mode 100644
index 000000000..2c418260b
--- /dev/null
+++ b/docs/development/entry-points.md
@@ -0,0 +1,80 @@
+# Entry Points
+
+Entry points offer distinct access routes to the application, each serving different functions apart from the REST API.
+
+Entry points are accessed by the following URL: `https://your-site-url?entryPoint={entryPointName}`. Note that *entryPointName* must start with a lower case letter.
+
+Usage examples:
+
+* file downloading;
+* rendering a web form that does not require authentication.
+
+Entry point classes are located in `Espo\Module\{ModuleName}\EntryPoint` namespace.
+
+## Creating entry point
+
+Assuming that our module is named *ModuleName*.
+
+Create a file `custom/Espo/Custom/Modules/ModuleName/EntryPoints/MyEntryPoint.php`:
+
+```php
+withData(['key' => 'value']);
+
+ $this->actionRenderer->write($response, $params);
+ }
+}
+```
diff --git a/docs/development/examples/dynamic-logic-multi-enum.md b/docs/development/examples/dynamic-logic-multi-enum.md
new file mode 100644
index 000000000..eabfc5316
--- /dev/null
+++ b/docs/development/examples/dynamic-logic-multi-enum.md
@@ -0,0 +1,55 @@
+# Example: Dynamic handler for multi-enum fields
+
+See [the dynamic handler documentation](../dynamic-handler.md).
+
+In this example we have two multi-enum fields `continents` and `countries`. We will make the logic that depending on selected continents only countries of those continents will be available for selection.
+
+1\. Create (or open if exists) a file `custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json` (`YourEntityType` is the name of your entity type):
+
+```json
+{
+ "dynamicHandler": "custom:my-dynamic-handler"
+}
+```
+
+2\. Create a file `client/custom/src/my-dynamic-handler.js`:
+
+```js
+define('custom:my-dynamic-handler', ['dynamic-handler'], (Dep) => {
+
+ return class extends Dep {
+
+ init() {
+ this.controlFields();
+ this.recordView.listenTo(this.model, 'change:continents', () => this.controlFields());
+ }
+
+ controlFields() {
+ const selectedContinentList = this.recordView.model.get('continents') || [];
+
+ const continentList = ['Africa', 'Asia', 'Europe', 'America'];
+
+ const countryMap = {
+ 'Africa': ['Nigeria', 'Ethiopia'],
+ 'Asia': ['India', 'Pakistan'],
+ 'Europe': ['United Kingdom', 'France'],
+ 'America': ['United States', 'Canada', 'Brazil'],
+ };
+
+ const countryList = [];
+
+ for (const continent of selectedContinentList) {
+ countryList = countryList.concat(
+ countryMap[continent] || []
+ );
+ }
+
+ this.recordView.setFieldOptionList('countries', countryList);
+ }
+ }
+});
+```
+
+3\. Clear cache at Administration > Clear Cache.
+
+4\. You need to refresh a page in your browser.
diff --git a/docs/development/extension-packages.md b/docs/development/extension-packages.md
index 5b1c55ed0..b6a106a32 100644
--- a/docs/development/extension-packages.md
+++ b/docs/development/extension-packages.md
@@ -1,24 +1,28 @@
# Making extension package
+!!! note
+
+ It's recommended to use the [ext-template](https://github.com/espocrm/ext-template) repository for extension development.
+
Extensions allow you to add extra functionality to EspoCRM. They can be installed at Administrator panel.
The file structure of the package:
-* `/manifest.json` – a file that contains extension properties;
-* `/files` – a directory that contains the extension files;
-* `/scripts` – contains the extension scripts.
+* `manifest.json` – a file that contains extension properties;
+* `files/` – a directory that contains extension files;
+* `scripts/` – a directory that contains extension scripts.
-### Manifest
+## Manifest
```json
{
"name": "Extension Name",
"version": "1.0.0",
"acceptableVersions": [
- ">=5.6.0"
+ ">=7.4.0"
],
"php": [
- ">=7.2.0"
+ ">=8.1"
],
"releaseDate": "2019-10-22",
"author": "Your name",
@@ -26,45 +30,63 @@ The file structure of the package:
}
```
-Syntax of `version` and `acceptableVersions` is described by the v2.0.0 specification found at http://semver.org.
+Syntax of `version` is described by the v2.0.0 the [SemVer](http://semver.org) specification. It's possible to define [ranges](https://getcomposer.org/doc/articles/versions.md#version-range) in `acceptableVersions`.
-### Files
+## Files
All extension files should be placed in `files` directory. They will be copied to EspoCRM core directory.
-### Scripts
+## Scripts
For different purposes EspoCRM supports the following types of scripts. All of them should be placed in `scripts` directory.
-* `BeforeInstall.php` – a script executed before an installation process
-* `AfterInstall.php` – executed once the installation process is finished
-* `BeforeUninstall.php` – executed before uninstallation process
-* `AfterUninstall.php` – executed once the uninstallation process is finished
+* `BeforeInstall.php` – a script executed before an installation process;
+* `AfterInstall.php` – executed once the installation process is finished;
+* `BeforeUninstall.php` – executed before uninstallation process;
+* `AfterUninstall.php` – executed once the uninstallation process is finished.
Example:
```php
+get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('MyCustomEntity', $tabList)) {
- $tabList[] = 'MyCustomEntity';
- $config->set('tabList', $tabList);
- }
+ $config = $container->getByClass(Config::class);
+
+ $configWriter = $container->getByClass(InjectableFactory::class)
+ ->create(ConfigWriter::class)
- $config->save();
- }
+ $tabList = $config->get('tabList') ?? [];
+
+ if (!in_array('MyCustomEntity', $tabList)) {
+ $tabList[] = 'MyCustomEntity';
+
+ $configWriter->set('tabList', $tabList);
+ }
+
+ $configWriter->save();
+ }
}
```
-### Package
+## Package
+
+In the end, we need to pack all these files into a ZIP archive.
+
+## Template repository
+
+You can use this [template repository](https://github.com/espocrm/ext-template) to create a git repository for your extension.
-At the end, we need to pack all these files into a .zip archive.
+## Recommendations
-## Repository
+!!! note
-You can use [this template repository](https://github.com/espocrm/ext-template) to create a git repository for your extension.
+ It's recommended to give some prefix to names of your custom entity types. E.g. `MyPrefixMyEntityTypeName`, this prefix can be the name of your company.
+ It will prevent possible conflicts with other extensions.
diff --git a/docs/development/frontend/ajax.md b/docs/development/frontend/ajax.md
new file mode 100644
index 000000000..deee7973e
--- /dev/null
+++ b/docs/development/frontend/ajax.md
@@ -0,0 +1,41 @@
+# Ajax Requests
+
+The *Espo.Ajax* object is used to make requests to Espo API endpoints. See the [source file](https://github.com/espocrm/espocrm/blob/master/client/src/ajax.js) with JSDoc for more info. An API base path `api/v1` is prepended to each request URL.
+
+GET:
+
+```js
+Espo.Ajax.getRequest(url, data, options)
+ .then(response => {})
+ .catch(xhr => {});
+```
+
+POST:
+
+```js
+Espo.Ajax.postRequest(url, data, options)
+ .then(response => {})
+ .catch(xhr => {
+ if (xhr.status === 403) {
+ // Prevent error handling in the global handler.
+ xhr.errorIsHandled = true;
+ // Do something.
+ }
+ });
+```
+
+Example:
+
+```js
+Espo.Ajax.getRequest('MyController/action/getSomeDataById', {id: id})
+ .then(response => {
+ // A parsed response.
+ console.log(response);
+ });
+```
+
+## Request options
+
+* `[timeout] {Number}` A timeout in milliseconds.
+* `[headers] {Object.}` A request headers.
+* `[dataType] {'xml'|'json'|'text'}` A data type.
diff --git a/docs/development/frontend/controller.md b/docs/development/frontend/controller.md
index f0d6ea456..37df5eeec 100644
--- a/docs/development/frontend/controller.md
+++ b/docs/development/frontend/controller.md
@@ -1,115 +1,158 @@
-# Client controller & routing
+# Client controller & routing
-## Custom controller
+## Routes
-Define a custom controller for the needed entity type (Account in our example).
+Client routes are defined in metadata > app > clientRoutes.
-Create a file `custom/Espo/Custom/Resources/metadata/clientDefs/Account.json`:
+Example:
```json
{
- "controller": "custom:controllers/account"
+ "MyEntityType/test/:id": {
+ "params": {
+ "controller": "custom:controllers/my-controller",
+ "action": "test"
+ },
+ "order": 1
+ },
+ "MyEntityType/hello/:id": {
+ "params": {
+ "controller": "MyEntityType",
+ "action": "hello"
+ },
+ "order": 2
+ }
}
```
-Create a file `client/custom/src/controllers/account.js`:
+If a controller name starts with a capital letter, then the value is treated as a scope name – the class name will be determined by the *controller* parameter: metadata > clientDefs > {scope} > controller.
-```js
-define('custom:controllers/account', ['controllers/record'], function (Dep) {
+## Custom route
- return Dep.extend({
+Create a file `custom/Espo/Custom/Resources/metadata/app/clientRoutes.json`:
- actionHello: function (options) {
- console.log('action: hello');
- console.log(options);
+```json
+{
+ "Account/test/:id": {
+ "params": {
+ "controller": "custom:controllers/my-controller",
+ "action": "test"
},
+ "order": 1
+ }
+}
+```
- actionTest: function (options) {
- if (!options.id) throw new Espo.Exceptions.NotFound();
+Create a client controller `client/custom/src/controllers/my-controller`:
- console.log('action: test');
- console.log(options);
- },
+```js
+define(['controller'], (Controller) => {
- });
-});
+ return class extends Controller {
+ actionTest(options) {
+ console.log(options);
+ }
+ }
+});
```
Clear cache.
-If you open in the browser URL `your-espo-url#Account/hello` it will execute *actionHello* method.
+If you open the URL `your-espo-url#Account/test/myId` in the browser, it will execute the *actionTest* method. The *options* argument will be the object `{id: 'myId'}`.
-`#Account/hello` – *options* variable value is an empty object
-`#Account/hello/p1=one&p2=two` – *options* variable value is an object `{p1: 'one', p2: 'two'}`
+## Custom controller
-## Custom route
+A scope controller.
-Create a file `custom/Espo/Custom/Resources/metadata/app/clientRoutes.json`:
+Define a custom controller for the needed entity type (MyEntityType in our example).
+
+Create a file `custom/Espo/Custom/Resources/metadata/clientDefs/MyEntityType.json`:
```json
- "Account/test/:id": {
- "params": {
- "controller": "Account",
- "action": "test"
+{
+ "controller": "custom:controllers/my-entity-type"
+}
+```
+
+Create a file `client/custom/src/controllers/my-entity-type.js`:
+
+```js
+define(['controllers/record'], (RecordController) => {
+
+ return class extends RecordController {
+
+ actionHello(options) {
+ console.log('action: hello');
+ console.log(options);
+ }
+
+ actionTest(options) {
+ if (!options.id) {
+ throw new Espo.Exceptions.NotFound();
+ }
+
+ console.log('action: test');
+ console.log(options);
}
}
+});
```
Clear cache.
-If you open in the browser URL `your-espo-url#Account/test/myId` it will execute *actionTest* method. Argument *options* will be the object `{id: 'myId'}`
+If you open in the browser URL `your-espo-url#MyEntityType/hello` it will execute *actionHello* method.
+
+`#MyEntityType/hello` – *options* variable value is an empty object
+`#MyEntityType/hello/p1=one&p2=two` – *options* variable value is an object `{p1: 'one', p2: 'two'}`
## Rendering view
In controller:
```js
- actionTest: function (options) {
- if (!options.id) throw new Espo.Exceptions.NotFound();
+ actionTest(options) {
+ if (!options.id) {
+ throw new Espo.Exceptions.NotFound();
+ }
- var id = options.id;
+ const id = options.id;
- // we need to define view in client/custom/src/views/account/test.js
- var viewName = 'custom:views/account/test';
+ // we need to define the view in client/custom/src/views/account/test.js
+ const viewName = 'custom:views/account/test';
- // this will render view in the main container element #main
- // id will be passed to the view
- this.main(viewName, {
- id: id,
- });
- },
+ // this will render view in the main container element #main
+ // id will be passed to the view
+ this.main(viewName, {id: id});
+ }
```
Create a view `client/custom/src/views/account/test.js`:
```js
-define('custom:views/account/test', ['view'], function (Dep) {
+define('custom:views/account/test', ['view'], (View) => {
- return Dep.extend({
+ return class extends View {
- templateContent: 'Id: {{id}}, name: {{name}}',
+ // language=Handlebars
+ templateContent = `Id: {{id}}, name: {{name}}`
- data: function () {
+ data() {
return {
- id: this.options.id,
- name: this.model.get('name')
+ id: this.model.id,
+ name: this.model.attributes.name,
}
- },
+ }
- setup: function () {
- this.wait(
- this.getModelFactory().create('Account')
- .then(
- function (model) {
- this.model = model;
- model.id = this.options.id;
- return model.fetch();
- }.bind(this)
- )
- );
- },
-
- });
-});
+ setup() {
+ this.wait(this.loadModel());
+ }
+ async loadModel() {
+ this.model = await this.getModelFactory().create('Account');
+ this.model.id = this.options.id;
+
+ await this.model.fetch();
+ }
+ }
+});
```
diff --git a/docs/development/frontend/dependency-injection.md b/docs/development/frontend/dependency-injection.md
new file mode 100644
index 000000000..4c3d5b331
--- /dev/null
+++ b/docs/development/frontend/dependency-injection.md
@@ -0,0 +1,177 @@
+# Dependency injection in frontend
+
+*As of v9.0.*
+
+!!! note
+
+ Using dependency injection in the frontend requires transpiling step. Hence, you need to use the [ext-template](https://github.com/espocrm/ext-template) repository for customization development.
+
+In this article:
+
+* [Injecting](#injecting)
+* [Registering](#registering)
+* [Built-in services](#built-in-services)
+
+## Injecting
+
+To inject a service into a class, apply *@inject* decorator with a needed class to a class property. Note that the injected class must be registered as a service.
+
+Example:
+
+```js
+import {inject} from 'di';
+import Settings from 'models/settings';
+
+class MyHelper {
+
+ /**
+ * @type {Settings}
+ */
+ @inject(Settings)
+ config
+}
+```
+
+## Registering
+
+To register a service, apply *@register* decorator to a class.
+
+Example:
+
+```js
+import {register} from 'di';
+
+@register()
+class MyService {
+
+}
+```
+
+## Built-in services
+
+### storage
+
+`storage`
+
+A local browser storage. Stored values preserved when re-visiting the site from the same device.
+
+### session-storage
+
+`session-storage`
+
+A session browser storage. Stored values are not preserved when re-visiting the site.
+
+### settings
+
+`models/settings`
+
+Config parameters.
+
+### preferences
+
+`models/preferences`
+
+User preferences parameters.
+
+### user
+
+`models/user`
+
+A current user.
+
+### language
+
+`language`
+
+Label translation functions.
+
+### metadata
+
+`metadata`
+
+Application metadata.
+
+### app-params
+
+`app-params`
+
+Application parameters.
+
+### model-factory
+
+`model-factory`
+
+Creates models for specific entity types.
+
+### collection-factory
+
+`collection-factory`
+
+Creates collections for specific entity types.
+
+### acl-manager
+
+`acl-manager`
+
+Access control checking functions.
+
+### field-manager
+
+`field-manager`
+
+A util related to record fields.
+
+### date-time
+
+`date-time`
+
+A date-time util.
+
+### theme-manager
+
+`theme-manager`
+
+Theme related functions.
+
+### number-util
+
+`number-util`
+
+A number util. For working with numbers.
+
+### view-helper
+
+`view-helper`
+
+A view helper. Markdown, sanitizing, etc.
+
+### layout-manager
+
+`layout-manager`
+
+A record layout provider.
+
+### router
+
+`router`
+
+Navigation and routing functions. The confirm leave-out functionality.
+
+### web-socket-manager
+
+`web-socket-manager`
+
+Web-socket functions.
+
+### broadcast-channel
+
+`broadcast-channel`
+
+For communication between browser tabs.
+
+### page-title
+
+`page-title`
+
+A page title util.
+
diff --git a/docs/development/frontend/html-css.md b/docs/development/frontend/html-css.md
new file mode 100644
index 000000000..91d212a8c
--- /dev/null
+++ b/docs/development/frontend/html-css.md
@@ -0,0 +1,291 @@
+# HTML & CSS
+
+## Button
+
+```html
+
+```
+
+Style classes:
+
+* `btn-default`
+* `btn-primary`
+* `btn-success`
+* `btn-danger`
+* `btn-warning`
+* `btn-info`
+* `btn-text`
+* `btn-link`
+
+Width classes:
+
+* `btn-xs-wide`
+* `btn-s-wide`
+* `btn-wide`
+* `btn-xx-wide`
+* `btn-icon-wide`
+* `btn-icon-x-wide`
+* `btn-icon-xx-wide`
+* `btn-full-wide` – 100% width;
+
+Size classes:
+
+* `btn-sm`
+* `btn-lg`
+
+Other classes:
+
+* `btn-icon` – a button supposed to contain only an icon;
+
+### Button group
+
+```html
+
+```
+
+Sizes:
+
+* `xxs`
+* `xs`
+* `sm`
+* `md`
+
+## Type
+
+### Text
+
+Style:
+
+* `text-soft`
+* `text-muted`
+* `text-primary`
+* `text-success`
+* `text-danger`
+* `text-warning`
+* `text-info`
+* `text-bold`
+* `text-italic` (as of v8.0)
+* `text-strikethrough` (as of v8.2)
+
+Size:
+
+* `text-large`
+* `text-2em`
+* `text-3em`
+* `text-4em`
+* `text-5em`
+* `text-6em`
+
+
+### Label
+
+```html
+Text
+```
+
+Style classes:
+
+* `label-default`
+* `label-primary`
+* `label-success`
+* `label-danger`
+* `label-warning`
+* `label-info`
+
+Size classes:
+
+* `label-md`
+
+## Misc
+
+Centering:
+
+* `center-align` – applies `text-align: center`;
+
+A horizontally centered block:
+
+* `block-center`
+* `block-center-sm`
+* `block-center-md`
+
+A container that horizontally & vertically centers its child:
+
+* `container-centering`
+
+Border radius:
+
+* `radius-left` – forces an element to have border radius on the left;
+* `radius-right` – forces an element to have border radius on the right;
+
+Floating:
+
+* `pull-left` – applies `float: left`;
+* `pull-right` – applies `float: right`;
+
+Cancelling margins:
+
+* `no-margin` – cancels margins for an element contained in a panel and other containers;
+* `no-side-margin` – cancels side margins for an element contained in a panel and other containers;
+
+Margins:
+
+* `margin` – applies a margin to all sides;
+* `margin-top-sm`
+* `margin-top`
+* `margin-top-2x`
+* `margin-bottom-sm`
+* `margin-bottom`
+* `margin-bottom-2x`
+* `margin-bottom-3x`
+* `margin-bottom-4x`
diff --git a/docs/development/frontend/monkey-patching.md b/docs/development/frontend/monkey-patching.md
new file mode 100644
index 000000000..2bca891a1
--- /dev/null
+++ b/docs/development/frontend/monkey-patching.md
@@ -0,0 +1,53 @@
+# Monkey patching
+
+[Monkey patching](https://en.wikipedia.org/wiki/Monkey_patch) allows you to dynamically extend any frontend class.
+
+
+!!! warning
+
+ Monkey patching is not considered an upgrade-safe method and should be used as a last resort.
+
+1\. Define the JS file that will be loaded with the Espo page.
+
+Create `custom/Espo/Custom/Resources/metadata/app/client.json`:
+
+```json
+{
+ "scriptList": [
+ "__APPEND__",
+ "client/custom/my-patch.js"
+ ],
+ "developerModeScriptList": [
+ "__APPEND__",
+ "client/custom/my-patch.js"
+ ]
+}
+```
+
+Note that *developerModeScriptList* is only needed when you use the developer mode.
+
+After that, clear cache.
+
+2\. Create a patching JS file.
+
+Create `client/custom/my-patch.js`:
+
+```js
+/**
+ * In this example, we extend the login view.
+ */
+require(['views/login'], View => {
+
+ const defaultAfterRender = View.prototype.afterRender;
+
+ // Extending the `afterRender` method.
+ View.prototype.afterRender = function () {
+ defaultAfterRender.call(this);
+
+ // Custom code here.
+ console.log("Custom login view is rendered.");
+ };
+});
+```
+
+Note that you can patch multiple classes in one file.
diff --git a/docs/development/frontend/record-panels.md b/docs/development/frontend/record-panels.md
index 4052a54cb..f2b88503f 100644
--- a/docs/development/frontend/record-panels.md
+++ b/docs/development/frontend/record-panels.md
@@ -36,16 +36,16 @@ The values of parameters *aclScope* and *acl* mean, that the panel will be visib
Create a file `client/custom/src/views/account/panels/my-test-panel.js`:
```js
-define('custom:views/account/panels/my-test-panel', ['views/record/panels/side'], function (Dep) {
+define(['views/record/panels/side'], (SidePanelView) => {
- return Dep.extend({
+ return class extends SidePanelView {
- templateContent: '
{{viewObject.someKey}}
',
+ templateContent = '
{{viewObject.someKey}}
'
- setup: function () {
+ setup() {
this.someKey = 'Hello';
- },
- });
+ }
+ }
});
```
diff --git a/docs/development/frontend/save-error-handlers.md b/docs/development/frontend/save-error-handlers.md
new file mode 100644
index 000000000..e983428f1
--- /dev/null
+++ b/docs/development/frontend/save-error-handlers.md
@@ -0,0 +1,60 @@
+# Save error handlers
+
+When a record is being saved, it's possible to throw an exception in the backend and then handle it in the frontend.
+
+In the backend the exception should is thrown with the *reason* parameter in the body. It can be done from a before-create or before-update [record hooks](../metadata/record-defs.md#beforereadhookclassnamelist).
+
+Only `Conflict` and `Error` exceptions are supported.
+
+```php
+ 'someValue1',
+ 'someKey2' => 'someValue2',
+ ])
+);
+```
+
+!!! note
+
+ It's also possible to throw exceptions with formula in [API before-save script](../../administration/api-before-save-script.md).
+
+Define a handler in metadata.
+
+`custom/Espo/Custom/Resources/metadata/clientDefs/{EntityType}.json`:
+
+```json
+{
+ "saveErrorHandlers": {
+ "myReason": "custom:my-error-handler"
+ }
+}
+```
+
+It's also possible to define handlers for all entity types in `custom/Espo/Custom/Resources/metadata/clientDefs/Global.json`.
+
+Create a handler `client/custom/src/my-error-handler.js`:
+
+```js
+
+define('custom:my-error-handler', [], function () {
+
+ return class {
+ constructor(view) {
+ /** @type {module:views/record/detail.Class} */
+ this.view = view;
+ }
+
+ process(data) {
+ Espo.Ui.error('Some error message.', true);
+
+ // Some logic.
+ }
+ }
+});
+```
diff --git a/docs/development/frontend/templates.md b/docs/development/frontend/templates.md
new file mode 100644
index 000000000..4dfc19f2e
--- /dev/null
+++ b/docs/development/frontend/templates.md
@@ -0,0 +1,188 @@
+# Templates
+
+A template of a [view](../view.md) is used to render an HTML. Before rendering, the view passes data to the template. Templates can be stored in separate .tpl files or defined right in a the view's `templateContent` property. [Handlebars](https://handlebarsjs.com) library is used for templating.
+
+## Expressions
+
+Expressions are enclosed by double curly braces `{{}}`.
+
+```
+{{name}}
+```
+### Path
+
+With dot-separated paths it's possible to look up in objects.
+
+```
+{{person.firstName}}
+```
+
+### Changing context
+
+Inside `{{#each}}` blocks you can change a context to parent with `../`.
+
+```
+{{#each people}}
+ {{../prefix}} {{name}}
+{{/each}}
+```
+
+### HTML escaping
+
+Values returned by the `{{expression}}` are HTML-escaped. You can suppress escaping by using triple braces.
+
+```
+{{text}} – escaped
+{{{text}}} – unescaped
+```
+
+Expressions rendering child views should be unescaped.
+
+### Whitespaces
+
+Template whitespace can be omitted from either side of any mustache statement by adding a `~` character by the braces.
+
+```
+{{#each items ~}}
+
+{{~/each}}
+```
+
+### Sub-expressions
+
+```
+{{complexText (translate 'myMessage' category='messages' scope='MyScope')}
+```
+
+## Helpers
+
+### if
+
+An if block conditional helper.
+
+```
+{{#if value}}
+
+{{/if}}
+```
+
+```
+{{#if value}}
+
+{{else}}
+
+{{/if}}
+```
+
+### unless
+
+An inversion of the if block.
+
+### each
+
+An iteration block helper.
+
+```
+{{#each array}}
+ {{this}} – item
+ {{@index}} – index
+{{/each}}
+```
+
+```
+{{#each object}}
+ {{this}} – item
+ {{@key}} – key
+{{/each}}
+```
+
+### lookup
+
+Accessing an object property by a key or an array item by an index.
+
+```
+{{lookup object 'property'}}
+```
+
+### ifEqual
+
+Compares two values for equality.
+
+```
+{{#ifEqual value1 value2}}
+
+{{/ifEqual}}
+```
+
+```
+{{#ifEqual value1 value2}}
+
+{{else}}
+
+{{/ifEqual}}
+```
+
+### ifNotEqual
+
+Compares two values for inequality.
+
+### get
+
+Gets an attribute value from a model.
+
+```
+{{get model 'name'}}
+```
+
+### translate
+
+Translates a label.
+
+```
+{{translate label}}
+{{translate field category='fields' scope='Account'}}
+```
+
+### translateOption
+
+Translates an enum option.
+
+```
+{{translateOption 'optionKey' field='myField' scope='MyEntityType'}}
+```
+
+### complexText
+
+Prints a parsed Markdown text.
+
+```
+{{complexText text}}
+```
+
+### hyphen
+
+Converts a camelCase to hyphen.
+
+```
+{{hyphen stringValue}}
+```
+
+### toDom
+
+Convert a string from camelCase to hyphen and replace dots with hyphens. Useful for DOM attributes.
+
+```
+data-{{toDom this}}="{{lookup ../this this}}"
+```
+
+### breaklines
+
+Replaces line breaks with ` ` tags.
+
+```
+{{breaklines text}}
+```
+
+### basePath
+
+A client base path.
diff --git a/docs/development/frontend/view-setup-handlers.md b/docs/development/frontend/view-setup-handlers.md
new file mode 100644
index 000000000..0406c1cb5
--- /dev/null
+++ b/docs/development/frontend/view-setup-handlers.md
@@ -0,0 +1,78 @@
+# View Setup Handlers
+
+*As of v7.0*
+
+ViewSetupHandlers framework provides the ability to customize existing views w/o extending. Multiple handlers can be attached to a view.
+
+In clientDefs:
+
+```json
+{
+ "viewSetupHandlers": {
+ "list": [
+ "__APPEND__",
+ "custom:some-handler-1"
+ ],
+ "record/search": [
+ "__APPEND__",
+ "custom:some-handler-2"
+ ]
+ }
+}
+```
+
+Can be defined:
+
+* for a scope (clientDefs > {ScopeName})
+* globally (clientDefs > Global)
+
+Handlers are processed in the `setup` method of the view.
+
+The following types are supported:
+
+* list – main list view;
+* detail – main detail view;
+* edit – main edit view;
+* record/list – list record view;
+* record/search – search view;
+* record/detail – detail record view;
+* record/edit – detail record view;
+* record/kanban – kanban record view;
+* login – the login view; only in Global scope; as of v8.3.0;
+
+!!! important
+
+ The `__APPEND__` element is needed in the beginning of arrays to establish extending of existing items that can be defined by other modules.
+
+Handler example:
+
+```js
+
+define('custom:some-handler', [], () => {
+
+ class Handler {
+
+ /**
+ * @param {import('view').default} view
+ */
+ constructor(view) {
+ this.view = view;
+ }
+
+ process() {
+ this.listenTo(this.view, 'after:render', () => {
+ // Do something with view after render.
+ });
+
+ this.view.listenTo(this.view.model, 'change', () => {});
+ }
+ }
+
+ // Establish event support. If needed.
+ Object.assign(Handler.prototype, Backbone.Events);
+
+ return Handler;
+});
+```
+
+The `process` method can return Promise. In this case the view will wait until the promise is resolved before proceeding to rendering.
diff --git a/docs/development/hooks.md b/docs/development/hooks.md
index e6f122163..5ad454b66 100644
--- a/docs/development/hooks.md
+++ b/docs/development/hooks.md
@@ -1,30 +1,64 @@
# Hooks
-Common hooks:
+The Hooks framework provides the ability to catch some actions in the system in order to call custom logic.
-- beforeSave
-- afterSave
-- beforeRemove
-- afterRemove
-- afterRelate
-- afterUnrelate
-- afterMassRelate
+Common hooks for all entity types (called from the ORM Repository class):
+
+- *beforeSave* – just before a record is saved;
+- *afterSave* – after a record is saved;
+- *beforeRemove* – before a record is removed;
+- *afterRemove* – after a record is removed;
+- *afterRelate* – when two records are related through a many-to-many relationship;
+- *afterUnrelate* – when two records are unrelated through a many-to-many relationship;
+- *afterMassRelate*
## Creating hook
-* create a file `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-* declare hook type action;
-- clear Cache in Administration.
+* create a file `custom/Espo/Custom/Hooks/{EntityType}/{HookName}.php` (you can also use a module directory);
+* declare a hook action method with a name the same as a hook name (e.g. *beforeSave*);
+* clear cache in Administration.
+
+!!! warning
+
+ {HookName} must be unique per entity type. If there are two hooks with the same name
+ for the same entity type (defined in different modules), only the first one will be applied (honoring the module order).
## Hook order
-If you have several hooks, related to one Entity Type and with the same hook type, and running order is important, you can set a `public static $order` property in an integer value.
-Ascending order - the hook with the smallest order number runs first.
+If you have several hooks related to the same entity type, you can set the order property with an integer value.
+
+```
+public static int $order = 10;
+```
+
+Ascending order is applied – a hook with the smallest order number runs first.
+
+If the *order* property is omitted, the value *9* is applied for the hook.
+
+Order values of existing hooks:
+
+* Before-Save formula script: *11*
+* After-Save workflow actions: *99* (in Advanced Pack)
+
+### Interfaces
+
+*As of v7.4.*
+
+There are interfaces for built-in hooks. It's recommended that your hooks implement these interfaces. This makes it easier for a developer to obtain needed data (passed to the hook) as each interface has a unique method signature. The list of interfaces:
+
+* `Espo\Core\Hook\Hook\BeforeSave`
+* `Espo\Core\Hook\Hook\AfterSave`
+* `Espo\Core\Hook\Hook\BeforeRemove`
+* `Espo\Core\Hook\Hook\AfterRemove`
+* `Espo\Core\Hook\Hook\AfterRelate`
+* `Espo\Core\Hook\Hook\AfterUnrelate`
+* `Espo\Core\Hook\Hook\AfterMassRelate`
## Example
-This example sets Account Name for new Leads, if it is not set.
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
+This example sets an Account Name for new Leads, if it's not set.
+
+`custom/Espo/Custom/Hooks/Lead/MyHook.php`
```php
$options
+ */
+ public function beforeSave(Entity $entity, array $options): void
{
if ($entity->isNew() && !$entity->get('accountName')) {
$entity->set('accountName', 'No Account');
@@ -45,50 +90,53 @@ class AccountName extends \Espo\Core\Hooks\Base
## Global hooks
-If you need to apply a hook for all entities, you can use common hooks. To do this, put your hook class in Common directory, e.g. `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
+If you need to apply a hook for all entities, you can use common hooks. To do this, put your hook class to `Common` directory, for example, `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
## Additional default hooks
#### TargetList
-* *afterOptOut* - when a target clicks an opt-out link, data are passed in the 3rd $data argument
-* *afterCancelOptOut* - when a target subscribes again
-* *afterOptIn* - when a target opts-in through Lead Capture, data are passed in the 3rd $data argument (since 5.6.9)
+* *afterOptOut* – when a target (recipient) clicks an opt-out link, data are passed in the 3rd $data argument;
+* *afterCancelOptOut* – when a target subscribes again;
+* *afterOptIn* – when a target opts-in through Lead Capture, data are passed in the 3rd $data argument;
#### Meeting / Call
-* *afterConfirmation* - when an event attendee clicks on accept/decline/tentative link; details are passed in the 3rd $data argument
+* *afterConfirmation* – when an event attendee clicks on accept/decline/tentative link; details are passed in the 3rd argument $data;
#### Contact
-* *afterLeadCapture* - when a contact (existing in crm) opts-in through Lead Capture, leadCaptureId is passed in the 3rd $data argument (since 5.6.9)
-* *afterOptOut* (since 5.7.0)
-* *afterCancelOptOut* (since 5.7.0)
+* *afterLeadCapture* – when a contact (existing in crm) opts-in through Lead Capture, leadCaptureId is passed in the 3rd argument $data;
+* *afterOptOut*
+* *afterCancelOptOut*
#### Lead
-* *afterLeadCapture* - when a lead opts-in through Lead Capture, leadCaptureId is passed in the 3rd $data argument (since 5.6.9)
-* *afterOptOut* (since 5.7.0)
-* *afterCancelOptOut* (since 5.7.0)
+* *afterLeadCapture* – when a lead opts-in through Lead Capture, leadCaptureId is passed in the 3rd argument $data;
+* *afterOptOut*
+* *afterCancelOptOut*
#### LeadCapture
-* *afterLeadCapture* - when a target (lead or contact) opts-in through Lead Capture, target data are passed in the 3rd $data argument (since 5.6.9)
+* *afterLeadCapture* – when a target (lead or contact) opts-in through Lead Capture, target data are passed in the 3rd argument $data;
#### CampaignTrackingUrl
-* *afterClick* - when a target (lead/contact/account) opened a tracking url in email (since 5.7.0)
+* *afterClick* - when a target (lead/contact/account) opened a tracking url in email;
#### Examples
`custom/Espo/Custom/Hooks/TargetList/MyHook.php`
+
```php
getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);
+hookManager->process($entityType, $hookType, $entity, $options);
```
-Note: A hook name can't start with `set`. It's reserved for a dependency injection.
+!!! note
+
+ A hook name can't start with `set`. It's reserved for a dependency injection.
+
+## Tips
+
+Avoid saving the same record in beforeSave hooks.
+
+In afterSave hooks, re-saving the same record usually should be avoided as it can disrupt following hooks. If saving is needed, consider passing SKIP_ALL, KEEP_NEW and KEEP_DIRTY save options to the *saveEntity* method or run an update query instead (using the query builder).
diff --git a/docs/development/how-to-create-a-dashlet.md b/docs/development/how-to-create-a-dashlet.md
index 89268494c..242086e81 100644
--- a/docs/development/how-to-create-a-dashlet.md
+++ b/docs/development/how-to-create-a-dashlet.md
@@ -1,4 +1,4 @@
-# How to create a dashlet
+# Custom dashlets
Create a file `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` with your dashlet configuration.
@@ -18,7 +18,7 @@ Also you can define other options, if your view needs more data. You will be abl
Create a file `custom/Espo/Custom/Resources/metadata/dashlets/MyDashlet.json`:
-```
+```json
{
"view": "custom:views/dashlets/my-dashlet",
"aclScope": "Account",
@@ -54,17 +54,17 @@ There you can find how default dashlets defined: `application/Espo/Modules/Crm/R
Create a view file `client/custom/src/views/dashlets/my-dashlet.js`:
```js
-define('custom:views/dashlets/my-dashlet', 'views/dashlets/abstract/base', function (Dep) {
- return Dep.extend({
- name: 'MyDashlet',
- template: 'custom:dashlets/my-dashlet',
- })
-});
-```
+define(['views/dashlets/abstract/base'], (BaseView) => {
-Create a template file `client/custom/res/templates/dashlets/my-dashlet.tpl`
-```
-
+ return class extends BaseView {
+ name = 'MyDashlet'
+
+ templateContent = `
+
My Dashlet
+
+ `
+ }
+});
```
## Translation
diff --git a/docs/development/how-to-start.md b/docs/development/how-to-start.md
index 2e9f7ea1e..1de519880 100644
--- a/docs/development/how-to-start.md
+++ b/docs/development/how-to-start.md
@@ -1,60 +1,115 @@
# How to get started
-## Option A. Using git repository
+*(for developers)*
-1. Clone [https://github.com/espocrm/espocrm](https://github.com/espocrm/espocrm) repository to your local computer.
+In this article:
+
+* [Option A. Extension development](#option-a-extension-development)
+* [Option B. Using git repository](#option-b-using-git-repository)
+* [Configuration for development](#configuration-for-development)
+* [Where to put customizations](#where-to-put-customizations)
+
+## Option A. Extension development
+
+Use this approach to customize Espo for a specific business.
+
+By utilizing the [ext-template](https://github.com/espocrm/ext-template) repository, you can craft an installable extension for EspoCRM. Your repository will contain only your custom files. The ext-template tools allow you to run your extension in an Espo instance for testing purposes. See more info in the repository's readme.
+
+It is possible to [install](autoload.md) additional composer libraries in your extension.
+
+## Option B. Using git repository
+
+Using the main EspoCRM repository. Contributors should use this approach.
+
+1. Clone [https://github.com/espocrm/espocrm](https://github.com/espocrm/espocrm) repository (or a forked one) to your local computer.
2. Change to the project's root directory: `cd path/to/espocrm`.
-3. Install [composer](https://getcomposer.org/doc/00-intro.md).
-4. Run `composer install` if composer is installed globally or `php composer.phar install` if locally.
+3. Install [Composer](https://getcomposer.org/doc/00-intro.md) if not installed (v2.0 or greater).
+4. Install npm if not installed (v8.0 or greater).
+5. Install [Grunt](https://gruntjs.com/installing-grunt).
+6. Run `composer install` if Composer is installed globally (or, `php composer.phar install`, if locally).
+7. Run `npm ci`.
-Note: Some dependencies require php extensions that you might don't have installed (e.g. zmq, ldap) and don't need to use. You can skip these requirements by installing with a flag *--ignore-platform-reqs*: `composer install --ignore-platform-reqs`.
+Then, you can build by running `grunt`.
-To compose a proper *config.php* and populate database you can run install by opening `http(s)://{YOUR_CRM_URL}/install` location in a browser.
+To build a proper *config.php* file and populate database you can run installation. Open `http(s)://{YOUR_CRM_URL}/install` location in the browser. It's assumed that your webserver is properly [configured](../administration/server-configuration.md).
-Then open `data/config.php` file and add:
+!!! note
-```php
-'isDeveloperMode' => true,
-```
+ Some dependencies require php extensions that you might not have installed. You can skip these requirements by installing with a flag *--ignore-platform-reqs*: `composer install --ignore-platform-reqs`.
-Branches:
+You also need to enable [developer mode](#configuration-for-development).
-* *hotfix/** – upcoming maintenance release; fixes should be pushed to this branch;
-* *master* – develop branch; new features should be pushed to this branch;
-* *stable* – last stable release.
+After building, you will be able to run the instance in your browser right from the project root directory, considering that your web server is properly configured.
### Building
-You need to have nodejs and Grunt CLI installed.
-
1. Change to the project's root directory.
-2. Install project dependencies with `npm install`.
-3. Run Grunt with `grunt`.
+2. Run Grunt with `grunt`.
The build will be created in the `build` directory.
-Note: By default grunt installs composer dependencies. You can skip it by running `grunt offline`.
+!!! note
+
+ By default, grunt installs composer dependencies. You can skip it by running `grunt offline`.
-Upgrade packages can be built with `grunt upgrade`. Note: You need to fetch tags to your git repository.
-## Option B. Using installed instance
+#### Javascript transpiling
+
+Building with *grunt* includes the transpiling step. You can also run it manually with the following commands.
+
+Transpile all:
+
+```
+node js/transpile
+```
-You can develop and make customizitions right on a regular installed EspoCRM instance.
+Transpile a specific file (can be useful for a file watcher in an IDE):
+
+```
+node js/transpile -f $FilePathRelativeToProjectRoot$
+```
+
+### Branches
+
+* *fix* – upcoming maintenance release; fixes should be pushed to this branch;
+* *master* – develop branch; new features should be pushed to this branch;
+* *stable* – last stable release.
+
+### Upgrade packages
+
+Preparation:
+
+1. Fetch tags to your git repository from the remote: `git fetch --tags`.
+2. Checkout to a needed version tag (or don't if you want to test upgrade to the most recent commit).
+3. Build EspoCRM with grunt (see above how to build).
+
+Build the upgrade package with the command:
+
+```
+node diff {version_from}
+```
+
+The package will be created in the `build` directory.
## Configuration for development
-Edit the config file `data/config.php`, add the parameter:
+EspoCRM instance configuration for development. Config parameters should be set in `data/config.php`.
+
+The developer mode:
```php
'isDeveloperMode' => true,
```
-You can also add the parameter:
+!!! note
+
+ The developer mode won't work on a release instance. It requires the *frontend* folder from the repository and *client/lib/transpiled* which should contain all JS files separately and transpiled.
+
+You can force using some additional cache in the developer mode. Can be reasonable as the application can run very slow w/o cache.
```php
-'useCacheInDeveloperMode' => true`,
+'useCacheInDeveloperMode' => true,
```
-That will force using a backend cache (metadata, langauge etc.).
## Where to put customizations
@@ -65,5 +120,7 @@ That will force using a backend cache (metadata, langauge etc.).
### Option B. Module dirs
-* `application/Espo/Modules/{YourModuleName}/` – for metadata and all files pertaining to backend
-* `client/modules/{your_module_name}/` – for client files
+* `custom/Espo/Modules/{YourModuleName}/` – for metadata and all files pertaining to backend
+* `client/custom/modules/{your-module-name}/` – for client files
+
+This method is the only appropriate method when developing an extension. The ext-template's initialization created needed folders automatically. The important advantage of using ext-template is the ability to use ESM modules in the frontend, which significantly improves the development experience.
diff --git a/docs/development/index.md b/docs/development/index.md
index 2e40e1761..fc3d63461 100644
--- a/docs/development/index.md
+++ b/docs/development/index.md
@@ -1,49 +1,71 @@
# Developer Documentation
-* [How to get started](how-to-start.md)
+### General
+
+* [Getting started](how-to-start.md)
* [Making extension package](extension-packages.md)
+* [Modules](modules.md)
* [Tests](tests.md)
* [Translation](translation.md)
* [Coding rules](coding-rules.md)
### Backend
-* [API](api.md)
-* [Custom API action](api-action.md)
-* [Services](services.md)
-* [ORM: How to manage entities](orm.md)
+* [Dependency injection](di.md)
* [Metadata](metadata.md)
-* [Select Manager](select-manager.md)
+* [ORM](orm.md)
+* [Select Builder](select-builder.md)
+* [API actions](api-action.md)
+* [Services](services.md)
* [Hooks](hooks.md)
* [ACL](acl.md)
-* [Dependency injection](di.md)
+* [Entry points](entry-points.md)
* Misc
- * [Template (PDF) custom helpers](template-custom-helper.md)
- * [Defining new funtions for formula](new-function-in-formula.md)
- * [Custom scheduled jobs](scheduled-job.md)
+ * [Autoload](autoload.md)
+ * [Entity type](custom-entity-type.md)
+ * [Container services](container-services.md)
+ * [Template helpers (PDF)](template-custom-helper.md)
+ * [Formula functions](new-function-in-formula.md)
+ * [Scheduled jobs](scheduled-job.md)
* [Duplicate checking](duplicate-check.md)
* [Database indexes](db-indexes.md)
* [App params](app-params.md)
* [Jobs](jobs.md)
+ * [Email sending](email-sending.md)
+ * [Calculated fields](calculated-fields.md)
+ * [Config parameters](custom-config-parameters.md)
+ * [Attachments](attachments.md)
### Frontend
* [View](view.md)
+* [Model](model.md)
+* [Collection](collection.md)
+* [Templates](frontend/templates.md)
+* [HTML & CSS](frontend/html-css.md)
+* [Ajax requests](frontend/ajax.md)
+* [Controller & routing](frontend/controller.md)
+* [Dependency injection](frontend/dependency-injection.md)
+* [Modal dialogs](modal.md)
+* [Confirmation dialogs](confirm-dialog.md)
* [Custom views (for records and fields)](custom-views.md)
+* [View setup handlers](frontend/view-setup-handlers.md)
+* [Save error handlers](frontend/save-error-handlers.md)
+* [Dynamic forms with dynamic handler](dynamic-handler.md)
* Fields
* [Custom field type](custom-field-type.md)
* [Customizing existing fields](customize-standard-fields.md)
-* [Controller & routing](frontend/controller.md)
-* [Model](model.md)
* Misc
- * [Custom buttons & dropdown actions for detail/edit/list views](custom-buttons.md)
- * [Modal dialogs](modal.md)
- * [Confirmation dialogs](confirm-dialog.md)
+ * [Buttons & dropdown actions for detail/edit/list views](custom-buttons.md)
* [Custom panels on record view](frontend/record-panels.md)
* [Including custom CSS file](custom-css.md)
- * [Custom dashlets](how-to-create-a-dashlet.md)
- * [Dynamic forms with dynamic handler](dynamic-handler.md)
+ * [Custom dashlets](how-to-create-a-dashlet.md)
* [Link-multiple field with primary record](link-multiple-with-primary.md)
-* Campaigns
- * [Custom unsubscribe page](campaign-unsubscribe-template.md)
-
+ * [Monkey patching](frontend/monkey-patching.md)
+ * Campaigns
+ * [Custom unsubscribe page](campaign-unsubscribe-template.md)
+
+
+### API
+
+* [API Overview](api.md)
diff --git a/docs/development/jobs.md b/docs/development/jobs.md
index 245b4628e..ee68c3bc9 100644
--- a/docs/development/jobs.md
+++ b/docs/development/jobs.md
@@ -1,58 +1,61 @@
# Jobs
-Sometimes it's reasonable to execute the script in background. For example, to avoid a used waiting for a response for a long time.
+Sometimes it's reasonable to execute some actions in background. For example, when sending an email, to prevent a user to wait until sending is processed.
-### Creating job record
+### Scheduling
```php
-$entityManager->createEntity('Job', [
- 'serviceName' => 'MyJobService',
- 'methodName' => 'jobDoSomething',
- 'data' => (object) [
- 'key1' => 'value1',
- 'key2' => 'value2',
- ],
- 'executeTime' => date('Y-m-d H:i:s'), // you can delay execution by setting a later time
- 'queue' => 'q0', // available queues are listed below
-]);
+create()
+ ->setClassName($jobClassName) // should implement `Espo\Core\Job\Job` interface
+ ->setQueue(QueueName::Q0) // optional
+ ->setGroup('some-group-name') // optional
+ ->setData([
+ 'someKey' => $someValue,
+ ])
+ ->schedule();
```
-### Job implementation
+You can pass JobSchedulerFactory as a constructor dependency.
-Create a service class file `custom/Espo/Custom/Services/MyJobService.php`:
+### Job
```php
addDependencyList([
- 'entityManager',
- ]);
- }
-
- public function jobDoSomething($data)
- {
- $key1 = $data->key1;
- $key2 = $data->key2;
-
- $entityManager = $this->getInjection('entityManager');
-
- // do something
- }
+ public function __construct(/* pass needed dependencies */)
+ {}
+
+ public function run(Data $data): void
+ {
+ // job logic here
+ }
}
-
```
-Clear cache from the admin panel.
+### Queues
+
+Jobs within a queue are processed one by one.
-More detail about services is [here](services.md).
+Queues available out of the box:
-### Queues
+* e0 – intended for email sending; run as often as possible; one-by-one;
+* q0 – for general use; run as often as possible; one-by-one;
+* q1 – for general use; run every minute; one-by-one;
+* m0 – run in-parallel along with the main queue; used to avoid disruption of the main queue; as of v9.2.
+
+Portion size is controller by [config parameters](../administration/config-params.md#jobs-daemon).
+
+### Groups
-* e0 - intended for email sending; run as often as possible;
-* q0 - for general use; run as often as possible;
-* q1 - for general use; run every minute.
+A group name can be any string with max length of 128 characters. Jobs with the same group name are processed one by one.
diff --git a/docs/development/link-multiple-with-primary.md b/docs/development/link-multiple-with-primary.md
index e9fc9d661..6cf71eda6 100644
--- a/docs/development/link-multiple-with-primary.md
+++ b/docs/development/link-multiple-with-primary.md
@@ -1,8 +1,8 @@
# Link Multiple field with Primary
-Sometimes you have `hasMany` relationship and need to have an ability to select primary record among related ones. As example, `Contacts` field of Case entity.
+Sometimes you have a *hasMany* relationship and need to have the ability to a select primary record among related ones. As example, a *Contacts* field of the *Case* entity.
->Need to create `contacts` linkMultiple field with a primary for our custom entity `Stock`.
+>Need to create a `contacts` linkMultiple field with a primary for our custom entity *Stock*.
>
### Step 1
@@ -39,6 +39,7 @@ Create (or edit) `custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`:
### Step 2
`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
+
```json
{
"links":{
@@ -58,65 +59,62 @@ Create (or edit) `custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`:
```
### Step 3
-`custom/Espo/Custom/Repositories/Stock.php`
+`custom/Espo/Custom/Hooks/Stock/AfterSave.php`
+
```php
handleAfterSaveContacts($entity, $options);
- return $result;
- }
+ public function __construct(private EntityManager $entityManager) {}
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
+ public function afterSave(Entity $entity, array $options): void
+ {
+ if (!$entity->isAttributeChanged('contactId')) {
+ return;
}
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
+
+ $contactId = $entity->get('contactId');
+ $fetchedContactId = $entity->getFetched('contactId');
+
+ $relation = $this->entityManager
+ ->getRDBRepository($entity->getEntityType())
+ ->getRelation($entity, 'contacts');
+
+ if (!$contactId) {
+ $relation->unrelateById($fetchedContactId);
+
+ return;
}
+
+ $relation->relateById($contactId);
}
}
```
### Step 4
`client/custom/src/views/stock/fields/contacts.js`
+
```js
-define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
+define(['views/fields/link-multiple-with-primary'], (Dep) => {
+ return class extends Dep {
+ primaryLink = 'contact'
+ }
});
```
### Step 5
-Run Rebuild
+
+Run Rebuild.
### Step 6
-Execute SQL query
+
+Execute an SQL query:
+
```sql
UPDATE stock
JOIN contact_stock
diff --git a/docs/development/metadata.md b/docs/development/metadata.md
index a280f8268..fa5b882a0 100644
--- a/docs/development/metadata.md
+++ b/docs/development/metadata.md
@@ -1,31 +1,129 @@
-# Metadata
-
-Metadata is intended for: storing system data such as entity's fields and relationships; specifying frontend controllers, views, panels; defining fields, dashlets; and other data needed for the application.
-
+---
+search:
+ boost: 2
+---
-## How to access
-
-#### Backend
+# Metadata
-Metadata object of `Espo\Core\Utils\Metadata` class can be accessed from Container. Path to a needed parameter is specified with an array.
+Metadata is intended for storing application data such as fields, relationships, front-end controllers, views, panels, dashlets etc.
+
+[JSON Schema](https://github.com/espocrm/espocrm/tree/master/schema/metadata) provides autocompletion for IDEs. It works in PhpStorm and VSCode with no setup required.
+
+In this article:
+
+* [Reference](#reference)
+* [Accessing](#accessing)
+* [How it's stored](#how-its-stored)
+* [Extending](#extending)
+
+## Reference
+
+* [scopes](metadata/scopes.md) – general parameters for scopes and entity types
+* [entityDefs](metadata/entity-defs.md) – entity defs (fields, links, indexes)
+* [aclDefs](metadata/acl-defs.md) – access control for scopes and entity types
+* [selectDefs](metadata/select-defs.md) – Select-framework defs for entity types
+* [recordDefs](metadata/record-defs.md) – CRUD-specific defs for entity types
+* [clientDefs](metadata/client-defs.md) – front-end defs for entity types
+* [entityAcl](metadata/entity-acl.md) – access restriction for specific fields and links for entity types
+* [pdfDefs](metadata/pdf-defs.md) – PDF generation defs for entity types
+* [logicDefs](metadata/logic-defs.md) – dynamic logic for entity types
+* [notificationDefs](metadata/notification-defs.md) – notification defs for entity types
+* [streamDefs](metadata/stream-defs.md) – stream defs for entity types
+* [fields](metadata/fields.md) – field types
+* [dashlets](metadata/dashlets.md)
+* [authenticationMethods](metadata/authentication-methods.md) – authentication methods
+* [integrations](metadata/integrations.md)
+* app – application definitions
+ * [acl](metadata/app-acl.md) – access control
+ * [aclPortal](metadata/app-acl-portal.md) – access control for portals
+ * [actions](metadata/app-actions.md) – Action framework
+ * [addressFormats](metadata/app-address-formats.md)
+ * [adminPanel](metadata/app-admin-panel.md) – Administration panel
+ * [api](metadata/app-api.md)
+ * [appParams](metadata/app-app-params.md) – AppParams framework
+ * [authentication](metadata/app-authentication.md)
+ * [authentication2FAMethods](metadata/app-authentication-2fa-methods.md) – 2-factor authentication methods
+ * [cleanup](metadata/app-cleanup.md)
+ * [client](metadata/app-client.md) – front-end client
+ * [clientNavbar](metadata/app-client-navbar.md) – front-end navbar
+ * [clientIcons](metadata/app-client-icons.md)
+ * [clientRecord](metadata/app-client-record.md)
+ * [clientRoutes](metadata/app-client-routes.md) – front-end routes
+ * [complexExpression](metadata/app-complex-expression.md)
+ * [config](metadata/app-config.md)
+ * [consoleCommands](metadata/app-console-commands.md)
+ * [containerServices](metadata/app-container-services.md)
+ * [currency](metadata/app-currency.md)
+ * [currencyConversion](metadata/app-currency-conversion.md)
+ * [databasePlatforms](metadata/app-database-platforms.md)
+ * [dateTime](metadata/app-date-time.md)
+ * [defaultDashboardLayouts](metadata/app-default-dashboard-layouts.md)
+ * [defaultDashboardOptions](metadata/app-default-dashboard-options.md)
+ * [emailTemplate](metadata/app-email-template.md)
+ * [entityManager](metadata/app-entity-manager.md)
+ * [entityManagerParams](metadata/app-entity-manager-params.md)
+ * [entityTemplateList](metadata/app-entity-template-list.md)
+ * [entityTemplates](metadata/app-entity-templates.md)
+ * [export](metadata/app-export.md)
+ * [fieldProcessing](metadata/app-field-processing.md)
+ * [file](metadata/app-file.md)
+ * [fileStorage](metadata/app-file-storage.md)
+ * [formula](metadata/app-formula.md)
+ * [hook](metadata/app-hook.md) – Hook framework
+ * [image](metadata/app-image.md)
+ * [jsLibs](metadata/app-js-libs.md) – JS libs
+ * [language](metadata/app-language.md)
+ * [layouts](metadata/app-layouts.md)
+ * [linkManager](metadata/app-link-manager.md)
+ * [mapProviders](metadata/app-map-providers.md)
+ * [massActions](metadata/app-mass-actions.md)
+ * [metadata](metadata/app-metadata.md)
+ * [orm](metadata/app-orm.md)
+ * [pdfEngines](metadata/app-pdf-engines.md)
+ * [popupNotifications](metadata/app-popup-notifications.md)
+ * [portalContainerServices](metadata/app-portal-container-services.md)
+ * [reactions](metadata/app-reactions.md)
+ * [rebuild](metadata/app-rebuild.md)
+ * [record](metadata/app-record.md)
+ * [recordId](metadata/app-record-id.md)
+ * [regExpPatterns](metadata/app-reg-exp-patterns.md)
+ * [relationships](metadata/app-relationships.md)
+ * [scheduledJobs](metadata/app-scheduled-jobs.md)
+ * [select](metadata/app-select.md)
+ * [smsProviders](metadata/app-sms-providers.md)
+ * [templateHelpers](metadata/app-template-helpers.md)
+ * [templates](metadata/app-templates.md)
+ * [webSocket](metadata/app-web-socket.md)
+
+
+## Accessing
+
+### Backend
+
+The Metadata instance (of `Espo\Core\Utils\Metadata` class) is available as a [container service](di.md).
+
+Path to a needed parameter is specified with an array.
```php
-$metadata->get(['entityDefs', 'Account', 'fields', 'name', 'type'])
+ Account > fields > type
+$value = $metadata->get(['entityDefs', 'Account', 'fields', 'name', 'type']);
```
-will return `'varchar'`.
+will return the string value `"varchar"`.
```php
-$metadata->get(['entityDefs', 'Account', 'fields'])
+get(['entityDefs', 'Account', 'fields']);
```
will return an associative array with definitions of all fields.
-#### Frontend
+### Frontend
-Metadata object is accessible from all view objects by method `#getMetadata`. It works the same way as backend's one.
+Metadata object is accessible from all view objects by method `#getMetadata`. It works the same way as the backend's one.
-```JavaScript
-this.getMetadata().get(['entityDefs', 'Account', 'fields', 'name', 'type'])
+```js
+this.getMetadata().get(['entityDefs', 'Account', 'fields', 'name', 'type']);
```
@@ -33,37 +131,44 @@ this.getMetadata().get(['entityDefs', 'Account', 'fields', 'name', 'type'])
Metadata is stored in JSON files that can be located in different places:
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
+* `application/Espo/Resources/metadata` – core;
+* `application/Espo/Modules/{ModuleName}/Resources/metadata` – internal modules;
+* `custom/Espo/Modules/{ModuleName}/Resources/metadata` – custom modules;
+* `custom/Espo/Custom/Resources/metadata` – instance specific customizations, customizations made via the admin UI are stored here.
+
+When you access data by a path `clientDefs.Account.views.edit` the first lexeme `clientDefs` corresponds to a dir name, the second `Account` – to a file name `Account.json`. All the following lexemes correspond to a path in the JSON object.
-When you access data by path `clientDefs.Account.views.edit` the first lexeme `clientDefs` corresponds to dir name, the second `Account` to file name `Account.json`. All following lexemes correspond to path in the JSON.
```json
{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
+ "views": {
+ "edit": "crm:views/account/views/edit"
+ }
}
```
-All JSON files from these directories get merged recursively into a single php array and stored in a cache file.
-
+All JSON files from these directories **get merged** recursively into a single file and stored in an application cache.
## Extending
-Since metadata is merged recursively you can easily redefine json objects and arrays in _custom_ and in your _module_. Also you can append to existing arrays by using `__APPEND__` (since version 2.6.0) as the first element of array.
+Since metadata is merged recursively, you can easily redefine JSON objects and arrays in the `custom` directory.
+
+You can **append** values to existing arrays by using the `__APPEND__` string as the first element of an array. This will preserve array values rather than override them.
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
+`custom/Espo/Custom/Resources/metadata/entityDefs/Account.json`:
```json
{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Dealer", "Lawyer"]
+ "fields": {
+ "employeeCount": {
+ "type": "int"
+ },
+ "type": {
+ "options": [
+ "__APPEND__",
+ "Dealer",
+ "Lawyer"
+ ]
+ }
}
- }
}
```
diff --git a/docs/development/metadata/acl-defs.md b/docs/development/metadata/acl-defs.md
new file mode 100644
index 000000000..9d3ffc0ea
--- /dev/null
+++ b/docs/development/metadata/acl-defs.md
@@ -0,0 +1,91 @@
+# aclDefs
+
+Path: metadata > aclDefs > {ScopeName}.
+
+Defines access control parameters for a specific scope (or entity type).
+
+## accessCheckerClassName
+
+An access checking class. Should implement `Espo\Core\Acl\AccessChecker` interface.
+
+Can optionally implement more interfaces that define what actions can be checked.
+
+Interfaces for access checking:
+
+* `Espo\Core\Acl\AccessChecker` – access to a scope;
+* `Espo\Core\Acl\AccessCreateChecker` – access to a create operation for a scope;
+* `Espo\Core\Acl\AccessReadChecker` – access to a read operation for a scope;
+* `Espo\Core\Acl\AccessEditChecker` – access to an edit operation for a scope;
+* `Espo\Core\Acl\AccessDeleteChecker` – access to a delete operation for a scope;
+* `Espo\Core\Acl\AccessStreamChecker` – access to the stream for a scope;
+* `Espo\Core\Acl\AccessEntityCreateChecker` – access to a create operation for an entity;
+* `Espo\Core\Acl\AccessEntityReadChecker` – access to a read operation for an entity;
+* `Espo\Core\Acl\AccessEntityEditChecker` – access to an edit operation for an entity;
+* `Espo\Core\Acl\AccessEntityDeleteChecker` – access to a delete operation for an entity;
+* `Espo\Core\Acl\AccessEntityStreamChecker` – access to the stream of an entity.
+
+Combined interfaces:
+
+* `Espo\Core\Acl\AccessEntityCREDChecker` – access to create/read/edit/delete of an entity (combined);
+* `Espo\Core\Acl\AccessEntityCREDSChecker` – access to create/read/edit/delete/stream of an entity (combined).
+
+
+Default class: `Espo\Core\Acl\DefaultAccessChecker`.
+
+
+## ownershipCheckerClassName
+
+An ownership checking class.
+
+Should implement one of the following interfaces:
+
+* `Espo\Core\Acl\OwnershipOwnChecker` – whether a user is an owner of an entity;
+* `Espo\Core\Acl\OwnershipTeamChecker` – whether an entity belongs to a user team.
+
+Default class: `Espo\Core\Acl\DefaultOwnershipChecker`.
+
+## portalAccessCheckerClassName
+
+The same as `accessCheckerClassName` but for the portal.
+
+## portalOwnershipCheckerClassName
+
+The same as `ownershipCheckerClassName` but for the portal.
+
+Can implement additional interfaces:
+
+* `Espo\Core\Portal\Acl\OwnershipAccountChecker`
+* `Espo\Core\Portal\Acl\OwnershipContactChecker`
+
+## assignmentCheckerClassName
+
+An assignment checking class.
+
+Should implement `Espo\Core\Acl\AssignmentChecker` interface.
+
+Default class: `Espo\Core\Acl\DefaultAssignmentChecker`.
+
+## readOwnerUserField
+
+Indicates what field is used for ownership checking. If an entity uses a field other than *assignedUser* or *assignedUsers*, you need to specify that field.
+
+## linkCheckerClassNameMap
+
+*Object.\>*
+
+*As of v7.4.*
+
+Linking/unlinking checking classes for specific links. A link-name => class-string map. The class receives two entities and should determine whether a user is allowed to link/unlink these records.
+
+
+## accountLink
+
+*As of v9.0.*
+
+A link with Account that will be used when access control applied for portal users.
+
+## contactLink
+
+*As of v9.0.*
+
+A link with Contact that will be used when access control applied for portal users.
diff --git a/docs/development/metadata/app-acl-portal.md b/docs/development/metadata/app-acl-portal.md
new file mode 100644
index 000000000..f534f1b41
--- /dev/null
+++ b/docs/development/metadata/app-acl-portal.md
@@ -0,0 +1,5 @@
+# app > aclPortal
+
+Path: metadata > app > aclPortal.
+
+Access control level parameters for portals. Has the same parameters as [app > acl](app-acl.md).
diff --git a/docs/development/metadata/app-acl.md b/docs/development/metadata/app-acl.md
new file mode 100644
index 000000000..745febb6c
--- /dev/null
+++ b/docs/development/metadata/app-acl.md
@@ -0,0 +1,172 @@
+# app > acl
+
+Path: metadata > app > acl.
+
+Access control level parameters for the system (excluding portals).
+
+## mandatory
+
+*Object.*
+
+Access levels forcibly applied for regular and API users. These roles can't be changed by Roles assigned to a user.
+
+### scopeLevel
+
+*Object.*
+
+Mandatory access levels for specific scopes.
+
+Example:
+
+```json
+{
+ "mandatory": {
+ "scopeLevel": {
+ "MyEntityType1": {
+ "create": "yes",
+ "read": "own",
+ "edit": "own",
+ "delete": "own",
+ "stream": "team"
+ },
+ "MyScope1": true,
+ "WorkingTimeRange": "WorkingTimeCalendar"
+ }
+ }
+}
+```
+
+* If set to *false*, then users won't have access to the scope.
+* True enables access to scopes w/o actions (scopes that have `"acl": "boolean"` in metadata > scopes).
+* A string value makes the framework to use roles from another scope and apply it to our scope. It can be useful to have roles only for one parent scope, when child scopes uses roles of the parent scope. E.g. *WorkingTimeCalendar* is a parent, *WorkingTimeRange* is a child. In Roles the admin defines only access levels to *WorkingTimeCalendar*, *WorkingTimeRange* will have the same access levels.
+* A string value in the format `boolean:{scope}` will convert a foreign scope data to a boolean value. As of v8.4.
+
+### scopeFieldLevel
+
+*Object.\>*
+
+Mandatory access levels for fields for scopific scopes (entity types). Available levels: *yes*, *no*. False disables access to a field.
+
+Example:
+
+```json
+{
+ "mandatory": {
+ "scopeFieldLevel": {
+ "MyEntityType": {
+ "myField1": {
+ "read": "yes",
+ "edit": "no"
+ },
+ "myField2": false
+ }
+ }
+ }
+}
+```
+
+### fieldLevel
+
+*Object.*
+
+Mandatory access levels for fields for any scope (entity type). E.g. if we define access levels to a field *assignedUsers*, then all fields with the name *assignedUsers* will obtain defined access levels (regardless of an entity type).
+
+
+Example:
+
+```json
+{
+ "mandatory": {
+ "fieldLevel": {
+ "myField1": {
+ "read": "yes",
+ "edit": "no"
+ },
+ "myField2": false
+ }
+ }
+}
+```
+
+## adminMandatory
+
+*Object.*
+
+Access levels forcibly applied for admin users. This section has the same parameters as the *mandatory* section: scopeLevel, scopeFieldLevel, fieldLevel.
+
+## strictDefault
+
+*Object.*
+
+Access levels applied for regular and API users when access is not defined by Roles assigned to those users. This section has the same parameters as the *mandatory* section: scopeLevel, scopeFieldLevel, fieldLevel.
+
+## valuePermissionList
+
+*string*
+
+The list of all available [permissions](../../administration/roles-management.md#special-permissions) in the system.
+
+Example:
+
+```json
+{
+ "valuePermissionList": [
+ "assignmentPermission",
+ "userPermission",
+ "portalPermission",
+ "groupEmailAccountPermission",
+ "exportPermission",
+ "massUpdatePermission",
+ "followerManagementPermission",
+ "dataPrivacyPermission"
+ ]
+}
+```
+
+Use `__APPEND__` as the first value if you want to extend the list.
+
+## permissionsStrictDefaults
+
+*Object.*
+
+Permissions applied for regular and API users when they are not defined by Roles assigned to those users.
+
+Example:
+
+```json
+{
+ "permissionsStrictDefaults": {
+ "assignmentPermission": "no",
+ "userPermission": "no",
+ "portalPermission": "no",
+ "groupEmailAccountPermission": "no",
+ "exportPermission": "no",
+ "massUpdatePermission": "no",
+ "followerManagementPermission": "no",
+ "dataPrivacyPermission": "no"
+ }
+}
+```
+
+## valuePermissionHighestLevels
+
+*Object.*
+
+Highest levels for permissions.
+
+Example:
+
+```json
+{
+ "valuePermissionHighestLevels": {
+ "assignmentPermission": "all",
+ "userPermission": "all",
+ "portalPermission": "yes",
+ "groupEmailAccountPermission": "all",
+ "exportPermission": "yes",
+ "massUpdatePermission": "yes",
+ "followerManagementPermission": "all",
+ "dataPrivacyPermission": "yes"
+ }
+}
+```
diff --git a/docs/development/metadata/app-actions.md b/docs/development/metadata/app-actions.md
new file mode 100644
index 000000000..a75ac7a83
--- /dev/null
+++ b/docs/development/metadata/app-actions.md
@@ -0,0 +1,31 @@
+# app > actions
+
+Path: metadata > app > actions.
+
+Definitions for the [Action]() framework. An action-name => Object map. A called action is applied to a single record.
+
+Example:
+
+```json
+{
+ "convertCurrency": {
+ "implementationClassName": "Espo\\Core\\Action\\Actions\\ConvertCurrency"
+ },
+ "merge": {
+ "implementationClassName": "Espo\\Core\\Action\\Actions\\Merge"
+ }
+}
+```
+
+API endpoint: `POST Action`.
+
+API payload params:
+
+* entityType – *string*
+* action – *string*
+* id – *string*
+* data – *Object.*
+
+## implementationClassName
+
+An action class. Should implement `Espo\Core\Action\Action` interface. Can be overridden for a specific entity type at: recordDefs > {EntityType} > actions > {action} > implementationClassName.
diff --git a/docs/development/metadata/app-address-formats.md b/docs/development/metadata/app-address-formats.md
new file mode 100644
index 000000000..52b2a139d
--- /dev/null
+++ b/docs/development/metadata/app-address-formats.md
@@ -0,0 +1,28 @@
+# app > addressFormats
+
+A mapping format => params. Defines address formats (used in the backend).
+
+## formatterClassName
+
+*class-string*
+
+A formatter class. Should implement `Espo\Core\Field\Address\AddressFormatter` interface.
+
+Example:
+
+```json
+{
+ "1": {
+ "formatterClassName": "Espo\\Classes\\AddressFormatters\\Formatter1"
+ },
+ "2": {
+ "formatterClassName": "Espo\\Classes\\AddressFormatters\\Formatter2"
+ },
+ "3": {
+ "formatterClassName": "Espo\\Classes\\AddressFormatters\\Formatter3"
+ },
+ "4": {
+ "formatterClassName": "Espo\\Classes\\AddressFormatters\\Formatter4"
+ }
+}
+```
diff --git a/docs/development/metadata/app-admin-panel.md b/docs/development/metadata/app-admin-panel.md
new file mode 100644
index 000000000..6235a6c8b
--- /dev/null
+++ b/docs/development/metadata/app-admin-panel.md
@@ -0,0 +1,85 @@
+# app > adminPanel
+
+Path: metadata > app > adminPanel.
+
+Defines what to display on the Administration page.
+
+```json
+{
+ "panelName": {
+ "label": "Some Panel Label",
+ "itemList": [
+ {
+ "url": "#SomeUrl",
+ "label": "Some Item Label",
+ "iconClass": "fas fa-cogs",
+ "description":"descriptionLanguageKey",
+ "tabQuickSearch": true
+ },
+ {
+ "url": "#Admin/mySettingsPage",
+ "label": "My Settings",
+ "iconClass": "fas fa-cogs",
+ "description":"mySettings",
+ "recordView": "custom:views/admin/my-settings"
+ }
+ ],
+ "order": 20
+ }
+}
+
+```
+
+## label
+
+*string*
+
+A panel label. A translation path: Admin > labels > {label}.
+
+## order
+
+*string*
+
+Used for ordering panels on the page.
+
+## itemList
+
+*Object[]*
+
+### url
+
+*string*
+
+A link URL. You can use an URL like #Admin/{myName}, in this case you also need to define a recordView.
+
+### label
+
+*string*
+
+An item (link) label. A translation path: Admin > labels > {label}.
+
+### iconClass
+
+*string*
+
+A CSS class for the icon.
+
+### description
+
+*string*
+
+A translation key for a description text. A translation page: Admin > descriptions > {description}.
+
+### recordView
+
+*string*
+
+A record view. Optional. Needed if you defined the URL like `#Admin/{myName}`. The record view displays settings fields. See [more](../custom-config-parameters.md).
+
+### tabQuickSearch
+
+*boolean*
+
+*As of v9.0.*
+
+Makes available in the navbar tab quick search.
diff --git a/docs/development/metadata/app-api.md b/docs/development/metadata/app-api.md
new file mode 100644
index 000000000..7a7bc9bdd
--- /dev/null
+++ b/docs/development/metadata/app-api.md
@@ -0,0 +1,83 @@
+# app > api
+
+Path: metadata > app > api.
+
+*As of v7.4.*
+
+Definitions for API framework.
+
+Provides the ability to add middlewares for all requests, specific routes, controllers and controller actions. Supporting the PSR-15 standard means that it's possible to use 3rd party middlewares, like [these](https://github.com/middlewares/psr15-middlewares). If a middleware you want to use has dependencies in a constructor, use DI binding to resolve them.
+
+Example:
+
+```json
+{
+ "globalMiddlewareClassNameList": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test1",
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test2"
+ ],
+ "routeMiddlewareClassNameListMap": {
+ "get_/:controller": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test3"
+ ]
+ },
+ "actionMiddlewareClassNameListMap": {
+ "get_/Activities": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test3"
+ ]
+ },
+ "controllerMiddlewareClassNameListMap": {
+ "Contact": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test4"
+ ]
+ },
+ "controllerActionMiddlewareClassNameListMap": {
+ "Contact_get_index": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test5"
+ ],
+ "Contact_post_create": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test6"
+ ],
+ "Contact_put_update": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test7"
+ ],
+ "Contact_get_read": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test8"
+ ],
+ "Contact_delete_delete": [
+ "Espo\\Custom\\Classes\\ApiMiddlewares\\Test9"
+ ]
+ }
+}
+
+```
+
+## globalMiddlewareClassNameList
+
+*class-string[]*
+
+A class list of global middlewares. Global middlewares applied for all API requests. Processed before authentication.
+
+## routeMiddlewareClassNameListMap
+
+*Object.[]\>*
+
+Middlewares for specific routes. Keys are composed in the form: `{method}_{route}`. Processed before authentication.
+
+## actionMiddlewareClassNameListMap
+
+*Object.[]\>*
+
+Middlewares for routes with *actionClassName*. Keys are composed in the form: `{method}_{route}`. Processed after authentication.
+
+## controllerMiddlewareClassNameListMap
+
+*Object.[]\>*
+
+Middlewares for specific controllers. A controller-name => class-string-list map. Processed after authentication.
+
+## controllerActionMiddlewareClassNameListMap
+
+*Object.[]\>*
+
+Middlewares for specific controller actions. Keys are composed in the form: `{ControllerName}_{method}_{actionName}`. Processed after authentication.
diff --git a/docs/development/metadata/app-app-params.md b/docs/development/metadata/app-app-params.md
new file mode 100644
index 000000000..1ac2da4f6
--- /dev/null
+++ b/docs/development/metadata/app-app-params.md
@@ -0,0 +1,20 @@
+# app > appParams
+
+Path: metadata > app > appParams.
+
+[AppParams framework](../app-params.md) definitions. A name => Object map.
+
+```json
+{
+ "paramName": {
+ "className": "Espo\\Modules\\MyModule\\Classes\\AppParams\\ParamName"
+ }
+}
+
+```
+
+## className
+
+*string*
+
+An implementation class name. Should implement `Espo\Tools\App\AppParam` interface.
diff --git a/docs/development/metadata/app-authentication-2fa-methods.md b/docs/development/metadata/app-authentication-2fa-methods.md
new file mode 100644
index 000000000..b8f24cd02
--- /dev/null
+++ b/docs/development/metadata/app-authentication-2fa-methods.md
@@ -0,0 +1,50 @@
+# app > authentication2FAMethods
+
+Path: metadata > app > authentication2FAMethods.
+
+Definitions for 2-factor authentication methods. A method-name => Object map.
+
+```json
+{
+ "Totp": {
+ "settings": {
+ "isAvailable": true
+ },
+ "userApplyView": "views/user-security/modals/totp",
+ "loginClassName": "Espo\\Core\\Authentication\\TwoFactor\\Totp\\TotpLogin",
+ "userSetupClassName": "Espo\\Core\\Authentication\\TwoFactor\\Totp\\TotpUserSetup"
+ }
+}
+
+```
+
+## settings
+
+*Object*
+
+### isAvailable
+
+*bool*
+
+Whether the method should be available as an option at Administration > Authentication > Available 2FA methods.
+
+## userApplyView
+
+*string*
+
+A front-end view for a user when they apply the 2FA method to their account.
+
+## loginClassName
+
+*class-string*
+
+A login class. Processes the second step of the login process.
+
+## userSetupClassName
+
+*class-string*
+
+A user-setup class.
+
+* Provides needed data for a front-end for a user when they setup the 2FA method.
+* Verifies entered user data before establishing the 2FA method for a user.
diff --git a/docs/development/metadata/app-authentication.md b/docs/development/metadata/app-authentication.md
new file mode 100644
index 000000000..153a41442
--- /dev/null
+++ b/docs/development/metadata/app-authentication.md
@@ -0,0 +1,51 @@
+# app > authentication
+
+## beforeLoginHookClassNameList
+
+Array of hook class names. Fired before logging in before credentials are checked. Can throw an exception. Should implement `Espo\Core\Authentication\Hook\BeforeLogin` interface.
+
+!!! important
+
+ Need to have `__APPEND__` item in the beginning of the array when extending.
+
+## onLoginHookClassNameList
+
+*As of v8.3.*
+
+Array of hook class names. Fired before when a user is found, credentials are fine. Can throw an exception. Should implement `Espo\Core\Authentication\Hook\OnLogin` interface.
+
+!!! important
+
+ Need to have `__APPEND__` item in the beginning of the array when extending.
+
+## onFailHookClassNameList
+
+Array of hook class names. Fired once logging in is failed. Should implement `Espo\Core\Authentication\Hook\OnResult` interface.
+
+!!! important
+
+ Need to have `__APPEND__` item in the beginning of the array when extending.
+
+## onSuccessHookClassNameList
+
+Array of hook class names. Fired once logging in is success (not by auth token). Should implement `Espo\Core\Authentication\Hook\OnResult` interface.
+
+!!! important
+
+ Need to have `__APPEND__` item in the beginning of the array when extending.
+
+## onSuccessByTokenHookClassNameList
+
+Array of hook class names. Fired once logging in by a token is success. Should implement `Espo\Core\Authentication\Hook\OnResult` interface.
+
+!!! important
+
+ Need to have `__APPEND__` item in the beginning of the array when extending.
+
+## onSecondStepRequiredHookClassNameList
+
+Array of hook class names. Fired once first step is success and second step is required. Should implement `Espo\Core\Authentication\Hook\OnResult` interface.
+
+!!! important
+
+ Need to have `__APPEND__` item in the beginning of the array when extending.
diff --git a/docs/development/metadata/app-cleanup.md b/docs/development/metadata/app-cleanup.md
new file mode 100644
index 000000000..919eabe14
--- /dev/null
+++ b/docs/development/metadata/app-cleanup.md
@@ -0,0 +1,20 @@
+# app > cleanup
+
+A Key-Value map. Defines cleaning up classes. Fired by the *Cleanup* job.
+
+Example:
+
+```json
+
+{
+ "someName": {
+ "className": "Espo\\SomeImplementation"
+ }
+}
+```
+
+## className
+
+*class-string*
+
+An implementation class. Should implement `Espo\Core\Cleanup\Cleanup` interface.
diff --git a/docs/development/metadata/app-client-icons.md b/docs/development/metadata/app-client-icons.md
new file mode 100644
index 000000000..50949fec0
--- /dev/null
+++ b/docs/development/metadata/app-client-icons.md
@@ -0,0 +1,13 @@
+# app > clientIcons
+
+Path: metadata > app > clientIcons.
+
+## classList
+
+*string[]*
+
+*As of v9.1.*
+
+Additional icon classes. Added icons will be available in the icon picker.
+
+Important: Prepend the `__APPEND__` value to the array.
diff --git a/docs/development/metadata/app-client-navbar.md b/docs/development/metadata/app-client-navbar.md
new file mode 100644
index 000000000..c3f998ba6
--- /dev/null
+++ b/docs/development/metadata/app-client-navbar.md
@@ -0,0 +1,135 @@
+# app > clientNavbar
+
+Navbar definitions.
+
+## items
+
+*Object.*
+
+*As of v8.1.*
+
+Navbar items (in the top right corner).
+
+Example:
+
+```json
+{
+ "items": {
+ "quickCreate": {
+ "view": "views/site/navbar/quick-create",
+ "class": "dropdown hidden-xs quick-create-container",
+ "order": 0,
+ "disabled": false
+ }
+ }
+}
+```
+
+### view
+
+*string*
+
+A frontend view.
+
+### class
+
+*string*
+
+A CSS class or multiple classes for the LI tag.
+
+### order
+
+*integer*
+
+An order position.
+
+### disabled
+
+*bool*
+
+Whether is disabled.
+
+### accessDataList
+
+*Object[]*
+
+*As of v9.1.*
+
+Access rules. See definitions in JSON schema: metadata/clientDefs.json#/definitions/accessDataList.
+
+## menuItems
+
+*Object.*
+
+*As of v8.4.*
+
+Menu items (in the top right corner).
+
+Example:
+
+```json
+{
+ "menuItems": {
+ "myItem": {
+ "order": 0,
+ "groupIndex": 5,
+ "link": "#MyItem",
+ "labelTranslation": "Global.labels.My Item"
+ }
+ }
+}
+```
+
+### labelTranslation
+
+*string*
+
+A label translation path.
+
+### link
+
+*string*
+
+A link (href).
+
+### order
+
+*integer*
+
+An order position.
+
+### groupIndex
+
+*integer*
+
+A group index. Groups are separated by a divider.
+
+### disabled
+
+*boolean*
+
+An item will be hidden.
+
+### handler
+
+*string*
+
+A handler class.
+
+### actionFunction
+
+*string*
+
+An action function in the handler.
+
+### configCheck
+
+*string*
+
+A config path to check. Path items are separated by a dot. If a config value is not empty, then the action is allowed. The `!` prefix negates the check result.
+
+### accessDataList
+
+*Object[]*
+
+Access rules. See definitions in JSON schema: metadata/clientDefs.json#/definitions/accessDataList.
diff --git a/docs/development/metadata/app-client-record.md b/docs/development/metadata/app-client-record.md
new file mode 100644
index 000000000..7652a68be
--- /dev/null
+++ b/docs/development/metadata/app-client-record.md
@@ -0,0 +1,13 @@
+# app > clientRecord
+
+Path: metadata > app > clientRecord.
+
+Client record definitions.
+
+## panels
+
+*Object.*
+
+*As of v9.0.*
+
+Detail view panels. Can be referenced from clientDefs > sidePanels/bottomPanels. The panel schema is the same as in clientDefs.
diff --git a/docs/development/metadata/app-client-routes.md b/docs/development/metadata/app-client-routes.md
new file mode 100644
index 000000000..dcb714cac
--- /dev/null
+++ b/docs/development/metadata/app-client-routes.md
@@ -0,0 +1,5 @@
+# app > clientRoutes
+
+Path: metadata > app > clientRoutes.
+
+Front-end client routes. See more [here](../frontend/controller.md#custom-route).
diff --git a/docs/development/metadata/app-client.md b/docs/development/metadata/app-client.md
new file mode 100644
index 000000000..12d881c43
--- /dev/null
+++ b/docs/development/metadata/app-client.md
@@ -0,0 +1,82 @@
+# app > client
+
+Path: metadata > app > client.
+
+General definitions for the front-end client.
+
+## scriptList
+
+*string[]*
+
+JS files to include on the HTML page. Use `__APPEND__` to append custom values w/o removing existing.
+
+Example:
+
+```json
+{
+ "scriptList": [
+ "__APPEND__",
+ "client/custom/modules/my-module/my-script.js"
+ ]
+}
+```
+
+## developerModeScriptList
+
+*string[]*
+
+JS files to include on the HTML page in the developer mode. Use `__APPEND__` to append custom values w/o removing existing.
+
+## linkList
+
+*Object[]*
+
+Example:
+
+```json
+{
+ "linkList": [
+ "__APPEND__",
+ {
+ "href": "client/custom/fonts/custom-font.woff2",
+ "as": "font",
+ "type": "font/woff2",
+ "rel": "preload",
+ "noTimestamp": true,
+ "crossorigin": true
+ }
+ ]
+}
+```
+
+Link tags to include on the HTML page. Use `__APPEND__` to append custom values w/o removing existing.
+
+## cssList
+
+*string[]*
+
+CSS files to include on the HTML page. Use `__APPEND__` to append custom values w/o removing existing.
+
+Example:
+
+```json
+{
+ "cssList": [
+ "__APPEND__",
+ "path/to/your/file.css"
+ ]
+}
+```
+
+## favicon
+
+*string*
+
+A favicon image. SVG or PNG The default value: `client/img/favicon.svg`.
+
+## faviconAlternate
+
+*string*
+
+An alternate 16px ICO favicon image. The default value: `client/img/favicon.ico`.
+
diff --git a/docs/development/metadata/app-complex-expression.md b/docs/development/metadata/app-complex-expression.md
new file mode 100644
index 000000000..ce5bd5ffd
--- /dev/null
+++ b/docs/development/metadata/app-complex-expression.md
@@ -0,0 +1,26 @@
+# app > complexExpression
+
+Path: metadata > app > complexExpression.
+
+Definitions for the [complex expression](../../user-guide/complex-expressions.md) editor.
+
+## functionList
+
+*Object[]*
+
+Functions available in the editor when editing a complex expression.
+
+Example:
+
+```json
+{
+ "functionList": [
+ "__APPEND__",
+ {
+ "name": "MY_CUSTOM_FUNCTION",
+ "insertText": "MY_CUSTOM_FUNCTION:(VALUE1, VALUE2)",
+ "returnType": "bool"
+ }
+ ]
+}
+```
diff --git a/docs/development/metadata/app-config.md b/docs/development/metadata/app-config.md
new file mode 100644
index 000000000..0ad0337b1
--- /dev/null
+++ b/docs/development/metadata/app-config.md
@@ -0,0 +1,58 @@
+# app > config
+
+Path: metadata > app > config.
+
+Application config definitions.
+
+## params
+
+*Object.\>*
+
+Parameters. A name => params map.
+
+Example:
+
+```json
+{
+
+ "params": {
+ "myParam": {
+ "level": "default",
+ "readOnly": true
+ },
+ "smtpPassword": {
+ "level": "internal"
+ },
+ "awsS3Storage": {
+ "level": "system"
+ }
+ }
+}
+```
+
+### level
+
+*string*
+
+Defines availability of the config parameter in the front-end. Possible values:
+
+* `default` – available for logged-in users (applied by default) (as of v7.4);
+* `global` – available even before logging in (value is exposed to the world);
+* `system` – never available;
+* `internal` – never available for read, admin can write (useful for passwords, secrets) (as of v7.3);
+* `admin` – available only for admin;
+* `superAdmin` – available only for super-admin.
+
+### readOnly
+
+*boolean*
+
+*As of v7.4.*
+
+Disables the ability to change a parameter value for admin users. Useful for parameters that are supposed to be set either manually by writing into the config file or automatically by the application.
+
+## entityTypeListParamList
+
+*string[]*
+
+A list of config parameters values of which are arrays of entity types. Needed to let the application know what params need to be filtered to remove entity types not available for a user.
diff --git a/docs/development/metadata/app-console-commands.md b/docs/development/metadata/app-console-commands.md
new file mode 100644
index 000000000..0da3e526b
--- /dev/null
+++ b/docs/development/metadata/app-console-commands.md
@@ -0,0 +1,37 @@
+# app > consoleCommands
+
+Path: metadata > app > consoleCommands.
+
+Console [commands](../../administration/commands.md). A command-name => defs map.
+
+Example:
+
+```json
+{
+ "myCommand": {
+ "className": "Espo\\Modules\\MyModule\\Classes\\ConsoleCommands\\MyCommand",
+ "listed": true
+ }
+}
+
+```
+
+## className
+
+*class-string*
+
+A command class. Should implement `Espo\Core\Console\Command` interface.
+
+## listed
+
+*boolean*
+
+Whether the command is listed when running `bin/command`.
+
+## noSystemUser
+
+*boolean*
+
+*As of v8.3.*
+
+Do not load the system user.
diff --git a/docs/development/metadata/app-container-services.md b/docs/development/metadata/app-container-services.md
new file mode 100644
index 000000000..11385db5c
--- /dev/null
+++ b/docs/development/metadata/app-container-services.md
@@ -0,0 +1,37 @@
+# app > containerServices
+
+Path: metadata > app > containerServices.
+
+Definitions of [container services](../di.md#container-services). A service-name => defs map.
+
+Example:
+
+```json
+{
+ "myService1": {
+ "className": "Espo\\Modules\\MyModule\\MyService1"
+ },
+ "myService2": {
+ "loaderClassName": "Espo\\Modules\\MyModule\\MyService2Loader"
+ }
+}
+
+```
+
+## className
+
+*class-string*
+
+A service class.
+
+## loaderClassName
+
+*class-string*
+
+A service loader class. Should implement `Espo\Core\Container\Loader` interface.
+
+## settable
+
+*boolean*
+
+Whether the service can be set to the container externally (with *set* method).
diff --git a/docs/development/metadata/app-currency-conversion.md b/docs/development/metadata/app-currency-conversion.md
new file mode 100644
index 000000000..b311187b8
--- /dev/null
+++ b/docs/development/metadata/app-currency-conversion.md
@@ -0,0 +1,19 @@
+# app > currencyConversion
+
+Example:
+
+```json
+{
+ "entityConverterClassNameMap": {
+ "MyEntityType": "Espo\\Modules\\MyModule\\Classes\\MyEntityCurrencyConverter"
+ }
+}
+```
+
+## entityConverterClassNameMap
+
+*Object.\>*
+
+*As of v7.5.*
+
+Entity currency converters.
diff --git a/docs/development/metadata/app-currency.md b/docs/development/metadata/app-currency.md
new file mode 100644
index 000000000..658a0658a
--- /dev/null
+++ b/docs/development/metadata/app-currency.md
@@ -0,0 +1,57 @@
+# app > currency
+
+Path: metadata > app > currency.
+
+Currency definitions.
+
+## symbolMap
+
+*Object*
+
+A currency-code => symbol mapping.
+
+Example:
+
+```json
+{
+ "EUR":"€",
+ "GBP":"£"
+}
+```
+
+## list
+
+*string[]*
+
+A list of currencies available in the system. Values defined as 3-letter currency codes in ISO 4217 standard. Use `__APPEND__` to add new currencies w/o deleting existing.
+
+Example:
+
+```json
+
+{
+ "list": [
+ "__APPEND__",
+ "COD"
+ ]
+}
+```
+
+## precisionMap
+
+*Object*
+
+*As of v9.3.*
+
+
+A currency-code => precision mapping. If not specified, 2 is used as a fallback value.
+
+Example:
+
+```json
+{
+ "precisionMap": {
+ "BHD": 3
+ }
+}
+```
diff --git a/docs/development/metadata/app-database-platforms.md b/docs/development/metadata/app-database-platforms.md
new file mode 100644
index 000000000..066980369
--- /dev/null
+++ b/docs/development/metadata/app-database-platforms.md
@@ -0,0 +1,44 @@
+# app > databasePlatforms
+
+Path: metadata > app > databasePlatforms.
+
+*Object.*
+
+*As of v7.4.*
+
+Example:
+
+```json
+{
+ "Mysql": {},
+ "Postgresql": {}
+}
+```
+
+## dbalConnectionFactoryClass
+
+*class-string*
+
+## detailsProviderClassName
+
+*class-string*
+
+## dbalTypeClassNameMap
+
+*Object.\>*
+
+## indexHelperClassName
+
+*class-string*
+
+## columnPreparatorClassName
+
+*class-string*
+
+## preRebuildActionClassNameList
+
+*class-string[]*
+
+## postRebuildActionClassNameList
+
+*class-string[]*
diff --git a/docs/development/metadata/app-date-time.md b/docs/development/metadata/app-date-time.md
new file mode 100644
index 000000000..69af6e805
--- /dev/null
+++ b/docs/development/metadata/app-date-time.md
@@ -0,0 +1,38 @@
+# app > dateTime
+
+Path: metadata > app > dateTime.
+
+Date-time definitions.
+
+Example:
+
+```json
+{
+ "dateFormatList": [
+ "DD.MM.YYYY",
+ "MM/DD/YYYY",
+ "DD/MM/YYYY",
+ "YYYY-MM-DD",
+ "DD. MM. YYYY"
+ ],
+ "timeFormatList": [
+ "HH:mm",
+ "hh:mma",
+ "hh:mmA",
+ "hh:mm A",
+ "hh:mm a"
+ ]
+}
+```
+
+## dateFormatList
+
+*string[]*
+
+A list of date formats available in the system.
+
+## timeFormatList
+
+*string[]*
+
+A list of time formats available in the system.
diff --git a/docs/development/metadata/app-default-dashboard-layouts.md b/docs/development/metadata/app-default-dashboard-layouts.md
new file mode 100644
index 000000000..a3bf5f8ef
--- /dev/null
+++ b/docs/development/metadata/app-default-dashboard-layouts.md
@@ -0,0 +1,45 @@
+# app > defaultDashboardLayouts
+
+Path: metadata > app > defaultDashboardLayouts.
+
+Default dashboard layouts.
+
+Example:
+
+```json
+{
+ "Standard": [
+ {
+ "name": "My Espo",
+ "layout": [
+ {
+ "id": "defaultActivities",
+ "name": "Activities",
+ "x": 2,
+ "y": 2,
+ "width": 2,
+ "height": 2
+ },
+ {
+ "id": "defaultStream",
+ "name": "Stream",
+ "x": 0,
+ "y": 0,
+ "width": 2,
+ "height": 4
+ },
+ {
+ "id": "defaultTasks",
+ "name": "Tasks",
+ "x": 2,
+ "y": 4,
+ "width": 2,
+ "height": 2
+ }
+ ]
+ }
+ ]
+}
+```
+
+The *Standard* layout is applied for new users (regular and admin) and when they reset their layout to default.
diff --git a/docs/development/metadata/app-default-dashboard-options.md b/docs/development/metadata/app-default-dashboard-options.md
new file mode 100644
index 000000000..80cdbf9b2
--- /dev/null
+++ b/docs/development/metadata/app-default-dashboard-options.md
@@ -0,0 +1,17 @@
+# app > defaultDashboardOptions
+
+Path: metadata > app > defaultDashboardOptions.
+
+Options for [default dashboard](app-default-dashboard-layouts.md) dashlets.
+
+Example:
+
+```json
+{
+ "Standard": {
+ "myDashletId": {
+ "displayRecords": 10
+ }
+ }
+}
+```
diff --git a/docs/development/metadata/app-email-template.md b/docs/development/metadata/app-email-template.md
new file mode 100644
index 000000000..d755b93ac
--- /dev/null
+++ b/docs/development/metadata/app-email-template.md
@@ -0,0 +1,63 @@
+# metadata > app > emailTemplate
+
+Email template definitions.
+
+## placeholders
+
+Placeholders.
+
+Example:
+
+```json
+
+{
+ "placeholders": {
+ "today": {
+ "className": "Espo\\Tools\\EmailTemplate\\Placeholders\\Today",
+ "order": 0
+ },
+ "now": {
+ "className": "Espo\\Tools\\EmailTemplate\\Placeholders\\Now",
+ "order": 1
+ },
+ "currentYear": {
+ "className": "Espo\\Tools\\EmailTemplate\\Placeholders\\CurrentYear",
+ "order": 2
+ }
+ }
+}
+```
+
+### className
+
+*class-string<\Espo\Tools\EmailTemplate\Placeholder\>*
+
+An implementation.
+
+### order
+
+*integer*
+
+An order position.
+
+## entityLinkMapping
+
+*object.\>*
+
+*As of v9.2.*
+
+Mappings of entity types to links. Used for placeholders.
+
+Example:
+
+```json
+{
+ "entityLinkMapping": {
+ "Opportunity": {
+ "Account": "account"
+ }
+ }
+}
+```
+
+If an Opportunity record is selected as an email parent, *{Account.\*}* placeholders will be substituted with the Account related to the Opportunity through the *account* link.
diff --git a/docs/development/metadata/app-entity-manager-params.md b/docs/development/metadata/app-entity-manager-params.md
new file mode 100644
index 000000000..516a13131
--- /dev/null
+++ b/docs/development/metadata/app-entity-manager-params.md
@@ -0,0 +1,65 @@
+# app > entityManagerParams
+
+*As of v7.5.*
+
+Path: metadata > app > entityManagerParams
+
+Additional entity parameters. Defined parameters are available in the entity manager. Global, template type and entity type specific parameters can be defined.
+
+Example:
+
+```json
+{
+ "Global": {
+ "optimisticConcurrencyControl": {
+ "location": "entityDefs",
+ "fieldDefs": {
+ "type": "bool",
+ "tooltip": true
+ }
+ }
+ },
+ "MyEntityType": {
+ "someParam": {
+ "location": "scopes",
+ "fieldDefs": {
+ "type": "int",
+ "tooltip": true
+ }
+ }
+ },
+ "@Event": {
+ "someParam": {
+ "location": "clientDefs",
+ "fieldDefs": {
+ "type": "varchar",
+ "tooltip": true
+ }
+ }
+ }
+}
+
+```
+
+*Global* parameters are available for all entity types. *@Event* defines template specific parameters.
+
+Field labels and tooltips should be defined in language data in the *EntityManager* scope.
+
+## location
+
+*string*
+
+A metadata location. Where the parameter will be stored. Supported values:
+
+* `scopes`
+* `entityDefs`
+* `clientDefs`
+* `recordDefs` (as of v8.0)
+
+## fieldDefs
+
+Field definitions (same as [entityDefs > fields](entity-defs.md#fields)). The defined field will be rendered on the entity manager edit view.
+
+!!! note
+
+ Only field types that have one attribute are supported. Meaning that you can't use field type like *link*, *linkParent*, *linkMultiple*.
diff --git a/docs/development/metadata/app-entity-manager.md b/docs/development/metadata/app-entity-manager.md
new file mode 100644
index 000000000..9ae77d1c2
--- /dev/null
+++ b/docs/development/metadata/app-entity-manager.md
@@ -0,0 +1,30 @@
+# app > entityManager
+
+Path: metadata > app > entityManager.
+
+
+## createHookClassNameList
+
+*class-string[]*
+
+*As of v8.0.*
+
+
+Hooks processed when a new custom entity type is created.
+
+
+## deleteHookClassNameList
+
+*class-string[]*
+
+*As of v8.0.*
+
+Hooks processed when a custom entity type is deleted.
+
+## updateHookClassNameList
+
+*class-string[]*
+
+*As of v8.0.*
+
+Hooks processed when parameters of an entity type are updated.
diff --git a/docs/development/metadata/app-entity-template-list.md b/docs/development/metadata/app-entity-template-list.md
new file mode 100644
index 000000000..9923b142a
--- /dev/null
+++ b/docs/development/metadata/app-entity-template-list.md
@@ -0,0 +1,19 @@
+# app > entityTemplateList
+
+Path: metadata > app > entityTemplateList.
+
+*string[]*
+
+A list of entity templates available when creating a new entity type in the Entity Manager tool. Use `__APPEND__` to add new values without deleting existing.
+
+Example:
+
+```json
+[
+ "Base",
+ "BasePlus",
+ "Event",
+ "Person",
+ "Company"
+]
+```
diff --git a/docs/development/metadata/app-entity-templates.md b/docs/development/metadata/app-entity-templates.md
new file mode 100644
index 000000000..6938157bb
--- /dev/null
+++ b/docs/development/metadata/app-entity-templates.md
@@ -0,0 +1,30 @@
+# app > entityTemplates
+
+Path: metadata > app > entityTemplates
+
+*As of v8.0.*
+
+Definitions for entity type templates.
+
+Example:
+
+```json
+{
+ "BasePlus": {
+ "entityClassName": "Espo\\Core\\Templates\\Entities\\BasePlus",
+ "repositoryClassName": "Espo\\Core\\Templates\\Repositories\\BasePlus"
+ }
+}
+```
+
+## entityClassName
+
+*class-string*
+
+An entity class to use for a template.
+
+## repositoryClassName
+
+*class-string*
+
+A repository class to use for a template.
diff --git a/docs/development/metadata/app-export.md b/docs/development/metadata/app-export.md
new file mode 100644
index 000000000..243293594
--- /dev/null
+++ b/docs/development/metadata/app-export.md
@@ -0,0 +1,80 @@
+# app > export
+
+Path: metadata > app > export.
+
+Definitions for the Export framework.
+
+## formatList
+
+*string*
+
+Available export formats.
+
+## formatDefs
+
+*Object.\>*
+
+Definitions for export formats. You can define here also custom params specific to your custom format.
+
+Example:
+
+```json
+{
+ "formatDefs": {
+ "csv": {
+ "processorClassName": "Espo\\Tools\\Export\\Format\\Csv\\Processor",
+ "additionalFieldsLoaderClassName": "Espo\\Tools\\Export\\Format\\Csv\\AdditionalFieldsLoader",
+ "mimeType": "text/csv",
+ "fileExtension": "csv"
+ }
+ }
+}
+```
+
+### processorClassName
+
+*class-string*
+
+A main processing class. Should implement `Espo\Tools\Export\Processor` interface.
+
+### additionalFieldsLoaderClassName
+
+*class-string*
+
+An additional field loader class. Should implement `Espo\Tools\Export\AdditionalFieldsLoader` interface.
+
+### mimeType
+
+*string*
+
+A mime type of export files.
+
+### fileExtension
+
+*string*
+
+An extension of export files.
+
+### params
+
+Additional export parameters.
+
+```json
+"fields": {
+ "myParam": {
+ "type": "bool"
+ }
+},
+"layout": [
+ [
+ {"name": "myParam"}
+ ]
+],
+"dynamicLogic": {
+ "myParam": {
+ "visible": {
+ "conditionGroup": []
+ }
+ }
+}
+```
diff --git a/docs/development/metadata/app-field-processing.md b/docs/development/metadata/app-field-processing.md
new file mode 100644
index 000000000..4656bdfe0
--- /dev/null
+++ b/docs/development/metadata/app-field-processing.md
@@ -0,0 +1,23 @@
+# app > fieldProcessing
+
+Path: metadata > app > fieldProcessing.
+
+Definitions for the Field Processing framework.
+
+## readLoaderClassNameList
+
+*class-string[]*
+
+A list of loader classes. Load additional fields when reading a record. Applied globally for all entity types.
+
+## listLoaderClassNameList
+
+*class-string[]*
+
+A list of loader classes for lists. Load additional fields when reading a list of record. Applied globally for all entity types.
+
+## saverClassNameList
+
+*class-string[]*
+
+A list of saver classes. Save additional fields. Applied globally for all entity types.
diff --git a/docs/development/metadata/app-file-storage.md b/docs/development/metadata/app-file-storage.md
new file mode 100644
index 000000000..50d167f09
--- /dev/null
+++ b/docs/development/metadata/app-file-storage.md
@@ -0,0 +1,22 @@
+# app > fileStorage
+
+Path: metadata > app > fileStorage.
+
+File storages.
+
+## implementationClassNameMap
+
+*Object.\>*
+
+Implementation classes for file storages.
+
+Example:
+
+``` json
+{
+ "implementationClassNameMap": {
+ "EspoUploadDir": "Espo\\Core\\FileStorage\\Storages\\EspoUploadDir",
+ "AwsS3": "Espo\\Core\\FileStorage\\Storages\\AwsS3"
+ }
+}
+```
diff --git a/docs/development/metadata/app-file.md b/docs/development/metadata/app-file.md
new file mode 100644
index 000000000..b3841bca6
--- /dev/null
+++ b/docs/development/metadata/app-file.md
@@ -0,0 +1,36 @@
+# app > file
+
+Path: metadata > app > file.
+
+## extensionMimeTypeMap
+
+*Object.*
+
+Mime types associated with file extensions.
+
+Example:
+
+```json
+{
+ "extensionMimeTypeMap": {
+ "aac": ["audio/aac"]
+ }
+}
+```
+
+## inlineMimeTypeList
+
+*string[]*
+
+Mime types that can be downloaded as inline attachments.
+
+Example:
+
+```json
+{
+ "inlineMimeTypeList": [
+ "__APPEND__",
+ "application/some-type"
+ ]
+}
+```
diff --git a/docs/development/metadata/app-formula.md b/docs/development/metadata/app-formula.md
new file mode 100644
index 000000000..ed2e0cc83
--- /dev/null
+++ b/docs/development/metadata/app-formula.md
@@ -0,0 +1,27 @@
+# app > formula
+
+Path: metadata > app > formula.
+
+Definitions for the formula editor.
+
+## functionList
+
+*Object[]*
+
+Functions available in the editor.
+
+Example:
+
+```json
+{
+ "functionList": [
+ "__APPEND__",
+ {
+ "name": "myNamespace\\myFunction",
+ "insertText": "myNamespace\\myFunction(STRING)",
+ "returnType": "string",
+ "unsafe": false
+ }
+ ]
+}
+```
diff --git a/docs/development/metadata/app-hook.md b/docs/development/metadata/app-hook.md
new file mode 100644
index 000000000..cac3eea34
--- /dev/null
+++ b/docs/development/metadata/app-hook.md
@@ -0,0 +1,13 @@
+# app > hook
+
+Path: metadata > app > hook.
+
+Definitions for the [Hook framework](../hooks.md).
+
+## suppressClassNameList
+
+*class-string[]*
+
+*As of v7.4.*
+
+A list of hook classes that should be ignored. Provides the ability to disable built-in hooks.
diff --git a/docs/development/metadata/app-image.md b/docs/development/metadata/app-image.md
new file mode 100644
index 000000000..273b7106a
--- /dev/null
+++ b/docs/development/metadata/app-image.md
@@ -0,0 +1,51 @@
+# app > image
+
+Path: metadata > app > image.
+
+## allowedFileTypeList
+
+*string[]*
+
+A list of allowed image mime types. Use `__APPEND__` for extending.
+
+## resizableFileTypeList
+
+*string[]*
+
+A list of image mime types that can be resized to be served in a smaller size. Use `__APPEND__` for extending.
+
+## fixOrientationFileTypeList
+
+*string[]*
+
+A list of image mime types orientation of which can be fixed using exif data.
+
+## previewFileTypeList
+
+*string[]*
+
+A list of image mime types that can be previewed in the File or Attachment-Multiple fields.
+
+## sizes
+
+*Object*
+
+Size dimensions.
+
+Example:
+
+```json
+{
+ "sizes": {
+ "xxx-small": [18, 18],
+ "xx-small": [32, 32],
+ "x-small": [64, 64],
+ "small": [128, 128],
+ "medium": [256, 256],
+ "large": [512, 512],
+ "x-large": [864, 864],
+ "xx-large": [1024, 1024],
+ "small-logo": [181, 44]
+ }
+}
+```
diff --git a/docs/development/metadata/app-js-libs.md b/docs/development/metadata/app-js-libs.md
new file mode 100644
index 000000000..d31838a75
--- /dev/null
+++ b/docs/development/metadata/app-js-libs.md
@@ -0,0 +1,90 @@
+# app > jsLibs
+
+Path: metadata > app > jsLibs.
+
+JS libraries definitions for the loader.
+
+Example:
+
+```json
+{
+ "some-lib": {
+ "path": "client/custom/modules/my-module/lib/some-lib.js",
+ "devPath": "client/custom/modules/my-module/lib/original/some-lib.js",
+ "exportsTo": "window",
+ "exportsAs": "LibObjectName",
+ "sourceMap": false
+ },
+ "some-umd-lib": {
+ "path": "client/custom/modules/my-module/lib/some-umd-lib.js"
+ },
+ "ace-ext-language_tools": {
+ "path": "client/lib/ace-ext-language_tools.js",
+ "exportsTo": "ace.require.define.modules",
+ "exportsAs": "ace/ext/language_tools"
+ },
+ "some-jquery-lib": {
+ "path": "client/custom/modules/my-module/lib/some-jquery-lib.js",
+ "devPath": "client/custom/modules/my-module/lib/original/some-jquery-lib.js",
+ "exportsTo": "$.fn",
+ "exportsAs": "some-jquery-lib",
+ "sourceMap": true
+ }
+}
+```
+
+Libs can be required in the front-end the following ways:
+
+```js
+define('my-module-name', ['some-lib'], (SomeLib) => {});
+```
+
+```js
+import MyLib from 'my-lib';
+```
+
+```js
+Espo.loader.requirePromise('some-lib').then(SomeLib => {});
+```
+
+## path
+
+*string*
+
+A path to a lib file.
+
+## devPath
+
+*string*
+
+A path to the lib file for the developer mode.
+
+## exportsTo
+
+*string*
+
+To where the lib is exported. Use dots to define a path.
+
+## exportsAs
+
+*string*
+
+A key name by which the lib is available in a containing object.
+
+## sourceMap
+
+*boolean*
+
+Whether the source map file is available.
+
+## exposeAs
+
+*string*
+
+If set, the lib will be exposed to the window object. A variable name the lib will be set to. To be used for backward compatibility reasons.
+
+## aliases
+
+*string[]*
+
+Additional module IDs the lib will be available by. Can be useful for establishing backward compatibility or when another lib requires this lib by a different ID.
diff --git a/docs/development/metadata/app-language.md b/docs/development/metadata/app-language.md
new file mode 100644
index 000000000..02da106e6
--- /dev/null
+++ b/docs/development/metadata/app-language.md
@@ -0,0 +1,57 @@
+# app > language
+
+Path: metadata > app > language.
+
+Application languages.
+
+## list
+
+*string*
+
+A list of languages available in the application. The name format: `en_US`.
+
+## aclDependencies
+
+*Object.\>*
+
+Rules making language translations available for a user when they don't have access to a scope.
+
+Example:
+
+```json
+{
+ "aclDependencies": {
+ "Lead.options.source": {
+ "scope": "Opportunity",
+ "field": "leadSource"
+ },
+ "Account.options.industry": {
+ "scope": "Lead",
+ "field": "industry"
+ },
+ "Meeting": {
+ "anyScopeList": ["Call"]
+ }
+ }
+}
+```
+
+Keys are paths to translation data.
+
+### scope
+
+*string*
+
+If a user has access to the scope, they will have access to translations defined by a key.
+
+### field
+
+*string*
+
+If a user has access to the field (of a scope), they will have access to translations defined by a key.
+
+### anyScopeList
+
+*string[]*
+
+If a user has access to any of listed scopes, they will have access to translations defined by a key.
diff --git a/docs/development/metadata/app-layouts.md b/docs/development/metadata/app-layouts.md
new file mode 100644
index 000000000..a65cebf98
--- /dev/null
+++ b/docs/development/metadata/app-layouts.md
@@ -0,0 +1,21 @@
+# app > layouts
+
+Path: metadata > app > layouts.
+
+Example:
+
+```json
+{
+ "Opportunity": {
+ "list": {
+ "module": "MyModule"
+ }
+ }
+}
+```
+
+## module
+
+*As of v8.1.*
+
+A module where the default layout is located. Provides the ability to re-define location of layouts for standard entity types.
diff --git a/docs/development/metadata/app-link-manager.md b/docs/development/metadata/app-link-manager.md
new file mode 100644
index 000000000..626839186
--- /dev/null
+++ b/docs/development/metadata/app-link-manager.md
@@ -0,0 +1,15 @@
+# app > linkManager
+
+Path: metadata > app > linkManager.
+
+## createHookClassNameList
+
+*class-string*
+
+Hooks called when creating a new relationship (in the Entity Manager tool). Use `__APPEND__` for extending.
+
+## deleteHookClassNameList
+
+*class-string*
+
+Hooks called when deleting a relationship (in the Entity Manager tool). Use `__APPEND__` for extending.
diff --git a/docs/development/metadata/app-map-providers.md b/docs/development/metadata/app-map-providers.md
new file mode 100644
index 000000000..8e3540868
--- /dev/null
+++ b/docs/development/metadata/app-map-providers.md
@@ -0,0 +1,19 @@
+# app > mapProviders
+
+Path: metadata > app > mapProviders
+
+Example:
+
+```json
+{
+ "Google": {
+ "renderer": "handlers/map/google-maps-renderer"
+ }
+}
+```
+
+## Renderer
+
+*As of v8.1.*
+
+A frontend renderer. Should extend `handlers/map/renderer`.
diff --git a/docs/development/metadata/app-mass-actions.md b/docs/development/metadata/app-mass-actions.md
new file mode 100644
index 000000000..bada5e1f5
--- /dev/null
+++ b/docs/development/metadata/app-mass-actions.md
@@ -0,0 +1,21 @@
+# app > massActions
+
+Path: metadata > app > massActions.
+
+Definitions for the Mass Action framework.
+
+Example:
+
+```json
+{
+ "myAction": {
+ "implementationClassName": "Espo\\Module\\MyModule\\Classes\\Actions\\MyAction"
+ }
+}
+```
+
+## implementationClassName
+
+*class-string*
+
+A main class for the mass action.
diff --git a/docs/development/metadata/app-metadata.md b/docs/development/metadata/app-metadata.md
new file mode 100644
index 000000000..e28d1bc32
--- /dev/null
+++ b/docs/development/metadata/app-metadata.md
@@ -0,0 +1,84 @@
+# app > metadata
+
+Path: metadata > app > metadata.
+
+Definitions for metadata itself.
+
+## frontendHiddenPathList
+
+*Array*
+
+Sections of metadata (defined as paths) to be hidden from the front-end.
+
+Example:
+
+```json
+{
+ "frontendHiddenPathList": [
+ "__APPEND__",
+ ["app", "calendar", "additionalAttributeList"]
+ ]
+}
+```
+
+## frontendNonAdminHiddenPathList
+
+*Array*
+
+*As of v8.0*.
+
+Sections of metadata (defined as paths) to be hidden from the front-end for non-admin users.
+
+## aclDependencies
+
+*Object.\>*
+
+Rules making a metadata sections available for the user when they don't have access to the scope.
+
+Example:
+
+```json
+{
+ "aclDependencies": {
+ "entityDefs.Lead.fields.source.options": {
+ "scope": "Opportunity",
+ "field": "leadSource"
+ },
+ "entityDefs.Account.fields.industry.options": {
+ "scope": "Lead",
+ "field": "industry"
+ },
+ "entityDefs.MyEntityType": {
+ "anyScopeList": ["AnotherEntityType"]
+ }
+ }
+}
+```
+
+### scope
+
+*string*
+
+If the user has access to the scope, they will have access to the metadata section defined by the key.
+
+### field
+
+*string*
+
+If the user has access to the field (of the scope), they will have access to the metadata section defined by the key.
+
+### anyScopeList
+
+*string[]*
+
+*As of v9.2.5.*
+
+If the user has access to any of the listed scopes, they will have access to the metadata section defined by the key.
+
+## additionalBuilderClassNameList
+
+*class-string[]*
+
+*As of v8.4.*
+
+Additional builders. Allows adding conditional metadata.
diff --git a/docs/development/metadata/app-orm.md b/docs/development/metadata/app-orm.md
new file mode 100644
index 000000000..680482b21
--- /dev/null
+++ b/docs/development/metadata/app-orm.md
@@ -0,0 +1,45 @@
+# app > orm
+
+Path: metadata > app > orm.
+
+Definitions for [ORM](../orm.md).
+
+Example:
+
+```json
+{
+ "platforms": {
+ "Mysql": {
+ "queryComposerClassName": "Espo\\ORM\\QueryComposer\\MysqlQueryComposer",
+ "pdoFactoryClassName": "Espo\\ORM\\PDO\\MysqlPDOFactory",
+ "functionConverterClassNameMap": {
+ "ABS": "Espo\\Core\\ORM\\QueryComposer\\Part\\FunctionConverters\\Abs"
+ }
+ }
+ }
+}
+```
+
+## platforms
+
+*As of v7.5.*
+
+Definitions for database platforms.
+
+### queryComposerClassName
+
+class-string
+
+A query composer.
+
+### pdoFactoryClassName
+
+class-string
+
+A PDO factory.
+
+### functionConverterClassNameMap
+
+*Object.\>*
+
+[Complex expression](../../user-guide/complex-expressions.md) function converters. Use it to define custom complex expression functions.
diff --git a/docs/development/metadata/app-pdf-engines.md b/docs/development/metadata/app-pdf-engines.md
new file mode 100644
index 000000000..32d01627a
--- /dev/null
+++ b/docs/development/metadata/app-pdf-engines.md
@@ -0,0 +1,41 @@
+# app > pdfEngines
+
+Path: metadata > app > pdfEngines.
+
+PDF printing engines. An engine-name => defs map.
+
+```json
+{
+ "MyCustomEngine": {
+ "implementationClassNameMap": {
+ "entity": "Espo\\Modules\\MyModule\\MyCustomEngine\\EntityPrinter",
+ "collection": "Espo\\Modules\\MyModule\\MyCustomEngine\\CollectionPrinter"
+ },
+ "fontFaceList": []
+ }
+}
+```
+
+## implementationClassNameMap
+
+Implementations.
+
+### entity
+
+*class-string*
+
+### collection
+
+*class-string*
+
+## fontFaceList
+
+*string[]*
+
+A list of fonts available for the engine.
+
+## additionalParams
+
+*object*
+
+Additional engine-wise parameters.
diff --git a/docs/development/metadata/app-popup-notifications.md b/docs/development/metadata/app-popup-notifications.md
new file mode 100644
index 000000000..0645a5af1
--- /dev/null
+++ b/docs/development/metadata/app-popup-notifications.md
@@ -0,0 +1,71 @@
+# app > popupNotifications
+
+Path: metadata > app > popupNotifications.
+
+Popup notifications. A name => defs map.
+
+Example:
+
+```json
+{
+ "event": {
+ "grouped": true,
+ "providerClassName": "Espo\\Modules\\Crm\\Tools\\Activities\\PopupNotificationsProvider",
+ "useWebSocket": true,
+ "portalDisabled": true,
+ "view": "crm:views/meeting/popup-notification"
+ }
+}
+```
+
+## grouped
+
+*boolean*
+
+*As of v7.3.*
+
+Grouped popup notifications are fetched with a single API request.
+
+## providerClassName
+
+*class-string*
+
+*As of v7.3.*
+
+A provider class. Actual only if the *grouped* parameter is set to true.
+
+## useWebSocket
+
+*boolean*
+
+If WebSocket is configured and the parameter is set to true, notifications won't be polled in the front-end (except once, when the page is loaded). A topic 'popupNotifications.{name}' should be submitted with *Espo\Core\WebSocket\Submission*.
+
+## disabled
+
+*boolean*
+
+Disables.
+
+## portalDisabled
+
+*boolean*
+
+Disables in portals.
+
+## view
+
+*string*
+
+A view for the popup notification.
+
+## interval
+
+*int*
+
+A polling interval in seconds. Actual if *grouped* is false.
+
+## url
+
+*string*
+
+An API endpoint used for polling. Actual if *grouped* is false.
diff --git a/docs/development/metadata/app-portal-container-services.md b/docs/development/metadata/app-portal-container-services.md
new file mode 100644
index 000000000..bab1b948e
--- /dev/null
+++ b/docs/development/metadata/app-portal-container-services.md
@@ -0,0 +1,5 @@
+# app > portalContainerServices
+
+Path: metadata > app > portalContainerServices.
+
+Overriding of container services for portals. Provides the ability to define custom implementations for portals. The schema is the same as in [containerServices](app-container-services.md).
diff --git a/docs/development/metadata/app-reactions.md b/docs/development/metadata/app-reactions.md
new file mode 100644
index 000000000..bdb8350f4
--- /dev/null
+++ b/docs/development/metadata/app-reactions.md
@@ -0,0 +1,32 @@
+# app > reactions
+
+Path: metadata > app > reactions.
+
+*As of v9.0.*
+
+## list
+
+A list of reactions.
+
+*Record[]*
+
+Example:
+
+```json
+{
+ "list": [
+ {
+ "type": "Smile",
+ "iconClass": "far fa-face-smile"
+ }
+ ]
+}
+```
+
+### type
+
+A reaction type. Must not be longer than 10 characters.
+
+### iconClass
+
+An icon CSS class.
diff --git a/docs/development/metadata/app-rebuild.md b/docs/development/metadata/app-rebuild.md
new file mode 100644
index 000000000..1adf84d5e
--- /dev/null
+++ b/docs/development/metadata/app-rebuild.md
@@ -0,0 +1,8 @@
+# app > rebuild
+
+## actionClassNameList
+
+*class-string*
+
+Array of class names. Actions being processed when the application is being rebuilt. Must implement `Espo\Core\Rebuild\RebuildAction` interface.
+
diff --git a/docs/development/metadata/app-record-id.md b/docs/development/metadata/app-record-id.md
new file mode 100644
index 000000000..9c1a77206
--- /dev/null
+++ b/docs/development/metadata/app-record-id.md
@@ -0,0 +1,34 @@
+# app > recordId
+
+Path: metadata > app > recordId.
+
+*As of v7.4.*
+
+## type
+
+*string*
+
+A type of generated IDs.
+
+Available types:
+
+* *id* – 17-character hex (set by default);
+* *uuid4* – UUID v4 (requires setting the *length* to *36* or using *uuid* data type).
+
+## length
+
+*int*
+
+ID column length. By default, set to *17*.
+
+## dbType
+
+*string*
+
+An ID column data type. By default, set to *string* (equivalent to *varchar* in MySQL). Changing this parameter will change types of all ID columns once you run rebuild.
+
+In MariaDB (as of v10.7) and PostgreSQL it's possible to use *uuid* data type.
+
+Beware of setting the *uuid* data type for instances with data. You will need to migrate all existing ID values to an UUID compatible format (e.g. by applying an MD5 function). Besides database ID columns, you will need to do the same for attachment files and all other references. This may be not a trivial task.
+
+Consider setting the *uuid* type for new instances. If you do it before installation, no any migration work will be needed.
diff --git a/docs/development/metadata/app-record.md b/docs/development/metadata/app-record.md
new file mode 100644
index 000000000..efe9051fb
--- /dev/null
+++ b/docs/development/metadata/app-record.md
@@ -0,0 +1,145 @@
+# app > record
+
+Record framework definitions.
+
+## selectApplierClassNameList
+
+*class-string*
+
+*As of v9.0.*
+
+Classes for additional handling of a select query. An entity type is passed to the constructor in `$entityType` parameter.
+
+## createInputFilterClassNameList
+
+*class-string[]*
+
+*As of v9.4.*
+
+Create input filters.
+
+## updateInputFilterClassNameList
+
+*class-string[]*
+
+*As of v9.4.*
+
+Update input filters.
+
+## outputFilterClassNameList
+
+*class-string[]*
+
+*As of v9.4.*
+
+Output filters.
+
+## beforeReadHookClassNameList
+
+*class-string[]*
+
+*As of v9.4.*
+
+An array of hooks (applied for API calls).
+
+## earlyBeforeCreateHookClassNameList
+
+*class-string[]*
+*class-string[]*
+
+*As of v9.4.*
+
+An array of hooks. Applied for API calls, before validation.
+
+## beforeCreateHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## afterCreateHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## earlyBeforeUpdateHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+*class-string[]*
+
+An array of hooks. Applied for API calls, before validation.
+
+## beforeUpdateHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## afterUpdateHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## beforeDeleteHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## afterDeleteHookClassNameList
+
+*As of v8.2.*
+
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## beforeLinkHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## beforeUnlinkHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## afterLinkHookClassNameList
+
+*As of v9.4.*
+
+*class-string[]*
+
+An array of hooks (applied for API calls).
+
+## afterUnlinkHookClassNameList
+
+*class-string[]*
+
+*As of v9.4.*
+
+An array of hooks (applied for API calls).
diff --git a/docs/development/metadata/app-reg-exp-patterns.md b/docs/development/metadata/app-reg-exp-patterns.md
new file mode 100644
index 000000000..5786e5831
--- /dev/null
+++ b/docs/development/metadata/app-reg-exp-patterns.md
@@ -0,0 +1,28 @@
+# app > regExpPatterns
+
+Path: metadata > app > regExpPatterns.
+
+Predefined regular expression patterns. A name => defs map. Predefined patterns can be used for field validation.
+
+Example:
+
+```json
+{
+ "myPattern": {
+ "pattern": "[0-9A-Za-z_@]+",
+ "isSystem": false
+ }
+}
+```
+
+## pattern
+
+*string*
+
+A pattern.
+
+## isSystem
+
+*boolean*
+
+If true, the pattern won't be available when defining a validation for a field.
diff --git a/docs/development/metadata/app-relationships.md b/docs/development/metadata/app-relationships.md
new file mode 100644
index 000000000..f90b38612
--- /dev/null
+++ b/docs/development/metadata/app-relationships.md
@@ -0,0 +1,25 @@
+# app > relationships
+
+Path: metadata > app > relationships.
+
+*Object.*
+
+Definitions of specific named relationships.
+
+*As of v7.4.*
+
+Example:
+
+```json
+{
+ "attachments": {
+ "converterClassName": "Espo\\Core\\Utils\\Database\\Orm\\LinkConverters\\Attachments"
+ }
+}
+```
+
+## converterClassName
+
+*class-string*
+
+Converts metadata link definitions to ORM definitions.
diff --git a/docs/development/metadata/app-scheduled-jobs.md b/docs/development/metadata/app-scheduled-jobs.md
new file mode 100644
index 000000000..0c9d97690
--- /dev/null
+++ b/docs/development/metadata/app-scheduled-jobs.md
@@ -0,0 +1,49 @@
+# app > scheduledJobs
+
+Path: metadata > app > scheduledJobs.
+
+Scheduled jobs definitions. A name => defs map. Defined scheduled job will be available for the admin when creating a scheduled job.
+
+Example:
+
+```json
+{
+ "MyJobName": {
+ "name": "Record Job Name",
+ "isSystem": false,
+ "scheduling": "* * * * *",
+ "jobClassName": "Espo\\Modules\\MyModule\\MyJob",
+ "preparatorClassName": "Espo\\Modules\\MyModule\\MyJobPreparator"
+ }
+}
+```
+
+## name
+
+*string*
+
+A name to be used for job records. Not important.
+
+## isSystem
+
+*boolean*
+
+Whether the job is system internal.
+
+## scheduling
+
+*string*
+
+A default scheduling in crontab notation.
+
+## jobClassName
+
+*class-string*
+
+A job implementation. Should implement either `Job` or `JobDataLess` interfaces. Usage of the former requires having the preparator.
+
+## preparatorClassName
+
+*class-string*
+
+A preparator. Optional. The preparator is called by the application. It serves for creating job records. E.g. for email checking, the preparator creates jobs for each email account.
diff --git a/docs/development/metadata/app-select.md b/docs/development/metadata/app-select.md
new file mode 100644
index 000000000..32e6949d0
--- /dev/null
+++ b/docs/development/metadata/app-select.md
@@ -0,0 +1,23 @@
+# app > select
+
+Path: metadata > app > select
+
+Select framework definitions.
+
+## boolFilterClassNameMap
+
+*Object.\>*
+
+Bool filters available for all entity types.
+
+## orderItemConverterClassNameMap
+
+*Object.\>*
+
+Order item converters for field types.
+
+## whereItemConverterClassNameMap
+
+*Object.\>*
+
+Where item converters.
diff --git a/docs/development/metadata/app-sms-providers.md b/docs/development/metadata/app-sms-providers.md
new file mode 100644
index 000000000..270998d7d
--- /dev/null
+++ b/docs/development/metadata/app-sms-providers.md
@@ -0,0 +1,21 @@
+# app > smsProviders
+
+Path: metadata > app > smsProviders.
+
+SMS providers. A name => defs map.
+
+Example:
+
+```json
+{
+ "Twilio": {
+ "senderClassName": "Espo\\Modules\\SmsProviders\\Twilio\\TwilioSender"
+ }
+}
+```
+
+## senderClassName
+
+*class-string*
+
+A sender class.
diff --git a/docs/development/metadata/app-template-helpers.md b/docs/development/metadata/app-template-helpers.md
new file mode 100644
index 000000000..a0b395ccf
--- /dev/null
+++ b/docs/development/metadata/app-template-helpers.md
@@ -0,0 +1,15 @@
+# app > templateHelpers
+
+Path: metadata > app > templateHelpers.
+
+[Template helpers](../template-custom-helper.md) for the back-end templating system (used for PDF printing, email templates).
+
+*Object.\>*
+
+Example:
+
+```json
+{
+ "MyHelper": "Espo\\Custom\\TemplateHelpers\\MyHelper"
+}
+```
diff --git a/docs/development/metadata/app-templates.md b/docs/development/metadata/app-templates.md
new file mode 100644
index 000000000..d8ae5cc00
--- /dev/null
+++ b/docs/development/metadata/app-templates.md
@@ -0,0 +1,44 @@
+# app > templates
+
+Path: metadata > app > templates.
+
+Templates (available at Administration > Templates). Usually used for system emails.
+
+Example:
+
+```json
+{
+ "myTemplateName": {
+ "scopeList": [
+ "EntityType1",
+ "EntityType2"
+ ],
+ "module": "MyModule"
+ }
+}
+```
+
+## scopeList
+
+*string[]*
+
+A list of scopes (entity types) for which the template is available.
+
+
+## scope
+
+*string*
+
+A scope (entity types) for which the template is available. Use it if it's needed only for one entity type.
+
+## scopeListConfigParam
+
+*string*
+
+A config parameter defining for which entity types the template is available.
+
+## module
+
+*string*
+
+A module name.
diff --git a/docs/development/metadata/app-web-socket.md b/docs/development/metadata/app-web-socket.md
new file mode 100644
index 000000000..99bcd9f73
--- /dev/null
+++ b/docs/development/metadata/app-web-socket.md
@@ -0,0 +1,61 @@
+# app > webSocket
+
+Path: metadata > app > webSocket.
+
+## categories
+
+*Object*
+
+A category-name => defs map. Define custom WebSocket events here. You can use dots in category names.
+
+Example:
+
+```json
+{
+ "categories": {
+ "myGroupName.myCustomName": {
+ "paramList": ["scope", "id"],
+ "accessCheckCommand": "AclCheck --userId=:userId --scope=:scope --id=:id --action=read"
+ }
+ }
+}
+```
+
+### paramList
+
+*string[]*
+
+Parameters passed within a topic. E.g. the topic name `myGroupName.myCustomName.Account.someId`. This makes a topic name unique for a specific record. For global events, omit this parameter.
+
+### accessCheckCommand
+
+*string*
+
+A console [command](../../administration/commands.md) that will be used to check whether a topic is allowed for a user when they attempting to subscribe. Parameter placeholders starts with the colon `:`. The `userId` parameter contains a user ID. If access checking is not needed, omit this parameter.
+
+## messagers
+
+*Object.*
+
+Provides the ability to implement other messagers rather than the default ZeroMQ. E.g. RabbitMQ.
+
+Example:
+
+```json
+{
+ "messagers": {
+ "ZeroMQ": {
+ "senderClassName": "Espo\\Core\\WebSocket\\ZeroMQSender",
+ "subscriberClassName": "Espo\\Core\\WebSocket\\ZeroMQSubscriber"
+ }
+ }
+}
+```
+
+### senderClassName
+
+*class-string*
+
+### subscriberClassName
+
+*class-string*
diff --git a/docs/development/metadata/authentication-methods.md b/docs/development/metadata/authentication-methods.md
new file mode 100644
index 000000000..8075812b3
--- /dev/null
+++ b/docs/development/metadata/authentication-methods.md
@@ -0,0 +1,82 @@
+# authenticationMethods
+
+Path: authenticationMethods > {MethodName}.
+
+## api
+
+*boolean*
+
+Defines that the method is to be used for pure API request, not from the front-end.
+
+## credentialsHeader
+
+*string*
+
+*As of v7.3.*
+
+A header that is supposed to contain credentials. Actual only for API methods.
+
+## login
+
+*As of v7.3.*
+
+A framework providing the ability to call custom code on *Sign-In* button click on the login page.
+
+```json
+{
+ "login": {
+ "handler": "my-module:handlers/login",
+ "fallback": true,
+ "data": {
+ "someKey": "someValue"
+ }
+ }
+}
+```
+
+Parameters:
+
+* *handler* – a front-end class (should extend the abstract class `handlers/login`).
+* *fallback* – defines that a regular username/password login method is also available on the login page.
+* *fallbackConfigParam* – a config parameter name to be used to check whether fallback login is allowed.
+* *portal* – whether the handler will be available for portals, (bool).
+* *portalConfigParam* – a config parameter name to be used to check whether the handler will be available for portals.
+* *data* – arbitrary data to be passed to the handler. Can be actual as application metadata is not yet available on the login page.
+
+The handler class should have a method *process* that returns a promise that resolves with HTTP headers. These headers will be sent to the back-end to the `App/user` endpoint.
+
+The label for the Sign-In button can be defined in the language at `signInLabels` > {MethodName}.
+
+Compatible with 2FA.
+
+On the login page only global config parameters are available. When implementing a custom login, consider having some global config parameters to access in the handler.
+
+## portalDefault
+
+*boolean*
+
+*As of v7.4.*
+
+If true, the method will be applied for portals when the method is selected as the default in the settings and the portal does not have a specific authentication provider.
+
+## settings
+
+Defines config parameters and a form on the admin UI. See `application/Espo\Resources/metadata/authenticationMethods/Oidc.json` for an example.
+
+### isAvailable
+
+*boolean*
+
+Whether the method is available in the settings.
+
+## provider
+
+*As of v7.4.*
+
+Parameters for the Authentication Provider entity. Same as in the *settings*. If omitted, then a corresponding parameter from the *settings* is used.
+
+### isAvailable
+
+*boolean*
+
+Whether is available in the Authentication Provider entity.
diff --git a/docs/development/metadata/client-defs.md b/docs/development/metadata/client-defs.md
index fe7707d83..d9b8bdc33 100644
--- a/docs/development/metadata/client-defs.md
+++ b/docs/development/metadata/client-defs.md
@@ -1,76 +1,107 @@
-# Client defenitions
+# clientDefs
-Path: `metadata/clientDefs/{ScopeName}.json`
-
-Can be one of:
-```
- 1) CUSTOM_PATH - custom/Espo/Custom/Resources/metadata/clientDefs/{ScopeName}.json;
- 2) MODULE_PATH - application/Espo/Modules/{ModuleName}/Resources/metadata/clientDefs/{ScopeName}.json;
- 3) BASE_PATH - application/Espo/Resources/metadata/clientDefs/{ScopeName}.json
-```
-
-Parameters used by front-end.
+Path: metadata > clientDefs > {Scope}
+Contains parameters used by the front-end.
## controller
-Defines a client controller class.
+*string*
+Defines a client controller class.
## collection
+*string*
+
Defines a client record collection class. Optional.
-By default `'collection'`. Path `client/src/collection.js`.
+The default value: `'collection'`. Corresponds to the path `client/src/collection.js`.
+
+## model
+
+*string*
+
+Defines a client record model class. Optional.
## acl
-Defines client a scope acl class. Optional.
+*string*
-By default `'acl'`. Path `client/src/acl.js`.
+Defines a client acl class. Optional.
+The default value: `'acl'`. Path `client/src/acl.js`.
## aclPortal
-Defines client scope acl for portals. Optional.
+*string*
+
+Defines a client acl class for portals. Optional.
-By default `'acl-portal'`. Path `client/src/acl-portal.js`.
+The default value: `'acl-portal'`. Path `client/src/acl-portal.js`.
+## modelDefaultsPreparator
+
+*string*
+
+*As of v8.4.*
+
+Default attributes preparator for a model when creating a new record. Should extend `handlers/model/defaults-preparator`.
## createDisabled
-Allows to disable to create entity with user interface.
+*boolean*
+Disables the ability to create a record from the user interface (from the list view).
## searchPanelDisabled
-Allows to hide a search panel on the list view.
+*boolean*
+
+Hides the search panel on the list view.
+
+## searchPanelInPortalDisabled
+
+*boolean*
+
+Hides the search panel on the list view in portals.
+
+## textFilterDisabled
+
+*boolean*
+
+Disables text search.
+
+## forceListViewSettings
+*boolean*
+
+*As of v9.2.0.*
+
+Force list view settings for non-object entity types.
## views
-list, detail, edit view classes
+Custom view classes for list, detail, edit.
Example:
+
```
{
"list": "custom:views/test/list",
"detail": "custom:views/test/detail"
}
-
```
-
## recordViews
-Record view classes. list, detail, edit, detailSmall, editSmall, kanban.
+Custom record view classes. For list, detail, edit, detailQuick, editQuick, kanban, listRelated.
Example:
```
{
"list": "custom:views/test/record/list"
}
-
```
## modalViews
@@ -85,48 +116,727 @@ Example:
}
```
+## listViewModeList
+
+*string[]*
+
+A list view mode list. E.g. *list*, *kanban*.
+
+## viewModeIconClassMap
+
+*object.*
+
+*As of v8.3.*
+
+View mode icon classes. mode => class map.
+
+## saveErrorHandlers
+
+Save error handlers. See [here](../frontend/save-error-handlers.md).
+
+## viewSetupHandlers
+
+View setup handlers. See [here](https://docs.espocrm.com/development/frontend/view-setup-handlers/).
+
+## inlineEditDisabled
+
+*boolean*
+
+Disable inline edit.
+
+## exportDisabled
+
+*boolean*
+
+Disable the *export* mass-action.
+
+## massUpdateDisabled
+
+*boolean*
+
+Disable the *mass-update* mass action.
+
+## massRemoveDisabled
+
+*boolean*
+
+*As of v7.4.*
+
+Disable the *remove* mass action.
+
+## massFollowDisabled
+
+*boolean*
+
+Disable the *follow* mass-action.
+
+## convertCurrencyDisabled
+
+*boolean*
+
+Disable the *convert-currency* mass-action and action.
+
+## mergeDisabled
+
+*boolean*
+
+Disable the record merge functionality.
+
## filterList
-Contains a list of primary (preset) filters.
+A list of primary filters.
+
+Example:
+
+```json
+{
+ "filterList": [
+ {
+ "name": "planned"
+ },
+ {
+ "name": "held",
+ "style": "success"
+ },
+ {
+ "name": "someFilter",
+ "accessDataList": []
+ },
+ {
+ "name": "notAvailableOnListViewFilter",
+ "aux": true
+ }
+ ]
+}
+```
## boolFilterList
+A list of bool filters.
+
+Example:
+
+```json
+{
+ "boolFilterList": ["onlyMy"]
+}
+```
+
+Example:
+
+```json
+{
+ "boolFilterList": [
+ {
+ "name": "onlyMy",
+ "accessDataList": []
+ }
+ ]
+}
+```
+
## defaultFilterData
+A default filter data.
+
## selectDefaultFilters
-Used as default set filter on the select modal
-Object 'filter' => 'active'
-
-## formDependency
+A default filter on the select-records modal.
+
+```json
+{
+ "selectDefaultFilters": {
+ "filter": "myPrimaryFilter"
+ }
+}
+```
-Deprecated
+## rowActionList
+*As of v8.1.*
+
+Row actions for the main list view.
+
+Example:
+
+```json
+{
+ "rowActionList": [
+ "moveToTop",
+ "moveUp",
+ "moveDown",
+ "moveToBottom"
+ ]
+}
+```
+
+Use `"__APPEND__"` for extending.
+
+## rowActionDefs
+
+*As of v8.1.*
+
+Row action definitions.
+
+Example:
+
+```json
+{
+ "rowActionDefs": {
+ "moveToTop": {
+ "label": "Move to Top",
+ "handler": "crm:handlers/knowledge-base-article/move",
+ "acl": "edit"
+ }
+}
+```
+
+### handler
+
+*string*
+
+A handler. Should extend handlers/row-action.
+
+### label
+
+*string*
+
+A translatable label.
+
+### labelTranslation
+
+*string*
+
+A label translation path.
+
+### acl
+
+*"edit"|"delete"*
+
+Required access.
+
+### groupIndex
+
+*integer*
+
+A group index. Starts from 0. As of v8.3.0.
+
+### nameAttribute
+
+*string*
+
+*As of v9.1.*
+
+An entity attribute to be used to display the record name on views.
+
## menu
+Top-right menu for views (list, detail, edit). Available types: *buttons*, *dropdown*.
-## relationshipPanels
+Example:
+
+```json
+{
+ "menu": {
+ "detail": {
+ "buttons": [
+ {
+ "labelTranslation": "Campaign.links.trackingUrls",
+ "link": "#CampaignTrackingUrl",
+ "acl": "read",
+ "aclScope": "CampaignTrackingUrl"
+ }
+ ],
+ "dropdown": [
+ {
+ "label": "Some Action",
+ "acl": "edit",
+ "aclScope": "SomeScope",
+ "action": "someAction"
+ }
+ ]
+ }
+ }
+}
+```
+See [more](../custom-buttons.md).
## sidePanels
+Definitions of side-panels for views (detail, edit, detailSmall, editSmall). Defined panels will be available in the layout manager.
+
+Example:
+
+```json
+{
+ "sidePanels": {
+ "detail": [
+ {
+ "name": "attendees",
+ "label": "Attendees",
+ "view": "crm:views/meeting/record/panels/attendees",
+ "options": {
+ "fieldList": [
+ "users",
+ "contacts",
+ "leads"
+ ]
+ },
+ "isForm": true,
+ "notRefreshable": true
+ }
+ ]
+ }
+}
+```
+
+### isForm
+
+*boolean*
+
+Needed for a proper UI styling when the panel contains a form.
+
+### notRefreshable
+
+*boolean*
+
+Not refreshable (when clicking on the header).
+
+### options
+
+*object*
+
+Options to pass to the panel view.
+
+### accessDataList
+
+Access control defs.
## bottomPanels
+Definitions of bottom-panels for views. The same as sidePanels.
+
+## relationshipPanels
+
+Parameters to be applied for specific relationship panels. Some parameters are also applied for link, link-multiple fields, e.g. *selectPrimaryFilterName*, *selectBoolFilterList*, *selectHandler*.
+
+Example:
+
+```json
+{
+ "relationshipPanels": {
+ "linkName": {
+ "view": "my-module:views/panels/panel-view",
+ "recordListView": "my-module:views/record/list",
+ "rowActionsView": "my-module:views/record/row-actions/view",
+ "label": "Panel Label",
+ "readOnly": false,
+ "selectDisabled": false,
+ "createDisabled": false,
+ "viewDisabled": false,
+ "unlinkDisabled": false,
+ "editDisabled": false,
+ "removeDisabled": false,
+ "orderBy": "someField",
+ "orderDirection": "asc",
+ "mandatoryAttributeList": ["status"],
+ "createRequiredAccess": "read",
+ "selectRequiredAccess": "edit",
+ "selectPrimaryFilterName": "filterName",
+ "selectBoolFilterList": ["onlyMy"],
+ "filterList": ["all", "filterName"],
+ "layout": "listLayoutName",
+ "selectMandatoryAttributeList": ["accountId", "accountName"],
+ "selectOrderBy": "createdAt",
+ "selectOrderDirection": "asc"
+ }
+ }
+}
+```
+
+### layout
+
+A layout name or a layout defined as an array.
+
+### createDisabled
+
+*boolean*
+
+Disable the ability to create related records.
+
+### selectDisabled
+
+*boolean*
+
+Disable the ability to select related records.
+
+### viewDisabled
+
+*boolean*
+
+Disable the ability to view related records in a modal.
+
+### unlinkDisabled
+
+*boolean*
+
+Disable the ability to unlink related records.
+
+### editDisabled
+
+*boolean*
+
+*As of v8.1.*
+
+Hide the edit action.
+
+### removeDisabled
+
+*boolean*
+
+*As of v8.1.*
+
+Hide the remove action.
+
+### label
+
+*string*
+
+A custom translatable label.
+
+### createRequiredAccess
+
+*string*
+
+Access (to a current entity type) required for creating related records.
+
+### selectRequiredAccess
+
+*string*
+
+Access (to a current entity type) required for selecting related records.
+
+### selectPrimaryFilterName
+
+*string*
+
+A primary filter applied when selecting records.
+
+### selectBoolFilterList
+
+*string[]*
+
+Bool filters applied when selecting records.
+
+### primaryFilter
+
+*string*
+
+*As of v8.1.*
+
+A default primary filter.
+
+### filterList
+
+*string[]*
+
+Filters available in the dropdown.
+
+### orderBy
+
+*string*
+
+An order-by field.
+
+### orderDirection
+
+*string*
+
+`"asc"` or `"desc"`.
+
+### mandatoryAttributeList
+
+*string[]*
+
+*As of v9.0.*
+
+Mandatory attributes to be selected in the list.
+
+### selectHandler
+
+*string*
+
+A select handler for providing filters when selecting related records. Should have a method *getFilters* returning a promise.
+
+Optionally, extend from `handlers/select-related`.
+
+### createHandler
+
+*string*
+
+A create handler. Provides attributes when creating a new related record. Should have a method *getAttributes* returning a promise.
+
+Optionally, extend from `handlers/create-related`.
+
+### selectFieldHandler
+
+*string*
+
+*As of v8.0.*
+
+A handler called when change a link field. Only for belongs-to and has-one relations. Should have *getAttributes* and *getClearAttributes* methods.
+
+### selectMandatoryAttributeList
+
+*string[]*
+
+*As of v8.0.*
+
+Attributes to be selected when selecting records.
+
+### selectLayout
+
+*string*
+
+*As of v8.0.3*
+
+A list layout name for the select dialog.
+
+### selectOrderBy
+
+*string*
+
+*As of v8.2.*
+
+A field to order by when selecting records.
+
+### selectOrderDirection
+
+*"asc"|"desc"*
+
+*As of v8.2.*
+
+An direction to order by when selecting records.
+
+### rowActionList
+
+*string[]*
+
+*As of v8.1.*
+
+Row actions.
+
+### syncWithModel
+
+*boolean*
+
+*As of v8.1.*
+
+Re-fetch records when the parent model is saved or refreshed by WebSocket.
+
+### syncBackWithModel
+
+*boolean*
+
+*As of v9.1.6.*
+
+Re-fetch the parent model when the relationship is updated. Ignored if WebSocked is enabled.
+
+### massSelect
+
+*bool*
+
+Enables mass select.
+
+### createAttributeMap
+
+*Object.*
+
+Attributes to carry over to a related record when creating. Mapping Parent => Related.
+
+### buttonList
+
+*Record[]*
+
+*As of v8.4.*
+
+Header buttons.
+
+Parameters:
+
+* name
+* label
+* handler
+* actionFunction
+* acl
+
+### actionList
+
+*Record[]*
+
+*As of v8.4.*
+
+Header dropdown items.
+
+Parameters:
+
+* name
+* label
+* handler
+* actionFunction
+* acl
+
+### viewModalView
+
+*string*
+
+A modal view for viewing relationships in a modal dialog.
+
+### allResultDisabled
+
+*boolean*
+
+*As of v9.2.*
+
+Disable the ability to select all results. Important for non-standard relationship panels.
## additionalLayouts
+
+Additional layouts for a scope.
+
+```json
+{
+ "additionalLayouts": {
+ "detailConvert": {
+ "type": "detail"
+ },
+ "listForAccount": {
+ "type": "listSmall"
+ },
+ "listForContact": {
+ "type": "listSmall"
+ }
+ }
+}
+```
-
## massActionList
+*string[]*
+
+Mass actions.
## checkAllResultMassActionList
+*string[]*
+
+Mass actions available when selecting all results.
## massActionDefs
+*Object.*
+
+Definitions for mass actions. See [more](../custom-buttons.md#mass-action-in-list-view).
+
+### handler
+
+*string*
+
+A handler class for the mass action.
+
+### initFunction
+
+*string*
+
+An init function of the handler.
+
+### configCheck
+
+*?string*
+
+A config path (separated by the `.`) to check whether the action is enabled. The `!` prefix reverts.
+
+### aclScope
+
+*?string*
+
+A scope access to which is required for the action.
+
+### acl
+
+*?string*
+
+An acl action access to which is required for the action.
+
+## detailActionList
+
+*Object[]*
+
+Detail view actions (available from the dropdown next to the *Edit* button).
+
+### name
+
+*string*
+
+An action name.
+
+### label
+
+A translatable label.
+
+### handler
+
+*string*
+
+A handler class for the action.
+
+### initFunction
+
+*string*
+
+An init function of the handler.
+
+### checkVisibilityFunction
+
+*?string*
+
+The handler function that checks whether the action is available. Should return a boolean value. Called on model sync.
+
+### configCheck
+
+*?string*
+
+A config path (separated by the `.`) to check whether the action is enabled. The `!` prefix reverts.
+
+### aclScope
+
+*?string*
+
+A scope access to which is required for the action.
+
+### acl
+
+*?string*
+
+An acl action access to which is required for the action.
+
+### groupIndex
+
+*number*
+
+A group index. 0 – is the first group. Groups are separated by a divider. As of v8.3.0.
+
+## modalDetailActionList
+
+*Object[]*
+
+Modal detail view actions. Parameters are the same as for *detailActionList*.
+
## iconClass
+A scope icon class.
+
Example: `"fas fa-chess-king"`
## color
@@ -135,4 +845,49 @@ Scope color in HEX.
## kanbanViewMode
-The scope has kanban view mode on the list view
+*boolean*
+
+Whether the scope has the kanban view mode on the list view.
+
+## allowInternalNotes
+
+*boolean*
+
+If true, it will be possible to post internal posts in the stream. Internal posts are not visible in portals.
+
+## isExpandedByDefault
+
+*boolean*
+
+Actual for category scopes (e.g. DocumentFolder). If true, then by default it will be in expanded mode.
+
+## dynamicLogic
+
+[Dynamic logic](../../administration/dynamic-logic.md) definitions making a form dynamic.
+
+```json
+{
+ "dynamicLogic": {
+ "fields": {
+ "fieldName": {
+ "visible": {
+ "conditionGroup": []
+ },
+ "required": {
+ "conditionGroup": []
+ },
+ "readOnly": {
+ "conditionGroup": []
+ }
+ }
+ },
+ "panels": {
+ "panelName": {
+ "visible": {
+ "conditionGroup": []
+ }
+ }
+ }
+ }
+}
+```
diff --git a/docs/development/metadata/dashlets.md b/docs/development/metadata/dashlets.md
new file mode 100644
index 000000000..f5d1f3ff4
--- /dev/null
+++ b/docs/development/metadata/dashlets.md
@@ -0,0 +1,94 @@
+# dashlets
+
+Path: metadata > dashlets > {DashletName}.
+
+Defines a dashlet.
+
+## view
+
+*string*
+
+A front-end view for a dashlet.
+
+## aclScope
+
+*string*
+
+A scope access to which is required to have access to the dashlet.
+
+## accessDataList
+
+*module:utils~AccessDefs[]*
+
+Access data list defining access to the dashlet for a user in the frontend (additionally to *aclScope*).
+
+```
+/**
+ * @typedef {Object} module:utils~AccessDefs
+ *
+ * @property {'create'|'read'|'edit'|'stream'|'delete'|null} action An ACL action to check.
+ * @property {string|null} [scope] A scope to check.
+ * @property {string[]} [portalIdList] A portal ID list. To check whether a user in one of portals.
+ * @property {string[]} [teamIdList] A team ID list. To check whether a user in one of teams.
+ * @property {boolean} [isPortalOnly=false] Allow for portal users only.
+ * @property {boolean} [inPortalDisabled=false] Disable for portal users.
+ * @property {boolean} [isAdminOnly=false] Allow for admin users only.
+ */
+```
+
+Example:
+
+```json
+{
+ "accessDataList": [
+ {
+ "inPortalDisabled": true
+ }
+ ]
+}
+```
+
+## options
+
+*Object*
+
+Dashlet options definitions.
+
+### view
+
+An options view. Can be omitted.
+
+### fields
+
+*Object*
+
+Definitions of dashlet options fields. The format is the same as in entityDefs > {EntityType} > fields.
+
+### defaults
+
+*Object*
+
+Default options values.
+
+### layout
+
+An options layout.
+
+Example:
+
+```json
+{
+ "options": {
+ "layout": [
+ {
+ "rows": [
+ [
+ {"name": "title"},
+ false
+ ]
+ ]
+ }
+ ]
+ }
+}
+```
diff --git a/docs/development/metadata/entity-acl.md b/docs/development/metadata/entity-acl.md
new file mode 100644
index 000000000..6a5c2d943
--- /dev/null
+++ b/docs/development/metadata/entity-acl.md
@@ -0,0 +1,33 @@
+# entityAcl
+
+Restrictions for fields and links can be defined here.
+
+Path: metadata > entityAcl > {EntityType}.
+
+Example:
+
+```json
+{
+ "fields": {
+ "someFieldName": {
+ "readOnly": true
+ },
+ "anotherFieldName": {
+ "forbidden": true
+ }
+ },
+ "links": {
+ "someLinkName": {
+ "nonAdminReadOnly": true
+ }
+ }
+}
+```
+
+Available params (all are booleans):
+
+* forbidden – totally forbidden;
+* internal – reading forbidden, writing allowed;
+* onlyAdmin – forbidden for non admin users;
+* readOnly – read-only for all users;
+* nonAdminReadOnly – read-only for non-admin users.
diff --git a/docs/development/metadata/entity-defs.md b/docs/development/metadata/entity-defs.md
new file mode 100644
index 000000000..520664332
--- /dev/null
+++ b/docs/development/metadata/entity-defs.md
@@ -0,0 +1,867 @@
+# entityDefs
+
+Path: metadata > entityDefs > {EntityType}.
+
+Contains entity definitions, particularly fields, links and indexes.
+
+```json
+{
+
+ "fields": {},
+ "links": {},
+ "indexes": {},
+ "collection": {}
+}
+```
+
+## fields
+
+A field-name => parameters map.
+
+
+```json
+
+{
+ "fields": {
+ "myField": {
+ "type": "varchar",
+ "someParam": "someValue"
+ }
+ }
+}
+```
+
+Here are defined: common parameters as well as parameters specific for a field type (defined in metadata > fields > {fieldType} > params).
+
+Common parameters are listed below.
+
+### type
+
+*string*
+
+A field type.
+
+### notStorable
+
+*boolean*
+
+The field will be marked as not-storable, a DB column won't be created.
+
+### orderDisabled
+
+*boolean*
+
+*As of v8.3.*
+
+Disables the ability to sort by the field.
+
+### readOnly
+
+*boolean*
+
+Read-only fields are stripped from a payload received from the front-end. Fields are not editable.
+
+
+### view
+
+*string*
+
+A custom field view. If not specified, then a value from metadata > fields > {fieldType} > view is used.
+
+### index
+
+*boolean*
+
+To create a DB index for the field.
+
+### dbType
+
+*string*
+
+Overrides the type of the DB column.
+
+### disabled
+
+*boolean*
+
+Disables the field.
+
+### utility
+
+*As of v8.0.*
+
+*boolean*
+
+The field will be hidden from the user on the UI whenever possible.
+
+### tooltip
+
+*boolean|string*
+
+Enable a tooltip for the field. A tooltip text is taken from the language by: {EntityType} > tooltips > {fieldName}.
+
+If defined as a string, then text will be taken from the language by a path {EntityType} > tooltips > {value}.
+
+If defined as a string containing a dot character, then parsed with {EntityType}.{key} format, a text will be taken by a path {EntityType} > tooltips > {key} (as of v8.0).
+
+### validatorClassName
+
+*class-string*
+
+A field validator. Legacy, consider using *validatorClassNameMap* or *validatorClassNameList*.
+
+### validatorClassNameMap
+
+*Object.*
+
+*As of v7.4.*
+
+Validators defined as validation-type => class-name map. Classes should implement `Espo\Core\FieldValidation\Validator` interface. If not defined for a type, metadata > fields > {fieldType} > validatorClassNameMap > {type} is used.
+
+Example:
+
+```json
+{
+ "validatorClassNameMap": {
+ "required": "Espo\\Modules\\MyModule\\Classes\\FieldValidators\\MyField\\RequiredValidator"
+ }
+}
+```
+
+See more about [field validation](fields.md#validationlist).
+
+### validatorClassNameList
+
+*class-string[]*
+
+A list of additional validators. Should implement `Espo\Core\FieldValidation\Validator` interface.
+
+### forceValidation
+
+*boolean*
+
+*As of v8.2.*
+
+Always to perform validation, regardless whether field values are sent.
+
+### validationList[]
+
+*string*
+
+A custom validation list for the field. Use this parameter to re-define validations applied for a specific field. By default, [validations](fields.md#validationlist) for a field type are applied.
+
+### mandatoryValidationList
+
+*string[]*
+
+A custom mandatory validation list for the field. Use this parameter to re-define mandatory validations applied for a specific field. By default, [mandatory validations](fields.md#mandatoryvalidationlist) for a field type are applied.
+
+### suppressValidationList
+
+*string[]*
+
+*As of v8.0.*
+
+A validation list to be bypassed for the field.
+
+### sanitizerClassNameList
+
+*class-string[]*
+
+*As of v8.1.*
+
+A list of input sanitizers. Should implement `Espo\Core\FieldSanitize\Sanitizer` interface.
+
+### sanitizerSuppressClassNameList
+
+*class-string[]*
+
+*As of v8.3.*
+
+A list of input sanitizers to be by-passed.
+
+### customizationDisabled
+
+*boolean*
+
+Disables the ability to customize the field in the Entity Manager tool.
+
+### dynamicLogicDisabled
+
+*boolean*
+
+Dynamic logic cannot be customized.
+
+### fieldManagerParamList
+
+*string[]*
+
+Parameters available in the Entity Manager tool when editing the field. Specify an empty array to disable all parameters.
+
+### fieldManagerAdditionalParamList
+
+*object[]*
+
+Additional field parameters available in the Entity Manager.
+
+### layoutAvailabilityList
+
+*string[]*
+
+A list of layout types available for the field. Specify an empty array to disable in all layouts. If not specified, then no limitation is applied.
+
+Example:
+
+```json
+{
+ "layoutAvailabilityList": [
+ "list",
+ "detail"
+ ]
+}
+```
+
+### layoutIgnoreList
+
+*string[]*
+
+*As of v8.2.*
+
+A list of layout types not available for the field.
+
+### textFilterDisabled
+
+*boolean*
+
+To disable the ability to add the field to text filters (in the Entity Manager tool).
+
+### directAccessDisabled
+
+*boolean*
+
+Indicates that the field value is not accessed or written directly but through some additional logic. The field won't be available in PDF Templates, Email Templates and some other tools.
+
+### directUpdateDisabled
+
+*boolean*
+
+Indicates that updating the field directly is not possible. The parameter is not needed if *directAccessDisabled* is true.
+
+### directUpdateEnabled
+
+*boolean*
+
+*As of v9.3.*
+
+Indicates that updating the field directly is possible. To be used if directAccessDisabled is true to indicate that update is possible.
+
+### filtersEnabled
+
+*boolean*
+
+*As of v9.2.*
+
+Indicates that the field can be used in filters regardless of directAccessDisabled being set to true. To be used only with directAccessDisabled.
+
+### listColumnEnabled
+
+*boolean*
+
+Indicated that the field can be used in list columns regardless of directAccessDisabled being set to true.
+
+### importDisabled
+
+*boolean*
+
+To disable the ability to import the field.
+
+### importEnabled
+
+*boolean*
+
+*As of v9.3.*
+
+Indicates that import for the field is allowed even if directAccessDisabled or directUpdateDisabled are true.
+
+### massUpdateDisabled
+
+*boolean*
+
+*As of v8.4.*
+
+To mass-update for the field.
+
+### exportDisabled
+
+*boolean*
+
+To disable the ability to export the field.
+
+### apiSpecDisabled
+
+*boolean*
+
+*As of v9.3.*
+
+Do not print the field in the OpenAPI spec.
+
+### isPersonalData
+
+*boolean*
+
+Whether the field may contain personal data.
+
+### valueFactoryClassName
+
+*class-string*
+
+A factory for [value objects](../orm-value-objects.md). For field types it's defined at metadata > fields. Here you can define a factory for a specific field.
+
+### attributeExtractorClassName
+
+*class-string*
+
+An extractor for [value objects](../orm-value-objects.md). For field types it's defined at metadata > fields. Here you can define an extractor for a specific field.
+
+### duplicatorClassName
+
+*class-string*
+
+Duplicates attributes of a field. Some fields can require some processing when an entity is being duplicated.
+
+### duplicateIgnore
+
+*boolean*
+
+Do not carry over a field value when duplicating an entity.
+
+### optimisticConcurrencyControlIgnore
+
+*boolean*
+
+*As of v9.1.*
+
+Ignore optimistic concurrency control.
+
+### additionalAttributeList
+
+*string[]*
+
+Additional attributes for a field. Attribute name will be derived by concatenating the specified name with the field name.
+
+### fullNameAdditionalAttributeList
+
+*string[]*
+
+Additional attributes for a field. As of v9.2.
+
+### dependeeAttributeList
+
+*string[]*
+
+Dependee attributes.
+
+### loaderClassName
+
+*class-string*
+
+*As of v9.1.*
+
+Loads the field value. Can be used to load non-storable fields (not stored in the entity table).
+
+Within an API request (Record service), processed after *readLoaderClassNameList*.
+
+### select
+
+*Object*
+
+A custom [complex expression](../../user-guide/complex-expressions.md) to be used for the field when reading from DB. It's possible to define *leftJoins* and *joins* that are needed to be applied when the field is being selected.
+
+Example:
+
+```json
+{
+ "fields": {
+ "myField": {
+ "type": "float",
+ "readOnly": true,
+ "notStorable": true,
+ "select": {
+ "select": "DIV:(MUL:(amount, probability, someTableAlias.rate), 100)",
+ "leftJoins": [
+ [
+ "SomeTable",
+ "someTableAlias",
+ {"someTableAlias.id:": "amountCurrency"}
+ ]
+ ]
+ }
+ }
+ }
+}
+```
+
+Parameters:
+
+* select – *string* – select expressions;
+* leftJoins – *Array[]* – left joins to apply;
+* joins – *Array[]* – joins to apply;
+
+### order
+
+*Object*
+
+Custom [complex expressions](../../user-guide/complex-expressions.md) to be used when ordering by the field. It's possible to define *leftJoins* and *joins* that are needed to be applied.
+
+Example:
+
+```json
+{
+ "fields": {
+ "myField": {
+ "type": "float",
+ "readOnly": true,
+ "notStorable": true,
+ "order": {
+ "order": [
+ ["DIV:(MUL:(amount, probability, someTableAlias.rate), 100)", "{direction}"]
+ ],
+ "leftJoins": [
+ [
+ "SomeTable",
+ "someTableAlias",
+ {"someTableAlias.id:": "amountCurrency"}
+ ]
+ ]
+ }
+ }
+ }
+}
+```
+
+Parameters:
+
+* order – *Array[]* – order expressions;
+* leftJoins – *Array[]* – left joins to apply;
+* joins – *Array[]* – joins to apply;
+* additionalSelect – *string[]* – additional columns to be selected when order by the field is applied.
+
+### where
+
+*Object*
+
+Custom where clause to be used when the field is met in a provided where-clause. It's possible to define *leftJoins* and *joins* that are needed to be applied. Every comparison operation that you need to support should have its own definitions.
+
+Supported comparison keys:
+
+* `=`
+* `<>`
+* `<`
+* `>`
+* `<=`
+* `>=`
+* `IS NULL`
+* `IS NOT NULL`
+* `LIKE`
+* `NOT LIKE`
+* `IN`
+* `NOT IN`
+* `= TRUE`
+* `= FALSE`
+
+Supported parameters:
+
+* whereClause – where-clause;
+* leftJoins – *Array[]* – left joins to apply;
+* joins – *Array[]* – joins to apply;
+* distinct – bool – apply DISTINCT to the query;
+
+Example:
+
+```json
+{
+ "fields": {
+ "myField": {
+ "type": "float",
+ "readOnly": true,
+ "notStorable": true,
+ "where": {
+ "=": {
+ "whereClause": {
+ "DIV:(MUL:(amount, probability, someTableAlias.rate), 100)=": "{value}"
+ },
+ "leftJoins": [
+ [
+ "SomeTable",
+ "someTableAlias",
+ {"someTableAlias.id:": "amountCurrency"}
+ ]
+ ]
+ },
+ "IS NULL": {
+ "whereClause": {
+ "IS_NULL:(amount)": true
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+### massUpdateActionList
+
+*string[]*
+
+Actions for mass update.
+
+### notLockable
+
+*boolean*
+
+The field is not locked when the record is locked. As of v9.4.
+
+## links
+
+A link-name => parameters map.
+
+Example:
+
+```json
+
+{
+ "links": {
+ "myLink1": {
+ "type": "belongsTo",
+ "entity": "ForeignEntity",
+ "foreign": "foreignLink1"
+ },
+ "myLink2": {
+ "type": "hasMany",
+ "entity": "ForeignEntity",
+ "foreign": "foreignLink2"
+ }
+ }
+}
+```
+
+Parameters are listed below.
+
+### type
+
+*string*
+
+A link type.
+
+Available types:
+
+* belongsTo
+* hasMany
+* hasOne
+* belongsToParent
+* hasChildren
+
+### entity
+
+*string*
+
+A foreign entity type.
+
+### foreign
+
+*string*
+
+A foreign link name.
+
+
+Parameters for specific types are listed below.
+
+### noJoin
+
+*boolean*
+
+*(available for belongsTo, hasOne)*
+
+Prevents joining a foreign table when fetching a record.
+
+### foreignName
+
+*string*
+
+*(available for belongsTo, hasOne)*
+
+A field to be used as a name of a foreign record. Needed when a foreign entity type does not have the field *name*.
+
+### audited
+
+*boolean*
+
+*(available for hasMany)*
+
+Linking and unlinking will be logged in the Stream.
+
+### auditView
+
+*string*
+
+*As of v9.2.3.*
+
+A view used for audit. If not specified, the ordinary view is used.
+
+### readOnly
+
+*boolean*
+
+Read-only links cannot be edited via link and unlink requests. Not possible to relate or unrelate records via the relationship panel. Read-only links can still be edited via the link and link-multiple fields.
+
+### layoutRelationshipsDisabled
+
+*boolean*
+
+*(available for hasMany)*
+
+Makes the link not available in the Bottom Panels layout (in the Layout Manager tool).
+
+### relationName
+
+*string*
+
+*(available for hasMany)*
+
+A relationship name. Defines how a middle table will be named (for a many-to-many relationships).
+
+### additionalColumns
+
+*Object*
+
+*(available for hasMany)*
+
+Additional columns to be created in a middle table (for a many-to-many relationships).
+
+Example:
+
+```json
+{
+ "additionalColumns": {
+ "role": {
+ "type": "varchar",
+ "maxLength": 64
+ },
+ "isPrimary": {
+ "type": "bool",
+ "default": false
+ }
+ }
+}
+```
+
+### conditions
+
+*(available for hasMany)*
+
+Where-conditions (for a many-to-many relationships). If multiple links share the same relationship name (middle table), conditions must be defined for each link.
+
+Example:
+
+```json
+{
+ "links": {
+ "toEmailAddresses": {
+ "type": "hasMany",
+ "entity": "EmailAddress",
+ "relationName": "emailEmailAddress",
+ "conditions": {
+ "addressType": "to"
+ },
+ "additionalColumns": {
+ "addressType": {
+ "type": "varchar",
+ "len": "4"
+ }
+ }
+ },
+ "ccEmailAddresses": {
+ "type": "hasMany",
+ "entity": "EmailAddress",
+ "relationName": "emailEmailAddress",
+ "conditions": {
+ "addressType": "cc"
+ },
+ "additionalColumns": {
+ "addressType": {
+ "type": "varchar",
+ "len": "4"
+ }
+ }
+ }
+ }
+}
+```
+
+### indexes
+
+*(available for hasMany)*
+
+*Object.*
+
+Indexes for a middle table. Definition is the same as for entity indexes.
+
+### notMergeable
+
+*boolean*
+
+*(available for hasMany, hasChildren)*
+
+Disable merging related records when duplicate records are being merged.
+
+### utility
+
+*boolean*
+
+The link will be hidden from the user on the UI whenever possible.
+
+### disabled
+
+*boolean*
+
+Disables the link.
+
+### apiSpecDisabled
+
+*boolean*
+
+*As of v9.3.*
+
+Do not print the link in the OpenAPI spec.
+
+### deferredLoad
+
+*(available for belongsTo and belongsToParent)*
+
+*As of v9.0.0.*
+
+When getting a related entity from an entity, it will be returned without loaded values. Values will be loaded on accessing. For belongsToParent there's a downside that it can return an entity even if it's deleted.
+
+## collection
+
+Collection parameters.
+
+### orderBy
+
+*string*
+
+The default order-by field.
+
+### order
+
+*"asc"|"desc"*
+
+The default order direction.
+
+### textFilterFields
+
+*string[]*
+
+Fields used by the text filter.
+
+### countDisabled
+
+*boolean*
+
+Disable fetching a total records number (on the list view).
+
+### fullTextSearch
+
+*boolean*
+
+Enable full-text search.
+
+### fullTextSearchOrderType
+
+*"original"|"relevance"|"combined"*
+
+How to order result of full-text search.
+
+
+## indexes
+
+Database indexes.
+
+Example:
+
+```json
+{
+
+ "indexes": {
+ "indexName1": {
+ "columns": ["createdById", "dateSent"]
+ },
+ "indexName2": {
+ "columns": ["messageId"],
+ "unique": true
+ }
+ }
+}
+```
+
+### columns
+
+*string[]*
+
+Database columns of the index.
+
+### unique
+
+*boolean*
+
+Whether the index is unique.
+
+## optimisticConcurrencyControl
+
+*boolean*
+
+Enables optimistic concurrency control for the entity type.
+
+## skipRebuild
+
+*boolean*
+
+To skip database table creation for the entity type.
+
+## hooksDisabled
+
+*boolean*
+
+*As of v8.2.*
+
+Disable hooks.
+
+## repositoryClassName
+
+*class-string*
+
+*As of v8.2.*
+
+A repository.
+
+## entityClassName
+
+*class-string*
+
+*As of v8.2.*
+
+An entity. Usually should extend `Espo\Core\ORM\Entity`.
+
+## noDeletedAttribute
+
+*boolean*
+
+Disables soft-deletes.
+
+## deleteId
+
+*boolean*
+
+*As of v8.4.*
+
+Adds an additional *deleteId* field that will be written with an random ID when a record is soft-deleted. Useful when need a unique index. Add *deleteId* column to the index.
diff --git a/docs/development/metadata/fields.md b/docs/development/metadata/fields.md
index 43ed94a1e..d2c3014ee 100644
--- a/docs/development/metadata/fields.md
+++ b/docs/development/metadata/fields.md
@@ -1,138 +1,266 @@
-# Field-type definition
+# fields
-Path: `metadata/fields/{fieldType}.json`
+Path: metadata > fields > {fieldType}.
-### notMergeable
+Definitions for field types.
-_true_ | _false_
+## notMergeable
-If you merge records, is this field type mergeable.
+*boolean*
-### notCreatable
+Whether this field type is mergeable (when merging duplicate records).
-_true_ | _false_
+## notCreatable
-Could be created a field with this type in Entity Manager.
+*boolean*
-### readOnly
+Whether the field of this type can be created in the Entity Manager tool.
-_true_ | _false_
+## readOnly
-Is this field type Read Only (can't be edit).
+*boolean*
+
+Is this field type Read Only (can't be edited).
-### skipOrmDefs
+## skipOrmDefs
-_true_ | _false_
+*boolean*
-Skip convert in ORM.
+Skip converting to defs for the ORM.
-### filter
+## filter
-_true_ | _false_
+*boolean*
-Entity could be filtered by field with this field type.
+Records can be filtered by this field (available as filter on the list view).
-### view
+## view
-By default for displaying a field with this field type the system try to read the view `"views/fields/{field-type}"` (path is `client/src/views/fields/{field-name}.js`). But if want to define own view, you can set this parameter here.
+*string*
-### params
+By default, when displaying a field, the system tries to read the view `"views/fields/{field-type}"` (path is `client/src/views/fields/{field-name}.js`). You can define a custom view with this parameter.
-Array of fields, that described field type parameters. This parameters could be set for each field with this field type in Entity Manager.
+## params
-#### Example
+Array of field parameters. Theses parameters then can be edited for every field of this field type in the Entity Manager tool.
-```
-[
- [
- "name": "required",
- "type": "bool",
- "default": false
- ],
- [
- "name": "translation",
- "type": "varchar",
- "hidden": true
- ],
- [
- "name": "audited",
- "type": "bool"
- ],
- [
- "name": "readOnly",
- "type": "bool"
- ]
-]
+### Example
+```json
+{
+ "params": [
+ [
+ "name": "required",
+ "type": "bool",
+ "default": false
+ ],
+ [
+ "name": "translation",
+ "type": "varchar",
+ "hidden": true
+ ],
+ [
+ "name": "audited",
+ "type": "bool"
+ ],
+ [
+ "name": "readOnly",
+ "type": "bool"
+ ]
+ ]
+}
```
-### fieldDefs
+Parameters are passed to the field view in the `params` option.
+
+## fieldDefs
An object of field type definition. The most of them is used as database column parameter:
-- `type` - _"varchar"_, _"int"_, _"bool"_, _"text"_, _"float"_ etc.;
-- `notNull` - value can't be set as NULL (_true_ | _false_);
-- `unique` - value is unique in the table column (_true_ | _false_);
-- `autoincrement` - value is autoincrement an is calculated with database (_true_ | _false_).
-Also you can set here such definition as:
-- `notStorable` - the column of field with this field type wont be created in the database (_true_ | _false_);
-- `readOnly` - field is not editable (_true_ | _false_);
-- `layoutListDisabled` - field can notbe displayed on the list view (_true_ | _false_).
+- *type* – _"varchar"_, _"int"_, _"bool"_, _"text"_, _"float"_ etc.;
+- *notNull* – value can't be set as NULL (_true_ | _false_);
+- *unique* – value is unique in the table column (_true_ | _false_);
+- *autoincrement* - value is autoincrement an is calculated with database (_true_ | _false_).
-### translatedOptions
+Some other parameters:
-_true_ | _false_
+- *notStorable* – the column of field with this field type wont be created in the database (_true_ | _false_);
+- *readOnly* – field is not editable (_true_ | _false_);
+- *layoutListDisabled* – field can not be displayed on the list view (_true_ | _false_).
-Does field have options, which can be translated.
+## translatedOptions
+*boolean*
-### hookClassName
+Does the field have options that can be translated.
-If field value has to be set before saving, here you need to set a class name of hook.
+## hookClassName
+
+Called after the field is created or edited in the Entity Manager tool.
Available methods:
-- onRead;
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove.
+
+- onRead
+- beforeSave
+- afterSave
+- beforeRemove
+- afterRemove
#### Example
```
-"hookClassName": "\\Espo\\Core\\Utils\\FieldManager\\Hooks\\NumberType"
+"hookClassName": "Espo\\Core\\Utils\\FieldManager\\Hooks\\NumberType"
```
-You can find this class in `application/Espo/Core/Utils/FieldManager/Hooks/NumberType.php` and read the code.
+## fields
-### fields
+Definitions of additional fields that will be created with this field. E.g. for address field, separate fields (street, city, etc.) are created.
-The definition of all additional fields, which contain this field type.
-
-### naming
+## naming
_"suffix"_ | _"prefix"_ ("suffix" is default)
-Naming is used for genefation a full name of additional fields. Field name + field from parameter fields.
+The naming determines how additional fields will be named.
#### Example
-Field name - __billingAddress__
+Field name: *billingAddress*.
+Additional field: *country*.
+The result (with default _suffix_ naming): *billingAddressCountry*.
+
+## actualFields
+
+*string[]*
+
+The list of actual attributes (which contain useful data).
+
+For example, for field type `link` in `actualFields` is `['id']`, in `notActualFields` is `['name']`.
+Means, if you load record with link field, you have values in `{fieldName}Id` and `{fieldName}Name` (suffix naming). But you need set only `{fieldName}Id`, if you want to update this field.
+
+Attributes for field are created by the ORM Converter framework.
+
+## notActualFields
+
+*string[]*
+
+The list of not actual attributes.
+
+## personalData
+
+*boolean*
+
+Where the field may contain personal data.
+
+## textFilter
+
+*boolean*
+
+The field will be available in the list of text filters (in the Entity Manager tool).
+
+## textFilterForeign
+
+*boolean*
+
+The field will be available in the list of text filters as a foreign field.
+
+## linkDefs
+
+*Object*
+
+If defined, a link with the same name as the field name will be created. Defines link parameters.
+
+## fullTextSearch
+
+*boolean*
+
+Full-text search will be available for the field.
+
+## fullTextSearchColumnList
+
+*string[]*
+
+Columns used in full-text search.
+
+## valueFactoryClassName
+
+*class-string*
+
+A factory that creates value-objects for this field. A value-object can be obtained by calling `getValueObject` method on an `Entity`.
+
+## attributeExtractorClassName
+
+*class-string*
+
+A class that extracts values (attribute => value map) from a value-object. Used internally for obtaining values from a value-object and writing them to an entity.
+
+## validationList
+
+*string[]*
+
+Validations applied server-side.
+
+## mandatoryValidationList
+
+*string[]*
+
+Mandatory validations applied server-side. The difference from regular validations is that mandatory are applied always, regardless a corresponding field parameter. E.g. if a field has a parameter *required = false*, then the validation *required* won't be applied unless it's listed as mandatory.
+
+
+## validatorClassNameMap
+
+*Object.\>*
+
+*As of v7.3.*
+
+Validators defined as validation-type => class-name map.
+
+Example:
+
+```json
+{
+ "validatorClassNameMap": {
+ "required": "Espo\\Modules\\MyModule\\Classes\\FieldValidators\\MyField\\RequiredValidator"
+ }
+}
+```
+
+## validatorClassName
+
+A validator class name. The class should contain validation method corresponding to validations listed in *validationList* and *mandatoryValidationList*. This is a legacy, consider using *validatorClassNameMap*. If not defined, then a class `Espo\Classes\FieldValidations\{Type}Type` is used.
+
+## duplicatorClassName
+
+*class-string*
+
+Duplicates attributes of a field. Some fields can require some processing when an entity is being duplicated.
+
+## converterClassName
+
+*class-string*
+
+*As of v7.4.*
+
+Converts field metadata to ORM metadata. Not applied if *fieldDefs* is specified.
+
+## sanitizerClassName
+
+*class-string*
-One of address type field - __country__
+*As of v8.1.*
-The result (with default _suffix_ naming) - __billingAddressCountry__
+An input sanitizer.
+## sanitizerClassNameList
-### actualFields
+*class-string[]*
-The list of actual fields.
+*As of v8.2.*
+Input sanitizers.
-### notActualFields
+## massUpdateActionList
-The list of not actual fields.
+*string[]*
->For example, for field type `link` in `actualFields` is `['id']`, in `notActualFields` is `['name']`.
->Means, if you load record with link field, you have values in `{fieldName}Id` and `{fieldName}Name` (suffix naming). But you need set only `{fieldName}Id`, if you want to update this field
+Actions for mass update.
diff --git a/docs/development/metadata/integrations.md b/docs/development/metadata/integrations.md
new file mode 100644
index 000000000..d62668ca2
--- /dev/null
+++ b/docs/development/metadata/integrations.md
@@ -0,0 +1,73 @@
+# integrations
+
+Path: metadata > integrations > {IntegrationName}.
+
+Integration definitions.
+
+## fields
+
+*Object.*
+
+Field definitions for the integration (to be available at Administration > Integrations).
+
+Example:
+
+```json
+{
+ "fields": {
+ "clientId": {
+ "type": "varchar",
+ "maxLength": 255,
+ "required": true
+ },
+ "clientSecret": {
+ "type": "varchar",
+ "maxLength": 255,
+ "required": true
+ },
+ "tenant": {
+ "type": "enum",
+ "options": ["common", "organizations", "consumers"],
+ "tooltip": "myIntegrationTenant"
+ }
+ },
+}
+```
+
+A label can be also specified with the *labelTranslation* parameter as of v9.2.
+
+## allowUserAccounts
+
+*boolean*
+
+Whether the integration supposes that users have their own accounts (at User > External Accounts).
+
+## userAccountAclScope
+
+*?string*
+
+A scope name, a user should have access to to be able to use the integration.
+
+## view
+
+*string*
+
+A front-end view for the integration page (at Administration > Integrations).
+
+## userView
+
+*string*
+
+A front-end view for the external account page (at User > External Accounts).
+
+## params
+
+*Object*
+
+Define any params needed for the integration.
+
+## externalAccountSecretAttributeList
+
+*string[]*
+
+External account attributes to be hidden from the front-end.
diff --git a/docs/development/metadata/logic-defs.md b/docs/development/metadata/logic-defs.md
new file mode 100644
index 000000000..b6bfefecd
--- /dev/null
+++ b/docs/development/metadata/logic-defs.md
@@ -0,0 +1,69 @@
+# logicDefs
+
+Path: metadata > logicDefs > {Scope}
+
+[Dynamic logic](../../administration/dynamic-logic.md) definitions for an entity type.
+
+*As of v9.1.*
+
+*Before v9.1, it was defined in clientDefs.*
+
+Example:
+
+```json
+{
+ "fields": {
+ "fieldName": {
+ "visible": {
+ "conditionGroup": []
+ },
+ "required": {
+ "conditionGroup": []
+ },
+ "readOnly": {
+ "conditionGroup": []
+ },
+ "readOnly": {
+ "conditionGroup": []
+ },
+ "readOnlySaved": {
+ "conditionGroup": []
+ }
+ "invalid": {
+ "conditionGroup": []
+ }
+ }
+ },
+ "panels": {
+ "panelName": {
+ "visible": {
+ "conditionGroup": []
+ }
+ }
+ },
+ "options": {
+ "fieldName": [
+ {
+ "optionList": [
+ "Value 1",
+ "Value 2"
+ ],
+ "conditionGroup": []
+ },
+ {
+ "optionList": [
+ "Value 3",
+ "Value 4"
+ ],
+ "conditionGroup": []
+ }
+ ]
+ }
+}
+```
+
+## fields
+
+## panels
+
+## options
diff --git a/docs/development/metadata/notification-defs.md b/docs/development/metadata/notification-defs.md
new file mode 100644
index 000000000..3b4d6e016
--- /dev/null
+++ b/docs/development/metadata/notification-defs.md
@@ -0,0 +1,36 @@
+# notificationDefs
+
+Path: metadata > notificationDefs > {EntityType}.
+
+## assignmentNotificatorClassName
+
+*class-string*
+
+An assignment notificator. Should implement `Espo\Core\Notification\AssignmentNotificator` interface. Processes assignment notifications.
+Called after entity is saved. By default, `Espo\Core\Notification\DefaultAssignmentNotificator` is used.
+
+## emailNotificationHandlerClassNameMap
+
+*Object.*
+
+Email notification handlers. Should implement `Espo\Core\Notification\EmailNotificationHandler` interface.
+Handles a notification emails (supposed for adding CC, BCC addresses). Provides sender parameters for notification emails (e.g. setting Reply-To address).
+
+Example:
+
+```json
+{
+ "emailNotificationHandlerClassNameMap": {
+ "notePost": "Espo\\Modules\\Crm\\Classes\\EmailNotificationHandlers\\CaseObj"
+ }
+}
+
+```
+
+## forceAssignmentNotificator
+
+*boolean*
+
+To force processing assignment notifications (upon record save). Otherwise, it may be bypassed in some scenarios (e.g. when the Stream is enabled
+for the entity type).
+
diff --git a/docs/development/metadata/pdf-defs.md b/docs/development/metadata/pdf-defs.md
new file mode 100644
index 000000000..883043af7
--- /dev/null
+++ b/docs/development/metadata/pdf-defs.md
@@ -0,0 +1,25 @@
+# pdfDefs
+
+Path: metadata > pdfDefs > {EntityType}.
+
+## dataLoaderClassNameList
+
+*class-string[]*
+
+List of classes that loads additional data for PDF. Classes should implement the interface `Espo\Tools\Pdf\DataLoader`. Use `__APPEND__` for extending.
+
+## pdfA
+
+*boolean*
+
+*As of v9.2.*
+
+Enables PDF/A.
+
+## attachmentProviderClassNameList
+
+*class-string[]*
+
+*As of v9.2.*
+
+Attachment providers. PDF/A has to be enabled to be able to include files in PDF.
diff --git a/docs/development/metadata/record-defs.md b/docs/development/metadata/record-defs.md
new file mode 100644
index 000000000..e05609247
--- /dev/null
+++ b/docs/development/metadata/record-defs.md
@@ -0,0 +1,279 @@
+# recordDefs
+
+Path: metadata > recordDefs > {EntityType}
+
+## duplicateWhereBuilderClassName
+
+A class for building a where clause for duplicate checking.
+
+Must implement `Espo\Core\Duplicate\WhereBuilder` interface.
+
+## defaultsPopulatorClassName
+
+*class-string*
+
+*As of v8.2.*
+
+Populates default values when creating a record.
+
+Is called after the entity is set with input payload values. Usually, it's reasonable to call the default implementation `Espo\Core\Record\Defaults\DefaultPopulator`.
+
+## readLoaderClassNameList
+
+Array of classes to load additional fields for an entity.
+
+Must implement `Espo\Core\FieldProcessing\Loader` interface.
+
+**Important**: Need to have `"__APPEND__"` item in the beginning of the array when extending.
+
+## listLoaderClassNameList
+
+Array of classes to load additional fields for an entity for the list view.
+
+Must implement `Espo\Core\FieldProcessing\Loader` interface.
+
+**Important**: Need to have `"__APPEND__"` item in the beginning of the array when extending.
+
+## saverClassNameList
+
+Array of classes to save additional fields.
+
+Must implement `Espo\Core\FieldProcessing\Saver` interface.
+
+!!! note
+
+ Savers are applied on the ORM level (in a hook), not on the Record Service level. Technically, they do not belong to the *recordDefs*, but they are kept here for backward compatibility.
+
+## selectApplierClassNameList
+
+Array of classes for additional handling of a select query. Use for joining additional fields. Do not use for access control logic.
+
+Must implement `Espo\Core\Select\Applier\AdditionalApplier` interface.
+
+
+## loadAdditionalFieldsAfterUpdate
+
+*boolean*
+
+*As of v8.0.*
+
+Load additional fields after update. Needed for cases when additional fields need to be re-loaded since they are not actual after update.
+
+## actions
+
+Parameters of actions (applied only for the back-end).
+
+Parameters:
+
+* disabled – disables the action;
+* allowed – allows the action for non-object scopes;
+* implementationClassName – a class name, should implement `Espo\Core\Action\Action`.
+
+## massActions
+
+Parameters of mass actions (applied only for the back-end).
+
+Example:
+
+```json
+{
+ "massActions": {
+ "delete": {
+ "allowed": true
+ }
+ }
+}
+```
+
+Parameters:
+
+* disabled – disables the action;
+* allowed – allows the action for non-object scopes;
+* implementationClassName – a class name, should implement `Espo\Core\MassAction\MassAction`.
+
+## actionsDisabled
+
+*bool*
+
+Disable actions in the back-end.
+
+## massActionsDisabled
+
+*bool*
+
+Disable mass actions in the back-end.
+
+## exportDisabled
+
+*bool*
+
+To disable export regardless ACL.
+
+## actionHistoryDisabled
+
+*bool*
+
+*As of v8.2.*
+
+Disable Action History processing.
+
+## updateDuplicateCheck
+
+*bool*
+
+A boolean parameter. If true, then duplicate checking will be processed while updating a record. By default, it's processed only when creating a new record.
+
+## forceSelectAllAttributes
+
+*bool*
+
+*As of v8.2.*
+
+To select all attributes when calling find.
+
+## mandatoryAttributeList
+
+*string[]*
+
+*As of v8.2.*
+
+Attributes to select when calling find.
+
+## duplicateLinkList
+
+*string[]*
+
+*As of v8.2.*
+
+Links to be copied when duplicating a record. As of v8.2.
+
+## relationships
+
+*As of v7.3.*
+
+Relationship parameters. Key-object pairs, where keys are link names.
+
+Example:
+
+```json
+{
+ "relationships": {
+ "cases": {
+ "linkRequiredAccess": "edit",
+ "linkRequiredForeignAccess": "read",
+ "linkForeignAccessCheckDisabled": false
+ "mandatoryAttributeList": ["number"]
+ }
+ }
+}
+```
+
+Parameters:
+
+* selectAccessControlDisabled – disable access control when listing related records; only access to a parent record will be checked; as of v8.0;
+* linkRequiredAccess – access to a current record that is needed to be able to link and unlink records (`create`, `read`, `edit`, `delete`, `stream`); applied only in the back-end, for the front-end specify clientDefs > {EntityType} > relationshipPanels > {link} > selectRequiredAccess (*edit* by default);
+* linkRequiredForeignAccess – access to a foreign record that is needed to be able to link and unlink (*edit* by default);
+* linkForeignAccessCheckDisabled – disable foreign record access check when linking; as of v7.4;
+* linkCheckDisabled – disable a link-check functionality linking when through link-multiple field; as of v7.4.4;
+* mandatoryAttributeList – *string[]* – mandatory attributes to be selected when find related; as of v8.2;
+* countDisabled – bool – disable total count; as of 8.2;
+* massLink – bool – allows mass linking; as of 8.2;
+* linkOnlyNotLinked – bool – allow linking only if a record is not linked with any; as of 8.3;
+
+## createInputFilterClassNameList
+
+*class-string[]*
+
+*As of v8.2.*
+
+Create input filters.
+
+## updateInputFilterClassNameList
+
+*class-string[]*
+
+*As of v8.2.*
+
+Update input filters.
+
+## outputFilterClassNameList
+
+*class-string[]*
+
+*As of v8.2.*
+
+Output filters.
+
+## beforeReadHookClassNameList
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\ReadHook` interface.
+
+## earlyBeforeCreateHookClassNameList
+
+*As of v9.0.*
+
+An array of hooks. Applied for API calls, before validation. Should implement `Espo\Core\Record\Hook\CreateHook` or `Espo\Core\Record\Hook\SaveHook` interface.
+
+## beforeCreateHookClassNameList
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\CreateHook` interface. As of v8.1, can also implement `Espo\Core\Record\Hook\SaveHook`.
+
+## afterCreateHookClassNameList
+
+*As of v8.2.*
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\CreateHook` or `Espo\Core\Record\Hook\SaveHook`.
+
+## earlyBeforeUpdateHookClassNameList
+
+*As of v9.0.*
+
+An array of hooks. Applied for API calls, before validation. Should implement `Espo\Core\Record\Hook\UpdateHook` or `Espo\Core\Record\Hook\SaveHook` interface.
+
+## beforeUpdateHookClassNameList
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\UpdateHook` interface. As of v8.1, can also implement `Espo\Core\Record\Hook\SaveHook`.
+
+## afterUpdateHookClassNameList
+
+*As of v8.2.*
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\UpdateHook` or `Espo\Core\Record\Hook\SaveHook`.
+
+## beforeDeleteHookClassNameList
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\DeleteHook` interface.
+
+## afterDeleteHookClassNameList
+
+*As of v8.2.*
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\DeleteHook` interface.
+
+## beforeLinkHookClassNameList
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\LinkHook` interface.
+
+## beforeUnlinkHookClassNameList
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\UnlinkHook` interface.
+
+## afterLinkHookClassNameList
+
+*As of v8.2.*
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\LinkHook` interface.
+
+## afterUnlinkHookClassNameList
+
+*As of v8.2.*
+
+An array of hooks (applied for API calls). Should implement the `Espo\Core\Record\Hook\UnlinkHook` interface.
+
+## deletedRestorerClassName
+
+*class-string*
+
+*As of v9.2.*
+
+A deleted record restorer.
diff --git a/docs/development/metadata/scopes.md b/docs/development/metadata/scopes.md
index 4b7d02628..752af2e5d 100644
--- a/docs/development/metadata/scopes.md
+++ b/docs/development/metadata/scopes.md
@@ -1,273 +1,278 @@
-# Scope definition
+# scopes
-Path: `/metadata/scopes/{ScopeName}.json`
+Path: metadata > scopes > {ScopeName}.
-Сontains scope definition. Parameters are optional. Scope can define an entity type.
+Сontains scope definitions.
-## List of options:
+## entity
-### entity
+*boolean*
->_Description_: is an entity, has own table in database;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether the scope represents an entity type.
+## object
-### object
+*boolean*
->_Description_: is an object, is available in ....;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether the entity is a business object. Means that it's not an entity for internal system purpose; an object entity represents some business entity.
+## module
-### module
+*string*
->_Description_: the name of the module, where is this scope defined;
->
->_Type_: string.
+The the name of the module, where this scope is defined. Must be set if the entity type is defined in a module.
+## stream
-### stream
+*boolean*
->_Description_: entity has Stream panel;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether the entity has the stream.
+## importable
-### importable
+*boolean*
->_Description_: could be imported with Import feature;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether the entity is available in the Import tool.
+## layouts
-### layouts
+*boolean*
->_Description_: has layouts, is available in Layout Manager;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether the entity is available in the Layout Manager tool.
+## tab
-### tab
+*boolean*
->_Description_: could be displayed on the tab list;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether the scope is available as a navbar tab.
+## tabPortal
-### type
+*boolean*
->_Description_: type of entity;
->
->_Type_: string;
->
->_Available value_: one of ["Base", "BasePlus", "Person", "Company", "CategoryTree", "Event"];
->
->_Default_: "Base".
+*As of v9.3.*
-### acl
+To allow the navbar tab for the portal even if *aclPortal* is false.
->_Description_: could be set permissions in Role;
->
->_Type_: boolean | string;
->
->_Available value_: true | false | 'boolean';
->
->_Default_: false.
+## tabAclPermission
+*?string*
-### aclActionList
+A permission level required for a user to have the scope available as a navbar tab. Examples: `portal`, `massUpdate`.
->_Description_: list of available actions in Role configuration;
->
->_Type_: array;
->
->_Available value_: array of ['create', 'read', 'edit', 'delete', 'stream'];
->
->_Default_: ['create', 'read', 'edit', 'delete'] if `acl` is `true`.
+## type
+*?string*
-### aclLevelList
+A template type of the entity.
->_Description_: list of available level for actions in Role configuration;
->
->_Type_: array;
->
->_Available value_: array of ['all', 'team', 'own', 'no'];
->
->_Default_: ['all', 'team', 'own', 'no'] if `acl` is `true`.
+Available values: Base, BasePlus, Person, Company, CategoryTree, Event.
+## acl
-### aclActionLevelListMap !!!!
+*boolean|"boolean"*
->_Description_: list of available level for actions in Role configuration;
->
->_Type_: object;
->
->_Available value_: array of ['all', 'team', 'own', 'no'];
->
->_Default_: ['all', 'team', 'own', 'no'] if `acl` is `true`.
+Whether the scope is available in Roles. Available values: true, false, "boolean". Boolean means that it will be available in roles w/o actions.
+
+## aclActionList
+
+*string[]*
+
+A list of available actions in Roles. Available item values: create, read, edit, delete, stream.
+
+## aclLevelList
+
+*string[]*
+
+A list of available levels in Roles. Available item values: all, team, own, no.
+
+## aclActionLevelListMap
+
+Lists of available levels for specific actions in Roles.
+
+Example:
+
+```json
+"aclActionLevelListMap": {
+ "edit": ["own", "no"]
+}
```
- array (
- 'edit' =>
- array (
- 0 => 'own',
- 1 => 'no',
- ),
- ),
-```
+
+## aclPortal
+
+*boolean|"boolean"*
+
+Whether the scope is available in Portal Roles. Available values: true, false, "boolean". Boolean means that it will be available in roles w/o actions.
+
+## aclPortalActionList
+
+*string[]*
+
+A list of available actions in Portal Roles. Available item values: create, read, edit, delete, stream.
-### aclPortal
+## aclPortalLevelList
->_Description_: could be set permissions in Portal Role;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+*string[]*
+A list of available levels in Portal Roles. Available item values: all, account, contact, own, no.
-### aclPortalLevelList
+## aclPortalActionLevelListMap
->_Description_: list of available level for actions in Portal Role configuration;
->
->_Type_: array;
->
->_Available value_: array of ['all', 'account', 'contact', 'own', 'no'];
->
->_Default_: ['all', 'account', 'contact', 'own', 'no'] if `aclPortal` is `true`.
+Lists of available levels for specific actions in Portal Roles.
+Example:
- ### statusField
-
->_Description_: the main enum field, with is used as status. Has different view in Stream;
->
->_Type_: string;
->
->_Available value_: the name of enum field;
->
->_Default_: no default.
-
-
+```json
+"aclPortalActionLevelListMap": {
+ "edit": ["own", "no"]
+}
+```
+
+## aclFieldLevelDisabled
+
+*boolean*
+
+*As of v8.2.*
+
+Disable field level security.
+
+## aclPortalFieldLevelDisabled
+
+*boolean*
+
+*As of v8.2.*
+
+Disable field level security for portals.
+
+## statusField
-### workflow
+*string*
+
+Defines a field that should be used as a status field.
+
+## statusFieldLocked
->_Description_: if Advanced Pack extension is installed and `"object"` is not set, but you need this entity in Target Entity list in Workflow;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+*bool*
+*As of v7.5.*
-### disabled
+Disables the ability to change the status field.
->_Description_: is disabled and invisible in the system;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+## disabled
+*boolean*
-### customizable
+Disables the scope in the system.
->_Description_: could entity be customized with Entity Manager;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+## customizable
+*boolean*
-### isCustom
+Whether the entity can be customized in the Entity Manager tool.
->_Description_: scope is custom. In general this parameter is set, if the entity was created with Entity Manager;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+## isCustom
+*boolean*
-### notifications
+Entities created in the Entity Manager tool marked as custom.
->_Description_: could be able for Notification;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+## notifications
-### calendar
+*boolean*
->_Description_: could be displayed on the Calendar;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether notifications can be enabled for the entity.
+## calendar
-#### activity
+*boolean*
->_Description_: could be displayed on the Activities panel;
->
->_Type_: boolean;
->
->_Available value_: true | false;
->
->_Default_: false.
+Whether the entity can be displayed on the Calendar.
+## activity
-### activityStatusList
+Whether the entity can be displayed on the Activities panel.
->_Description_: filter by status values, which defines, that event is an activity;
->
->_Type_: array;
->
->_Available value_: options of status field
->
->_Default_: ['Planned'].
+## activityStatusList
+
+*string[]*
+
+Status values that determine that a record should be shown in the Activities panel.
-### historyStatusList
-
->_Description_: filter by status values, which defines, that event is in history;
->
->_Type_: array;
->
->_Available value_: options of status field
->
->_Default_: ['Held', 'Not Held'].
+## historyStatusList
+
+*string[]*
+
+Status values that determine that a record should be shown in the History panel.
+
+## calendarOneDay
+
+*boolean*
+
+*As of v9.2.*
+
+Display as one-day events in the calendar. Applicable only if the *calendar* parameter is enabled.
+
+## languageIsGlobal
+
+*boolean*
+
+Language labels will be available for all users (not restricted by ACL).
+
+## languageAclDisabled
+
+*boolean*
+
+Disables access control application for language labels. All labels of the scope will be available in the front-end regardless of user roles.
+
+## kanbanStatusIgnoreList
+
+*string[]*
+
+Status values to be ignored on the Kanban view.
+
+## kanbanOrderDisabled
+
+*boolean*
+
+Disable the ability to order items for users.
+
+## hasPersonalData
+
+*boolean*
+
+Whether the entity may contain personal data.
+
+## preserveAuditLog
+
+*boolean*
+
+*As of v9.0.*
+
+Disables audit log cleanup.
+
+## exportFormatList
+
+*string[]*
+
+A list of allowed export formats.
+
+Example:
+
+```json
+{
+ "exportFormatList": ["csv"]
+}
+```
+
+## currencyConversionAccessRequiredFieldList
+
+*string[]*
+
+*As of v7.5.*
+
+When a user converts currency of an entity, edit access to all listed fields is checked. Otherwise, the operation will be forbidden.
+
+## lastViewed
+
+Force to be available in Last Viewed.
diff --git a/docs/development/metadata/select-defs.md b/docs/development/metadata/select-defs.md
new file mode 100644
index 000000000..056c9e473
--- /dev/null
+++ b/docs/development/metadata/select-defs.md
@@ -0,0 +1,148 @@
+# selectDefs
+
+Path: metadata > selectDefs > {EntityType}.
+
+Parameters used by the [Select](../select-builder.md) framework. This framework converts [search parameters](../api-search-params.md) (from the front-end or API) into ORM-compatible queries.
+
+## accessControlFilterClassNameMap
+
+Class names for access control filters. Classes should implement `Espo\Core\Select\AccessControl\Filter` interface.
+
+Default filters are available at `Espo\Core\Select\AccessControl\Filters`.
+
+The `mandatory` filter is applied for all users. Use it if you need to apply some access restrictions for all users (including admin).
+
+Example:
+
+```json
+{
+ "accessControlFilterClassNameMap": {
+ "onlyOwn": "Espo\\Custom\\Classes\\Select\\MyEntityType\\AccessControlFilters\\OnlyOwn",
+ "mandatory": "Espo\\Custom\\Classes\\Select\\MyEntityType\\AccessControlFilters\\Mandatory"
+ }
+}
+```
+
+Available out-of-the-box filters:
+
+* mandatory
+* all
+* onlyTeam
+* onlyOwn
+* portalAll
+* portalOnlyAccount
+* portalOnlyContact
+* portalOnlyOwn
+
+## boolFilterClassNameMap
+
+Class names for bool filters. Classes should implement `Espo\Core\Select\Bool\Filter` interface.
+
+## primaryFilterClassNameMap
+
+Class names for primary filters. Classes should implement `Espo\Core\Select\Primary\Filter` interface.
+
+Example:
+
+```json
+{
+ "primaryFilterClassNameMap": {
+ "myCustomFilter": "Espo\\Custom\\Classes\\Select\\MyEntityType\\PrimaryFilters\\MyCustomFilter"
+ }
+}
+```
+
+## selectAttributesDependencyMap
+
+When the system asking to select a specific attribute, this mapping will force the framework to also select some other fields along with the requested field.
+
+Example:
+
+```json
+{
+ "selectAttributesDependencyMap": {
+ "subject": ["name"],
+ "personStringData": ["fromString", "fromEmailAddressId"],
+ "id": ["order"]
+ }
+}
+```
+
+In the example, when the *subject* attribute is requested, the *name* attribute will be selected. We can have the *subject* field on the list layout but don't have the *name* field. Without this mapping the *name* field won't be fetched when we fetch a collection for the list view.
+
+Map to the *id* attribute to make specific attributes to be always selected. This works as the *id* attribute is always requested.
+
+## whereItemConverterClassNameMap
+
+Implementations for custom where items.
+
+Example:
+
+```json
+{
+ "whereItemConverterClassNameMap": {
+ "id_isOfType": "Espo\\Classes\\Select\\User\\Where\\ItemConverters\\IsOfType"
+ }
+}
+```
+
+Classes should implement `Espo\Core\Select\Where\ItemConverter` interface.
+
+Mapping keys a formatted as: `{fieldName}_{conditionItemType}`.
+
+This mapping allows you to define a custom field filtering implementation. The *conditionItemType* is passed in a [where item](../api-search-params.md#where-items) in the *type* parameter.
+
+## accessControlFilterResolverClassName
+
+A resolver is responsible for choosing an access filter to apply to a select query. Should implement `Espo\Core\Select\AccessControl\FilterResolver` interface.
+
+## portalAccessControlFilterResolverClassName
+
+A filter resolver for portals. Should implement `Espo\Core\Select\AccessControl\FilterResolver` interface.
+
+## textFilterClassName
+
+A class that processes the text filter search. Should implement `Espo\Core\Select\Text\Filter` interface. By default, `Espo\Core\Select\Text\DefaultFilter` is used.
+
+## orderItemConverterClassNameMap
+
+An order converter converts order parameters (passed from the frontend through the REST API) to an order data acceptable for the ORM. One can implement a custom converter for a specific field. For example, to make an address field be ordered by a city (when the user sorts by the address column, it will order by the city under the hood).
+
+Classes should implement `Espo\Core\Select\Order\ItemConverter` interface.
+
+Example:
+
+```json
+{
+ "orderItemConverterClassNameMap": {
+ "someFieldName": "Espo\\Custom\\Classes\\Select\\MyEntityType\\Order\\ItemConverters\\MyConverter"
+ }
+}
+```
+
+## ordererClassNameMap
+
+*As of v7.1.*
+
+Provides the ability to apply custom order for a specific field.
+
+Classes should implement `Espo\Core\Select\Order\Orderer` interface.
+
+Example:
+
+```json
+{
+ "ordererClassNameMap": {
+ "someFieldName": "Espo\\Custom\\Classes\\Select\\MyEntityType\\Order\\SomeOrderer"
+ }
+}
+```
+
+## additionalApplierClassNameList
+
+*As of v9.1.*
+
+*class-string[]*
+
+Additional appliers. Used for additional handling of a select query. They are always applied. The logic inside the applier can apply some filters conditionally.
+
diff --git a/docs/development/metadata/stream-defs.md b/docs/development/metadata/stream-defs.md
new file mode 100644
index 000000000..40a309bdf
--- /dev/null
+++ b/docs/development/metadata/stream-defs.md
@@ -0,0 +1,44 @@
+# streamDefs
+
+Path: metadata > streamDefs > {EntityType}.
+
+Example:
+
+```json
+{
+ "followingUsersField": "users",
+ "subscribersCleanup": {
+ "enabled": true,
+ "dateField": "dateStart",
+ "statusList": ["Held", "Not Held"]
+ }
+}
+```
+
+## followingUsersField
+
+*string*
+
+A field (of a link-multiple type) that store users which should automatically follow a record. If not set, then the *assignedUsers* field is checked for existence and then used. E.g. for the *Meeting*, it's the *users* field.
+
+## subscribersCleanup
+
+*Object*
+
+### enabled
+
+*boolean*
+
+Enables the cleanup of subscribers.
+
+### dateField
+
+*string*
+
+A date (or date-time) field that stores a value after which followers will automatically unfollow a record.
+
+### statusList
+
+*string[]*
+
+A list of statuses records should have to be eligible for the subscribers cleanup. E.g. for the *Meeting*, it's `["Held", "Not Held"]`.
diff --git a/docs/development/modal.md b/docs/development/modal.md
index 59776c4fa..bfafe5456 100644
--- a/docs/development/modal.md
+++ b/docs/development/modal.md
@@ -1,34 +1,35 @@
# Modal view (dialog)
-## Modal form
+## Modal with a form
+Example of a modal dialog with a form.
Modal view: `client/custom/src/views/modals/my-dialog.js`
```js
+define('custom:views/modals/my-dialog', ['views/modal', 'model'], (ModalView, Model) => {
-define('custom:views/modals/my-dialog', ['views/modal', 'model'], function (Dep, Model) {
+ return class extends ModalView {
- return Dep.extend({
+ className = 'dialog dialog-record'
- className: 'dialog dialog-record',
+ // language=Handlebars
+ templateContent = `
+
{{{record}}}
+ `,
- // template content can be defined right here or externally
- templateContent: '
{{{record}}}
',
+ // If true, clicking on the backdrop will close the dialog.
+ // Can be 'static', true or false.
+ backdrop = true
- // template content can be defined in external file client/custom/res/templates/my-dialog.tpl
- // template: 'custom:modals/my-dialog',
-
- // if true, clicking on the backdrop will close the dialog
- backdrop: true, // 'static', true, false
-
- setup: function () {
+ setup() {
// action buttons
this.buttonList = [
{
name: 'doSomething', // handler for 'doSomething' action is bellow
- html: this.translate('Some Action', 'labels', 'MyScope'), // button label
+ text: this.translate('Some Action', 'labels', 'MyScope'), // button label
style: 'danger',
+ onClick: () => this.actionDoSomething(),
},
{
name: 'cancel',
@@ -36,21 +37,20 @@ define('custom:views/modals/my-dialog', ['views/modal', 'model'], function (Dep,
},
];
- var title = this.options.title || ''; // passed from the parent view
+ const title = this.options.title || ''; // assuming it's passed from our parent view
- this.headerHtml = this.getHelper().escapeString(title); // escape to prevent XSS
+ this.headerText = title;
+ // this.headerHtml = this.getHelper().escapeString(title);
this.formModel = new Model();
- this.formModel.name = 'None'; // dummy name
// define fields
this.formModel.setDefs({
fields: {
'someString': {
type: 'varchar', // field type
- view: 'views/fields/varchar', // can define custom view
- required: true, // field params
- trim: true,
+ view: 'views/fields/varchar', // optional, to define custom view
+ required: true, // field param
},
'someCheckbox': {
type: 'bool',
@@ -59,11 +59,9 @@ define('custom:views/modals/my-dialog', ['views/modal', 'model'], function (Dep,
});
this.createView('record', 'views/record/edit-for-modal', {
- scope: 'None', // dummy name
model: this.formModel,
- el: this.getSelector() + ' .record',
- // define layout
- detailLayout: [
+ selector: '.record',
+ detailLayout: [ // form layout
{
rows: [
[
@@ -74,77 +72,83 @@ define('custom:views/modals/my-dialog', ['views/modal', 'model'], function (Dep,
{
name: 'someCheckbox',
labelText: this.translate('Some Checkbox', 'labels', 'MyScope'),
- }
- ]
- ]
- }
+ },
+ ],
+ ],
+ },
],
});
- },
+ }
- actionDoSomething: function () {
- // fetch data from form to model and validate
- var isValid = this.getView('record').processFetch();
-
- if (isValid) {
- // make POST request
- Espo.Ajax.postRequest('MyScope/action/doSomething', {
- id: this.options.id, // passed from the parent view
- someString: this.formModel.get('someString'),
- someCheckbox: this.formModel.get('someCheckbox'),
- }).then(
- function (response) {
- Espo.Ui.success(this.translate('Done'));
- // event 'done' will be catched by the parent view
- this.trigger('done', response);
- this.close();
- }.bind(this)
- );
- }
- },
- });
-});
+ async actionDoSomething() {
+ /** @type {import('views/record/edit').default} */
+ const recordView = this.getView('record');
-```
+ const isValid = recordView.processFetch();
-Parent view calling our modal view:
+ if (!isValid) {
+ return;
+ }
-```js
+ Espo.Ui.notify(' ... ');
+
+ const response = await Espo.Ajax.postRequest('MyScope/action/doSomething', {
+ id: this.options.id, // passed from the parent view
+ someString: this.formModel.attributes.someString,
+ someCheckbox: this.formModel.attributes.someCheckbox,
+ });
-...
- this.createView('dialog', 'custom:views/modals/my-dialog', {
- id: this.model.id,
- title: this.model.get('name'),
- }, function (view) {
- view.render();
+ Espo.Ui.success(this.translate('Done'));
- this.listenToOnce(view, 'done', function (response) {
- console.log(response);
- }, this)
- });
+ // We assume that the event 'done' will be caught by the parent view.
+ this.trigger('done', response);
-...
+ // Close the modal dialog.
+ this.close();
+ }
+ }
+});
+```
+Parent view calling our modal view:
+
+```js
+this.createView('dialog', 'custom:views/modals/my-dialog', {
+ id: this.model.id,
+ title: this.model.get('name'),
+}, view => {
+ view.render();
+
+ this.listenToOnce(view, 'done', response => {
+ console.log(response);
+ })
+});
```
## Simple dialog w/o separate view
-Available since 5.7.0.
-
```js
-
- this.createView('dialog', 'views/modal', {
- templateContent: '
',
+ headerText: 'Hello world',
+ backdrop: true,
+ message: 'Some *message*\n\nHello world!',
+ buttonList: [
+ {
+ name: 'doSomething',
+ label: this.translate('Do Something'),
+ onClick: () => {
+ // Do something.
+ this.close();
+ },
+ style: 'primary',
+ },
+ {
+ name: 'close',
+ label: this.translate('Close'),
+ }
+ ],
+}, view => {
+ view.render();
+});
```
diff --git a/docs/development/model.md b/docs/development/model.md
index fe42df83f..7678ba357 100644
--- a/docs/development/model.md
+++ b/docs/development/model.md
@@ -1,124 +1,208 @@
# Model
+A model instance usually represents a single entity record. See the [class](https://github.com/espocrm/espocrm/blob/stable/client/src/model.js).
+
## Methods
-Setting and getting attributes:
+### set
+
+Sets an attribute or multiple attributes.
```js
-// specific attribute
+// Set one attribute.
model.set('attributeName', value);
-// multiple attributes
-model.set({
+// Multiple at once.
+model.setMultiple({
attributeName1: value1,
attributeName2: value2,
});
-// specific attribute
-var value = model.get('attributeName');
+// With options.
+model.setMultiple(attributes, {
+ // suppresses 'change' events
+ silent: true,
+});
+```
+
+You can pass custom options and check them in 'change' event listeners.
+
+### get
+
+Gets an attribute.
+
+```js
+const value = model.get('attributeName');
+// or model.attributes.attributeName;
// all attributes
-var attributes = Espo.Utils.cloneDeep(model.attributes);
+const attributes = Espo.Utils.cloneDeep(model.attributes);
+```
+
+### save
+
+Saves the model (to the back-end).
+```js
+// Assuming model.id is set.
+try {
+ await model.save()
+} catch() {
+ // Error occurred.
+ return;
+}
```
-Saving model (to backend):
+### fetch
+
+Fetches the model (from the backend). Loads attribute values to the model. Returns a promise.
```js
-// assuming model.id is set
-model.save()
- .then(
- function () {
-
- }.bind(this)
- )
- .fail(
- function () {
-
- }.bind(this)
- );
+// Assuming model.id is set.
+async model.fetch();
```
-Fetching model (from backend):
+### getClonedAttributes
+
+Get cloned attributes. Returns an object.
```js
-// assuming model.id is set
-model.fetch()
- .then(
- function () {
+const attributes = model.getClonedAttributes();
+```
+
+### populateDefaults
+
+Populate default values.
- }.bind(this)
- );
+```js
+model.populateDefaults();
```
-## Instantiating
+### setDefs
-Model-factory is available in views. The model-factory allows to create a model instance of a specific entity type.
+Sets field and link defs. May be needed if a model instantiated explicitly, not by the factory.
```js
-define('custom:views/some-custom-view', 'view', function (Dep) {
- return Dep.extend({
- setup: function () {
- var entityType = 'Account';
- // use wait to hold off rendering until model is loaded
- this.wait(
- this.getModelFactory().create(entityType)
- .then(
- function (model) {
- var entityType = model.entityType; // entityType property is set by the factory
- this.model = model;
- model.id = this.options.id;
- return model.fetch(); // this will make API call using an appropriate URL
- }.bind(this)
- )
- .then(
- function () {
- // here you can do some stuff with model
- }.bind(this)
- )
- );
- },
- });
+model.setDefs({
+ fields: {},
+ links: {},
});
```
+## Properties
+
+### id
+
+*string*
+
+A record ID.
+
+### entityType
+
+*string*
+
+An entity type.
+
+### urlRoot
+
+*string*
+
+A root API URL to use for syncing with the backend. For non-new records, an ID part will be appended.
+
+### url
+
+*string*
+
+An API URL to use for syncing with the backend. If specified, urlRoot will be omitted.
+
+### attributes
+
+*Record*
+
+Attribute values.
+
+```js
+const name = model.attributes.name;
+```
+
+## Instantiating
+
+Model-factory is available in views. The model-factory allows you to create a model instance of a specific entity type.
+
+```js
+export default class extends View {
+
+ setup() {
+ // Use wait to hold off rendering until model is loaded.
+ this.wait(this.loadModel());
+ }
+
+ async loadModel() {
+ this.model = await this.getModelFactory().create('Account');
+
+ // entityType is set by the factory.
+ //const entityType = this.model.entityType;
+
+ this.model.id = this.options.id;
+
+ await model.fetch();
+ }
+}
+```
+
Instantiating w/o factory:
```js
-define('custom:views/some-custom-view', ['view', 'model'], function (Dep, Model) {
- return Dep.extend({
- setup: function () {
- var model = new Model;
- model.urlRoot = 'MyModel'; // URL will be used when fetching and saving
- model.id = 'someId';
- model.fetch(); // this will make GET MyModel/someId API call
- },
- });
-});
+import View from 'view';
+import Model from 'model';
+
+export default class extends View {
+
+ setup() {
+ const model = new Model();
+
+ // URL will be used when fetching and saving.
+ model.urlRoot = 'MyModel';
+ model.id = 'someId';
+
+ this.wait(
+ // This performs `GET MyModel/someId` API call.
+ model.fetch();
+ );
+ }
+}
```
## Events
-Note: `listenTo` and `listenToOnce` are methods of *view*.
+Note: `listenTo` and `listenToOnce` are methods of the *view* class.
### change
When model attributes get changed (not necessarily synced with backend).
```js
-this.listenTo(model, 'change', function (model, options) {
+this.listenTo(model, 'change', (model, options) => {
if (this.model.hasChanged('someAttribute')) {
// someAttribute is changed
}
+
if (options.ui) {
// changed via UI
// this options is set by field view
}
-}, this);
-this.listenToOnce(model, 'change:someAttribute', function (model, value, options) {
+ // The 'action' option indicates how the change originated.
+ // Possible values: fetch, save, ui, cancel-edit.
+ console.log(options.action);
+
+ // If you want to change the same model within this handler,
+ // use setTimeout with a zero delay to avoid a potential loop.
+});
+
+this.listenToOnce(model, 'change:someAttribute', (model, value, options) => {
// someAttribute is changed
-}, this);
+});
```
### sync
@@ -126,9 +210,13 @@ this.listenToOnce(model, 'change:someAttribute', function (model, value, options
Model synced with backend.
```js
-this.listenTo(model, 'sync', function () {
- // synced with backend (fired after fetch or save)
-}, this);
+this.listenTo(model, 'sync', (model, response, options) => {
+ // Synced with backend – fired after fetch or save.
+
+ // The 'action' option indicates how the sync originated.
+ // Possible values: fetch, save, destroy.
+ console.log(options.action);
+});
```
### destroy
@@ -141,11 +229,20 @@ Defined in the application.
### after:relate
-Once relationship panel updated. Available on detail/edit views.
+Once relationship panel updated. Available on the detail view.
+
+### after:relate:{link}
+
+Once a specific relationship panel updated. Available on the detail view.
### update-all
-This event is not fired. But you can fire it to update all relationship panels. Available on detail/edit views.
+This event is not fired. But you can fire it to refresh all relationship panels. Available on the detail view.
+
+### update-related:{link}
+
+Fire this event to refresh a specific relationship panel. Available on the detail view.
+
## Other
@@ -156,3 +253,9 @@ this.createView('someName', 'custom:views/some-view', {
model: this.model,
});
```
+
+Or:
+
+```js
+const view = new MyView({model});
+```
diff --git a/docs/development/modules.md b/docs/development/modules.md
new file mode 100644
index 000000000..cf5944cf9
--- /dev/null
+++ b/docs/development/modules.md
@@ -0,0 +1,36 @@
+# Modules
+
+The best practice is to place customizations in a module directory:
+
+* `custom/Espo/Modules/{YourModule}/` – backend (CamelCase name);
+* `client/custom/modules/{your-module}/` – frontend (hyphen name).
+
+## Order
+
+Every module has its *order* property. The order is used by the system to define which module to load first. For example, if two modules have some metadata with the same key, the metadata of the module that has a higher order will be used. If two modules have the controller classes with the same name, then the class of the module that has a higher order will be used.
+
+The *order* property is defined in `custom/Espo/Modules/{YourModule}/Resources/module.json`:
+
+```json
+{
+ "order": 16
+}
+```
+
+Requires clearing cache after changes.
+
+## Routes
+
+A module can define additional [API routes](api-action.md#routing). They are defined in `custom/Espo/Modules/{YourModule}/Resources/routes.json`.
+
+Requires clearing cache after changes.
+
+## Composer
+
+You can create a `composer.json` in your module directory to include 3rd party libraries. To let Espo know about these libraries, you need to create an [autoload configuration file](autoload.md) in your module.
+
+## JS modules
+
+When referencing ES (or AMD) modules located in an Espo module, use the path: `module/{your-module}/*`. Example: `module/my-module/views/fields/my-field`.
+
+When using [ext-template](https://github.com/espocrm/ext-template), the path to your Espo module will be automatically written in *jsconfig.json*. That will allow an IDE to properly locate module files.
diff --git a/docs/development/new-function-in-formula.md b/docs/development/new-function-in-formula.md
index 66b719fd6..dd99bbfc7 100644
--- a/docs/development/new-function-in-formula.md
+++ b/docs/development/new-function-in-formula.md
@@ -1,52 +1,57 @@
-# Defining new funtions for Formula
+# Custom functions for Formula
-EspoCRM provides the possibility to create custom functions that can be used in formula.
+EspoCRM provides the ability to create custom functions that can be used in formula-script.
-Create a file `custom/Espo/Custom/Core/Formula/Functions/StringGroup/MyContainsType.php` with the code:
+Create a file `custom/Espo/Custom/FormulaFunctions/MyContains.php` with the code:
```php
fetchArguments($item);
-
- if (count($args) < 2) {
- throw new Error("MyContains: Too few arguments.");
+ if (count($arguments) < 2) {
+ throw TooFewArguments::create(2);
}
- $haystack = $args[0];
- $needle = $args[1];
+ $haystack = $arguments[0];
+ $needle = $arguments[1];
- if (count($args) > 2) {
- $offset = $args[2];
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
+ if (count($arguments) > 2) {
+ $offset = $arguments[2];
+
+ return strpos($haystack, $needle, $offset) !== false;
}
+
+ return strpos($haystack, $needle) !== false;
}
}
```
-In order to add the created function to the function list of formula, create a file `custom/Espo/Custom/Resources/metadata/app/formula.json` and add the code:
+Create a file `custom/Espo/Custom/Resources/metadata/app/formula.json` and add the code:
+
```json
{
+ "functionClassNameMap": {
+ "myNamespace\\myContains": "Espo\\Custom\\FormulaFunctions\\MyContains"
+ },
"functionList": [
"__APPEND__",
{
- "name": "string\\myContains",
- "insertText": "string\\myContains(HAYSTACK, NEEDLE, OFFSET)"
+ "name": "myNamespace\\myContains",
+ "insertText": "myNamespace\\myContains(HAYSTACK, NEEDLE, OFFSET)"
}
- ],
- "functionClassNameMap": {
- "string\\myContains": "\\Espo\\Custom\\Core\\Formula\\Functions\\StringGroup\\MyContainsType"
- }
+ ]
}
```
Clear cache.
+
diff --git a/docs/development/orm-value-objects.md b/docs/development/orm-value-objects.md
new file mode 100644
index 000000000..20f9c504d
--- /dev/null
+++ b/docs/development/orm-value-objects.md
@@ -0,0 +1,172 @@
+# Value Objects
+
+*As of v7.0.*
+
+* Value objects are immutable.
+* Value objects contain modification methods that return a cloned instance.
+* Default value objects are available in the namespace `Espo\Core\Field`.
+* It's possible to register custom value object for a specific field type or for a specific field.
+
+When defining getters and setters in an Entity class, it's recommended to use value objects for such field types:
+
+* date
+* datetime
+* datetimeOptional
+* address
+* currency
+
+All field types with registered value object:
+
+* date
+* datetime
+* datetimeOptional
+* address
+* currency
+* email
+* phone
+* link
+* linkParent
+* linkMultiple
+
+BaseEntity's methods *getValueObject* and *setValueObject* will work for field types with registered value object.
+
+```php
+getValueObject($field);
+$entity->setValueObject($field, $valueObject);
+$entity->setValueObject($field, null);
+```
+
+Getter and setter:
+
+```php
+get('dateDue');
+
+ if ($rawValue === null) {
+ return null;
+ }
+
+ return Date::fromString($rawValue);
+ }
+
+ public function setDateDue(?Date $dateDue): self
+ {
+ $this->setValueObject('dateDue', $dateDue);
+
+ return $this;
+ }
+}
+
+```
+
+## Supported field types
+
+### Address
+
+```php
+getBillingAddress() ?? new Address();
+
+$country = $address->getCountry();
+$city = $address->getCity();
+```
+
+```php
+withCity($city)
+ ->withCountry($country)
+ ->withPostalCode($postalCode);
+
+$accountEntity->setBillingAddress($address);
+```
+
+### Currency
+
+```php
+convert($value, 'EUR');
+
+$opportunityEntity->setAmount($valueInEur);
+```
+
+### Email address, Phone number
+
+```php
+getEmailAddressGroup();
+
+$primary = $emailAddressGroup->getPrimary();
+
+$modifiedEmailAddressGroup = $emailAddressGroup
+ ->withAddedEmailAddress(
+ EmailAddress::create('address@test.com')->optedOut()
+ );
+
+$accountEntity->setEmailAddressGroup($modifiedEmailAddressGroup);
+```
+
+The same is available for phone numbers.
+
+### Date, DateTime, DateTimeOptional
+
+```php
+getCloseDate();
+
+$opportunityEntity->setCloseDate(
+ $closeDate->modify('+1 month')
+);
+```
+
+### Link, Link-Parent, Link-Multiple
+
+```php
+getId())
+ ->withColumnValue('role', 'Decision Maker');
+
+$contacts = LinkMultiple::create([$contact->getId()]);
+```
+
+## Registering
+
+!!! note
+
+ Registering own value object types might be excessive as it's possible to manually handle value object creation and consumption in getter and setters of an entity.
+
+Registering a custom value object type for a specific field type.
+
+For a field type you need to define 2 parameters in metadata > fields > {fieldType}:
+
+* `valueFactoryClassName` – implementation of `Espo\ORM\Value\ValueFactory` interface;
+* `attributeExtractorClassName` – implementation of `Espo\ORM\Value\AttributeExtractor` interface.
+
+It's also possible to register a value object for a specific field in metadata > entityDefs > {entityType} > fields > {fieldName}:
+
+* `valueFactoryClassName`;
+* `attributeExtractorClassName`.
diff --git a/docs/development/orm.md b/docs/development/orm.md
index 7edc79b1f..b74c56a18 100644
--- a/docs/development/orm.md
+++ b/docs/development/orm.md
@@ -1,298 +1,599 @@
-# ORM, How to manage entities and perform queries
+# ORM
-EspoCRM has built-in own ORM (Object-relational mapping). It’s very simple to create, update, read, delete and search entities. All these operations available through EntityManager object.
+EspoCRM utilizes own built-in ORM (object-relational mapping). Create, update, read, delete and search operations are performed via the Entity Manager instance.
-**EntityManager** is available in [*Container*](di.md). It can be obtained in [record services](services.md#record-service) by method `#getEntityManager()`. It provides an access to repositories.
+The *EntityManager* is available as a [*container service*](di.md). It's a central access point for ORM functionalities.
-**Repository** serves for fetching and storing records. Each entity type has its own repository. Base classes: `Espo\ORM\Repositories\RDB`, `\Espo\Core\Repositories\Database`. *RDB* stands for *relational database*.
+A *Repository* class serves for fetching and storing records. Base classes: `Espo\ORM\Repositories\RDBRepository`, `Espo\Core\Repositories\Database`. *RDB* stands for a *relational database*.
-**Entity** represents a single record. Each entity type has it's own entity class. Base classes: `\Espo\ORM\Entity`, `\Espo\Core\ORM\Entity`.
+An *Entity* class represents a single record. Each [entity type](../administration/terms-and-naming.md#entity-type) has its own entity class. Base class: `Espo\Core\ORM\Entity`, interface: `Espo\ORM\Entity`.
-**EntityCollection** is a collection of entities. It's returned by *find* operations.
+An *EntityCollection* is a collection of entities. It's returned by *find* operations. An *SthCollection* is a collection of entities, consuming much less memory than EntityCollection. Collections are iterable.
-Obtaining the entity manager in the record service:
+The ORM uses a data-mapper approach. Note that it does not have an identity map – fetching the same record multiple times in a row will return different instances (of the same record).
+
+## See also
+
+* [Complex expressions](../user-guide/complex-expressions.md)
+* [Value objects](orm-value-objects.md)
+* [Custom entity type](custom-entity-type.md)
+* [Entity definitions](metadata/entity-defs.md)
+
+## Injecting Entity Manager
+
+The Entity Manager is available as a [*Container*](di.md) service.
+
+A class with the `entityManager` dependency:
```php
-$entityManager = $this->getEntityManager();
+getEntity('Account')
+getNewEntity($entityType);
+```
+
+Or type hinted:
+
+```php
+getRepository('Account')->get();
+// Will infer a proper MyEntity type. Useful for static analysis and IDEs
+// that support generic types.
+$entity = $entityManager->getRDBRepositoryByClass(MyEntity::class)->getNew();
```
-Note: It creates a new instance but doesn't store it in DB. The entity doesn't have ID yet.
+!!! note
-### Fetch existing
+ It creates a new instance but doesn't store it in DB. The entity doesn't have an ID yet.
+
+### Fetch existing entity
+
+```php
+getEntityById($entityType, $id);
+```
+
+Or type hinted:
```php
-$account = $entityManager->getRepository('Account')->get($accountId);
+getEntity('Account', $accountId);
+$entity = $entityManager->getRDBRepositoryByClass(MyEntity::class)->getById($id);
```
-### Get value
+### Store entity
```php
-$fieldValue = $account->get('fieldName');
+saveEntity($entity);
```
-### Has value
+#### Save options
-Checks whether attribute is set. Note: If it's set to `NULL` it will return `true`.
+Save with options:
```php
-$fieldNameIsSet = $account->has('fieldName'); // true or false
+saveEntity($entity, [SaveOption::SILENT => true]);
```
-### Set value
+Available options:
-One:
+* skipAll – skip all additional processing;
+* skipHooks – skip all hooks; workflows, formula will be ignored;
+* silent – workflows will be ignored, modifiedAt and modifiedBy fields won't be changed;
+* skipCreatedBy – createdBy won't be set to the current user;
+* skipModifiedBy – modifiedBy won't be set to the current user;
+* createdById – override createdBy with a passed user ID;
+* modifiedById – override modifiedBy.
+
+Options in constants available here: `Espo\Core\ORM\Repository\Option\SaveOption`.
+
+### Create and store entity
+
+Stores the record in DB and returns an entity instance.
```php
-$account->set('fieldName', 'Test Account');
+createEntity($entityType, [
+ 'name' => 'Test',
+ 'status' => 'Hello',
+]);
```
-Multiple:
+### Remove entity
+
+Soft-deletes the record.
```php
-$account->set([
- 'name' => 'Test Account',
- 'assignedUserId' => '1',
-]);
+removeEntity($entity);
```
-### Clear value
+### Get attribute value
+
+Return the value of a given attribute. An attribute usually corresponds to a column in DB.
```php
-$entity->clear('attributeName');
+get('attributeName');
+```
+
+!!! note
+
+ As EspoCRM supports custom fields and relationships which are added dynamically without the need to compile, attribute accessor methods *get*, *set* and *has* were introduced. For type safety, consider creating getters and setters for needed attributes in your custom Entity class. Use these methods in your business logic code.
+
+### Has attribute value
+
+Checks whether an attribute is set. Note: If it's set to *null*, it will return *true*. An attribute may not be set if the entity was fetched with only a specified attribute list.
+
+```php
+has('attributeName'); // true or false
+```
+
+### Set attribute value
+
+One:
+
+```php
+set('attributeName', 'Test Value');
```
-It will unset the attribute. If you save the entity after that, it will not change the value to NULL in database.
+Multiple:
+
+```php
+setMultiple([
+ 'name' => 'Test Name',
+ 'assignedUserId' => '1',
+]);
+```
-### Reset
+### Clear attribute value
-Resets all attributes.
+This will unset the attribute. If you save the Entity after that, it will not change the value to NULL in database. Very rarely used. Not recommended.
```php
-$entity->reset();
+clear('attributeName');
```
### Fetched attributes
-You can check whether an attribute was changed.
+Check whether an attribute was changed.
```php
+getFetched('attributeName')
+$value = $entity->getFetched('attributeName');
// check whether an attribute was changed since the last syncing with DB
-$entity->isChanged('attributeName');
+$attributeChanged = $entity->isAttributeChanged('attributeName');
```
-### Get all values
+### Get all attribute values
+
+Returns all attributes with their values.
```php
-$account->getValueMap();
+getValueMap();
```
-### Store
+### Delete from DB
-```php
-$entityManager->saveEntity($account);
+Deletes the record permanently.
-// or
-$entityManager->getRepository('Account')->save($account);
+```php
+getRDBRepository($entityType)->deleteFromDb($id);
```
-Options:
+## Repository
+
+Use ORM's repositories to fetch and save entities. A repository instance is instantiated per entity type.
+
+!!! note
+
+ It may be reasonable to wrap all interactions with the repository in a higher-level class (usually also called a Repository), so that your business-logic classes do not depend directly on the Entity Manager. This improves testability.
+
+Get a repository by an entity class:
```php
-$options = [
- 'skipHooks' => true, // skip all hooks; workflows, formula will be ignored
- 'silent' => true, // workflows will be ignored, modified fields won't be changed
- 'skipCreatedBy' => true, // createdBy won't be set with current user
- 'skipModifiedBy' => true, // modifiedBy won't be set with current user
- 'createdById' => true, // override createdBy
- 'modifiedById' => true, // override modifiedBy
-];
+saveEntity($account, $options);
+// Returns `Collection`.
+$accountRepository = $entityManager->getRDBRepositoryByClass(Account::class);
+```
-// or
-$entityManager->getRepository('Account')->save($account, $options);
+```php
+getRDBRepositoryByClass(Account::class)
+ ->getById($id);
```
-### Create and store
+Note: To be able to fetch the repository by an entity type, your [custom entity](custom-entity-type.md#entity-class) needs to have the *ENTITY_TYPE* constant.
+
+Get a repository by an entity type:
```php
-$account = $entityManager->createEntity('Account', [
- 'name' => 'Test',
-]);
+getRDBRepository($entityType);
```
-### Remove
+### Find
```php
-$entityManager->removeEntity($account);
+getRDBRepository($entityType)
+ ->where([
+ 'type' => 'Customer',
+ ])
+ ->find();
+```
-// or
-$entityManager->getRepository('Account')->remove($account);
+Descending order:
+
+```php
+getRDBRepository($entityType)
+ ->limit(0, 10)
+ ->order('createdAt', 'DESC')
+ ->find();
```
-### Delete from DB
+Complex order:
```php
-$entityManager->getRepository('Account')->deleteFromDb($id);
+getRDBRepository($entityType)
+ ->order([
+ ['createdAt', 'ASC'],
+ ['name', 'DESC'],
+ ])
+ ->find();
```
-This will delete a record permanently.
+Or:
-### Attribues
+```php
+getRDBRepository($entityType)
+ ->order('createdAt', 'ASC')
+ ->order('name', 'DESC')
+ ->find();
+```
-Each entity type has its own set of defined attributes. You cannot set an arbitrary attribute name.
+Or:
```php
-// whether attribute is defined for entity
-$hasAttribute = $entity->hasAttribute('attributeName');
+getRDBRepository($entityType)
+ ->order(
+ Expr::concat(
+ Expr::column('firstName'),
+ Expr::column('lastName')
+ ),
+ 'DESC',
+ )
+ ->find();
+```
-$attributeList = $entity->getAttributeList();
+Ordering by a value list:
+
+```php
+getRDBRepository('Opportunity')
+ ->order('LIST:stage:Prospecting,Qualification,Proposal')
+ ->find();
+```
-$attributeType = $entity->getAttributeType('attributeName');
+Feeding a query to a repository:
-$paramValue = $entity->getAttributeParam('attributeName', 'attributeParam');
+```php
+getRDBRepository($entityType)
+ ->clone($query)
+ ->limit(0, 10)
+ ->find();
```
-Attribute types:
+Finding the first one:
-* id
-* varchar
-* int
-* float
-* text
-* bool
-* foreign
-* foreignId
-* foreignType
-* date
-* datetime
-* jsonArray
-* jsonObject
+```php
+getRDBRepository($entityType)
+ ->where([
+ 'type' => 'Customer',
+ ])
+ ->findOne();
+```
-### Relations
+You can use *getRDBRepositoryByClass* for type safety:
```php
-$relationList = $entity->getRelationList();
+getRelationType('relationName');
+$entity = $entityManager
+ ->getRDBRepositoryByClass(Account::class)
+ ->findOne();
-$paramValue = $entity->getRelationParam('relationName', 'paramName')
+// Static analysis infers the entity's type.
```
-Relation types:
+### Get new
-* manyMany
-* hasMany
-* belongsTo
-* hasOne
-* belongsToParent
-* hasChildren
+Prepare a new entity without saving it:
-### Find
+```php
+getRDBRepositoryByClass(Account::class)
+ ->getNew();
+```
+
+### Save
+
+Save an entity:
```php
-$accountList = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer',
-])->find();
+getRDBRepositoryByClass(Account::class)
+ ->save($account);
```
-Descending order:
+### Remove
+
+Remove an entity (soft delete):
```php
-$accountList = $entityManager->getRepository('Account')
- ->limit(0, 10)
- ->order('createdAt', true)
- ->find();
+getRDBRepositoryByClass(Account::class)
+ ->remove($account);
```
-Ascending order:
+## Relations
+
+!!! note
+
+ As of v8.4, the *getRelation* method is available in the *EntityManager*. `$entityManager->getRelation($entity, 'relationName');` Before, it could be accessed from a repository.
+
+### Find related
+
+Has-Many:
+
```php
-$accountList = $entityManager->getRepository('Account')
+getRelation($account, 'opportunities')
+ ->find();
+
+// Filter.
+$opportunityCollection = $entityManager
+ ->getRelation($account, 'opportunities')
->limit(0, 10)
- ->order('createdAt')
+ ->where($whereClause)
->find();
+
+// First one.
+$opportunity = $entityManager
+ ->getRelation($account, 'opportunities')
+ ->order('createdAt', 'DESC')
+ ->findOne();
```
-or:
+Belongs-To or Has-One:
+
```php
-$accountList = $entityManager->getRepository('Account')
- ->limit(0, 10)
- ->order('createdAt', 'DESC')
- ->find();
+getRelation($task, 'account')
+ ->findOne();
```
-Complex order:
+Filtering by a relation column:
+
```php
-$accountList = $entityManager->getRepository('Account')
- ->order([
- ['createdAt', 'ASC'],
- ['name', 'DESC'],
- ])
+getRelation($targetList, 'leads')
+ ->where(['@relation.optedOut' => false])
->find();
```
-Ordering by list:
+*optedOut* is a column in the middle table.
+
+### Relate entities
```php
-$opportunityList = $entityManager->getRepository('Opportunity')
- ->order('LIST:stage:Prospectring,Qualification,Proposal')
- ->find();
+getRelation($account, 'opportunities')
+ ->relate($opportunity);
+
+$entityManager
+ ->getRelation($account, 'opportunities')
+ ->relateById($opportunityId);
+
+// With relationship column setting.
+$entityManager
+ ->getRelation($account, 'contacts')
+ ->relate($contact, ['role' => 'CEO']);
```
-### Find the first one
+### Unrelate entities
```php
-$account = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer',
-])->findOne();
+getRelation($account, 'opportunities')
+ ->unrelate($opportunity);
+
+$entityManager
+ ->getRelation($account, 'opportunities')
+ ->unrelateById($opportunityId);
```
-### Find related
+### Update columns
```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
+getRelation($account, 'contacts')
+ ->updateColumns($contact, ['role' => 'CEO']);
+
+$entityManager
+ ->getRelation($account, 'contacts')
+ ->updateColumnsById($contactId, [
+ 'role' => 'CEO', // relationship column
+ ]);
```
-### Relate entities
+### Check whether related
+
+```php
+getRelation($account, 'opportunities')
+ ->isRelated($opportunity);
+```
+
+### Managing from within Entity class
+
+*As of v9.0.*
+
+A developer can add getter and setters to an Entity class which will allow to read and set related records.
+
+In a custom entity type class, you can define getter and setters for relationships. If you call the same getter multiple times, it will return the same instance. It's useful when the same related entity is accessed in multiple hooks during save. After save, the map will be reset – the getter won't return the same instance as before save.
+
+Get one:
```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
+relations->getOne('account');
+}
+```
+
+Set one:
-// or
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
+```php
+setRelatedLinkOrEntity('account', $account);
+}
```
-### Unrelate entities
+Get many:
+
+```php
+
+ */
+public function getAccounts(): Traversable
+{
+ /** @var Traversable */
+ return $this->relations->getMany('accounts');
+}
+```
+
+Note that setting collections (many-to-many, one-to-many) is not supported. Use *$entityManager->getRelation* or set the *LinkMultiple* value object instead.
+
+Usage:
```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
+setAccount($account);
-// or
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
+$account = $entity->getAccount();
+
+// The same instance is returned. Useful to prevent re-fetching in different hooks.
+assert($account === $entity->getAccount());
+
+$em->saveEntity($entity);
```
-### Check related
+
+## Collections
+
+Collections contains Entities. An *EntityCollection* is a regular collection of entities. An *SthCollection* is a collection of entities, consuming much less memory. It's reasonable when working with large query results. It does not allocate memory for all results but only for a current entity (e.g. when iterating).
+
+Iteration:
```php
-$entityManager->getRepository('EntityType')->isRelated($entity, 'relationName', $relatedEntity);
+getRepository('EntityType')->isRelated($entity, 'relationName', $id);
+```php
+getValueMapList(); // stdClass[]
+```
+
+Factory:
+
+```php
+getCollectionFactory()->create(); // EntityCollection
+$collection[] = $entity;
+
+$sthCollection = $entityManager->getCollectionFactory()->createFromQuery($selectQuery); // SthCollection
```
## Select Query Parameters
@@ -304,23 +605,35 @@ $entityManager->getRepository('EntityType')->isRelated($entity, 'relationName',
Supported comparison operators: `>`, `<`, `>=`, `<=`, `=`, `!=`.
```php
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'amount>=' => 100
-])->find();
+getRDBRepository('Opportunity')
+ ->where([
+ 'amount>=' => 100
+ ])
+ ->find();
```
#### IN and NOT IN operators
```php
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage' => ['Closed Lost', 'Closed Won']
- ])->find();
+getRDBRepository('Opportunity')
+ ->where([
+ 'stage' => ['Closed Lost', 'Closed Won']
+ ])
+ ->find();
```
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage!=' => ['Closed Lost', 'Closed Won']
-])->find();
+```php
+getRDBRepository('Opportunity')
+ ->where([
+ 'stage!=' => ['Closed Lost', 'Closed Won']
+ ])
+ ->find();
```
#### LIKE operators
@@ -331,32 +644,89 @@ Supported operators:
* `!*` - NOT LIKE
```php
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'name*' => '%service%',
-])->find();
+getRDBRepository('Opportunity')
+ ->where([
+ 'name*' => '%service%',
+ ])
+ ->find();
```
#### OR, AND operators
```php
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- [
- 'OR' => [
- ['stage' => 'Closed Won'],
- ['stage' => 'Closed Lost'],
- ],
- 'AND' => [
- 'amountConverted>' => 100,
- 'amountConverted<=' => 999,
+getRDBRepository('Opportunity')
+ ->where([
+ [
+ 'OR' => [
+ ['stage' => 'Closed Won'],
+ ['stage' => 'Closed Lost'],
+ ],
+ 'AND' => [
+ 'amountConverted>' => 100,
+ 'amountConverted<=' => 999,
+ ],
]
- ]
-])->findOne();
+ ])
+ ->findOne();
```
-### Distinct
+#### Sub-query
+
+```php
+getRDBRepository($entityType)
+ ->where(
+ Cond::in(Cond::column('id'), $subQuery)
+ )
+ ->find();
+```
+
+#### Condition
+*As of v7.0.*
+
+```php
+getRDBRepository($entityType)
+ ->where(
+ Cond::or(
+ Cond::equal(Cond::column('someColumn'), '1'),
+ Cond::equal(Cond::column('someColumn'), '2')
+ )
+ )
+ ->find();
```
-$opportunityList = $entityManager->getRepository('Opportunity')->distinct()->find();
+
+```php
+getRDBRepository($entityType)
+ ->where(
+ Cond::in(Cond::column('id'), $subQuery)
+ )
+ ->find();
+```
+
+### Distinct
+
+```php
+getRDBRepository('Opportunity')
+ ->distinct()
+ ->find();
```
### Join
@@ -364,18 +734,23 @@ $opportunityList = $entityManager->getRepository('Opportunity')->distinct()->fin
Join relationship:
```php
-$contactList = $entityManager->getRepository('Contact')
+getRDBRepository('Contact')
->distinct()
->join('opportunities')
->where([
- 'opportunities.stage' => 'Closed Won',
- ])->find();
+ 'opportunities.stage' => 'Closed Won'
+ ])
+ ->find();
```
-Left Join relationship:
+Left-Join relationship:
```php
-$contactList = $entityManager->getRepository('Contact')
+getRDBRepository('Contact')
->distinct()
->leftJoin('opportunities')
->find();
@@ -383,74 +758,498 @@ $contactList = $entityManager->getRepository('Contact')
'opportunities' is a relationship name.
-Joining any table:
+Join alias:
```php
-$meetingList = $entityManager->getRepository('Meeting')
- ->join([
- [
- 'MeetingUser', // meeting_user table
- 'meetingUser', // it's an alias
- [
- 'meetingUser.meetingId:' => 'meeting.id' // join condition;
- // colon indicates that the right part is not a value;
- // it translates to meetingUser.meeting_id = meeting.id
- ]
- ]
- ])->where([
- 'meetingUser.userId' => $user->id,
- ])->find();
+getRDBRepository('Contact')
+ ->distinct()
+ ->join('opportunities', 'aliasForJoinedTable')
+ ->where([
+ 'aliasForJoinedTable.stage' => 'Closed Won'
+ ])
+ ->find();
```
-Join table alias:
+Joining any table (a table name should start with an upper case letter):
```php
-$contactList = $entityManager->getRepository('Contact')
- ->distinct()
- ->join([['opportunities', 'aliasForJoinedTable']])
+getRDBRepository('Meeting')
+ ->join(
+ 'MeetingUser', // meeting_user table
+ 'meetingUser', // alias
+ [
+ // Colon indicates that the right part is not a value.
+ // It translates to `meetingUser.meeting_id = meeting.id`.
+ 'meetingUser.meetingId:' => 'id', // join condition
+ 'meetingUser.deleted' => false, // important
+ ],
+ )
->where([
- 'aliasForJoinedTable.stage' => 'Closed Won'
- ])->find();
+ 'meetingUser.userId' => $user->getId()
+ ])
+ ->find();
```
-### Group By
+Joining a table with the query builder:
```php
-$selectParams = [
- 'select' => ['MONTH:closeDate', 'SUM:amountConverted']
- 'groupBy' => ['MONTH:closeDate'],
- 'whereClause' => [
- 'stage' => 'Closed Won'
- ],
- 'orderBy' => 1, // ordering by the first column
-];
+getRDBRepository('Meeting')
+ ->select([
+ 'id',
+ 'name',
+ ['meetingUser.status', 'meetingStatus'], // expression and alias
+ ])
+ ->join(
+ 'MeetingUser', // meeting_user table
+ 'meetingUser', // alias
+ [
+ 'meetingUser.meetingId:' => 'id', // join condition
+ 'meetingUser.deleted' => false, // important
+ ],
+ )
+ ->where([
+ 'meetingUser.userId' => $user->getId(),
+ ])
+ ->find();
+```
-$pdo = $this->getEntityManager()->getPDO();
-$sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams);
-$sth = $pdo->prepare($sql);
-$sth->execute();
+!!! important
-// results
-$rowList = $sth->fetchAll(\PDO::FETCH_ASSOC);
-```
+ When joining by a table name (upper case is used), `'deleted' => false` filter is not applied implicitly. You need to provide it explicitly.
-### Additional Params
+### Group By
-#### STH collection
+```php
+getQueryBuilder()
+ ->select()
+ ->from('Opportunity') // entity type
+ ->select(['MONTH:(closeDate)', 'SUM:(amountConverted)']) // complex expressions
+ ->groupBy('MONTH:(closeDate)') // complex expression
+ ->where([
+ 'stage' => 'Closed Won'
+ ])
+ ->order('MONTH:(closeDate)')
+ ->build();
-Can be used with `find` and `findRelated` methods. With this param provided, they will return a collection that doesn't allocate memory for all result data.
+$pdoStatement = $entityManager
+ ->getQueryExecutor()
+ ->execute($query);
+$rowList = $pdoStatement->fetchAll(\PDO::FETCH_ASSOC);
```
-$collection = $entityManager->getRepository('Email')
- ->limit(0, 10000)
- ->sth()
- ->find();
+
+## STH collection
+
+If STH is set (with `sth` method), the find method will return a collection (instance of `SthCollection`) that doesn't allocate memory for all result data.
+
+```php
+getRDBRepository('Email')
+ ->limit(0, 10000)
+ ->sth()
+ ->find();
foreach ($collection as $entity) {
// memory is allocated for each item, when collection is iterated
}
```
-### Complex expressions
+## Complex expressions
+
+`MONTH:(closeDate)` and `SUM:(amountConverted)` in the example above are complex expressions. [See more](../user-guide/complex-expressions.md) about them.
+
+It's possible to build expressions with the *Expression* class (as of v7.0).
+
+```php
+select(
+ Expr::if(
+ Expr::greaterOrEqual(Expr::column('opportunity.amount'), 1000),
+ '1000 or more',
+ 'less than 1000'
+ ),
+ 'alias'
+);
+```
+
+```php
+where(
+ Expr::greater(
+ Expr::column('opportunity.amount'),
+ 1000
+ )
+);
+```
+
+It's possible to add custom functions (as of v7.0.8). An implementation class name for a custom function should be defined in metadata by a path app > orm > platforms > Mysql > functionConverterClassNameMap. The class should implement `Espo\ORM\QueryComposer\Part\FunctionConverter` interface.
+
+## Query builder
+
+Delete:
+
+```php
+from('SomeTable')
+ ->where([
+ 'someColumn' => 'someValue'
+ ])
+ ->build();
+
+$entityManager->getQueryExecutor()->execute($query);
+```
+
+Select:
+
+```php
+select(['column1', 'column2', 'someExpression'])
+ ->from('SomeTable')
+ ->order('column1', 'DESC')
+ ->limit(0, 10)
+ ->build();
+
+$pdoStatement = $entityManager->getQueryExecutor()->execute($query);
+```
+
+```php
+select('SUM:(someColumn)', 'value')
+ ->from('SomeTable')
+ ->select('anotherColumn')
+ ->groupBy('anotherColumn')
+ ->build();
+
+$pdoStatement = $entityManager->getQueryExecutor()->execute($query);
+$row = $pdoStatement->fetch();
+$sum = $row['value'] ?? 0.0;
+```
+
+Update:
+
+```php
+in('SomeTable')
+ ->set(['status' => 'Expired'])
+ ->where([
+ 'status' => 'Pending',
+ 'expiresAt' => $dateTimeString,
+ ])
+ ->build();
+
+$entityManager->getQueryExecutor()->execute($query);
+```
+
+Update with join (in PostgreSQL, a subquery will be used):
+
+```php
+in('SomeTable')
+ ->set(['column:' => 'joinAlias.foreignColumn'])
+ ->join('AnotherTable', 'joinAlias', ['joinAlias.foreignId:' => 'id'])
+ ->where([
+ 'someColumn' => 'someValue'
+ ])
+ ->build();
+
+$entityManager->getQueryExecutor()->execute($query);
+```
+
+Insert:
+
+```php
+into('SomeTable')
+ ->columns(['column1', 'column2'])
+ ->values([
+ 'column1' => 'value1',
+ 'column2' => 'value2',
+ ])
+ ->build();
+
+$entityManager->getQueryExecutor()->execute($query);
+```
+
+Mass insert:
+
+```php
+into('SomeTable')
+ ->columns(['column'])
+ ->values([
+ ['column1' => 'value1'],
+ ['column2' => 'value2'],
+ ])
+ ->build();
+
+$entityManager->getQueryExecutor()->execute($query);
+```
+
+Mass insert by populating with a select sub-query:
+
+```php
+into('SomeTable')
+ ->columns(['column'])
+ ->valuesQuery($subQuery)
+ ->build();
+
+$entityManager->getQueryExecutor()->execute($query);
+```
+
+Union:
+
+```php
+all()
+ ->query($subQuery1)
+ ->query($subQuery2)
+ ->order(1, 'DESC')
+ ->limit(0, 5)
+ ->build();
+
+$pdoStatement = $entityManager->getQueryExecutor()->execute($query);
+```
+
+Cloning and modifying an existing query:
+
+```php
+limit(0, 10)
+ ->build();
+```
+
+## Mass insert
+
+Mass insert with Mapper:
+
+```php
+getMapper()->massInsert($collection);
+```
+
+## Transaction manager
+
+Transaction:
+
+```php
+getTransactionManager();
+
+$tm->start();
+
+try {
+ // do something
+ $tm->commit();
+} catch (Throwable $e) {
+ $tm->rollback(); // this will roll back everything done within the transaction
+}
+```
+
+Nested transactions:
+
+```php
+getTransactionManager();
+
+$tm->start();
+// do something
+$tm->start();
+// do something
+$tm->commit();
+// do something
+$tm->commit();
+```
+
+Running a function in a transaction:
+
+```php
+getTransactionManager()
+ ->run(
+ function () {
+ // Transaction started implicitly.
+ // Do something.
+ // Transaction committed implicitly or rolled back if an exception occurred.
+ }
+ );
+```
+
+Locking:
+
+```php
+getTransactionManager()->start();
+
+$entity = $entityManager
+ ->getRDBRepository('SomeTable')
+ ->where(['id' => $id])
+ ->forUpdate() // This will lock the selected rows until the transaction is finished.
+ ->findOne();
+
+// Do something with the entity.
+
+$entityManager->saveEntity($entity);
+
+$entityManager->getTransactionManager()->commit();
+```
+
+## Locker
+
+```php
+getLocker()->lockExclusive('SomeEntityType');
+
+// Do something.
+
+// This will unlock all locked tables.
+$entityManager->getLocker()->commit();
+```
+
+## Defs
+
+*As of v7.0.*
+
+An access point to read ORM metadata: entity, attribute, field, relation and index definitions.
+
+```php
+getDefs();
+```
+
+ORM Defs can also be required as a dependency so that it will be injected into your class. Use the type hint `Espo\ORM\Defs`.
+
+Check entity existence:
+
+```php
+hasEntity($entityType);
+```
+
+Entity defs:
+
+```php
+getEntity($entityType);
+```
+
+An attribute list:
+
+```php
+getAttributeNameList();
+```
+
+Attribute defs:
+
+```php
+getAttribute($attributeName);
+```
+
+A relation list:
+
+```php
+getRelationNameList();
+```
+
+Relation defs:
+
+```php
+getRelation($relationName);
+```
+
+A field list:
+
+```php
+getFieldNameList();
+```
+
+Field defs:
+
+```php
+getField($field);
+```
+
+See all available methods in:
+
+* `Espo\ORM\Defs\EntityDefs`
+* `Espo\ORM\Defs\AttributeDefs`
+* `Espo\ORM\Defs\RelationDefs`
+* `Espo\ORM\Defs\FieldDefs`
+* `Espo\ORM\Defs\IndexDefs`
+
+Attribute types:
+
+* `Entity::ID`
+* `Entity::VARCHAR`
+* `Entity::INT`
+* `Entity::FLOAT`
+* `Entity::TEXT`
+* `Entity::VARCHAR`
+* `Entity::FOREIGN`
+* `Entity::FOREIGN_ID`
+* `Entity::FOREIGN_TYPE`
+* `Entity::DATE`
+* `Entity::DATETIME`
+* `Entity::JSON_ARRAY`
+
+Relation types:
+
+* `Entity::MANY_MANY`
+* `Entity::HAS_MANY`
+* `Entity::BELONGS_TO`
+* `Entity::HAS_ONE`
+* `Entity::BELONGS_TO_PARENT`
+* `Entity::HAS_CHILDREN`
+* `Entity::JSON_OBJECT`
-`MONTH:closeDate` and `SUM:amountConverted` in the example above are complex expressions. [See more](../user-guide/complex-expressions.md) about them.
diff --git a/docs/development/quote-custom-calculations.md b/docs/development/quote-custom-calculations.md
index fd0737768..65caf20f2 100644
--- a/docs/development/quote-custom-calculations.md
+++ b/docs/development/quote-custom-calculations.md
@@ -10,36 +10,44 @@ You have added custom fields to quote items or/and quote entity types. You want
### Server-side calculation
-You need to create custom repository for Quote entity type.
+You need to create a custom Hook for the Quote entity type.
Create a new file:
-`custom/Espo/Custom/Repositories/Quote.php`
+`custom/Espo/Custom/Hooks/Quote/CalculateItems.php`
```php
has('itemList')) {
+ $entity->loadItemListField();
+ }
$itemList = $entity->get('itemList');
- $amount = 0.0;
+ $amount = 0.0;
foreach ($itemList as $item) {
$amount += $item->quantity * $item->unitPrice * $item->factor;
- }
+ }
$entity->set('amount', $amount);
- }
-}
-
+ }
+}
```
-Note: For Sales Orders use `SalesOrder` file and class names. For Invoices use `Invoice` file and class names. Extend from a corresponding classes: `\Espo\Modules\Sales\Repositories\SalesOrder` or `\Espo\Modules\Sales\Repositories\Invoice`.
+Note: For other entity types, e.g. SalesOrder, do the same but use *SalesOrder* namespace and file location instead of *Quote*.
### Client-side calculation
@@ -60,16 +68,53 @@ Create a new file:
`client/custom/src/quote-calculation-handler.js`
```js
-Espo.define('custom:quote-calculation-handler', ['sales:quote-calculation-handler'], function (Dep) {
+define(['sales:quote-calculation-handler'], (Dep) => {
+
+ return class extends Dep {
- return Dep.extend({
-
// Define custom calculations here.
// Use client/modules/sales/quote-calculation-handler.js as an example.
- });
+ /**
+ * Calculate.
+ *
+ * @param {import('model').default} model An order.
+ */
+ calculate(model) {
+ super.calculate(model);
+ }
+
+ /**
+ * Calculate item.
+ *
+ * @param {import('model').default} model An item.
+ * @param {string} [field] A field that was changed.
+ */
+ calculateItem(model, field) {
+ super.calculateItem(model, field);
+ }
+
+ /**
+ * Select product.
+ *
+ * @param {import('model').default} model
+ * @param {import('model').default} product
+ */
+ selectProduct(model, product) {
+ super.selectProduct(model, product);
+ }
+
+ /**
+ * Get select product attributes.
+ *
+ * @param {import('model').default} model
+ * @return {string[]}
+ */
+ getSelectProductAttributeList(model) {
+ super.getSelectProductAttributeList(model);
+ }
+ }
});
-
```
It's also possible to make certain product fields copied to a quote item on product selection. The logic is determined in selectProduct method.
diff --git a/docs/development/resources.md b/docs/development/resources.md
index f2917e8ae..e651ca2cc 100644
--- a/docs/development/resources.md
+++ b/docs/development/resources.md
@@ -18,7 +18,7 @@ Translation.
## layouts
-Layouts of enities.
+Layouts of entities.
`{PATH}/layouts/{EntityName}/{layoutName}.json`
@@ -27,115 +27,7 @@ Layouts of enities.
## metadata
-### app
-
-`{PATH}/Resources/metadata/app/`
-
-There are could be such `.json` files:
-- `acl`
-- `aclPortal`
-- `adminPanel`
-- `model`,
-- `currency`
-- `defaultDashboardLayouts`
-- `defaultDashboardOptions`
-- `deprecatedControllerActions`
-- `emailNotifications`
-- `entityTemplateList`
-- `export`
-- `fileStorage`
-- `formula`
-- `jsLibs`
-
-
-### clientDefs
-
-`{PATH}/metadata/clientDefs/{EntityName}.json`
-
-Contains data, related with view only. More Information is here
-clientDefs.md
-
-### dashlets
-
-Dashlet definition.
-
-`{PATH}/metadata/dashlets/{DashletName}.json`
-
-[How to create a dashlet](how-to-create-a-dashlet.md)
-
-
-### entityDefs
-
-Contains data, related to entity definition like fields definition, links definition (relationships), indexes, collection. In general data related with database.
-
-
-### fields
-
-Field types definition.
-
-fields.md link
-
-
-### integrations
-
-Integration definition. Options:
-
-- `fields` - definition of the fields, which are available on Itegration configuration view;
-
-- `params` - parameters of integrations, like `endpoint` and `scope`;
-
-- `clientClassName` - class name of Client of External Account, by defout is ;
-
-- `authMethod` - the method of authorization; in Client Manager has to be defined a method `create` + this value;
-
-- `view` - a view of the Integration configuration;
-
-- `allowUserAccounts` - could users configure own External Account of this integration,
-
-- `userView` - if `"allowUserAccounts": true"`, here you need to set a view of this configuring page.
-
- You can also define own options, you will use in your integration.
-
-
-`{PATH}/metadata/integrations/{IntegartionName}.json`
-
-
-### scopes
-
-Scope definition. scopes.md link
-
-
-### themes
-
-Theme definition.
-
-`{PATH}/metadata/themes/{ThemeName}.json`
-
-#### Example
-
-```
-{
- "stylesheet": "client/css/espo/espo-vertical.css",
- "stylesheetIframe": "client/css/espo/espo-vertical-iframe.css",
- "navbarIsVertical": true,
- "navbarStaticItemsHeight": 65,
- "recordTopButtonsStickTop": 61,
- "recordTopButtonsBlockHeight": 21,
- "dashboardCellHeight": 155,
- "dashboardCellMargin": 19,
- "modalFooterAtTheTop": true,
- "modalFullHeight": true,
- "fontSize": 14,
- "textColor": "#333",
- "chartGridColor": "#ddd",
- "chartTickColor": "#e8eced",
- "chartSuccessColor": "#87C956",
- "chartColorList": ["#6FA8D6", "#4E6CAD", "#EDC555", "#ED8F42", "#DE6666", "#7CC4A4", "#8A7CC2", "#D4729B"],
- "chartColorAlternativeList": ["#6FA8D6", "#EDC555", "#ED8F42", "#7CC4A4", "#D4729B"]
-}
-```
->Used `application/Espo/Resources/metadata/themes/EspoVertical.json`
-
+Metadata.
## templates
diff --git a/docs/development/scheduled-job.md b/docs/development/scheduled-job.md
index 30524571a..655d7ea85 100644
--- a/docs/development/scheduled-job.md
+++ b/docs/development/scheduled-job.md
@@ -1,23 +1,42 @@
-# Creating custom Job (& Scheduled Job)
+# Scheduled Jobs
-To define a custom Scheduled Job, create a file `custom/Espo/Custom/Jobs/YourJobName.php` with the content.
+## Creating custom scheduled job
+
+Create a file `custom/Espo/Custom/Resources/metadata/app/scheduledJobs.json`:
+
+```json
+{
+ "YourJobName": {
+ "jobClassName": "Espo\\Custom\\Jobs\\YourJobName"
+ }
+}
+```
+
+Create a file `custom/Espo/Custom/Jobs/YourJobName.php` with the content.
```php
Scheduled Jobs.
+Now, you can create a scheduled job at Administration > Scheduled Jobs. *YourJobName* will be available in the picklist.
+
+You can also run your job **from CLI**:
+
+```
+bin/command run-job YourJobName
+```
diff --git a/docs/development/select-builder.md b/docs/development/select-builder.md
new file mode 100644
index 000000000..8c0a5be08
--- /dev/null
+++ b/docs/development/select-builder.md
@@ -0,0 +1,119 @@
+# Select Builder
+
+*As of v7.0.*
+
+The Select Builder builds select queries for the ORM. It applies search parameters (passed from the frontend), access control restrictions, text filters, bool filters, primary filters. It's utilized as a layer over the ORM, since the ORM does not know anything about access control, predefined filters. It does not know how to handle text filters. As well as it does not understand the format of search parameters passed from the frontend.
+
+See all available methods in the class `Espo\Core\Select\SelectBuilder`.
+
+Usage example (building a query):
+
+```php
+selectBuilderFactory->create();
+
+$query = $selectBuilder
+ ->from($entityType)
+ ->withStrictAccessControl() // applies ACL
+ ->withSearchParams($searchParams) // search parameters passed from the frontend
+ ->build();
+
+$collection = $this->entityManager
+ ->getRDBRepository($entityType)
+ ->clone($query)
+ ->find();
+```
+
+Usage example (building a query builder):
+
+```php
+from($entityType)
+ ->withPrimaryFilter($primaryFilter)
+ ->buildQueryBuilder() // to continue building by means of ORM
+ ->where([
+ 'someAttribute' => $someValue,
+ ])
+ ->build();
+```
+
+Usage example (another user):
+
+```php
+from($entityType)
+ ->forUser($user) // to apply access control for another user
+ ->withStrictAccessControl()
+ ->build();
+```
+
+In your class you need to require `Espo\Core\Select\SelectBuilderFactory` as a dependency.
+
+```php
+getRDBRepository($entityType)
+ ->clone($query)
+ ->find();
+```
+
+Or you can pass it to the QueryExecutor:
+
+```php
+getQueryExecutor()->execute($query);
+```
+
+## Search Params
+
+Search parameters. Usually passed from the frontend. The SearchParams object contains a primary filter, bool filters, text filter, where conditions, offset, limit, order, and what columns to select. When a frontend collection is fetched, search parameters are passed in the request.
+
+Class: `Espo\Core\Select\SearchParams`.
+
+A SearchParams object can be fetched from a Request object by using `Espo\Core\Record\SearchParamsFetcher`. Usually it's done in API action classes.
+
+```php
+searchParamsFetcher->fetch($request);
+
+ // ...
+ }
+}
+```
+
+## See also
+
+* [Definitions of Select framework, metadata > selectDefs](metadata/select-defs.md)
+
diff --git a/docs/development/select-manager.md b/docs/development/select-manager.md
index d99a1352c..b25697ad5 100644
--- a/docs/development/select-manager.md
+++ b/docs/development/select-manager.md
@@ -1,5 +1,7 @@
# Select Manager
+Important: Deprecated as of v6.1.0. Use Select Builder instead.
+
Select Manager can be utilized for generating and managing select params which subsequently will be feed to ORM.
Base class: [Base.php](https://github.com/espocrm/espocrm/blob/stable/application/Espo/Core/SelectManagers/Base.php).
@@ -16,7 +18,7 @@ $selectManager->applyOrder('createdAt', true, $params);
$selectManager->applyLimit(0, 5, $params);
$params['whereClause'][] = [
- 'accontId' => $accountId,
+ 'accountId' => $accountId,
];
$entityManager->getRepository('Opportunity')->find($params);
@@ -95,7 +97,7 @@ $selectManager->addLeftJoin([
## Custom Select Manager
-How to extend an existing salect manager for a specific entity type.
+How to extend an existing select manager for a specific entity type.
Example for *Account*. There is already extended class in `application/Espo/Modules/Crm/SelectManagers/Account.php`, so we need to extend from it.
diff --git a/docs/development/services.md b/docs/development/services.md
index 61db32f9f..ddc24d27d 100644
--- a/docs/development/services.md
+++ b/docs/development/services.md
@@ -1,144 +1,112 @@
-# Service classes
+# Service Classes
-It's supposed to write business logic in services.
+!!! note
-Locations of services:
+ Not to be confused with [*Container services*](di.md).
-* `application/Espo/Services/`
-* `application/Espo/Modules/{moduleName}/Services/`
-* `custom/Espo/Custom/Services/`
+Services are entry points for business logic. They are just regular PHP classes. You can write business logic right in a service class or delegate it inside the service to another classes. Controllers and Action classes are supposed to have little code. Usually, they call service methods.
-Service objects are created by the *serviceFactory*. Usually services are created inside controllers or another services.
+You can create a service class in any namespace you like (inside your module). Use the dependency injection to require this class in your Controller or Action class (your class will be passed to a constructor).
-*serviceFactory* utilizes *injectableFactory* (since v5.10.0). More info [here](di.md).
+## Creating service class
-Note that you need to clear cache after creating a service class.
-
-To **customize** an existing service you need to create a class in the custom directory and extend it from the existing one. It's also possible to customize within a module directory. Make sure that the *order* param of your module is higher than the value of the module of the extended service.
-
-Services can be placed in sub-directory: `SubDir\MyService`(since v5.10.0).
-
-## Example
-
-Controller `custom/Espo/Controllers/Opportunity.php`:
+Controller `custom/Espo/Custom/Controllers/SomeController.php`:
```php
getContainer()->get('serviceFactory')->create('HelloTest');
+ public function __construct(private MyService $myService)
+ {}
- return $service->doSomething($data);
+ public function postActionHello(Request $request, Response $response): void
+ {
+ $data = $request->getParsedBody();
+
+ $id = $data->id ?? null;
+
+ if (!$id) {
+ throw new BadRequest();
+ }
+
+ $this->myService->doSomething($id);
+
+ $response->writeBody('true');
}
}
-
```
-Service `custom/Espo/Services/HelloTest.php`:
+Service `custom/Espo/Custom/MyNamespace/MyService.php`:
```php
id)) throw new BadRequest();
+ public function __construct(private Acl $acl, private EntityManager $entityManager)
+ {}
- $em = $this->getInjection('entityManager');
- $acl = $this->getInjection('acl');
+ public function doSomething(string $id): void
+ {
+ $opportunity = $this->entityManager->getEntityById(Opportunity::ENTITY_TYPE, $id);
- $opportunity = $em->getEntity('Opportunity', $data->id);
+ if (!$opportunity) {
+ throw new NotFound();
+ }
- if (!$opportunity) throw new NotFound();
- if (!$acl->check($opportunity, 'edit')) throw new Forbidden();
+ if (!$this->acl->check($opportunity, Table::ACTION_EDIT)) {
+ throw new Forbidden("No 'edit' access.");
+ }
- $opportunity->set('stage', 'Closed Won');
+ $opportunity->set('stage', Opportunity::STATUS_CLOSED_WON);
$opportunity->set('probability', 100);
- $em->saveEntity($opportunity);
-
- return $opportunity->getValueMap();
+ $this->entityManager->saveEntity($opportunity);
}
}
```
-Services are not necessary need to be extended from *Base* class. Dependencies can be detected from constructot param names by *serviceFactory*. (available since v5.10.0)
-
## Record service
-Operations (CRUD and others) over entities (records) are handled by Record service `application/Espo/Services/Record`.
+The Record Service is a layer to access records via API. It handles CRUD (and some others) operations over entities (records). It applies validation and access checks before saving or reading.
-If your entity type belongs to a module, you can create its record service in `application/Espo/Modules/{moduleName}/Services/` directory. Otherwise the default record service will be used. You can also override existing record services in custom folder.
+The base class `Espo\Core\Record\Service`.
-Main methods:
+Main methods of the Record service class:
-* read
-* create
-* update
-* delete
-* find - used by list view
-* findLinked - used by relationship panels
-* massUpdate
-* massDelete
-* findDuplicates
-* loadAdditionalFields - for detail view
-* loadAdditionalFieldsForList - for list view
+* read – get an entity
+* create – create an entity
+* update – update an entity
+* delete – delete an entity
+* find – get a list of entities, used by list view
+* findLinked – get a list of related entities, used by relationship panels
+* loadAdditionalFields – to load additional fields for an entity before returning it, for detail view
-Hook-methods:
+!!! note
+
+ Record services can be extended in the `Espo\Modules\{MyModule}\Services` namespace. But it's recommended to avoid extending.
+ The framework allows customization by means of composition. See metadata > [recordDefs](metadata/record-defs.md).
-* beforeCreateEntity
-* afterCreateEntity
-* beforeUpdateEntity
-* afterUpdateEntity
-* beforeDeleteEntity
-* afterDeletEntity
+### Accessing record service
-Service `custom/Espo/Custom/Services/Opportunity.php`:
+Record services can be accessed from the record service container `Espo\Core\Record\ServiceContainer`.
```php
set('myNotStorableField', $someValue);
- }
-
- protected function afterDeleteEntity(Entity $entity, $data)
- {
- // do something after entity is deleted
- }
-}
+$service = $this->recordServiceContainer->get($entityType);
```
diff --git a/docs/development/template-custom-helper.md b/docs/development/template-custom-helper.md
index 1559f0dad..970563156 100644
--- a/docs/development/template-custom-helper.md
+++ b/docs/development/template-custom-helper.md
@@ -1,14 +1,15 @@
# Custom Template Helpers
-Available since version 5.8.0.
+*As of v7.0.*
-For PDF templates and system email templates.
+Helpers works for PDF templates and system email templates (Administration > Template Manager).
-Create a file `custom/Espo/Resources/metadata/app/templateHelpers.json`:
+
+Create a file `custom/Espo/Custom/Resources/metadata/app/templateHelpers.json`:
```json
{
- "myHelper": "Espo\\Custom\\TemplateHelpers\\MyHelper::myHelper"
+ "myHelper": "Espo\\Custom\\TemplateHelpers\\MyHelper"
}
```
@@ -16,40 +17,37 @@ Create a file `custom/Espo/Custom/TemplateHelpers/MyHelper.php`:
```php
" . $value . "";
+class MyHelper implements Helper
+{
+ public function __construct(
+ // Pass needed dependencies.
+ ) {
- return new LightnCandy\SafeString($html);
+ }
+
+ public function render(Data $data): Result
+ {
+ $color = $data->getOption('color');
+ $text = $data->getArgumentList()[0] ?? '';
+
+ return Result::createSafeString(
+ "" . $text . ""
+ );
}
}
```
-Then in a template you can use:
+Clear cache.
+
+Then, in a template, you can use:
```
-{{myHelper name color='#bd318e'}}
+{{myHelper 'some text' color='#bd318e'}}
```
+
diff --git a/docs/development/tests.md b/docs/development/tests.md
index 99c4d2515..ba9b4feca 100644
--- a/docs/development/tests.md
+++ b/docs/development/tests.md
@@ -1,19 +1,12 @@
# Tests
-Before running tests, you need to build for testing:
-
-```
-grunt test
-```
-
-This will build an inctance for integration tests and install phpunit (from require-dev).
-
## Unit tests
+
Command to run:
```
-vendor/bin/phpunit --bootstrap=./vendor/autoload.php tests/unit
+vendor/bin/phpunit
```
## Integration tests
@@ -39,7 +32,22 @@ return [
This config will be used for test instances that are built for each test.
+
+Before running tests, you need to build for testing:
+
+```
+grunt test
+```
+
+Running tests:
+```
+vendor/bin/phpunit tests/integration
+```
+
+## Static analysis
+
Command to run:
+
```
-vendor/bin/phpunit --bootstrap=./vendor/autoload.php tests/integration
+vendor/bin/phpstan
```
diff --git a/docs/development/translation.md b/docs/development/translation.md
index 37733c066..ce2754cae 100644
--- a/docs/development/translation.md
+++ b/docs/development/translation.md
@@ -12,11 +12,11 @@ Build po file with the following command:
node po.js en_EN
```
-(specify needed language instead of en_EN)
+(specify the needed language instead of en_EN)
-The file will be created in `build` directory.
+The file will be created in the `build` directory.
-After that you can translate the generated po file. You can use some utilite or service for PO file translating.
+After that you can translate the generated po file. You can use some utilities or service for PO file translating.
### Building language files from PO file
@@ -46,6 +46,6 @@ To add a new language create a file `custom/Espo/Custom/Resources/metadata/app/l
}
```
-Where *lg_LG* is a IETF language tag. 'lg' is the language code specified by ISO 639, 'CN' is a country code specified by 3166.
+Where *lg_LG* is a IETF language tag. 'lg' is the language code specified by ISO 639, 'CN' is a country code specified by ISO 3166.
Clear cache after that (Administration > Clear Cache). The language will be available at Administration > Settings and user's preferences.
diff --git a/docs/development/view.md b/docs/development/view.md
index 3b307e414..ef1b00ac5 100644
--- a/docs/development/view.md
+++ b/docs/development/view.md
@@ -1,204 +1,384 @@
# View
+The View is the most oftenly used class in the frontend. Every page is rendered by multiple view objects. Views can have child views. Child views can have their own child views and so on. When a parent view is rendered (by calling the `render` method), it generates a single HTML and adds it to the DOM. That HTML contains HTML of all child views. Any view can be re-rendered later.
-View is the most oftenly used class in frontend. Every page is rendered by multiple view objects. Views can have child views. Child views can have their own child views. And so on. When a parent view is rendered (by calling render() method), it generates HTML from all children and adds it to DOM.
-
-
-View file `client/custom/src/views/test/my-custom-view.js`:
+A view file `client/custom/src/views/test/my-custom-view.js`:
```js
-define('custom:views/test/my-custom-view', 'view', function (Dep) {
-
- return Dep.extend({
-
- // template file, contents is printed below
- template: 'custom:test/my-custom-view',
-
- // altertatively template can be defined right here
- //templateContent: '
{{{someKeyName}}}
',
-
- // initializing logic
- setup: function () {
- // calling parent setup method, you can omit it
- Dep.prototype.setup.call(this);
+// AMD module definition (ES modules are supported in ext-template). The first argument can be omitted.
+// Names should be in a lower case. A hyphen to be used for word separation.
+// The `custom:` prefix indicates to the loader that the base path is `client/custom/src`.
+// A `my-module:` prefix would correspond to `client/custom/modules/my-module/src`.
+define('custom:views/test/my-custom-view', ['view'], (View) => {
+
+ // Extending from the base `view` class.
+ return class extends View {
+
+ // Optionally, define an extended constructor.
+ constructor(options) {
+ super(options);
+ }
+
+ // A template. See the separate article about templates.
+ // language=Handlebars
+ templateContent = `
+
+
+ `
+
+ // Alternatively, a template can be defined in a separate file.
+ // The `custom` prefix indicates that the base path is `client/custom/res/templates`.
+ //template = 'custom:test/my-custom-view'
+
+ // Initializing. Called on view creation, the view is not yet rendered.
+ setup() {
+ // Calling the parent `setup` method, can be omitted.
+ super.setup();
+ // Instantiate some property.
this.someParam1 = 'test 1';
- // when we create a child view in setup method, rendering of the view will be held off
- // until the child view is loaded (ready)
+ this.addHandler('focus', '.record input[data-name="hello"]', (event, target) => {
+ // Do something.
+ });
+
+ // When we create a child view in the setup method, rendering of the view is held off
+ // until the child view is loaded (ready), the child view will be rendered along with the parent view.
+ // The first argument is a key name that can be used to access the view further.
+ // The second argument is a view name.
+ // The method returns a promise that resolves to a view object.
this.createView('someKeyName', 'custom:test/my-custom-child-view', {
- el: this.getSelector() + ' .some-test-container',
+ // A relative selector of the DOM container.
+ selector: '.some-test-container',
+ // Or a full selector.
+ //fullSelector: '#some-id',
+ // Pass some parameter.
someParam: 'test',
- });
+ });
- console.log(this.options); // options passed from a parent view
+ // Options passed from the parent view.
+ console.log(this.options);
- // all event listeners are recommended to be initialized here
-
- this.on('remove', function () {
-
- }, this);
+ // A model can be passed from the parent view.
+ console.log(this.model);
- // use listenTo & listenToOnce methods fore listening to events of another object
- // to prevent memory leakage
-
- this.listenTo(this.model, 'change', function () { // model changed
- if (this.model.hasChanged('test')) { // whether specific attribute changed
+ // All event listeners are recommended to be initialized in the `setup` method.
+
+ // Use listenTo & listenToOnce methods for listening to events of another object
+ // to prevent memory leakage.
+
+ // Subscribe to model change.
+ // Subscribing with the `listenTo` method guarantees automatic unsubscribing on view removal,
+ // so there won't be a memory leak.
+ this.listenTo(this.model, 'change', () => {
+ // Whether a specific attribute changed.
+ if (this.model.hasChanged('someAttribute')) {
+ const value = this.model.get('someAttribute');
}
- }, this);
+ });
- this.listenTo(this.model, 'sync', function () { // model saved or fetched
- }, this);
- },
-
- // called after contents is added to DOM
- afterRender: function () {
- console.log(this.$el); // view container DOM element
+ // Subscribe to model sync (saved or fetched). Fired only once.
+ this.listenToOnce(this.model, 'sync', () => {});
+
+ // Subscribe to a DOM event. `cid` contains an ID unique among all views.
+ // Requires explicit unsubscribing on view removal.
+ $(window).on('some-event.' + this.cid, () => {});
+
+ // Translating a label.
+ const translatedLabel = this.translate('myLabel', 'someCategory', 'MyScope');
+ }
+
+ // Called after contents is added to the DOM.
+ afterRender() {
+ // The view container (DOM element).
+ console.log(this.element);
+
+ // Accessing a child view.
+ const childView = this.getView('someKeyName');
- var childView = this.getView('someKeyName'); // get child view
+ // Checking whether a view is set.
+ const hasSomeView = this.hasView('someKeyName');
- this.clearView('someKeyName'); // destroy child view, will also remove it from DOM
- },
+ // Destroying a child view, also removes it from DOM.
+ this.clearView('someKeyName');
+
+ // Initializing a reference to some DOM element.
+ this.$someElement = this.$el.find('.some-element');
+ }
- // data passed to template
- data: function () {
+ // Data to be passed to the template.
+ data() {
return {
someParam2: 'test 2',
};
- },
-
- // DOM event handlers
- events: {
- 'click a[data-action="test"]': function (e) {
- console.log(e.currentTarget);
- this.actionTest();
- },
- },
+ }
- // called when the view is removed
- // useful for destroying some event listeners inialized for the view
- onRemove: function () {
-
- },
+ // Called when the view is removed.
+ // Useful for destroying event listeners initialized for the view.
+ onRemove() {
+ $(window).off('some-event.' + this.cid);
+ }
- // custom method
- actionTest: function () {
+ // A custom method.
+ someMethod1(value) {
+ // Create and render a child view.
+ this.createView('testKey', 'custom:test/my-another-custom-child-view', {
+ selector: '.another-test-container',
+ value: value,
+ })
+ .then(view => view.render());
+ }
- },
- });
-});
+ someMethod2() {
+ // To proceed only when the view is rendered.
+ // Useful when the method can be invoked by a caller before the view is rendered.
+ this.whenRendered().then(() => {
+ // Do something with DOM.
+ });
+ }
+ }
+}
```
-Template file `client/custom/res/templates/test/my-custom-view.tpl`:
+See more about [templates](frontend/templates.md).
-```html
-
{{{someKeyName}}}
+See [the source file](https://github.com/yurikuzn/bull/blob/master/src/bull.view.js) of the view class.
-
-```
+## Waiting for some data loaded before rendering
-[Handlebars](https://handlebarsjs.com/) library is used for template rendering.
+Sometimes we need to get some data loaded asynchronously before the view is rendered. For this purpose we can use the `wait` method inside the `setup` method.
-Note: When you extend a view that already has its *events* and you want to add more events, do it the following way:
+The `wait` method can receive a promise:
```js
- events: _.extend({
- 'click a[data-action="test"]': function () {
-
- },
- }, Dep.prototype.events),
+setup() {
+ this.wait(
+ Promise.all([
+ this.model.fetch(),
+ this.model.collection.fetch(),
+ ])
+ );
+}
```
-## Waiting for some data loaded before rendering
+The model factory returns a promise, so we can pass it to the `view` method:
-Sometimes we need to get some data loaded asynchronously before the view is rendered. For this purpose we can use `wait` method inside `setup` method.
+```js
+setup() {
+ this.wait(
+ this.getModelFactory().create('Case')
+ .then(model => {
+ model.id = this.model.id;
+
+ return model.fetch();
+ })
+ .then(data => {
+ console.log(data);
+ })
+ );
+}
+```
-Wait method can receive a promise:
+Wait until a model is fetched. The `fetch` method returns a promise.
```js
- setup: function () {
- this.wait(
- Promise.all([
- this.model.fetch(),
- this.model.collection.fetch()
- ])
- );
- },
+setup() {
+ this.wait(
+ this.model.fetch()
+ );
+}
```
-Model factory returns a promise.
+Wait for multiple independent promises:
```js
- setup: function () {
- this.wait(
- this.getModelFactory().create('Case')
- .then(
- function (model) {
- model.id = this.model.id
- return model.fetch();
- }.bind(this)
- )
- .then(
- function (data) {
- console.log(data);
- }
- )
- );
- },
+setup() {
+ this.wait(
+ this.model.fetch()
+ );
+
+ this.wait(
+ Espo.Ajax.getRequest('SomeUrl')
+ );
+}
```
-Wait for model is fetched. Fetch returns a promise.
+```js
+setup() {
+ this.wait(
+ Promise.all([
+ this.model.fetch(),
+ Espo.Ajax.getRequest('SomeUrl'),
+ ])
+ );
+}
+```
+
+A simple way to wait:
```js
- setup: function () {
- this.wait(
- this.model.fetch()
- );
- },
+setup() {
+ // This holds off the rendering.
+ this.wait(true);
+
+ Espo.Ajax.getRequest('Some/Request')
+ .then(response => {
+ // This cancels waiting and proceeds to rendering.
+ this.wait(false);
+ });
+}
+```
+
+!!! note
+
+ Feel free to use the async/await syntax instead of explicit promises.
+
+### setup
+
+Called internally on initialization. Put initialization logic here. Options passed by the parent view are available in `this.options`.
+
+### afterRender
+
+Called internally after render. Put manipulation with DOM here.
+
+### onRemove
+
+Called internally on view removal. Reasonable for unsubscribing.
+### createView
+
+Creates a child view. When we create a child view in the setup method, rendering of the view is held off until the child view is loaded (ready), the child view will be rendered along with the parent view. The first argument is a key name that can be used to access the view further (with `getView` method). The second argument is a view name. The method returns a promise that resolves to a view object.
+
+Arguments:
+
+* *viewKey* – a view key;
+* *viewName* – a view name (path);
+* *options* – options.
+
+Standard options (all are optional):
+
+* *selector* – a relative CSS to the view selector (as of v7.3);
+* *model* – a model;
+* *collection* – a collection.
+
+It's important that every view have their actual selector so that the application knows how to access them (for re-rendering).
+
+### clearView
+
+Removes a child view.
+
+Arguments:
+
+* *viewKey* – a view key.
+
+### getView
+
+Get a child view by a key.
+
+Arguments:
+
+* *viewKey* – a view key.
+
+### assignView
+
+*As of v7.5.*
+
+Assign a view instance as a child view.
+
+Arguments:
+
+* *viewKey* – a view key;
+* *view* – a view instance;
+* *selector* – a relative CSS selector.
+
+```js
+this.assignView('someKey', new SomeView(options), 'some-selector');
```
-Wait for multiple independent promises:
+### reRender
+
+Re-renders a view. Usually, called from inside the view. Returns a promise resolved once rendering is finished.
+
+Arguments:
+
+* *force* – *boolean* – force rendering if the view was not rendered before.
+
+### render
+
+Renders a view. Should be called if the view is called not in the *setup* method (after the view is already ready or rendered). Returns a promise resolved once rendering is finished.
```js
- setup: function () {
- this.wait(
- this.model.fetch()
- );
+templateContent = `
+
{{{someKeyName}}}
+`
+
+setup() {
+ this.createView('someKeyName', 'custom:test/my-custom-child-view', {});
+}
+
+async actionShowModal() {
+ const view = await this.createView('dialog', 'custom:test/my-modal-view', {selector: '[data-name="someName]'})
+
+ this.listenToOnce(view, 'some-event', eventData => {
+ console.log(eventData);
- this.wait(
- Espo.Ajax.getRequest('SomeUrl')
- );
- },
+ this.clearView('dialog');
+ });
+ await view.render();
+}
```
+### whenRendered
+
+Returns the promise resolving when the view is rendered.
+
```js
- setup: function () {
- this.wait(
- Promise.all([
- this.model.fetch(),
- Espo.Ajax.getRequest('SomeUrl')
- ])
- );
- },
+this.whenRendered().then(() => doSomethingWithDom());
```
-A simple way to wait:
+### data
+
+The method is called internally when rendering. Should return a key => value data (*Object.*) that will be passed to a template.
+
+
+### addHandler
+
+*As of v8.0.*
+
+Adds a DOM event handler.
```js
- setup: function () {
- this.wait(true); // this holds off the rendering
+this.addHandler('click', 'selector', 'methodName');
+this.addHandler('mousedown', 'selector', (event, target) => { ... });
+```
- Espo.Ajax.getRequest('Some/Request').then(
- function (response) {
- this.wait(false); // this cancels waiting and proceeds to rendering
- }.bind(this)
- );
- },
+## Events
+```js
+setup() {
+ // Use this way only when the view subscribes to self.
+ this.on(eventName, callback); // subscribe to self
+ this.once(eventName, callback); // subscribe once
+ this.off(eventName, callback); // unsubscribe
+
+ // Use this way to subscribe to another object. Prevents memory leaking.
+ this.listenTo(object, eventName, callback); // subscribe to another object
+ this.listenToOnce(object, eventName, callback);
+ this.stopListening(object, eventName); // unsubscribe
+
+ // Triggering event.
+ this.trigger(eventName);
+ this.trigger(eventName, objectWithEventData); // passing data
+}
```
+
+Multiple events can be specified separated by a whitespace.
+
+### Built-in events
+
+* `after:render` – after the view is rendered;
+* `remove` – when the view is removed (destroyed); use it for cleaning up.
diff --git a/docs/development/workflow-service-actions.md b/docs/development/workflow-service-actions.md
index d8f283d21..df0e128f4 100644
--- a/docs/development/workflow-service-actions.md
+++ b/docs/development/workflow-service-actions.md
@@ -2,41 +2,48 @@
Workflows allow to create custom service actions. This example will show how this can be done for a Call entity.
-## Step 1. Create service class
+*As of Advanced Pack v3.2.3.*
+
+## Step 1. Create a class
```php
Clear Cache. Now the service action is available for Workflows in the Run Service Action form.
+Administration panel > Clear Cache. Now the service action is available for Workflows in the *Run Service Action* form.
diff --git a/docs/extensions/advanced-pack/overview.md b/docs/extensions/advanced-pack/overview.md
new file mode 100644
index 000000000..f51ee375b
--- /dev/null
+++ b/docs/extensions/advanced-pack/overview.md
@@ -0,0 +1,9 @@
+# Advanced Pack Overview
+
+Advanced Pack is an [extension](https://www.espocrm.com/extensions/advanced-pack/) for EspoCRM.
+
+Features:
+
+* [Reports](../../user-guide/reports.md) – analytics, report panels and custom list view filters;
+* [Workflows](../../administration/workflows.md) – automation rules;
+* [BPM](../../administration/bpm.md) – business process management – automation with flowcharts.
diff --git a/docs/extensions/export-import/compare.md b/docs/extensions/export-import/compare.md
new file mode 100644
index 000000000..3eebaaaa4
--- /dev/null
+++ b/docs/extensions/export-import/compare.md
@@ -0,0 +1,264 @@
+# Compare changes
+
+The export feature is available in the [Export Import](https://github.com/espocrm/ext-export-import/releases) extension.
+
+## Usage
+
+In order to use the compare feature, you need to have an exported data (e.g. from a backup).
+
+This extension works via console (CLI). Commands should be executed from the `root directory` of your EspoCRM instance.
+
+```bash
+bin/command export-import compare --format=json --path="./data/export-import" --result-path="./data/export-import-result" --compare-type="all" --entity-list="Account" --skip-related-entities --pretty-print --info
+```
+
+## Result
+
+The result will be in a JSON format, so you can use `Total Commander`, `Double Commander` or even `git` to compare the results.
+
+### Statuses
+
+For each entity, the following statuses may be shown:
+
+* `Total`: total number of compared records.
+* `Created`: number of created records.
+* `Modified`: number of modified records.
+* `Skipped (both modified)`: number of modified records that have already been modified by another user or workflow. This is where records can be checked manually. To enable this folder, use [`--info`](#-info) and [`--from-date`](#-from-date) options.
+* `Unmodified`: number of unmodified records.
+* `Deleted`: number of deleted records.
+
+### Data structure
+
+This folder will contain data in a separate sub-folders:
+
+```
+.
+├── changed
+│ ├── actual
+│ ├── prev
+├── skipped
+│ ├── actual
+│ ├── prev
+```
+
+* `changed` folder contains the changed data.
+* `skipped` folder contains the both modified data that is skipped based on modifications found in the `modifiedAt` attribute, `Stream`, `Action History` and `Workflow Log`. To enable this folder, use [`--info`](#-info) and [`--from-date`](#-from-date) options.
+
+## Available options
+
+#### `--y`
+
+Confirmation of running the import. By default, a prompt will be displayed.
+
+#### `--path`
+
+A path for earlier exported data. The default value is `./data/export-import`. Example: `--path="PATH"`.
+
+#### `--result-path`
+
+A path for the comparison result. The default value is `./data/export-import-result`. Example: `--result-path="PATH"`.
+
+#### `--compare-type`
+
+A compare type. By default will be compared `all` records. Example: `--compare-type="TYPE"`.
+
+Available options:
+
+* `all`
+* `created`
+* `updated`
+* `deleted`
+
+#### `--skip-data`
+
+Skip comparison of changed data. By default, the data will be compared.
+
+#### `--skip-customization`
+
+**Note:** not yet implemented.
+
+Skip customization comparison made for the instance. By default, all customization will be compared.
+
+#### `--skip-config`
+
+**Note:** not yet implemented.
+
+Skip configuration comparison of the instance. By default, all configuration data will be compared.
+
+#### `--skip-internal-config`
+
+**Note:** not yet implemented.
+
+Skip comparison of internal configuration data which are stored at `config-internal.php`.
+Use [`--user-password`](import.md/#-user-password) in order to set a user password since the `passwordSalt` will not be exported / imported.
+
+#### `--entity-list`
+
+!!! note
+
+ - For advanced users only.
+ - The defined list will be imported only with data of `Many-to-One`, `One-to-One Right`, `Children-to-Parent` relationships.
+ - The `Many-to-Many`, `One-to-Many`, `One-to-One Left`, `Parent-to-Children` relationships for related entities should be defined in the list additionally.
+
+A list of Entity Type. If omitted, then all entity types are applied. Example: `--entity-list="ENTITY_TYPE1, ENTITY_TYPE2"`
+
+Supported values:
+
+* a string, e.g. `"Account"`;
+* a string which is separated by a comma, e.g. `"Account, Contact"`.
+
+#### `--all-customization`
+
+**Note**: This option works along with the `--entity-list` option only.
+
+This option allows you to compare all customization, ignoring the `--entity-list' option.
+
+#### `--skip-related-entities`
+
+Skip comparison of data and customization for related entities. This option is used in conjunction with `--entity-list`. By default, this option is `off`.
+
+#### `--pretty-print`
+
+Store data in a pretty print format. By default this option is `off`.
+
+#### `--info`
+
+Display information about skipped modifications. By default this option is `off`.
+
+#### `--from-date`
+
+The date and time in UTC from which the comparison will be made. By default this option is `off`. Example: `--from-date="2025-01-01 00:00:00"`
+
+#### `--skip-modified-at`
+
+Skip comparison of `modifiedAt` attribute. By default this option is `off`.
+
+#### `--skip-stream`
+
+Skip looking for modifications in a stream. By default this option is `off`.
+
+#### `--skip-action-history`
+
+Skip looking for modifications in Action History. By default this option is `off`.
+
+#### `--skip-workflow-log`
+
+Skip looking for modifications in Workflow Log. By default this option is `off`.
+
+#### `--skip-attribute-list`
+
+Skip comparison of attribute list. By default all attributes will be compared. Example: `--skip-attribute-list="name, Account.description, Call.firstName"`.
+
+Possible values:
+
+* a global attribute, e.g. `"name"`.
+* a local attribute, e.g. `"Account.description, Call.firstName"`.
+
+#### `--user-skip-list`
+
+Define a list of users to be skipped. The value can be a list of `ID` or `User Name`. Example: `--user-skip-list="admin"`.
+
+Available values:
+
+* `a string`, e.g. `"admin"`,
+* `a string which is separated by a comma`, e.g. `"admin, 65d34ab18e81e286e"`.
+
+#### `--entity-skip-list`
+
+This option allows you to compare data for defined entities. Example: `--entity-skip-list="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"Account"`,
+* `a string which is separated by a comma`, e.g. `"Account, Contact"`.
+
+#### `--entity-hard-list`
+
+This option allows you to export or import data for entities which are disabled by default, in `exportImportDefs` with the `"exportDisabled": true` or `"importDisabled": true` option. Example: `--entity-hard-list="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"ScheduledJob"`,
+* `a string which is separated by a comma`, e.g. `"ScheduledJob, ScheduledJobLogRecord"`.
+
+#### `--config-hard-list`
+
+**Note:** not yet implemented.
+
+This option allows you to compare data for config options which are disabled by default. Ex. `--config-hard-list="CONFIG_OPTION"`.
+The default list is defined in `application/Espo/Modules/ExportImport/Resources/metadata/app/exportImport.json`.
+
+Available values:
+
+* `a string`, e.g. `"database"`,
+* `a string which is separated by a comma`, e.g. `"database, siteUrl"`.
+
+## Use cases
+
+### Complete process for comparison
+
+This example will show how to compare your production data with data from a backup.
+
+1\. Restore your backup to a temporary instance. For example you have a backup from `2025-01-01 01:00:00`.
+
+2\. Install the [Export Import](https://github.com/espocrm/ext-export-import/releases) extension.
+
+3\. Run the export command to create a dump of your previous data:
+
+```bash
+bin/command export-import export --format=json --path="./data/export-import"
+```
+
+4\. Install the [Export Import](https://github.com/espocrm/ext-export-import/releases) extension on your production instance.
+
+5\. Copy the exported data from the step 3 to your production server.
+
+6\. Run the comparison command on your production instance:
+
+```bash
+bin/command export-import compare --format=json --path="./data/backup-data/export-import" --result-path="./data/export-import-result" --compare-type=all --from-date="2025-01-01 01:00:00" --pretty-print --info
+```
+
+* `--from-date` - the date and time in UTC from which the comparison will be made.
+
+7\. Check the result in the `./data/export-import-result` directory. See [Result](#result) section.
+
+### Restoring data
+
+!!! note
+
+ Before you start this process, make sure that you have a backup of your production data.
+
+!!! tip
+
+ It is recommended to restore only specified entities.
+
+1\. Follow the 1-5 steps described in [Complete process for comparison](#complete-process-for-comparison) section.
+
+2\. Run the comparison command on your production instance:
+
+```bash
+bin/command export-import compare --format=json --path="./data/backup-data/export-import" --result-path="./data/export-import-result" --compare-type=updated --from-date="2025-01-01 01:00:00" --pretty-print --info --entity-list="Account, Contact" --skip-related-entities
+```
+
+3\. If the comparison result is OK, then you can import the data to your production instance:
+
+```bash
+bin/command export-import import --format=json --path="./data/export-import-result/changed/prev" --import-type=update
+```
+
+### Compare data when modifiedAt is changed daily by a workflow
+
+For understanding how to compare data, see [Complete process for comparison](#complete-process-for-comparison) section.
+
+```bash
+bin/command export-import compare --format=json --path="./data/export-import" --result-path="./data/export-import-result" --compare-type=all --from-date="2025-01-01 01:00:00" --pretty-print --info --skip-modified-at
+```
+
+### Compare data when an attribute is changed daily by a workflow
+
+For understanding how to compare data, see [Complete process for comparison](#complete-process-for-comparison) section.
+
+```bash
+bin/command export-import compare --format=json --path="./data/export-import" --result-path="./data/export-import-result" --compare-type=all --from-date="2025-01-01 01:00:00" --pretty-print --info --skip-modified-at --skip-attribute-list="Lead.cAge"
+```
diff --git a/docs/extensions/export-import/customization.md b/docs/extensions/export-import/customization.md
new file mode 100644
index 000000000..99d516b93
--- /dev/null
+++ b/docs/extensions/export-import/customization.md
@@ -0,0 +1,189 @@
+# Customization
+
+Some additional features can be configured in the metadata defs. The path is `custom/Espo/Custom/Resources/metadata/exportImportDefs`.
+
+## Export additional fields
+
+If need to export additional fields that out of the standard functionality.
+
+#### exportAdditionalFieldList
+
+Example for Quotes: `custom/Espo/Custom/Resources/metadata/exportImportDefs/Quote.json`
+
+```json
+{
+ "exportAdditionalFieldList": [
+ "itemList"
+ ]
+}
+```
+
+## Skip export list
+
+If need to skip some records like `system` user or others.
+
+#### exportSkipLists
+
+Example for User: `custom/Espo/Custom/Resources/metadata/exportImportDefs/User.json`
+
+```json
+{
+ "exportSkipLists" : {
+ "id": [
+ "system"
+ ],
+ "userName": [
+ "tester"
+ ]
+ }
+}
+```
+
+## Placeholders
+
+Edit the file: `custom/Espo/Custom/Resources/metadata/exportImportDefs/ENTITY.json`.
+
+### Config
+
+#### Get
+
+```json
+{
+ "fields": {
+ "amountCurrency": {
+ "placeholderAction": "Config\\Get",
+ "placeholderData": {
+ "key": "defaultCurrency",
+ "default": null
+ }
+ }
+ }
+}
+```
+
+### User
+
+#### Password
+
+```json
+{
+ "fields": {
+ "password": {
+ "placeholderAction": "User\\Password",
+ "placeholderData": {
+ "value": "1"
+ }
+ }
+ }
+}
+```
+
+#### Active
+
+```json
+{
+ "fields": {
+ "isActive": {
+ "placeholderAction": "User\\Active"
+ }
+ }
+}
+```
+
+### Datetime
+
+#### Now
+
+```json
+{
+ "fields": {
+ "dateStart": {
+ "placeholderAction": "DateTime\\Now"
+ }
+ }
+}
+```
+
+#### ExportDifference
+
+The difference between the record date and the export date.
+E.g. record date = `2025-05-01`, export date = `2025-08-01`. When import data at `2025-12-01`, the record data will be `2025-09-01`.
+
+```json
+{
+ "fields": {
+ "dateStart": {
+ "placeholderAction": "DateTime\\ExportDifference"
+ }
+ }
+}
+```
+
+#### ExportDifferenceField
+
+The same logic as `ExportDifference`, but the initial value gets from another field.
+
+```json
+{
+ "fields": {
+ "createdAt": {
+ "placeholderAction": "DateTime\\ExportDifferenceField",
+ "placeholderData": {
+ "field": "dateStart",
+ "defaultAction": "DateTime\\Now"
+ }
+ }
+ }
+}
+```
+
+To get the initial value from a couple fields. The value will be obtained from the first defined field.
+
+```json
+{
+ "fields": {
+ "createdAt": {
+ "placeholderAction": "DateTime\\ExportDifferenceField",
+ "placeholderData": {
+ "fieldList": [
+ "dateStart",
+ "dateEnd",
+ "dateCompleted"
+ ],
+ "default": "2026-01-01 01:00:00"
+ }
+ }
+ }
+}
+```
+
+The `placeholderData` parameter accepts the following options:
+
+- `field` – Specifies the field name from which to retrieve the value. Note: `field` and `fieldList` are mutually exclusive.
+- `fieldList` – An array of field names to check for a value. The first non-empty field will be used.
+- `default` – A fallback value to use when the specified field(s) contain no data. Note: `default` and `defaultAction` are mutually exclusive.
+- `defaultAction` – A fallback placeholder action to execute when the specified field(s) contain no data.
+
+#### CurrentMonth
+
+```json
+{
+ "fields": {
+ "dateStart": {
+ "placeholderAction": "DateTime\\CurrentMonth"
+ }
+ }
+}
+```
+
+#### CurrentYear
+
+```json
+{
+ "fields": {
+ "dateStart": {
+ "placeholderAction": "DateTime\\CurrentYear"
+ }
+ }
+}
+```
diff --git a/docs/extensions/export-import/export.md b/docs/extensions/export-import/export.md
new file mode 100644
index 000000000..3172d10a9
--- /dev/null
+++ b/docs/extensions/export-import/export.md
@@ -0,0 +1,236 @@
+# Export
+
+The export feature is available in the [Export Import](https://github.com/espocrm/ext-export-import/releases) extension.
+
+## Usage
+
+This extension works via console (CLI). Commands should be executed from the `root directory` of your EspoCRM instance.
+
+```
+bin/command export-import export --format=json --path="./data/export-import"
+```
+
+## Available options
+
+#### `--y`
+
+Confirmation of running the import. By default, a prompt will be displayed.
+
+#### `--path`
+
+An export path. The default value is `./data/export-import`. Example: `--path="PATH"`.
+
+#### `--skip-data`
+
+Skip exporting data. By default, all data will be exported / imported.
+
+#### `--skip-customization`
+
+Skip exporting all customization made for the instance. By default, all customization will be exported.
+
+#### `--skip-config`
+
+Skip exporting configuration data. By default, all configuration data will be exported.
+
+#### `--skip-internal-config`
+
+Skip exporting internal configuration data which are stored at `config-internal.php`.
+Use [`--user-password`](import.md/#-user-password) in order to set a user password since the `passwordSalt` will not be exported.
+
+#### `--entity-list`
+
+!!! note
+
+ - For advanced users only.
+ - The defined list will be imported only with data of `Many-to-One`, `One-to-One Right`, `Children-to-Parent` relationships.
+ - The `Many-to-Many`, `One-to-Many`, `One-to-One Left`, `Parent-to-Children` relationships for related entities should be defined in the list additionally.
+
+A list of Entity Types. If omitted, then all entity types are applied. Example: `--entity-list="ENTITY_TYPE1, ENTITY_TYPE2"`
+
+Supported values:
+
+* a string, e.g. `"Account"`;
+* a string which is separated by a comma, e.g. `"Account, Contact"`.
+
+#### `--all-customization`
+
+**Note**: This option works along with the `--entity-list` option only.
+
+This option enables exporting all customization, ignoring the `--entity-list` option for customization.
+
+#### `--skip-related-entities`
+
+Skip exporting data and customization for related entities. This option is used in conjunction with `--entity-list`. By default, this option is `off`.
+
+#### `--pretty-print`
+
+Store data in a pretty print format. By default this option is `off`.
+
+#### `--user-skip-list`
+
+Define a list of users to be skipped. The value can be a list of `ID` or `User Name`. Example: `--user-skip-list="admin"`.
+
+Available values:
+
+* `a string`, e.g. `"admin"`,
+* `a string which is separated by a comma`, e.g. `"admin, 65d34ab18e81e286e"`.
+
+#### `--skip-password`
+
+Skip exporting passwords and changing passwords for existing users. Example: `--skip-password`.
+Use [`--user-password`](import.md/#-user-password) in order to set a user password.
+
+#### `--from-date`
+
+Export data from a specific date and time. All data before this date will be ignored. Applies only to entities with a `modifiedAt` field.
+The date should be in UTC and in the format *YYYY-MM-DD HH:mm:ss*.
+By default, this option is `off`. Example: `--from-date="2025-01-01 00:00:00"`
+
+#### `--entity-skip-list`
+
+This option allows you to skip exporting data for defined entities. Example: `--entity-skip-list="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"Account"`,
+* `a string which is separated by a comma`, e.g. `"Account, Contact"`.
+
+#### `--entity-hard-list`
+
+This option allows you to export data for entities which are disabled by default, in `exportImportDefs` with the `"exportDisabled": true` or `"importDisabled": true` option. Example: `--entity-hard-list="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"ScheduledJob"`,
+* `a string which is separated by a comma`, e.g. `"ScheduledJob, ScheduledJobLogRecord"`.
+
+#### `--config-hard-list`
+
+This option allows you to export data for config options which are disabled by default. Ex. `--config-hard-list="CONFIG_OPTION"`.
+The default list is defined in `application/Espo/Modules/ExportImport/Resources/metadata/app/exportImport.json`.
+
+Available values:
+
+* `a string`, e.g. `"database"`,
+* `a string which is separated by a comma`, e.g. `"database, siteUrl"`.
+
+## Use cases
+
+### Skip exporting passwords
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --skip-password
+```
+
+### Export customization only
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --skip-data --skip-config
+```
+
+### Export customization for a single entity along with relationships
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --skip-data --skip-config --entity-list="Account"
+```
+
+### Export customization for a single entity without relationships
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --skip-data --skip-config --entity-list="Account" --skip-related-entities
+```
+
+### Export data, configuration, customization for a single entity along with relationships
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Account"
+```
+
+### Export data, configuration, customization for a single entity without relationships
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Account" --skip-related-entities
+```
+
+## Use cases for Advanced Pack
+
+### Reports
+
+#### Export reports
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Report, ReportCategory, ReportFilter, ReportPanel" --skip-config --skip-customization --skip-related-entities
+```
+
+#### Export reports with custom entities
+
+If the Target Entity of at least one of the reports is a custom entity, you need to add it to the `--entity-list` option. Example:
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Report, ReportCategory, ReportFilter, ReportPanel, CustomEntity" --skip-config --skip-customization --skip-related-entities
+```
+
+#### Export reports with custom fields
+
+If the Target Entities of the reports are default entities, but at least one field in the one report is a custom field, you should add an `--all-customization` option and remove `--skip-customization` option. Example:
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Report, ReportCategory, ReportFilter, ReportPanel" --skip-config --all-customization --skip-related-entities
+```
+
+### Workflow
+
+If there are certain actions in the workflow, it's important to add the following entities to the `--entity-list` option (depending on the workflow actions):
+
+- Send Email - EmailTemplate, User, Team
+- Create Record - custom entity name if it is present in the action
+- Create Related Record - custom entity name if it is present in the action
+- Update Related Record - custom entity name if it is present in the action
+- Link with another Record - custom entity name if it is present in the action
+- Unlink from another Record - custom entity name if it is present in the action
+- Apply Assignment Rule - Team, Report
+- Create Notification - User, Team
+- Make Followed - User, Team
+- Start BPM Process - BpmnFlowchart
+
+#### Export workflows
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Workflow, WorkflowCategory, WorkflowCategoryPath" --skip-config --skip-customization --skip-related-entities
+```
+
+#### Export workflows created or changed since a specific date
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Workflow, WorkflowCategory, WorkflowCategoryPath" --skip-config --skip-customization --skip-related-entities --from-date="2025-01-01 00:00:00"
+```
+
+#### Export workflows with custom entities
+
+If the Target Entity of at least one of the workflows is custom entity, you need to add it to the `--entity-list` option. Example:
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="Workflow, WorkflowCategory, WorkflowCategoryPath, CustomEntity" --skip-config --skip-customization --skip-related-entities
+```
+
+### BPM
+
+Depending on the presence of certain BPM elements, the following entities should be added to the `--entity-list` option:
+
+- Task - see [Actions performance for Workflow and BPMs](#workflow)
+- Send Message Task - EmailTemplate, User, Team
+- User Task - Team
+
+#### Export BPMs
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="BpmnFlowchart" --skip-config --skip-customization --skip-related-entities
+```
+
+#### Export BPMs with custom entities
+
+If the Target Entity of at least one of the BPMs is custom entity, you need to add it to the `--entity-list` option. Example:
+
+```
+bin/command export-import export --format=json --path="./data/export-import" --entity-list="BpmnFlowchart, CustomEntity" --skip-config --skip-customization --skip-related-entities
+```
diff --git a/docs/extensions/export-import/import.md b/docs/extensions/export-import/import.md
new file mode 100644
index 000000000..2ae9498a2
--- /dev/null
+++ b/docs/extensions/export-import/import.md
@@ -0,0 +1,216 @@
+# Import
+
+The import feature is available in the [Export Import](https://github.com/espocrm/ext-export-import/releases) extension.
+
+## Usage
+
+This extension works via console (CLI). Commands should be executed from the `root directory` of your EspoCRM instance.
+
+```
+bin/command export-import import --format=json --path="./data/export-import" --import-type=createAndUpdate
+```
+
+## Available options
+
+#### `--y`
+
+Confirmation of running the import. By default, a prompt will be displayed.
+
+#### `--path`
+
+An import path. The default value is `./data/export-import`. Example: `--path="PATH"`.
+
+#### `--skip-data`
+
+Skip importing data. By default, all data will be imported.
+
+#### `--skip-customization`
+
+Skip importing all customization made for the instance. By default, all customization will be imported.
+
+#### `--skip-config`
+
+Skip importing configuration data. By default, all configuration data will be imported.
+
+#### `--skip-internal-config`
+
+Skip importing internal configuration data which are stored at `config-internal.php`.
+Use [`--user-password`](#-user-password) in order to set a user password since the `passwordSalt` will not be imported.
+
+#### `--entity-list`
+
+!!! note
+
+ - For advanced users only.
+ - The defined list will be imported only with data of `Many-to-One`, `One-to-One Right`, `Children-to-Parent` relationships.
+ - The `Many-to-Many`, `One-to-Many`, `One-to-One Left`, `Parent-to-Children` relationships for related entities should be defined in the list additionally.
+
+A list of Entity Types. If omitted, then all entity types are applied. Example: `--entity-list="ENTITY_TYPE1, ENTITY_TYPE2"`
+
+Supported values:
+
+* a string, e.g. `"Account"`;
+* a string which is separated by a comma, e.g. `"Account, Contact"`.
+
+#### `--all-customization`
+
+**Note**: This option works along with the `--entity-list` option only.
+
+This option enables importing all customization, ignoring the `--entity-list` option for customization.
+
+#### `--skip-related-entities`
+
+Skip importing data and customization for related entities. This option is used in conjunction with `--entity-list`. By default, this option is `off`.
+
+#### `--import-type`
+
+An import type. The default value is `createAndUpdate`. Example: `--import-type="TYPE"`.
+
+Available values:
+
+* `create`
+* `createAndUpdate`
+* `update`
+
+#### `--activate-users`
+
+Activate all imported users. The `Is Active` option will be defined as `true`.
+
+#### `--deactivate-users`
+
+Deactivate all imported users. The `Is Active` option will be defined as false.
+In order to keep at least one active user, use `--user-active-list="admin"`.
+
+#### `--user-active-list`
+
+Define a list of active users. The value can be a list of `ID` or `User Name`. Other users will be deactivated. Example: `--user-active-list="admin"`.
+
+Available values:
+
+* `a string`, e.g. `"admin"`,
+* `a string which is separated by a comma`, e.g. `"admin, 65d34ab18e81e286e"`.
+
+#### `--user-skip-list`
+
+Define a list of users to be skipped. The value can be a list of `ID` or `User Name`. Example: `--user-skip-list="admin"`.
+
+Available values:
+
+* `a string`, e.g. `"admin"`,
+* `a string which is separated by a comma`, e.g. `"admin, 65d34ab18e81e286e"`.
+
+#### `--user-password`
+
+A user password for all imported users. Example: `--user-password="PASSWORD"`.
+
+For resetting the password, use `bin/command set-password [username]`.
+
+#### `--skip-password`
+
+Skip changing passwords for existing users. Example: `--skip-password`.
+Use [`--user-password`](#-user-password) in order to set a user password.
+
+#### `--update-currency`
+
+To update all currency fields. This option depends on [`currency`](#-currency). If the `currency` option is not defined, the default currency will be used instead. By default, this option is `off`.
+
+#### `--currency`
+
+Currency symbol. If not defined, the default currency will be used instead. Example: `--currency="USD"`.
+
+#### `--update-created-at`
+
+Current time for the `createdAt` field. By default, this option is `off`.
+
+#### `--entity-skip-list`
+
+This option allows you to skip importing data for defined entities. Example: `--entity-skip-list="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"Account"`,
+* `a string which is separated by a comma`, e.g. `"Account, Contact"`.
+
+#### `--entity-hard-list`
+
+This option allows you to import data for entities which are disabled by default, in `exportImportDefs` with the `"exportDisabled": true` or `"importDisabled": true` option. Example: `--entity-hard-list="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"ScheduledJob"`,
+* `a string which is separated by a comma`, e.g. `"ScheduledJob, ScheduledJobLogRecord"`.
+
+#### `--config-hard-list`
+
+This option allows you to import data for config options which are disabled by default. Ex. `--config-hard-list="CONFIG_OPTION"`.
+The default list is defined in `application/Espo/Modules/ExportImport/Resources/metadata/app/exportImport.json`.
+
+Available values:
+
+* `a string`, e.g. `"database"`,
+* `a string which is separated by a comma`, e.g. `"database, siteUrl"`.
+
+#### `--entity-import-type-create`
+
+This option allows you to define a custom `create` import type for specified entity types. Example: `--entity-import-type-create="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"User"`,
+* `a string which is separated by a comma`, e.g. `"Account, Contact"`.
+
+#### `--entity-import-type-update`
+
+This option allows you to define a custom `update` import type for specified entity types. Example: `--entity-import-type-update="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"User"`,
+* `a string which is separated by a comma`, e.g. `"Account, Contact"`.
+
+#### `--entity-import-type-create-and-update`
+
+This option allows you to define a custom `createAndUpdate` import type for specified entity types. Example: `--entity-import-type-create-and-update="ENTITY_TYPE"`.
+
+Available values:
+
+* `a string`, e.g. `"User"`,
+* `a string which is separated by a comma`, e.g. `"Account, Contact"`.
+
+## Use cases
+
+### Keep passwords for existing users
+
+```
+bin/command export-import import --format=json --path="./data/export-import" --skip-internal-config --skip-password
+```
+
+### Import customization only
+
+```
+bin/command export-import import --format=json --path="./data/export-import" --skip-data --skip-config
+```
+
+### Import customization for a single entity along with relationships
+
+```
+bin/command export-import import --format=json --path="./data/export-import" --skip-data --skip-config --entity-list="Account"
+```
+
+### Import customization for a single entity without relationships
+
+```
+bin/command export-import import --format=json --path="./data/export-import" --skip-data --skip-config --entity-list="Account" --skip-related-entities
+```
+
+### Import data, configuration, customization for a single entity along with relationships
+
+```
+bin/command export-import import --format=json --path="./data/export-import" --import-type=createAndUpdate --entity-list="Account"
+```
+
+### Import data, configuration, customization for a single entity without relationships
+
+```
+bin/command export-import import --format=json --path="./data/export-import" --import-type=createAndUpdate --entity-list="Account" --skip-related-entities
+```
diff --git a/docs/extensions/export-import/overview.md b/docs/extensions/export-import/overview.md
new file mode 100644
index 000000000..ddb711bd2
--- /dev/null
+++ b/docs/extensions/export-import/overview.md
@@ -0,0 +1,33 @@
+# Export Import extension
+
+The Export Import extension is a tool for transferring data between EspoCRM instances using CLI commands.
+
+What can be transferred:
+
+* records
+* settings
+* customizations
+* files
+
+How it can be used:
+
+* as a part of a continuous delivery pipeline (e.g. to transfer roles, workflows, BPM flowcharts from dev to production);
+* for demo data;
+* when migrating to another instance;
+* to track changes;
+* to restore updated or deleted records.
+
+## Installing
+
+You need to install the Export Import extension on your EspoCRM instance. Download the latest release package from the [GitHub repository](https://github.com/espocrm/ext-export-import/releases). Follow [instructions](https://docs.espocrm.com/administration/extensions/#installing) to install the extension.
+
+## Features
+
+* [Export](export.md)
+* [Import](import.md)
+* [Compare changes](compare.md)
+
+## Additional information
+
+* [Run by code](run-by-code.md)
+* [Customization](customization.md)
diff --git a/docs/extensions/export-import/run-by-code.md b/docs/extensions/export-import/run-by-code.md
new file mode 100644
index 000000000..442151e31
--- /dev/null
+++ b/docs/extensions/export-import/run-by-code.md
@@ -0,0 +1,63 @@
+# Run by code
+
+In addition to the CLI, the commands can be executed by a code.
+
+## Import
+
+The `ExportImport` service can be injected as a constructor parameter.
+
+```php
+namespace Espo\Custom\Tools;
+
+use Espo\Modules\ExportImport\Tools\ExportImport;
+
+class MyImportTest
+{
+ public function __construct(private ExportImport $exportImportTool)
+ {}
+
+ public function runImport()
+ {
+ $this->exportImportTool->runImport([
+ 'path' => 'custom/Espo/Custom/MyData',
+ 'skipInternalConfig' => true,
+ 'userPassword' => 1,
+ 'userActiveList' => [
+ 'admin'
+ ],
+ 'updateCurrency' => true,
+ 'updateCreatedAt' => true,
+ 'entityHardList' => [
+ 'ScheduledJob'
+ ],
+ ]);
+ }
+}
+```
+
+## Export
+
+To export data, you can use the `runExport` method of the `ExportImport` service.
+
+```php
+namespace Espo\Custom\Tools;
+
+use Espo\Modules\ExportImport\Tools\ExportImport;
+
+class MyExportTest
+{
+ public function __construct(private ExportImport $exportImportTool)
+ {}
+
+ public function runExport()
+ {
+ $this->exportImportTool->runExport([
+ 'path' => 'custom/Espo/Custom/MyData',
+ 'entityList' => ['Account', 'Contact'],
+ 'skipConfig' => true,
+ 'skipCustomization' => true,
+ 'skipRelatedEntities' => true,
+ ]);
+ }
+}
+```
diff --git a/docs/extensions/google-integration/calendar.md b/docs/extensions/google-integration/calendar.md
index 4c7f53630..3f5379b9c 100644
--- a/docs/extensions/google-integration/calendar.md
+++ b/docs/extensions/google-integration/calendar.md
@@ -1,18 +1,22 @@
# Google Integration. Calendar sync
+!!! note
+
+ Before proceeding to this article, it's recommended to [set up the integration](setting-up.md).
+
[Google Integration](https://www.espocrm.com/extensions/google-integration) provides the ability to sync calendar events in both directions.
Features:
-* The ability to monitor multiple calendars
-* Syncing since specified date
-* Syncing attendees
-* The ability to choose what event types to sync
-* Private events are not synced
+* The ability to monitor multiple calendars.
+* Syncing since specified date.
+* Syncing attendees.
+* The ability to choose what event types to sync.
+* Private events are not synced.
## Setting-up for users
-Assuming, that the administrator has already set up the integration.
+Assuming that the administrator has already set up the integration.
Go to your user detail view (the menu on the very top-right corner > click on your user name). Then click *External Account* button.
@@ -26,7 +30,9 @@ A popup will show up asking for a user consent.
If everything went fine, a green label *Connected* should show up.
-**Important**: If you connected successfully, but *Google Calendar* checkbox didn't show up, that means that the administrator did not grant you access to *Google Calendar* scope.
+!!! important
+
+ If you connected successfully, but *Google Calendar* checkbox didn't show up, that means that the administrator did not grant you access to *Google Calendar* scope.
Check *Google Calendar* checkbox and configure sync parameters.
@@ -34,7 +40,7 @@ After that, you need to click *Save*.

-### Parameters
+## Parameters
* Direction – a type of sync. Possible types: *One-way: EspoCRM to Google*, *One-way: Google to EspoCRM*, and *Two-way*.
@@ -44,10 +50,16 @@ After that, you need to click *Save*.
* Default Entity – by default, events will be synced as entities of a selected type.
-* Remove Google Calendar Event upon removal in EspoCRM – if you create an event in Google Calendar, you can not delete it from EspoCRM (if you delete it in CRM, this event won’t be deleted in Google Calendar). If you check this box, it will allow to delete Google event from EspoCRM as well.
+* Remove Google Calendar Event upon removal in EspoCRM – if you create an event in Google Calendar, you can not delete it from EspoCRM (if you delete it in CRM, this event won’t be deleted in Google Calendar). If you check this box, it will allow to delete Google event from EspoCRM as well.
* Don’t sync event attendees.
* Main Calendar – all new events from EspoCRM will be created in this calendar (actual for *One-way: EspoCRM to Google* or *Two-way*).
* Other Calendars – other calendars to monitor.
+
+* Assign User's Default Team - a user default team will be auto-assigned to an event synced from Google Calendar to EspoCRM (see the `Default Team` parameter in a user's profile).
+
+## Misc
+
+If your Espo entity type has a *Varchar* or *Text* field named `location`, it will be synced with the Google Calendar's location.
diff --git a/docs/extensions/google-integration/contacts.md b/docs/extensions/google-integration/contacts.md
index 1d3ab1699..55dfeda2f 100644
--- a/docs/extensions/google-integration/contacts.md
+++ b/docs/extensions/google-integration/contacts.md
@@ -1,16 +1,18 @@
# Google Integration. Contacts
-[Google Integration](https://www.espocrm.com/extensions/google-integration) provides the ability to sync calendar events in both directions.
+!!! note
+
+ Before proceeding to this article it's recommended to [set up the integration](setting-up.md).
Features:
* The ability to push your EspoCRM contacts and leads to Google Contacts;
* The ability to choose Google Contacts groups;
-* Available fields: *Name*, *Description*, *Email Addresses*, *Phone Numbers*, and *Account Name*.
+* Fields pushed: *Name*, *Description*, *Email Addresses*, *Phone Numbers*, *Account Name*, *Account Title*, *Address*.
## Setting-up for users
-Assuming, that the administrator has already set up the integration.
+Assuming that the administrator has already set up the integration.
Go to your user detail view (the menu on the very top-right corner > click on your user name). Then, click *External Account* button.
@@ -24,7 +26,9 @@ A popup will show up asking for a user consent.
If everything went fine, a green label *Connected* should show up.
-**Important**: If you connected succesfully, but *Google Contacts* checkbox didn't show up, that means that the administrator did not grant you access to *Google Contacts* scope.
+!!! important
+
+ If you connected successfully, but *Google Contacts* checkbox didn't show up, that means that the administrator did not grant you access to *Google Contacts* scope.
Check *Google Calendar* checkbox. You can select *Google Contacts Groups*, to which EspoCRM records will be pushed.
diff --git a/docs/extensions/google-integration/gmail.md b/docs/extensions/google-integration/gmail.md
index 8bd375a1c..21d0e6750 100644
--- a/docs/extensions/google-integration/gmail.md
+++ b/docs/extensions/google-integration/gmail.md
@@ -1,18 +1,24 @@
# Google Integration. Gmail
+!!! note
+
+ Before proceeding to this article it's recommended to [set up the integration](setting-up.md).
+
Gmail Secure Authentication is available in [Google Integration](https://www.espocrm.com/extensions/google-integration) extension. It provides a secure authentication for Gmail accounts via OAuth2. With this extension, you won’t need to store your Gmail password in EspoCRM and enable access for less secure applications in your Google Account settings.
Note: Using in personal email accounts requires 5.9.2 version or later. Using in group email accounts requires 5.8.0 version or later.
## Setting-up email account
-Assuming, that the administrator has already set up the integration.
+Assuming that the administrator has already set up the integration.
Create a personal or group email account. Specify IMAP and SMTP parameters for Gmail (hosts: `imap.gmail.com` & `smtp.gmail.com`). Leave *Password* fields empty. Then, save the record.
After that, *Gmail* panel should appear on the right. You need to click *Connect* button. A popup will show up asking for a user consent.
-Note: You need to be logged in to Google as a user to which an email address of the current email account record belongs. For example, if you configure email account for *example@gmail.com*, you need to log in to Google as a user who has *example@gmail.com* email address.
+!!! note
+
+ You need to be logged in to Google as a user to which an email address of the current email account record belongs. For example, if you configure email account for *example@gmail.com*, you need to log in to Google as a user who has *example@gmail.com* email address.

diff --git a/docs/extensions/google-integration/setting-up.md b/docs/extensions/google-integration/setting-up.md
index 791c6d1ae..b01ea99b1 100644
--- a/docs/extensions/google-integration/setting-up.md
+++ b/docs/extensions/google-integration/setting-up.md
@@ -1,6 +1,6 @@
# Google Integration. Setting-up for Administrator
-Note, that the integration requires curl, libxml and xml PHP extensions installed. If any is not installed, you will be notified after saving.
+Note that the integration requires curl, libxml and xml PHP extensions installed. If any is not installed, you will be notified after saving.
* [Integration](#integration)
* [Access control](#access-control)
@@ -22,25 +22,45 @@ Do the following steps.
**3\.** Enable needed APIs.
-On the *Dashboard*, click *ENABLE APIS AND SERVICES*. Use search to find *Google Calendar API*, *Contacts API* and *Gmail API*. Enable those that you need to be used by the integration. Note, that some APIs can be already enabled.
+From the Navigation menu, click *APIs & Services* > *Enabled APIs & services*.
-
+
-**4\.** Create credentials.
+Then, click *+ ENABLE APIS AND SERVICES*.
+
+
+
+On the API Library page, use search to find the relevant APIs:
+
+* Google Calendar API (for Calendar sync);
+* Google People API (for Contacts pushing);
+* Gmail API (for secure connection to Gmail).
+
+Enable the APIs that you need to use in your CRM. Note that some APIs can be already enabled.
+
+
+
+**4\.** Configure consent screen.
+
+To create an OAuth client ID, you must first configure your OAuth consent screen. Go to OAuth consent screen and follow the instructions on the page.
+
+
+
+**5\.** Create credentials.
On the *Credentials* page, click *CREATE CREDENTIALS*, select *OAuth client ID*.
-
+
-Select 'Web application' in *Appication type* field. Add your site URL in *Authorized JavaScript origins*. Add *Redirect URI* (copied from EspoCRM integration panel) to *Authorized redirect URIs*.
+Select 'Web application' in *Application type* field. Add your site URL in *Authorized JavaScript origins*. Add *Redirect URI* (copied from EspoCRM integration panel) to *Authorized redirect URIs*.
-
+
-**5\.** Find *Client ID* and *Client secret*. Copy them to EspoCRM integration panel and save.
+**6\.** Find *Client ID* and *Client secret*. Copy them to EspoCRM integration panel and save.
-**6\.** Configure consent screen.
+!!! note
-In Google Developers Console, click *Oauth consent screen* on the sidebar. Follow the instructions on the page.
+ The Site URL should be configured properly in EspoCRM – it should be the URL address used to access your CRM instance. Otherwise, the integration will not work. The parameter is available under: Administration > Settings > Site URL.
## Access control
@@ -50,4 +70,4 @@ In Google Developers Console, click *Oauth consent screen* on the sidebar. Follo
* Google Calendar;
* Google Contacts.
-
\ No newline at end of file
+
diff --git a/docs/extensions/meeting-scheduler/index.md b/docs/extensions/meeting-scheduler/index.md
new file mode 100644
index 000000000..f549566f1
--- /dev/null
+++ b/docs/extensions/meeting-scheduler/index.md
@@ -0,0 +1,333 @@
+# Meeting Scheduler
+
+*Requires EspoCRM v9.0.*
+
+Available in the [Meeting Scheduler](https://www.espocrm.com/extensions/meeting-scheduler/) extension.
+
+With the Meeting Scheduler tool you can create online pages where contacts can book meetings with CRM users. Contacts can choose from time slots when the host is available. The scheduler configuration can help avoid meeting overload. You can also set up automated meeting distribution among multiple hosts.
+
+In this article:
+
+* [Access](#access)
+* [General](#general)
+* [Setting up](#setting-up)
+* [Overrides](#overrides)
+* [Questions](#questions)
+* [One-time links](#one-time-links)
+* [Requests](#requests)
+* [Round-robin host distribution](#round-robin-host-distribution)
+* [Zoom integration](#zoom-integration)
+* [Microsoft Teams integration](#microsoft-teams-integration)
+
+See more:
+
+* [Quick tour](https://app.supademo.com/demo/cmk18ly211ylwgmn8ctdsigqr)
+
+## Access
+
+Access to Meeting Schedulers and Meeting Requests are controlled by roles.
+
+An administrator can allow regular users to create and edit scheduler pages by setting needed access levels for the Meeting Scheduler scope.
+
+There's a possible configuration where a Meeting Scheduler is managed by one user but requests are distributed to other users. To be able to access Meeting Requests where the user is a host, the user should have the Meeting Scheduler scope enabled. Setting the action levels for the scope is not required – they all can be set to 'no'.
+
+The Meeting Scheduler Hosts scope allows users to configure schedulers that distribute meetings to other users.
+
+## General
+
+The system uses the parameter *Free/Busy Entity List* when determining busy time slots. This parameter is available under: Administration > Settings.
+
+!!! note
+
+ An attendee is required to fill in the email address when booking a meeting.
+
+## Setting up
+
+You can access the Meeting Schedulers list view from the navbar. There, you can create a new Meeting Scheduler.
+
+It's also possible to access Meeting Schedulers from the Meeting's list view.
+
+### General
+
+#### Name
+
+The name field will be used for meeting names and for the page title of the scheduling page.
+
+#### Active
+
+If a scheduler is not set as Active, the scheduling page will be unaccessible.
+
+#### Date Start, Date End
+
+The Date Start and Date End fields allow to set a period during which the scheduling page is functional.
+
+#### Description
+
+The description does not play any role other than of a description text for a user who view the scheduler.
+
+### Setup
+
+#### Meeting durations
+
+Specify meeting duration options an invitee can pick from.
+
+#### Meeting time precision
+
+The granularity of time slots available for scheduling meetings.
+
+#### Buffer time before meeting
+
+The amount of time automatically reserved before a meeting starts to prevent back-to-back scheduling.
+
+#### Buffer time after meeting
+
+The amount of time automatically reserved after a meeting ends to prevent back-to-back scheduling.
+
+#### Minimum lead time before meeting
+
+The shortest amount of time that must pass between the moment a meeting is scheduled and its start time.
+
+#### Scheduling window
+
+How far in the future a meeting can be scheduled.
+
+#### Daily limit
+
+*As of v1.1.*
+
+Maximum number of meetings that can be scheduled in a day. If more than the specified number are scheduled via the form, the day will be excluded from availability.
+
+#### Require approval by host
+
+A meeting won't be created until the request is approved by the host. The primary host can approve requests.
+
+#### Do not require approval if Contact exists
+
+If a meeting request is created by an invitee that already exists in the CRM as a Contact, then the approval step will be skipped. The email address is used to find a matching Contact.
+
+#### Do not reserve if unapproved
+
+If checked, then while a request is created but still is unapproved, it won't affect the host's availability. Multiple requests on the same time slots are possible in this case.
+
+#### Require confirmation by invitee
+
+A meeting won't be created until the request is confirmed by the invitee. The invitee will receive an email asking for confirmation. They can also cancel the request from the email.
+
+#### Do not require approval if Contact exists
+
+If a meeting request is created by an invitee that already exists in the CRM as a Contact, then the confirmation step will be skipped. The email address is used to find a matching Contact.
+
+#### Do not reserve if unconfirmed
+
+If checked, then while a request is created but still is unconfirmed, it won't affect the host's availability. Multiple requests on the same time slots are possible in this case.
+
+#### Confirmation window
+
+A period during which the invitee can confirm the request. After its expiration, the request will be marked as Expired.
+
+#### Send email invitation
+
+If checked, then an email invitation will be sent to the invitee upon meeting creation. The email invitations functionality is an out-of-the-box feature of EspoCRM. The email template can be configured under Administration > Template Manager > Invitation · Meeting.
+
+The invitee can accept or decline the meeting from the invitation email.
+
+#### Online location
+
+Specify the external service that will be used for online meetings. See below about the Zoom integration.
+
+#### Forbid free email domains
+
+If checked, an invitee won't be able to specify an email address of free email providers. Such as gmail.com, outlook.com, etc. They will be asked to use their work email address.
+
+#### Blocklists
+
+Selected Target Lists will be used as blocklists. If an invitee uses an email address that matches the email address of any target of the selected Target List, they won't be able to create a request.
+
+#### Meeting Description
+
+The description text that will be added to the meeting record.
+
+### Schedule
+
+Here you need to specify the availability schedule.
+
+The *Schedule* field defines time ranges of the general day schedule. Below, specify available weekdays. For each weekday, it's possible to define a custom day schedule. For example, on Friday you can have a shorter working day.
+
+The *Time Zone* defines the time zone of the configured schedule. Only this time zone is taken into account for the availability schedule. The user's time zone and the system default time zone have no effect here.
+
+#### Consider working time
+
+If checked, the working time of a host will be taken into account in their availability. For example, if a host is on day-off, they won't be available in the scheduler.
+
+The Working Time Calendar is the out-of-the-box feature in EspoCRM.
+
+Note that it's possible to override the availability schedule for specific day ranges and for specific hosts. See below about overrides.
+
+### Form
+
+Here you configure the scheduling page (form). The form URL will be generated after the Meeting Scheduler record is created. You can also re-generate the form URL. After re-generating, the form won't be accessible by the previous URL.
+
+#### Language used on form
+
+Choose the language that will be used on the scheduling form. You can edit labels for the needed language under Administration > Label Manager > Meeting Scheduler, Meeting Request.
+
+#### Allowed hosts for form embedding
+
+It's possible to include the scheduling form in an inline frame element (iframe) on a website. You need to specify the host of the website you are going to include the form on.
+
+#### Form Captcha
+
+Enables ReCaptcha for the form. To be able to use Captcha, you need to configure it under Administration > Integrations.
+
+#### Text to display on form
+
+The text will be displayed on the scheduling page at the top.
+
+#### URL to redirect to after form submission
+
+If specified, once an invitee submits the form, they will be redirected to the specified URL.
+
+The `meetingSchedulerRequest` URI parameter with the request ID will be appended to the URL. This allows you to retrieve the request data (for software developers).
+
+#### Text to display after form submission
+
+The text that will be displayed to an invitee once they submitted the form.
+
+#### Enable Form URL
+
+If not checked, the form won't be accessible by the form URL.
+
+### Hosts
+
+Here you can specify hosts and configure their distribution.
+
+If no hosts are specified, then meetings will be assigned to the assigned user of the Meeting Scheduler record.
+
+Only users who have the Meeting Scheduler Hosts scope enabled in their roles can edit the Hosts section.
+
+More information about host distribution is available in the Round-Robin section below.
+
+#### Fixed hosts
+
+Designate hosts that should always attend a meeting. If at least one of the fixed hosts is not available at a specific time, it won't be possible to schedule a meeting then.
+
+One of the fixed hosts is designated as primary. Meetings will be assigned to the primary host.
+
+It's possible to have no fixed hosts.
+
+#### Rotating hosts
+
+Rotating hosts are automatically picked by a specific round-robin algorithm. If at least one rotating host is available at a specific time, the time slot is treated as available for scheduling.
+
+#### Number of rotating hosts per meeting
+
+It's possible to have multiple rotating hosts picked per meeting. A meeting cannot be scheduled if the number of available hosts is fewer than the specified number.
+
+If the value is not specified, it's treated as one – only one rotating host will be picked.
+
+## Overrides
+
+Overrides allow to change scheduling for a specific date period. There are two types of overrides: *Not Available* and *Available*.
+
+An override can be associate with a specific user (host). If the host is not specified, the override is applied to the entire scheduler.
+
+## Questions
+
+By default, there are two mandatory fields on the scheduling form: *Name* and *Email Address*. It's possible to add additional custom question.
+
+Available field types:
+
+* String
+* Text
+* Enum
+* Checkbox
+* Checklist
+* Phone
+* Number
+* Decimal
+
+Questions can be set as required or optional. It's possible to specify a tooltip text for specific questions. Certain questions can be inactivated.
+
+An attendee's answers to the questions will be available in the Meeting Request record. They will be also added to the meeting's description.
+
+## One-time links
+
+One-time links are useful when you don't want to share your main scheduler page to avoid unwanted meetings. You can send a one-time link to a specific customer, allowing them to book a meeting with you.
+
+* Once a link is consumed, it's not available anymore.
+* Optionally, you can set an expiration date and time for a link.
+* A link can be associated with a specific Contact or Lead. In this case the created meeting will be automatically associated with that contact regardless of what email address the attendee specified. On the scheduling form, the email address will be pre-filled with the contact's email address.
+
+Note that one-time links function even if the Form URL is deactivated.
+
+## Requests
+
+Once an invitee filled in the scheduling form a Meeting Request is created. The request is assigned to the primary host of the meeting. If neither approval nor confirmation are required, the request will be set as Completed. Otherwise, it will be set as Pending.
+
+Requests can be approved and canceled by the request assignee, the scheduler assignee, and users who have edit access to the scheduler.
+
+Meetings requests can be accessed from navbar. The My Meeting Requests dashlet can be added on the dashboard.
+
+Unconfirmed requests expire. The expiry period is defined by the scheduler's configuration.
+
+On the Meeting Request detail view you can view the attendee's answers to the questions.
+
+## Round-robin host distribution
+
+!!! note
+
+ Host distribution can be configured only by users who have the Meeting Scheduler Hosts scope enabled in their roles.
+
+There are two distribution methods available:
+
+* Priority-Least-Recent
+* Balanced
+
+### Priority-Least-Recent method
+
+Available hosts with the highest priority are picked. Among them, the one that has been scheduled least recently is chosen.
+
+There are three priority levels for hosts: Low, Medium, and High.
+
+You can view and edit hosts selection orders by clicking *View Rotating Hosts* next to the *Edit* button.
+
+#### Assignee priority boost
+
+A host assigned to the Contact will receive the priority boost. This value defines the number of priority steps to increase.
+
+### Balanced method
+
+The available host with the fewest past selections adjusted by weight is chosen.
+
+You can view and edit hosts' weights and selection numbers by clicking *View Rotating Hosts* next to the *Edit* button.
+
+Weight can be an arbitrary number. A host with a weight of 100 will receive twice as many meetings as a host with a weight of 50.
+
+#### Assignee weight boost
+
+A host assigned to the Contact will receive the specified weight boost.
+
+Use this parameter if you want to give priority to a contact's assignee.
+
+#### Out-runner threshold
+
+Hosts that were selected more than the average, exceeding the specified threshold, will be excluded from availability. Weights are taken into account in calculation.
+
+Use this parameter if you don't want having hosts who received substantially more meetings than other hosts.
+
+## Zoom integration
+
+The Zoom integration is available as a separate [extension](../zoom-integration/index.md).
+
+With the Zoom integration installed, Zoom is available as an option in the *Online Location* field of a Meeting Scheduler record. To be able to select the Zoom location, users need to have access to the *Zoom Meetings* scope in their roles.
+
+When a meeting is created through the scheduler, a Zoom meeting is automatically created in the meeting assignee's Zoom account. The Join URL is stored in the Espo meeting.
+
+## Microsoft Teams integration
+
+The integration with Microsoft Teams is implemented in the [Outlook Integration](https://www.espocrm.com/extensions/outlook-integration/) extension.
+
+With the extension installed, the Microsoft is available as an option in the *Online Location* field of a Meeting Scheduler record. To be able to select the Microsoft location, users need to have access to the *Outlook Calendar* scope in their roles. They also need to be connected to Outlook in their External Account settings and to have the Calendar checkbox enabled. Note that the sync direction can be set to any value including *None*.
+
+When a meeting is created through the scheduler, a Microsoft meeting is automatically created in the meeting assignee's calendar. The Join URL is stored in the Espo meeting.
+
diff --git a/docs/extensions/outlook-integration/calendar.md b/docs/extensions/outlook-integration/calendar.md
index 39201bf32..e8b42f0e3 100644
--- a/docs/extensions/outlook-integration/calendar.md
+++ b/docs/extensions/outlook-integration/calendar.md
@@ -1,23 +1,33 @@
# Outlook Integration. Calendar
-Outlook Calendar Sync is available in the [extension](https://www.espocrm.com/extensions/outlook-integration/). Compatible with EspoCRM 5.6.3 and higher.
+!!! note
+
+ Before proceeding to this article, it's recommended to [set up the integration](setting-up.md).
+
+Outlook Calendar Sync is available in the [extension](https://www.espocrm.com/extensions/outlook-integration/).
Features:
-* Meetings, Calls, custom entities of Event type can be synced from EspoCRM to Outlook.
-* Attendees are synced from Outlook to EspoCRM as Contacts, Leads, and Users.
-* Attendees are not synced from EspoCRM to Outlook.
-* Outlook recurring activities are not synced to EspoCRM.
+* Meetings, Calls, custom entities of Event type can be synced from Espo to Outlook.
+* Attendees are synced from Outlook to Espo as Contacts, Leads, and Users.
Three modes of sync are supported:
-* Outlook to EspoCRM
-* EspoCRM to Outlook
+* Outlook to Espo
+* Espo to Outlook
* Both
+Limitations:
+
+* Attendees are not synced from Espo to Outlook.
+* Outlook recurring activities are not synced to Espo.
+* *Description* field is not synced back from Outlook to Espo if an event was created in Espo.
+* *Description* field is not synced back from Espo to Outlook if an event was created in Outlook.
+* Events created in Espo won't be removed in Espo on removal in Outlook. A measure to overcome a bug in Outlook that could cause unwanted event removals.
+
## Setting up for users
-Assuming, that the administrator has already set up the integration.
+Assuming that the administrator has already set up the integration.
Go to your user detail view (the menu on the very top-right corner > click on your user name). Then, click *External Account* button.
@@ -31,10 +41,16 @@ A popup will show up asking for a user consent.
If everything went fine, a green label *Connected* should show up.
-**Important**: If you connected successfully, but *Outlook Calendar* checkbox didn't show up, that means that the administrator did not grant you access to *Outlook Calendar* scope.
+!!! important
+
+ If you connected successfully, but *Outlook Calendar* checkbox didn't show up, that means that the administrator did not grant you access to *Outlook Calendar* scope.
Check *Outlook Calendar* checkbox and configure sync parameters.

-After that, you need to click *Save*.
\ No newline at end of file
+After that, you need to click *Save*.
+
+## Misc
+
+If your Espo entity type has a custom *Varchar* field named `location`, it will be synced with Outlook Calendar. As of v1.4.0.
diff --git a/docs/extensions/outlook-integration/contacts.md b/docs/extensions/outlook-integration/contacts.md
index c4407025b..45171dda8 100644
--- a/docs/extensions/outlook-integration/contacts.md
+++ b/docs/extensions/outlook-integration/contacts.md
@@ -1,15 +1,19 @@
# Outlook Integration. Contacts
-Outlook Contacts Integration is available in the [extension](https://www.espocrm.com/extensions/outlook-integration/). Compatible with EspoCRM 5.6.3 and higher.
+!!! note
-Provides the ability to push EspoCRM contacts and leads to Outlook Contacts (People) into a specific folder. Fields being pushed: First Name, Last Name, Email Address, Phone Number, and Account Name.
+ Before proceeding to this article it's recommended to [set up the integration](setting-up.md).
+
+Outlook Contacts Integration is available in the [extension](https://www.espocrm.com/extensions/outlook-integration/).
+
+Provides the ability to push EspoCRM contacts and leads to Outlook Contacts (People). The following fields are pushed: First Name, Last Name, Email Address, Phone Number, and Account Name.
* [Setting up for users](#setting-up-for-users)
* [Pushing to Outlook](#pushing-to-outlook)
## Setting up for users
-Assuming, that the administrator has already set up the integration.
+Assuming that the administrator has already set up the integration.
Go to your user detail view (the menu on the very top-right corner > click on your user name). Then, click *External Account* button.
@@ -23,14 +27,18 @@ A popup will show up asking for a user consent.
If everything went fine, a green label *Connected* should show up.
-**Important**: If you connected successfully, but *Outlook Contacts* checkbox didn't show up, that means that the administrator did not grant you access to *Outlook Contacts* scope.
+!!! important
+
+ If you connected successfully, but *Outlook Contacts* checkbox didn't show up, that means that the administrator did not grant you access to *Outlook Contacts* scope.
Check *Outlook Contacts* checkbox and configure parameters and then click *Save*.
+Optionally, you can select a contact folder. Contacts will be pushed to that folder.
+
## Pushing to Outlook
1. Go to the contacts or leads list view.
2. Select needed items. You can also select all search results.
3. From *Actions* dropdown menu click *Push to Outlook*.
-It's also possible to push from the detail view. The action is available in the dropdown next to *Edit* button.
\ No newline at end of file
+It's also possible to push from the detail view. The action is available in the dropdown next to *Edit* button.
diff --git a/docs/extensions/outlook-integration/email.md b/docs/extensions/outlook-integration/email.md
index 5c33cf56c..eab20a89a 100644
--- a/docs/extensions/outlook-integration/email.md
+++ b/docs/extensions/outlook-integration/email.md
@@ -1,19 +1,57 @@
# Outlook Integration. Email
-Oauth authentication is available in [Outlook Integration](https://www.espocrm.com/extensions/outlook-integration) extension. It provides a secure authentication for Office 365 accounts. With this extension, you won’t need to store your Outlook password in EspoCRM.
+!!! note
-Note: At the current moment (June 2020) Oauth for IMAP & SMTP is supported **only for Office 365**. It doesn't work for regular Outlook accounts.
+ Before proceeding to this article it's recommended to [set up the integration](setting-up.md).
-Note: Requires EspoCRM v5.9.3 or later.
+OAuth IMAP and SMTP authentication is available in the [Outlook Integration](https://www.espocrm.com/extensions/outlook-integration) extension. It provides a secure authentication for Microsoft 365 and Outlook.com accounts. With this extension, you won’t need to store your Outlook password in EspoCRM.
+
+Optionally, the extension allows the use of the Microsoft Graph API for sending emails.
+
+In this article, both Microsoft 365 and Outlook.com will be referred to as *Outlook*.
## Setting-up email account
-Assuming, that the administrator has already set up the integration.
+Assuming that the administrator has already set up the Outlook integration.
+
+Create a Personal or Group Email Account. The the you create, specify IMAP and SMTP parameters for Outlook. IMAP host: `outlook.office365.com` or `imap-mail.outlook.com`; SMTP host: `smtp.office365.com`. Leave the *Password* fields empty for both IMAP and SMTP. Then, save the record.
+
+After that, the *Outlook* panel should appear on the right. You need to click *Connect* button. A popup will show up asking for a user consent.
+
+!!! note
+
+ You need to be logged in to Outlook as a user to which an email address of the current email account record belongs. For example, if you configure an email account for *example@outlook.com*, you need to log in to Outlook as a user who has *example@outlook.com* email address.
+
+After that, you can test IMAP connection and sent a test email to make sure everything works fine.
+
+!!! note
+
+ If during IMAP testing STARTTLS doesn't work, try the SSL/TLS option.
+
+## Recommendations
+
+Recommendations for setting up an email account if you encounter errors when connecting to SMTP:
+
+1. Ensure you are not signed into `office.com`.
+2. Clear cookies and other site data.
+3. Go to email account and connect to Outlook.
+4. Click Test Connection button, check if successful.
+6. Click Send Test Email button, check if successful.
+
+## Graph API
+
+*As of v1.6.*
+
+Requires EspoCRM v9.1 or greater.
+
+*Mail.Send* API permission should be enabled for the Azure application in the API Permissions tab.
+
+An administrator can enable sending emails via Graph API. Under Administration > Integrations > Outlook, check *Send emails via Graph API*.
-Create a personal or group email account. Specify IMAP and SMTP parameters for Office 365 (hosts: `outlook.office365.com` & `smtp.office365.com`). Leave *Password* fields empty. Then, save the record.
+!!! important
-After that, *Outlook* panel should appear on the right. You need to click *Connect* button. A popup will show up asking for a user consent.
+ When the Graph API is enabled for sending, it's not possible to use the same Espo email account record for both sending emails and receiving emails. Separate email accounts for the same email address should be created. One – for sending (via Graph API), another – for receiving (classic IMAP). Then, connect both accounts to Microsoft using the *Connect* button.
-Note: You need to be logged in to Outlook as a user to which an email address of the current email account record belongs. For example, if you configure email account for *example@outlook.com*, you need to log in to Outlook as a user who has *example@outlook.com* email address.
+!!! note
-After that, you can test imap connection and sent test email to make sure everything works fine.
+ We recommended to use the standard SMTP for email sending. Use Graph API only if necessary.
diff --git a/docs/extensions/outlook-integration/setting-up.md b/docs/extensions/outlook-integration/setting-up.md
index 7294f9e13..810bcbc80 100644
--- a/docs/extensions/outlook-integration/setting-up.md
+++ b/docs/extensions/outlook-integration/setting-up.md
@@ -11,6 +11,7 @@ Go to the Administration > Integrations > Outlook. Check *Enabled* checkbox.
* You will obtain *Client ID* and *Client Secret* in Azure Active Directory admin center.
* You will need to copy *Redirect URI* to Azure Active Directory admin center.
+* It is recommended to set `select_account` option as an *Authorization Prompt*.

@@ -40,6 +41,8 @@ Copy *Redirect URI* from EspoCRM. Note, that type should be set to `Web`.

+If the *Never* option is not available, choose *In 2 years*. In this case you will need to re-generate the secret in 2 years.
+


@@ -48,7 +51,9 @@ Copy *Redirect URI* from EspoCRM. Note, that type should be set to `Web`.
**6\.** Grant required permissions for Azure app.
-Note: This step is required for Office365 users. For Outlook, it usually works without this step, but it might be needed either.
+!!! note
+
+ This step is required for Microsoft 365 users. For Outlook.com, it usually works without this step, but it might be needed either.
Click *Api Permissions* on the left panel. Click *Add a permission*. Click *Microsoft Graph*. Click *Delegated permissions*. Then, use search to find the needed permissions and enable them.
@@ -62,6 +67,11 @@ Permissions that need to be enabled:

+After adding the above listed API permissions, click Grant Admin Consent for (your organization).
+
+!!! note
+
+ The Site URL should be configured properly in EspoCRM – it should be the URL address used to access your CRM instance. Otherwise, the integration will not work. The parameter is available under: Administration > Settings > Site URL.
## Access control
@@ -82,4 +92,10 @@ Sync is run by the scheduled job *Outlook Calendar Sync*. By default, it is exec
Check whether the scheduled job is running Administration > Scheduled Jobs > Outlook Calendar Sync > Log.
-Check EspoCRM log at `data/logs` directory. You can also set the [log mode](../../administration/troubleshooting.md#enabling-debug-mode-for-a-logger) to `DEBUG` level to obtain more info from the log.
\ No newline at end of file
+Check EspoCRM log at `data/logs` directory. You can also set the [log mode](../../administration/troubleshooting.md#debug-mode) to `DEBUG` level to obtain more info from the log.
+
+## Microsoft 365 configuration
+
+### Enabling SMTP
+
+For Microsoft 365, you might need to enable SMTP AUTH for specific mailboxes. See how to do it in the [Microsoft documentation](https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission#use-the-microsoft-365-admin-center-to-enable-or-disable-smtp-auth-on-specific-mailboxes).
diff --git a/docs/extensions/project-management/projects.md b/docs/extensions/project-management/projects.md
new file mode 100644
index 000000000..fa968e3cb
--- /dev/null
+++ b/docs/extensions/project-management/projects.md
@@ -0,0 +1,334 @@
+# Projects
+
+The Projects functionality is available in the [Project Management](https://www.espocrm.com/extensions/project-management/) extension.
+
+In this article:
+
+* [Projects](#projects)
+* [Boards](#boards)
+* [Access control](#access-control)
+* [Members](#members)
+* [Tasks](#tasks)
+* [Milestones](#milestones)
+* [Groups](#groups)
+* [Plan view](#plan-view)
+* [Board view](#board-view)
+* [Gantt view](#gantt-view)
+* [Project cloning](#project-cloning)
+* [Dashlet](#dashlet)
+* [Shortcut keys](#shortcut-keys)
+
+## Projects
+
+The Projects list view is available from the Projects tab in the navigation bar. Here you can create a new Project.
+
+A project owner can manage the project team by adding or removing members (Users) and changing their roles in the project.
+
+Each Project has a Stream. It can be used to post information or attach files. Project updates are automatically posted in the Stream.
+
+A Project has Activities and History panels. Meetings, Calls, and Emails can be related to a Project.
+
+{width="594"}
+
+
+### Project categories
+
+*As of v1.4.*
+
+Projects can be organized into categories. Categories follow a hierarchical, tree-like structure.
+
+Access to categories is controlled by Roles, with the Project Category scope. Only administrators can create or edit categories.
+
+## Boards
+
+A Project Board defines board Stages for a Project. The *Board* field is mandatory in a Project. It can be set only when you create a Project. Multiple Projects can use the same Project Board.
+
+Each Stage is mapped to a specific Status value. Multiple Stages can be mapped to the same status. For example, the *In Progress* and *Review* stages are mapped to the status *Started*.
+
+Available statuses:
+
+* Not Started
+* Started
+* Completed
+* Canceled
+* Deferred
+
+A Task in a Project is usually assigned to a specific Stage. When a Stage is changed, the Task's status is automatically changed to a mapped status.
+
+The *Default* Project Board is available out of the box. You can create new Project Boards. When you create a Project Board, default Stages are automatically added. You can rename the Stages or add new ones.
+
+## Access control
+
+Access control for Projects is managed by Roles and project-level roles.
+
+### Roles
+
+To be able to access Projects, a user must have the *Project* scope enabled in Roles. For minimum access, set: create = no, read = own, edit = no, delete = no.
+
+To be able to create Projects, a user must have *Create* access for the Project scope and *Read* access for the Project Board scope.
+
+### Project-level Roles
+
+A project owner or a user with *Edit* access can manage project members. Each member has a specific project-level Role.
+
+Built-in roles:
+
+* Owner – can edit the Project; can manage members; can create and edit Tasks; has access to the Stream of the Project;
+* Editor – can edit the Project; can create and edit Tasks; has access to the Stream of the Project;
+* Member – can view Tasks assigned to them; can move assigned Tasks between Stages; can edit Tasks they own.
+
+The admin can create custom Project Roles. The Project Roles list view is available at: the Project list view > the dropdown menu in the top-right corner > Roles.
+
+Project Roles allow fine-grained access control.
+
+A Project Role defines the following Task related permissions:
+
+* Create – yes/no – can create Tasks;
+* Assignment – all/own – whom can assign Tasks to;
+* Read – all/own – what Tasks can view;
+* Stream – all/own – access to the Tasks's Stream;
+* Edit – all/assigned/own – what Tasks can edit;
+* Stage Edit – all/assigned/own – what Tasks can move on the board;
+* Delete – all/own/no – what Tasks can delete.
+
+It also defines one Project related permission:
+
+* Project Stream – yes/no – can view the Project's stream (as of v1.4).
+
+!!! note
+
+ If a project member has access to the project's stream but does not have access to a task, they can still see that task in the stream. But they cannot open it to view details.
+
+## Members
+
+The Members panel is available in the Project's detail view, in the button under the the Teams tab. Here, the project owner can add or remove members as well as change their roles.
+
+It's possible to add or remove members for multiple projects at once from the Projects list view.
+
+## Tasks
+
+In the Project Management tool, a Task is represented by the *Project Task* entity type.
+
+A Project can have multiple Tasks. Tasks can belong to different Groups. Tasks can be re-ordered within a Group. Tasks are also placed in specific Stages of the Board.
+
+Tasks can have Sub-tasks.
+
+### Status
+
+Available Task statuses:
+
+* Not Started
+* Started
+* Completed
+* Canceled
+* Deferred
+
+The Status field is read-only: it cannot be edited explicitly. The status is updated automatically after changing the Stage value (moving the Task on the Board) and when completing or canceling the Task.
+
+### Stage
+
+The *Stage* field indicates in which Stage a Task is placed on the Board. It also defines the Status of the Task.
+
+The available Stages in a Project are defined by the assigned Project Board.
+
+A project member with the *Member* role has access to update the Stage field.
+
+### Group
+
+The *Group* field defines in what Group a Task is placed in.
+
+When creating a new Task, the *Active Group* of the Project is pre-selected.
+
+### Task dependencies
+
+A Task can be dependent on multiple Tasks.
+
+There are the following dependency types:
+
+* Finish to Start – the predecessor must be finished before the successor can be started;
+* Finish to Finish – the predecessor must be finished before the successor can be finished;
+* Start to Start – the predecessor must be started before the successor can be started;
+* Start to Finish – the predecessor must be started before the successor can be finished.
+
+The dependency type can be omitted: in this case, the dependency will be only declarative but not required. Meaning, it will be possible to finish a successor Task regardless of the predecessor's status.
+
+The default dependency type can be set at: Administration > Entity Manager > Project Task > Fields > Dependency Type.
+
+The label color indicates the predecessor's task status. Gray – Not Started, Blue – Started, Green – Completed.
+
+The task dependency feature can be enabled or disabled in the Project settings.
+
+### Owner
+
+The Task's Owner is a User who oversees the Task. A User who created a Task automatically becomes the Task's Owner.
+
+### Assignee
+
+The Assignee of a Task is a User who is responsible for performing the Task. A Task can be unassigned.
+
+Only members of the Project can be selected as assignees.
+
+### Collaborators
+
+The Collaborators feature can be enabled per project in the Project settings. Users who are collaborators can view the Task and post in its Stream.
+
+### Timeline
+
+A Task can have a Date Start and Date End. Both are non-mandatory fields.
+
+### Priority
+
+Available priority values:
+
+- Low
+- Normal
+- High
+- Urgent
+
+The Priority field can be enabled or disabled in the Project settings.
+
+### Points
+
+Is meant to represent the relative complexity of the Task, amount of work needed to complete the Task. The field can be enabled or disabled in the Project settings.
+
+Note that if the team won't use Points, the administrator can hide the field in the Entity Manager.
+
+### Hours
+
+May represent how many hours is required to complete the Task. The field can be enabled or disabled in the Project settings.
+
+### Sub-tasks
+
+A Task can have sub-tasks. A task that has sub-tasks can be completed only when all sub-tasks are completed or canceled.
+
+Sub-tasks can be owned by and assigned to different Users.
+
+Sub-tasks can be re-ordered by dragging and dropping.
+
+### Stream
+
+A Task has a Stream. The Stream can be used for communication between the Project's members. It also shows Task's updates.
+
+## Milestones
+
+A milestone is a significant point in a project's timeline that marks the completion of a key phase.
+
+## Groups
+
+A Project has a unique set of Groups. A project Owner or Editor can manage Groups of the Project – add, remove, and edit.
+
+To add a new Group to the Project, open the *Plan* view, click *Create Group* from the dropdown next to the *Edit* button. To reorder existing groups, click *Reorder Groups* from the same dropdown, then use dragging to reorder listed groups.
+
+Tasks are ordered within their Group. It's possible to reorder Tasks and move Tasks from one Group to another.
+
+A specific color can be assigned to a Group.
+
+When a new Task is added to a Group, it is placed either at the top or the bottom depending on the parameter Group's parameter *New Task Placement*.
+
+### Group type
+
+A specific type is assigned to every group. The following types are available:
+
+- Triage
+- Backlog
+- Work
+- Phase
+- Sprint
+
+The *Work* type is set by default.
+
+Only *Work*, *Phase* and *Sprint* groups are displayed on the Gantt chart.
+
+The Project Task dashlet allows you to limit tasks by specific group types. For example, one may want to list only tasks from the Work and Sprint groups, or display only Triage tasks in a separate dashlet.
+
+Group types are also useful for automation. For example, a workflow rule can be triggered when a task is moved to a Sprint group. A single rule can be applied across all projects.
+
+Another application of group types is Dynamic Logic. For example, the Assignee field can be automatically required if a task is linked to a group of the Work type.
+
+The Project Task entity type has a foreign field *Group Type*, which holds the type value of the related Group. It can be used in conditions of the Dynamic Logic.
+
+### Calendar
+
+*Requires EspoCRM v9.2.*
+
+Project Tasks can be displayed on the Calendar in read-only mode. For this, an administrator should enable Project Tasks under: Administration > Settings > General > Calendar Entity List.
+
+## Plan view
+
+Here, you can see Tasks in Groups. You can add new Groups, remove Groups, and reorder Groups. Here, you can also create, edit, and remove Tasks.
+
+By using drag-and-drop, it's possible to reorder Tasks within a Group or move Tasks from one Group to another.
+
+To reorder Groups, click *Reorder Groups* from the dropdown menu, use drag-and-drop, and then apply changes.
+
+
+
+## Board view
+
+On the Board view, tasks are visualized as sticky notes. This tool is also known as a Kanban board.
+
+It's possible to drag tasks from one column to another and reorder tasks within a column. Columns represent task's Stages.
+
+Stages of the board are defined by the Project Board assigned to the Project.
+
+The Board view displays tasks from only one Group at a time. You can switch between Groups to view tasks from different ones.
+
+
+
+## Gantt view
+
+The Gantt view visualizes the timeline of a project. It shows:
+
+* start and end dates of tasks and their durations;
+* milestones;
+* tasks dependencies.
+
+
+
+You can drag Tasks to change their timeline and resize to change their duration. By holding the CTRL/⌘ key, you can select multiple Tasks and drag them together.
+
+If you select two Tasks, you can manage their dependency:
+
+* add a dependency;
+* remove an existing dependency;
+* change the type of an existing dependency.
+
+The order in which you select two tasks determines the direction of the dependency. You can also click on a dependency path to select two tasks which this path connects.
+
+When creating a task or milestone while another task is selected, it will create a dependent task in the same group right after the selected task.
+
+If the default [Working Time Calendar](../../user-guide/working-time-calendar.md) is set in the system, non-working days will be highlighted with a darker background.
+
+The Gantt view can be disabled for a specific Project in its Settings.
+
+## Project cloning
+
+A Project can be cloned along with its Groups and Tasks. Optionally, it's possible to also include:
+
+* Members
+* Task Owners
+* Task Assignees
+* Attachments
+
+The Date Start should be set in the source Project. When cloning, the user needs to set a new Date Start for the Project. Dates of cloned Tasks will be calculated based on the difference between the source and cloned Projects.
+
+To be able to clone a Project, the user should have *create* access to the Project scope and *edit* access to the source Project. To clone a Project, open the detail view and click the *Clone* action from the dropdown next to the *Edit* button.
+
+If you clone a Project and then decide to remove it, it won't be possible until you remove all related Tasks.
+
+## Dashlet
+
+Users can add the Project Task dashlet to their dashboard. They can add multiple such dashlets, each with different options.
+
+Dashlet options:
+
+- Next X Days – the number of future days from which to display tasks;
+- Include Owned – to list tasks where the current user is the owner;
+- Include Shared – to list tasks where the current user is in collaborators;
+- Exclude Assigned to Me – to exclude tasks assigned to the current user;
+- Limit by Group Type – to list only tasks from specific group types; for example, exclude Backlog tasks;
+
+## Shortcut keys
+
+* `Ctrl + Backspace` – complete selected Tasks from the Plan view;
+* `Ctrl + Quote` – self-assign selected Tasks from the Plan view; only unassigned tasks are affected;
diff --git a/docs/extensions/sales-pack/bill-credits.md b/docs/extensions/sales-pack/bill-credits.md
new file mode 100644
index 000000000..2d6a4ec00
--- /dev/null
+++ b/docs/extensions/sales-pack/bill-credits.md
@@ -0,0 +1,23 @@
+# Bill Credits
+
+*As of Sales Pack v4.0.*
+
+Bill credits are reversal transactions for bills – the same as credit notes to invoices.
+
+Access to Bill Credits is controlled by Roles.
+
+A bill credit can be created from a bill.
+
+A bill credit can be allocated to a bill or multiple bills. Inbound payments can be allocated to a bill credit.
+
+A bill credit should be used to cancel an issued bill if the issuance locking in enabled in the system. Bill credits can be used to reduce the payable outstanding amount.
+
+## Automatic numbering
+
+The prefix of the next number, the next number itself and the quantity of digits in the number can be configured at Administration > Entity Manager > Bill Credit > Fields > numberA.
+
+## Locking
+
+A Bill Credit can be locked if it's resolved or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Bill Credit > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
diff --git a/docs/extensions/sales-pack/bills.md b/docs/extensions/sales-pack/bills.md
new file mode 100644
index 000000000..9a1f95027
--- /dev/null
+++ b/docs/extensions/sales-pack/bills.md
@@ -0,0 +1,25 @@
+# Bills
+
+*As of Sales Pack v4.0.*
+
+Bills represent invoices from suppliers.
+
+Access to Bills is controlled by Roles.
+
+A bill can be created from a [purchase order](purchase-orders.md). To create a bill from a purchase order, in the purchase order detail view, click on the plus button in the Bills panels.
+
+Outbound payments and [bill credits](bill-credits.md) can be allocated to a bill. To be able to set a bill as paid or cancel an issued bill, you need to zero the amount due by allocating payments or bill credits.
+
+Bill credits can be created from a bill to fully or partially reverse it.
+
+## Automatic numbering
+
+The prefix of the next number, the next number itself and the quantity of digits in the number can be configured at Administration > Entity Manager > Bill > Fields > numberA.
+
+## Locking
+
+A Bill can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Bill > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
+
+
diff --git a/docs/extensions/sales-pack/credit-notes.md b/docs/extensions/sales-pack/credit-notes.md
new file mode 100644
index 000000000..9a06c1ecc
--- /dev/null
+++ b/docs/extensions/sales-pack/credit-notes.md
@@ -0,0 +1,42 @@
+# Credit Notes
+
+*As of Sales Pack v3.0.*
+
+Credit Notes document adjustments made to previously issued invoices, such as returns, post-sale discounts, or error corrections.
+
+Credit notes can be created from an invoice.
+
+In the article:
+
+* [Printing to PDF](#printing-to-pdf)
+* [Sending in email](#sending-in-email)
+* [Locking](#locking)
+* [E-Credit notes](#e-credit-notes)
+
+## Printing to PDF
+
+Invoices can be printed to PDF. This action is available in the dropdown next to Edit button on the Invoice detail view. Then, you will be prompted to select a template. More info about printing to PDF is available [here](../../user-guide/printing-to-pdf.md).
+
+### Templates
+
+See the documentation [for quote templates](../../user-guide/quotes.md#templates).
+
+## Sending in email
+
+A Credit Note PDF can be sent in an email as an attachment. Open a credit note record, click the dropdown next to Edit button and then click Email PDF.
+
+The default email template can be set by the administrator: Administration > Sales Pack Settings > Email Templates.
+
+To have the Credit Note entity selected as the email's parent, the administrator should add the Credit Note entity type to the parent type list. Administration > Entity Manager > Email > Fields > Parent > Entity List. As of v3.0.
+
+## Locking
+
+An Credit Note can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Credit Note > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
+
+## E-Credit notes
+
+Credit notes can be exported to EN 16931 electronic credit notes in a UBL format.
+
+To export a Credit Note to a UBL file, click **E-Credit Note** from the dropdown menu next to the **Edit** button on the Credit detail view. The UBL file can be also attached along with a PDF when sending a credit note in email.
diff --git a/docs/extensions/sales-pack/delivery-orders.md b/docs/extensions/sales-pack/delivery-orders.md
new file mode 100644
index 000000000..18a2bdd13
--- /dev/null
+++ b/docs/extensions/sales-pack/delivery-orders.md
@@ -0,0 +1,38 @@
+# Delivery Orders
+
+*As of Sales Pack v2.0.*
+
+Delivery Orders document the shipment of products to customers.
+
+If the Warehouses feature is enabled, every Delivery Order record must be associated with a Warehouse.
+
+Multiple Delivery Orders can be created from a single [Sales Order](../../user-guide/sales-orders.md). It may be reasonable when a delivery is split into parts or shipped from different warehouses.
+
+When a delivery order is issued, the stock quantities of the included products are reduced.
+
+The Delivery Order statuses:
+
+* Draft – inventory is soft-reserved;
+* Ready – inventory is reserved;
+* In Progress – inventory is removed from stock;
+* Completed – inventory is removed from stock;
+* Canceled – inventory is unreserved or added back to stock (depending on the previous status);
+* Failed – inventory is removed from stock.
+
+Access to Delivery Orders is controlled by Roles.
+
+It's possible to print a Delivery Order to PDF and send the PDF in an email.
+
+## Locking
+
+A Delivery Order can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Delivery Order > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
+
+## Sending delivery order in email
+
+A Delivery Order PDF can be sent in an email as an attachment. Open an Delivery Order record, click the dropdown next to Edit button and then click Email PDF.
+
+The default email template can be set by the administrator: Administration > Sales Pack Settings > Email Templates.
+
+To have the Delivery Order entity selected as the email's parent, the administrator should add the Delivery Order entity type to the parent type list. Administration > Entity Manager > Email > Fields > Parent > Entity List. As of v3.0.
diff --git a/docs/extensions/sales-pack/inventory-management.md b/docs/extensions/sales-pack/inventory-management.md
new file mode 100644
index 000000000..6936682c6
--- /dev/null
+++ b/docs/extensions/sales-pack/inventory-management.md
@@ -0,0 +1,197 @@
+# Inventory Management
+
+*As of Sales Pack v2.0.*
+
+The Inventory Management feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/).
+
+The Inventory Management feature allows tracking of product quantities, locations in warehouses, transfers between warehouses, and the history of purchases and sales. It allows validating product availability before selling it to a customer.
+
+The Inventory Management feature is disabled by default. To enable it, you need to enable **Inventory Transactions** at Administration > Sales Pack (Settings).
+
+In this article:
+
+* [Inventory Transactions](#inventory-transactions)
+* [Quantity](#quantity)
+* [Inventory Numbers](#inventory-numbers)
+* [Warehouses](#warehouses)
+* [Inventory Adjustments](#inventory-adjustments)
+* [Transfer Orders](#transfer-orders)
+* [Transaction compressing](#transaction-compressing)
+* [Formula functions](#formula-functions)
+
+## Inventory Transactions
+
+The transactional model is used for the inventory management. Each transaction record represents an action performed on a specific inventory item. It includes the following fields:
+
+* Number – auto-increment number;
+* Product;
+* Quantity – a positive or negative value: positive for a movement in, negative for movement out;
+* Parent – a record that is generated the transaction; e.g. Receipt Order, Delivery Order;
+* Type – transfer, reserve, or soft-reserve;
+* Warehouse – what warehouse the transaction is related to;
+* Inventory Number – used for products tracked by number.
+
+Access to Inventory Transactions is controlled by Roles. The administrator can allow specific users to read and/or create transactions.
+
+Note that usually users are not supposed to create transactions manually. Transactions are created automatically when the status of an order record is changed.
+
+The following entity types automatically create inventory transaction records:
+
+* Delivery Order – items are removed from stock or reserved;
+* Receipt Order – items are added to stock;
+* Transfer Order – items are moved between warehouses or reserved before the move;
+* Inventory Adjustment – items added or removed;
+* Sales Order – items are soft-reserved before delivery is created.
+
+## Quantity
+
+The following quantity values are available for a Product:
+
+* Available – all items excluding reserved and soft-reserved;
+* On Hand – all excluding reserved;
+* Soft-Reserved – selected for a Sales Order, or selected for a draft Delivery or Transfer;
+* Reserved – selected for a Delivery or Transfer;
+* In Transit – currently moved between warehouses;
+* On Order – ordered from a supplier and not yet received.
+
+!!! note
+
+ In some cases, the total available quantity displayed for a product may be less than the sum of available quantities across individual warehouses. This occurs because Sales Orders soft-reserve inventory. Since the Sales Order entity is not linked to a specific warehouse, the reservation is applied globally and does not directly reduce the quantities shown for each warehouse.
+
+ You can disable soft-reservation for Sales Orders by removing the *Ready* status from the Soft-Reserve status list. The parameter is available under: Administration > Entity Manager > Sales Order > Edit.
+
+## Inventory Numbers
+
+It's possible to track specific products by Inventory Numbers. There are two type of numbers: Batch and Serial. The type of the Inventory Number is defined by the field *Inventory Number Type* in a Product.
+
+Access to Inventory Numbers is controlled by Roles.
+
+From the Inventory Number detail view it's possible to view the **History**: receipts, deliveries, transfers between warehouses, and adjustments.
+
+It's possible to view quantity for a specific Inventory Number.
+
+### Batch
+
+Multiple inventory items can be assigned to one Batch number.
+
+When inventory is received, Batch numbers should be assigned to products that are tracked by batch. It's possible to split a Receipt Order Item into multiple batches.
+
+When inventory is delivered to a customer, Batch numbers should be selected for products that are tracked by batch.
+
+### Serial
+
+Only one inventory item can be assigned to one Serial number.
+
+When inventory is received, Serial numbers should be assigned to every item for products that are tracked by serial. It's possible to **Import Serial Numbers** from a CSV file within a Receipt Order.
+
+When inventory is delivered to a customer, Serial numbers should be selected for products that are tracked by serial.
+
+!!! important
+
+ You can create Batch or Serial numbers for a product only if that product is marked as tracked by Batch or Serial correspondingly.
+
+### Removal Strategy
+
+The Removal Strategy is defined in a Product record. It determines how Inventory Numbers will be sorted when a user picks a number for a delivery or transfer order.
+
+Available options:
+
+* FIFO – first in, first out; sorted by *Incoming Date* in ascending order;
+* FEFO – first expired, first out; sorted by *Expiration Date* in ascending order;
+* LIFO – last in, first out; sorted by *Incoming Date* in descending order.
+
+## Warehouses
+
+The Warehouses feature is disabled by default. It can be enabled at Administration > Sales Pack (Settings).
+
+Access to Warehouses is controlled by Roles.
+
+The Receipt Order and Delivery Order have the mandatory *Warehouse* field. When products are delivered to a customer, they can be shipped from multiple warehouses. In this case, you need to create multiple Delivery Orders.
+
+Inventory can be moved between Warehouses with Transfer Orders.
+
+Inventory from a specific Warehouse can be excluded from stock availability by disabling the *Available for Stock* field in the Warehouse record.
+
+
+## Transfer Orders
+
+Transfer Orders can be utilized only if the Warehouses feature is enabled. Access to Transfer Orders is controlled by Roles.
+
+Transfer Orders allow moving inventory between Warehouses. When a Transfer Order record has the *In Progress* status, its items are counted as In Transit. They do not belong to any warehouse while in this state.
+
+## Inventory Adjustments
+
+Inventory Adjustments are used to correct inventory quantity manually. Within a single adjustment, it's possible to specify a new quantity for multiple products. You can also utilize Inventory Adjustments to enter initial stock quantities.
+
+If the Warehouses feature is enabled, a specific warehouse must be selected for an adjustment.
+
+When an adjustment is *Started*, all the affected inventory will be locked in the entire system until the adjustment is *Complete*. It's not possible to reserve or transfer inventory that is being locked by a started adjustment.
+
+Access to Inventory Adjustments is controlled by Roles.
+
+## Transaction compressing
+
+As the Inventory Transaction table grows, the system may became slower to calculate product quantities. For this reason, there is the functionality that compresses the inventory transaction table.
+
+Balanced transaction pairs can be removed. E.g. when the same item quantity is reserved and then unreserved, it will generate two transactions with opposite quantity values.
+
+If there are multiple transactions that differentiate only by quantity, they can be merged into one. The new quantity will be the sum of all.
+
+Compressing can be configured to be run automatically. You need to create **Inventory Transaction Compress** job at Administration > Scheduled Jobs.
+
+It's also possible to run compressing manually from the CLI:
+
+```
+bin/command inventory-compress
+```
+
+Only for transactions prior a specific date:
+
+```
+bin/command inventory-compress --before=2024-01-01
+```
+
+Receipt Orders, Delivery Orders and Transfer Orders can be marked as *Locked*. It will disallow changing their status and items. After that, it is possible to detach transactions from records that were locked. These detached transactions can be consequently compressed.
+
+Detaching can be configured to be run automatically. You need to create **Inventory Transaction Detaching** job at Administration > Scheduled Jobs.
+
+Or run from the CLI:
+
+```
+bin/command inventory-detach
+```
+
+It's also possible create a scheduled job that automatically locks old Receipt Orders, Delivery Orders and Transfer Orders.
+
+
+## Formula functions
+
+*As of Sales Pack v3.0.*
+
+### ext\product\quantity
+
+`ext\product\quantity(PRODUCT_ID, [WAREHOUSE_ID])`
+
+### ext\product\quantityOnHand
+
+`ext\product\quantityOnHand(PRODUCT_ID, [WAREHOUSE_ID])`
+
+### ext\product\quantityReserved
+
+`ext\product\quantityReserved(PRODUCT_ID, [WAREHOUSE_ID])`
+
+### ext\product\quantityInTransit
+
+`ext\product\quantityInTransit(PRODUCT_ID)`
+
+### ext\inventoryNumber\quantityOnHand
+
+`ext\inventoryNumber\quantityOnHand(INVENTORY_NUMBER_ID, [WAREHOUSE_ID])`
+
+### ext\inventoryNumber\quantityReserved
+
+`ext\inventoryNumber\quantityReserved(INVENTORY_NUMBER_ID, [WAREHOUSE_ID])`
+
+### ext\inventoryNumber\quantityInTransit
+
+`ext\inventoryNumber\quantityInTransit(INVENTORY_NUMBER_ID)`
diff --git a/docs/extensions/sales-pack/issuance-locking.md b/docs/extensions/sales-pack/issuance-locking.md
new file mode 100644
index 000000000..448629aa7
--- /dev/null
+++ b/docs/extensions/sales-pack/issuance-locking.md
@@ -0,0 +1,53 @@
+# Issuance locking
+
+*As of Sales Pack v4.0.*
+
+The issuance locking mode enforces stricter rules on transaction behavior. You may need to have it enabled for a compliance purpose, or if you want to Espo as a billing software. Without issuance locking enabled, balance reports cannot guarantee correct results.
+
+!!! note
+
+ Not to be confused with the record locking.
+
+The issuance locking can be enabled at Administration > Sales Pack Settings.
+
+Issuance locking affects the following document transactions:
+
+- Invoice
+- Credit Note
+- Bill
+- Bill Credit
+
+And the following settlement transactions:
+
+- Payment
+- Write-off
+
+Transaction issuance implies changing status from Draft to any other status except Canceled. Upon issuance, the boolean field *Issued* becomes true.
+
+Issued document transactions affect the balance regardless of their status. Issued settlement transactions (payments and write-offs) affect the balance unless their status is canceled.
+
+With the issuance locking mode enabled, an issued transaction:
+
+- Cannot be unissued or removed.
+- Has certain fields locked for editing.
+- Cannot be completed if not cleared.
+- Cannot be canceled if not cleared (except for Payment and Write-off).
+
+For document transactions, clearance implies that the Amount Due is zeroed. For settlement transactions, clearance implies that the Unallocated Amount is zeroed.
+
+If a transaction was issued by a mistake, it's not possible to just remove it. To cancel a document transaction, you need to negate it with an opposite transaction first.
+
+How transactions can be negated for cancellation:
+
+- Invoice can be negated with Credit Notes.
+- Credit Note can be negated by allocating it to an Invoice (often, it should be a Debit Note).
+- Bill can be negated with a Bill Credit.
+- Bill Credit can be negated by allocating it to a Bill.
+- Payment and Write-off can be canceled if they don't have allocations. If there are allocations, you need to remove them first.
+
+As issued transactions are not fully protected from editing, it's reasonable to use the regular locking once the transaction is completed. The system will automatically lock the record once it is completed.
+
+## System-level parameter
+
+To disallow admin users to disable the issuance locking, set `salesForceIssuanceLocking` to true in the config file. Doing so may be necessary for a compliance purpose.
+
diff --git a/docs/extensions/sales-pack/multi-currency.md b/docs/extensions/sales-pack/multi-currency.md
new file mode 100644
index 000000000..2a9be5382
--- /dev/null
+++ b/docs/extensions/sales-pack/multi-currency.md
@@ -0,0 +1,28 @@
+# Multi-currency
+
+*As of Sales Pack v4.0.*
+
+Multi-currency is activated when you have more than one currency set in the *Currency List* settings parameter. Currencies are configured at: Administration > Currency. Here you can specify which currencies to have available in the system, as well as the base, and the default currency. Here, you can also set currency rates.
+
+The base currency is the company's local currency. Tax, sales and purchase reports use the base currency.
+
+The default currency is pre-selected by default when documents and transactions are created. It can be the same as the base currency.
+
+## Transaction currency
+
+Invoices, Credit Notes, Bills, Bill Credits, and Payments have the *Currency Rate* field.
+Amounts (including tax amounts) are stored in both the document currency and the local currency.
+
+Allocations, Tax Line Items, and Tax Total Items store amounts in both currencies as well.
+
+For a document with different local and document currencies, you can view total amounts in the local currency by clicking *View in Local Currency* from the menu next to the Edit button.
+
+The currency rate is set to the today's exchange rate. If you change the document date (Date Invoiced or Date Paid) to an earlier date, if the exchange rate for that day differs, the system will suggest to set that rate.
+
+When a Credit Note is created from an Invoice, it inherits its currency rate. The same applies for Bill Credits.
+
+## FX gain/loss
+
+If the exchange rates used for an invoice and its payment differ, a foreign exchange gain or loss arises. You can view the FX gain/loss amount for a particular allocation: the Invoice detail view > Allocations panel > click View for an allocation.
+
+The same applies for Bills and Bill Credits.
diff --git a/docs/extensions/sales-pack/overview.md b/docs/extensions/sales-pack/overview.md
new file mode 100644
index 000000000..bf7a05b74
--- /dev/null
+++ b/docs/extensions/sales-pack/overview.md
@@ -0,0 +1,30 @@
+# Sales Pack Overview
+
+Sales Pack is an [extension](https://www.espocrm.com/extensions/sales-pack/) for EspoCRM.
+
+Features:
+
+* [Products](../../user-guide/products.md)
+* [Prices](prices.md)
+* Sales
+ * [Quotes](../../user-guide/quotes.md)
+ * [Sales orders](../../user-guide/sales-orders.md)
+ * [Invoices](../../user-guide/invoices.md)
+ * [Credit notes](credit-notes.md)
+ * [Delivery orders](delivery-orders.md)
+ * [Return orders](return-orders.md)
+ * [Write-offs](write-offs.md)
+ * [Subscriptions](subscriptions.md)
+* Purchases
+ * [Purchase orders](purchase-orders.md)
+ * [Receipt orders](receipt-orders.md)
+ * [Suppliers](suppliers.md)
+ * [Bills](bills.md)
+ * [Bill credits](bill-credits.md)
+* [Inventory management](inventory-management.md)
+* [Payments](payments.md)
+* [Taxes](taxes.md)
+* [Tax codes](tax-codes.md)
+* [Issuance locking](issuance-locking.md)
+* [Multi-currency](multi-currency.md)
+* [Reports](reports.md)
diff --git a/docs/extensions/sales-pack/payments.md b/docs/extensions/sales-pack/payments.md
new file mode 100644
index 000000000..007d683aa
--- /dev/null
+++ b/docs/extensions/sales-pack/payments.md
@@ -0,0 +1,114 @@
+# Payments
+
+*As of Sales Pack v3.0.*
+
+*Compatible with EspoCRM v9.1 or greater.*
+
+In this article:
+
+* [Payment entries](#payment-entries)
+* [Payment methods](#payment-methods)
+* [Payment channels](#payment-channels)
+* [Payment requests](#payment-requests)
+
+## Payment entries
+
+A Payment entry captures a single payment transaction, either inbound or outbound.
+
+Access to Payments is controlled by Roles. Payments can be created from the Payments list view. Payments can also be created from the Invoice and Credit Note detail views.
+
+An inbound payment can be allocated to one or more Invoices. An outbound payment can be allocated to one or more Credit Notes.
+
+When a payment amount is received, the payment entry is supposed to be set to the *Paid* status. After the payment amount is fully allocated, it has to be set to *Completed*.
+
+When the payment amount is received, the status of the payment entry should be set to *Paid*. Once the full amount has been allocated, the status has to be updated to *Completed*.
+
+If a payment exceeds the invoices' outstanding amount, the surplus can be allocated later to future invoices of the customer.
+
+The Party Type field has two options: Customer and Supplier. A payment with the Customer party type can be allocated to invoices or credit notes, depending on its direction. A payment with the Supplier party type can be allocated to bills or bill credits.
+
+## Payment methods
+
+A Payment Method must be specified for each Payment entry. By default, there's no any payment method in the system, hence
+an administrator needs to create at least one payment method.
+Payment method examples: Wire Transfer, Cash, Stripe.
+
+Only an administrator can manage Payment Methods. Regular users can read payment methods if their Role grants access.
+
+A payment method can be marked as eligible for inbound, outbound, or both payment directions.
+
+You can add text instructions for a specific inbound payment method. These instructions will appear on the payment link page.
+
+Multiple payment methods can be associated with a single Invoice, with one designated as primary.
+
+Multiple payment methods can be associated with an Account, with one designated as primary. When an Invoice is created for an Account, the account's payment methods are carried over to the invoice.
+
+## Payment channels
+
+An inbound payment method can be associated with a specific Payment Channel, which encapsulates the credentials and settings for a particular payment provider.
+
+Only an administrator can manage payment channels. Regular users cannot view payment channel records.
+
+Out of the box, the following providers are available:
+
+* Wire Transfer
+* SEPA Credit Transfer
+* SEPA Direct Debit
+
+Providers shipped separately:
+
+* [Stripe](../stripe-integration/index.md)
+
+### Wire Transfer
+
+A generic bank credit transfer. The payment channel record stores bank credentials, which can be presented to a customer on a payment link page.
+
+The credentials are included in an E-invoice if the payment method is set for the invoice.
+
+### SEPA Credit Transfer
+
+The payment channel record stores bank credentials, which can be presented to a customer on a payment link page.
+
+The credentials are included in an E-invoice if the payment method is set for the invoice.
+
+### SEPA Direct Debit
+
+The payment channel record stores bank credentials and the creditor identifier.
+
+A Direct Debit Mandate can be created for an Account.
+
+To generate a payment XML file, you need to create a Payment Request with the method set to *SEPA Direct Debit*. Then, the button will be available on the Payment Request detail view.
+
+When *SEPA Direct Debit* is selected as the Invoice's payment method, the generated E-invoice file includes the bank credentials and mandate data.
+
+## Payment requests
+
+Payment Requests can be used to create unique payment links. Payment links can be sent to customers. No Espo user account is required to access these links.
+
+Payment instructions and bank credentials can be displayed on the payment link page. In the case of an automated payment channel like Stripe, the customer can make a payment from the payment link.
+
+Payment requests can be created from an Invoice.
+
+Access to payment requests is controlled by Roles.
+
+### Sending in email
+
+To send a payment link in an email, click *Send in Email* from the dropdown next to the *Edit* button on the Payment Request detail view.
+
+An administrator can select the default email template for payment requests: Administration > Sales Pack Settings > Email Templates > Payment Request Email Template.
+
+Use the placeholder `{PaymentRequest.paymentUrl}` in the email template for a link. Note that the link will automatically be appended to the email body if there's no URL placeholder in the email template.
+
+Note that you can also access the payment URL from a Formula script.
+
+It is also possible to include payment links when sending an invoice in email. Use the following code in the email template:
+
+```
+
+ {{#each paymentRequests}}
+ {{#if (equal status 'Pending') }}
+ Payment Link {{number}}
+ {{/if}}
+ {{/each}}
+
+```
diff --git a/docs/extensions/sales-pack/prices.md b/docs/extensions/sales-pack/prices.md
new file mode 100644
index 000000000..21de05f1a
--- /dev/null
+++ b/docs/extensions/sales-pack/prices.md
@@ -0,0 +1,181 @@
+# Prices
+
+Product sales prices can be determined by:
+
+* price books (enabled by default);
+* product-level prices.
+
+Both price sources can be enabled or disabled under Administration > Sales Pack (Settings). Both sources can be enabled
+simultaneously. In this case, the product-level price is used as a fallback.
+
+In this article:
+
+* [Price books](#price-books)
+* [Supplier prices](#supplier-prices)
+* [Tax inclusive pricing](#tax-inclusive-pricing)
+* [Import](#import)
+* [Mass update](#mass-update)
+
+## Price books
+
+*As of Sales Pack v2.0.*
+
+The Price Books feature allows you to set different prices for the same product. A price book record contains prices for multiple products. One price book can contain different prices for a single product, applied for a specific effective date period or a specific item quantity.
+
+The Price Books feature can be enabled or disabled under Administration > Sales Pack (Settings). Access to Price Books is controlled by Roles.
+
+The Price Books list view can be accessed at Products > the top-right menu > Price Books.
+
+A price book can be associated with a specific Account. Note that the administrator needs to add the **Price Book** field to the *Detail* layout of the Account entity type to be able to associate accounts with price books.
+
+The Quote, Sales Order and Invoice have the **Price Book** field. When a new record is created, the Price Book is carried over from the related Account. It's possible to change the Price Book for a specific document.
+
+A Price Book can have a **Parent Price Book** and so on. If there's no price found for a specific product in a Price Book, then the system will look up the price in the Parent Price Book.
+
+The **Default Price Book** can be specified at Administration > Sales Pack (Settings). It will be used to fetch default prices when there's no Price Book associated with an order.
+
+When a product is added to a document as a line item and there's no price found in the related Price Book or there's no related Price Book, the Default Price Book will be used. If there's no Default Price Book, and product-level prices are enabled, the price from the Product record will be used. Otherwise, the price won't be set for the line item, and the user will need to set it manually.
+
+When a user changes the quantity in a line item, the system will look up the new unit price for the new quantity. If the new unit price is found, it will prompt the user to apply the new unit price. The user can reject and keep the previous price.
+
+It is possible to apply a Price Book to already added line items. The **Apply Price Book** action is available from the dropdown menu next to the plus button that adds line items.
+
+### Min. Quantity
+
+If set, the price applies only if the item quantity exceeds the specified value.
+
+### Effective dates
+
+The Date Start and Date End fields determine when the price is applicable. The Date End is inclusive. Both the Date Start and the Date End fields are optional.
+
+### Rules
+
+*As of Sales Pack v2.2.*
+
+Price Rules can be added to a specific Price Book. One Rule can modify the base price for multiple Products. It's possible to add or subtract a percentage of the price, apply rounding, add or subtract a specific amount.
+
+
+
+#### Target
+
+The Target field determines when the Rule should be applied. The following options are available:
+
+* Product Category – applies to all Products of a specific Category, including sub-categories;
+* All – applies to all Products;
+* Conditional – when a specific condition is met.
+
+An administrator can add custom Conditions at Administration > Price Rule Conditions. Created conditions then will be available on the Price Rule form. Conditions are defined with a [Formula](../../administration/formula.md) expression. An expression should return true or false.
+
+Special functions available for conditions:
+
+* `ext\priceRule\accountAttribute` – returns an Account attribute value, e.g. `ext\priceRule\accountAttribute('type')`;
+* `ext\priceRule\productAttribute` – returns a Product attribute value, e.g. `ext\priceRule\productAttribute('id')`.
+
+Formula based conditions make the pricing functionality highly flexible, allowing to implement a wide range of pricing models. See a few simple use cases below.
+
+**Use case 1:** A rule applied to Accounts with type Partner.
+
+```
+ext\priceRule\accountAttribute('type') == 'Partner'
+```
+
+**Use case 2:** A rule applied to Accounts that have already purchased the same product before.
+
+```
+record\exists(
+ 'SalesOrderItem',
+ 'productId', ext\priceRule\productAttribute('id'),
+ 'accountId', ext\priceRule\accountAttribute('id'),
+ 'salesOrderStatus', 'Completed'
+)
+```
+
+#### Based On
+
+What to use as a base price.
+
+* Unit – the price for a quantity of 1 defined in the Price Book or the unit price defined in the Product record; Price Book rules are not taken into account;
+* Price Book – the price is obtained from the same Price Book with rules are applied;
+* Supplier – the price of the Supplier;
+* Cost – the cost specified in the Product record.
+
+Use the *Price Book* base if your Price Book defines prices based on a markup and you also want to give an additional discount upon those calculated prices.
+
+#### Percentage
+
+A percentage of the standard price to deduct or add.
+
+#### Rounding Method
+
+* Half Up
+* Up
+* Down
+
+#### Rounding Factor
+
+The amount will be round off to the multiple of the specified value. E.g. if set to 100, prices will be 100, 400, 5200.
+
+#### Surcharge
+
+An amount to add after percentage and rounding are applied. Use a negative number to subtract.
+
+To make prices to end with *9.99*, specify *-0.01* surcharge and use pricing factor *10*.
+
+#### Min. Quantity
+
+If specified, the rule applies only if the item quantity exceeds the value.
+
+#### Effective dates
+
+The Date Start and Date End fields determine when the rule is applicable. The Date End is inclusive. Both the Date Start and the Date End fields are optional.
+
+## Tax inclusive pricing
+
+*As of Sales Pack v4.0.*
+
+Tax inclusive pricing can be enabled for a price book. When a tax inclusive price book is selected for a document, all unit prices are treated as tax inclusive.
+
+If the default price book is set as tax inclusive, documents without a selected price book will use tax inclusive pricing. In other words, if you want to use tax inclusive pricing by default, your default price book should be set to tax inclusive.
+
+Tax inclusive pricing is available only for sales, it's not available for purchases.
+
+## Supplier prices
+
+*As of Sales Pack v2.0.*
+
+A *Supplier* record can have prices for specific products. These prices are used when adding products to a Purchase Order associated with that Supplier.
+
+A Supplier record can contain different prices for a single product: applied for a specific date period or a specific item quantity.
+
+If there's no supplier price found for a product, and product-level prices are enabled (in settings), then the *Cost Price* of the product will be used as a unit price.
+
+## Import
+
+It's possible to import Product Prices from a CSV file using the basic [Import tool](../../administration/import.md). To import into a specific Price Book, select that Price Book as a default field value at the second step of the Import.
+
+Each CSV row must be associated with a corresponding Product record. It can be:
+
+* The *Name* of the Product;
+* The *Part Number* of the Product (as of v8.2).
+
+In the similar fashion, it's possible to import Supplier Prices.
+
+!!! tip
+
+ It's possible to export Product Prices from Espo, update prices in a spreadsheet software using formula and then, import new prices back into Espo.
+
+## Mass update
+
+*As of Sales Pack v2.3.*
+
+It's possible to update prices for multiple records from the list view. Select specific records or all search results, then click **Actions** and **Update Price**. It will propose to enter a markup or discount, add a surcharge amount.
+
+Mass price update is supported for:
+
+* Products (Cost, List and Unit price)
+* Product Prices
+* Supplier Product Prices
+
+The Product Prices list view can be reached by: Products tab > top-right menu > Price Books > top-right menu > Product Prices.
+
+The Supplier Product Prices list view can be reached by: Products tab > top-right menu > Suppliers > top-right menu > Supplier Product Prices.
diff --git a/docs/extensions/sales-pack/purchase-orders.md b/docs/extensions/sales-pack/purchase-orders.md
new file mode 100644
index 000000000..871df09b6
--- /dev/null
+++ b/docs/extensions/sales-pack/purchase-orders.md
@@ -0,0 +1,43 @@
+# Purchase Orders
+
+*As of Sales Pack v2.0.*
+
+The Purchase Orders feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/).
+
+Purchase Orders are issued to suppliers. They specify the products the company needs to purchase from the supplier, along with their quantities and agreed prices.
+
+Access to Purchase Orders is controlled by Roles.
+
+The Purchase Order has the *Supplier* field. Upon selecting the supplier, the Purchase Order's address fields will be automatically populated. The selected supplier also determines prices that will be applied for products in the order.
+
+Purchase Orders can be printed to PDF and sent in an email.
+
+Multiple [Receipt Orders](receipt-orders.md) can be created from one Purchase Order. If Receipt Orders created for a Purchase Order do not fully cover all its items, the next created Receipt Order will include the missing items. You can also add extra items to the Receipt Order if needed.
+
+In the article:
+
+* [Printing to PDF](#printing-to-pdf)
+* [Sending in email](#sending-in-email)
+* [Locking](#locking)
+
+## Printing to PDF
+
+Purchase Orders can be printed to PDF. This action is available in the dropdown next to the *Edit* button on the record detail view. Then, you will be prompted to select a template. More info about printing to PDF is available in the [article](../../user-guide/printing-to-pdf.md).
+
+### Templates
+
+See the documentation [for quote templates](../../user-guide/quotes.md#templates).
+
+## Sending in email
+
+A Purchase Order PDF can be sent in an email as an attachment. Open a Purchase Order record, click the dropdown next to Edit button, and then click Email PDF.
+
+The default email template can be set by the administrator: Administration > Sales Pack Settings > Email Templates.
+
+To have the Purchase Order entity selected as the email's parent, the administrator should add the Purchase Order entity type to the parent type list. Administration > Entity Manager > Email > Fields > Parent > Entity List. As of v3.0.
+
+## Locking
+
+A Purchase Order can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Purchase Order > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by the administrator.
diff --git a/docs/extensions/sales-pack/receipt-orders.md b/docs/extensions/sales-pack/receipt-orders.md
new file mode 100644
index 000000000..e603e39c7
--- /dev/null
+++ b/docs/extensions/sales-pack/receipt-orders.md
@@ -0,0 +1,36 @@
+# Receipt Orders
+
+*As of Sales Pack v2.0.*
+
+Receipt Orders are used to document products received from suppliers or returned by customers.
+
+If the Warehouses feature is enabled, every Receipt Order record must be associated with a Warehouse.
+
+Multiple Receipt Orders can be created from a single [Purchase Order](purchase-orders.md), for example when deliveries are split into parts or sent to different warehouses. A Purchase Order must have status *Released* or *Complete* to be able to create a Receipt Order from it.
+
+Receipt Orders can be created from a [Return Order](return-orders.md).
+
+The following Receipt Order statuses are available:
+
+* Draft;
+* Ready;
+* Completed – inventory is added to stock;
+* Canceled.
+
+It's possible to lock a Receipt Order. Locking disables the ability to change the status and items.
+
+Access to Receipt Orders is controlled by Roles.
+
+It's possible to print a Receipt Order to PDF and send the PDF in an email.
+
+Upon receipt completion, stock quantities for the included products increase.
+
+When a Receipt Order contains products that are tracked by Batch or Serial numbers, to be able to complete the order, one needs to specify numbers for those products.
+
+It's possible to import Serial numbers from a CSV file within a Receipt Order.
+
+## Locking
+
+A Receipt Order can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Receipt Order > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
diff --git a/docs/extensions/sales-pack/reports.md b/docs/extensions/sales-pack/reports.md
new file mode 100644
index 000000000..dfa81a6bc
--- /dev/null
+++ b/docs/extensions/sales-pack/reports.md
@@ -0,0 +1,128 @@
+# Sales and Purchase Reports
+
+*As of Sales Pack v4.0.*
+
+!!! warning
+
+ The Sales Pack reports are integrated with the Reports feature of the Advanced Pack. You need the Advanced Pack extension installed to be able to use the reports.
+
+
+To create a report, follow: Reports tab > top-right menu > Create Internal Report. Select the needed report, after that you can to tweak the report's parameters and run preview. After the report is saved, it will be available in the system as a regular report record. You can assign the report to a specific team for access control purposes.
+
+All reports use the base currency (which is the company's local currency). If you change the base currency in the system, the report will not show the result for previous transactions (which use the previous local currency).
+
+Reports:
+
+- [Customer balances](#customer-balances)
+- [Customer aging](#customer-aging)
+- [Supplier balances](#supplier-balances)
+- [Sales tax summary](#sales-tax-summary)
+- [Purchase tax summary](#purchase-tax-summary)
+- [Sales list by tax code](#sales-list-by-tax-code)
+- [Sales revenue](#sales-revenue)
+- [Sales by customer](#sales-by-customer)
+- [Sales by product](#sales-by-product)
+- [Sales by category](#sales-by-category)
+- [Purchase expenditure](#purchase-expenditure)
+- [Purchases by product](#purchases-by-product)
+- [Ledger summary](#ledger-summary)
+
+!!! important
+
+ Reports that concern taxes require the tax codes feature to be enabled.
+
+## Customer balances
+
+Displays opening balance, debits, credits, and closing balance for each customer. The Date and Accounts filters are available. By clicking a customer, you can view Invoices, Credit Notes, Payments, and Allocations that affect the balance for the selected date range.
+
+You can configure the report to include customers with a zero balance or not.
+
+## Customer aging
+
+The report shows outstanding customer balances grouped by how long they have been overdue. The following date brackets are used: Current, 1-30 days, 31-60 days, 61-90 days, and 91+ days.
+
+The basis for the report be set to one of the following values:
+
+- Date Due
+- Installment Date Due
+- Date Invoiced
+
+You click on a customer and on a date bracket to view the invoices that affect the balance for a particular row or column.
+
+## Supplier balances
+
+Displays opening balance, debits, credits, and closing balance for each supplier. The Date and Accounts filters are available. By clicking a supplier, you can view Bills, Bill Credits, Payments, and Allocations that affect the balance for the selected date range.
+
+You can configure the report to include supplier with a zero balance or not.
+
+## Sales tax summary
+
+Displays a summary of taxes related to invoices and credit notes. The report can be used for VAT and sales tax report preparation.
+
+In the report parameters, you need to select tax codes and the basis: Accrual or Cash. The report will show summary for each tax codes: the Base and the Tax amount.
+
+## Purchase tax summary
+
+Displays a summary of taxes related to bills and bill credits. The report can be used for VAT and sales tax report preparation.
+
+In the report parameters, you need to select tax codes and the basis: Accrual or Cash. The report will show summary for each tax codes: the Base and the Tax amount.
+
+In the result table, clicking a tax code displays the tax items that contribute to the result.
+
+## Sales list by tax code
+
+This report can be used for EU Sales List report preparation.
+
+The report displays the following columns:
+
+- Account – a customer
+- Tax Code
+- Country – stored in the tax code record
+- Tax Number – VAT number, stored in the account record
+- Item Type – Goods or Service
+- Amount – total amount of sales
+
+In the report parameters you need to select tax codes and an item type for each tax code (goods or service).
+
+In the result table, clicking an account and tax code displays the invoices and credit notes that contribute to the result.
+
+## Sales revenue
+
+Breaks down revenue by date. The following date grouping options are available: Month, Quarter, Year, Week, Fiscal Quarter, Fiscal Year. The shipping amount can be optionally included in results.
+
+In the result table, clicking a group displays the invoices and credit notes that contribute to the result.
+
+## Sales by customer
+
+Breaks down revenue by customer.
+
+## Sales by product
+
+Breaks down revenue by product. Product categories can be selected in the report parameters.
+
+## Sales by category
+
+Breaks down revenue by product category.
+
+## Purchase expenditure
+
+Breaks down purchases by date. The following date grouping options are available: Month, Quarter, Year, Week, Fiscal Quarter, Fiscal Year. The shipping amount can be optionally included in results.
+
+In the result table, clicking a group displays the bills and bill credits that contribute to the result.
+
+## Purchases by product
+
+Breaks down purchase expenditure by product. Product categories can be selected in the report parameters.
+
+## Ledger summary
+
+This report generates a consolidated journal entry for a selected date period. The result can be exported to CSV for further
+import into an accounting software.
+
+For example, a company may export the operational summary at the end of an accounting period and import it into its
+General Ledger as a single journal entry. In this setup, Espo functions as an operational billing system
+and serves as the source of truth for billing transactions.
+
+For each account category, a GL account number can be specified. This simplifies the import mapping process.
+
+Payment methods and tax codes can be split into separate lines, each can be assigned to a specific account number.
diff --git a/docs/extensions/sales-pack/return-orders.md b/docs/extensions/sales-pack/return-orders.md
new file mode 100644
index 000000000..1dd0bfc38
--- /dev/null
+++ b/docs/extensions/sales-pack/return-orders.md
@@ -0,0 +1,21 @@
+# Return Orders
+
+*As of Sales Pack v2.0.*
+
+Return Orders are used to document product returned from customers. A Return Order can be created from a completed Sales Order. Multiple [Receipt Orders](receipt-orders.md) can be created from a single Return Order.
+
+If the Warehouses feature is enabled, a Receipt Order record can be associated with a Warehouse the return is supposed to be shipped to.
+
+Access to Return Orders is controlled by Roles.
+
+## Printing to PDF
+
+Return Orders can be printed to PDF. This action is available in the dropdown next to Edit button on the Delivery Order detail view. Then, you will be prompted to select a template.
+
+## Sending in email
+
+A Return Order PDF can be sent in an email as an attachment. Open a Return Order record, click the dropdown next to Edit button and then click Email PDF.
+
+The default email template can be set by the administrator: Administration > Sales Pack Settings > Email Templates.
+
+To have the Return Order entity selected as the email's parent, the administrator should add the Return Order entity type to the parent type list. Administration > Entity Manager > Email > Fields > Parent > Entity List. As of v3.0.
diff --git a/docs/extensions/sales-pack/subscriptions.md b/docs/extensions/sales-pack/subscriptions.md
new file mode 100644
index 000000000..58f7230ab
--- /dev/null
+++ b/docs/extensions/sales-pack/subscriptions.md
@@ -0,0 +1,279 @@
+# Subscriptions
+
+*As of Sales Pack v4.0.*
+
+The Subscription feature provides the ability to invoice customers on a recurring basis.
+
+In this article:
+
+- [Subscription records](#subscription-records)
+- [Billing plans](#billing-plans)
+- [Periods](#periods)
+- [Subscription templates](#subscription-templates)
+- [Updates and proration](#updates-and-proration)
+
+Access to Subscriptions is controlled by Roles.
+
+The life cycle of subscriptions is controlled by the scheduled job *Control Subscriptions*. Make sure you have this job active at Administration > Scheduled Jobs.
+
+Terms:
+
+- Charge period. Defines the period used to calculate the subscription price For example, 1 Month or 1 Year.
+- Billing period. A period the customer is invoiced for. A billing period can include multiple charge periods. For example, a subscription with a 1-month charge period may be billed every 12 such periods, resulting in a single annual charge covering 12 months.
+- Grace period. A period during which the subscription remains active despite being unpaid.
+- Alignment period. An additional period used to align the subscription billing cycle to a specific day of the month. It is always shorter than one month and may be charged or free, depending on configuration.
+- Trial period. A free period at the start of the subscription.
+- Pause period. A period during which the subscription is suspended.
+
+## Subscription records
+
+A Subscription entry represents one subscription.
+
+### Status
+
+A subscription can be in one of the following statuses:
+
+- Draft
+- Trial
+- Active
+- Paused
+- Stopped
+
+A subscription that is processed automatically can be in one of the following statuses: Trial, Active, and Paused. The system automatically transitions the subscription between these three statuses depending on the current period and billing conditions. The system changes the status to Stopped when the subscription reaches its End Date or remains unpaid after the grace period. When a subscription reaches the Stopped status, the system stops controlling its state – user intervention is required to reactivate it.
+
+A subscription status is automatically changed to Paused when it reaches a *Pause* period. A user can create such periods to temporarily suspend the subscription.
+
+A user can stop a subscription manually by setting the status to Stopped.
+
+### Billing state
+
+A subscription can be in one of the following billing states:
+
+- Clear. No action required.
+- Due. When there is a period with billing status *Invoiced*. The customer needs to pay.
+- Past Due. Same as Due, but the invoice is overdue.
+
+The system updates billing states automatically depending on current conditions.
+
+### Billing plan
+
+The subscription billing plan defines billing-related parameters for the subscription. See more about billing plans below.
+
+### Line items
+
+A subscription can have one or multiple line items. Each line item specifies a product, quantity and unit price. Only products marked as *Subscribable* can be added to a subscription. The product of the first line item is designated as a primary product of the subscription.
+
+When the system generates an invoice for a billing period, it carries over the line items from the subscription. While the quantity is preserved, the unit price is adjusted based on the billing period.
+
+### Tax profile
+
+A subscription must be associated with a Tax Profile. This tax profile will be applied for invoices.
+
+### Payment method
+
+The selected payment method will be applied for invoices. The payment method of the related Account is automatically pre-selected when a subscription is created.
+
+### Price book
+
+Subscriptions can be linked to a Price Book which enables customer-specific pricing. The price book of the related Account is automatically pre-selected.
+
+## Billing plans
+
+A Billing Plan encapsulates parameters for subscriptions. Each subscription is associated with a single billing plan, while a billing plan can be used by multiple subscriptions.
+
+Access to Subscription Billing Plans is controlled by Roles. Billing plans are available under: Subscriptions tab > top-right menu > Billing Plans.
+
+### Parameters
+
+#### Charge period
+
+An interval that defines how the subscription is charged and identifies which price book prices apply to the subscription plan. For example, if the period is set to 1 Month, the subscription will use product prices defined specifically for the '1 Month' period.
+
+The list of charge periods available for billing plans and product prices is defined system-wide. An administrator can configure it under: Administration > Subscription Intervals. Interval values are defined by a number and unit. The following units are available: Day, Week, Month, and Year.
+
+#### Billing cycle length
+
+Number of charge periods within a billing cycle. For example, if the cycle length is set to 12 and the charge period is 1 month, the customer will receive one invoice per year.
+
+#### Grace period days
+
+How many days an unpaid subscription remains active after the invoice is overdue.
+
+#### Invoice due period days
+
+Defines how the invoice date due is calculated. The specified number of days is added to the invoice date (the day the invoice is issued).
+
+#### Invoice lead time days
+
+How many days in advance of the next billing cycle an invoice is created. If it is set to 0, the invoice will be issued on the first day of the next billing cycle.
+
+#### Alignment
+
+Enables billing cycle alignment. The following alignment options are available:
+
+- Immediate. A prorated period is created first to align the billing cycle. The following period is a normal billing period.
+- Delayed. A normal billing period is created first. The following period is prorated to align the billing cycle.
+
+#### Alignment days
+
+Available if the alignment is enabled and the charge period unit is a month or a year.
+
+Defines month days the subscription will be aligned to. For example, if it is set to 1, subscriptions billing cycles will be aligned to the first day of month. If it is set to 31, then – to the last day of month. Multiple alignment days can be selected, for example 1 and 15 to align subscriptions to the beginning and the middle of the month.
+
+#### Alignment weekdays
+
+Available if the alignment is enabled and the charge period unit is a week.
+
+Defines week days the subscription will be aligned to. Multiple days can be selected.
+
+#### Alignment proration policy
+
+Available if the alignment is enabled.
+
+Controls whether alignment prorated periods are charged. Available options:
+
+- No Charge. The alignment period will be always free for the customer.
+- Charge. The alignment period will be proportionally charged if the length exceeds the specified threshold.
+
+#### Alignment charge min. days
+
+Available if the alignment is enabled and the proration policy is set to *Charge*.
+
+Alignment prorated periods shorter than the specified number of days won't be charged. If the value is not specified, then the alignment period will always be charged.
+
+#### Create payment requests
+
+If enabled, payment requests will be automatically created upon invoice creation.
+
+#### Send payment request
+
+If enabled, then created payment requests will be also sent to customers in email.
+
+#### Send invoices
+
+Created invoices will be also automatically sent to customers.
+
+## Periods
+
+A Period entry represents a billing, trial, alignment, or pause period. A sequence of periods defines the subscription's life cycle. A period has Date Start and Date End. Periods cannot overlap. The end date is exclusive – the end date of the previous period becomes a start date of the next period.
+
+The system automatically creates next periods, automatically controls the life cycle of periods, and creates invoices and payments for active periods. A user can create and edit periods manually when needed. A user can also initiate invoice and payment creation manually by clicking *Process Billing* for a particular period.
+
+!!! note
+
+ Payments can be automatically created only if the subscription or the related account has at least one payment method specified.
+
+Periods of a subscription are available in the subscription's detail view in a bottom panel.
+
+### Fields
+
+#### Type
+
+There are the following period types:
+
+- Regular. The subscription is active during this period.
+- Pause. The subscription is suspended during this period.
+- Trial. The subscription is in trial status during this period.
+
+#### Status
+
+Period statuses:
+
+- Scheduled. The period is not yet started. The system creates scheduled periods automatically beforehand.
+- Active. The current active period.
+- Ended. The period has ended.
+- Canceled. The system can cancel a period in certain error situations. Or a user may set this status to cancel a period manually.
+
+#### Billing status
+
+Billing statuses:
+
+- Pending. Used when a paid period is created but an invoice has not yet been created.
+- Invoiced. An invoice is created for the period.
+- Settled. The invoice is paid or the period is free of charge.
+- Canceled. Can be used for canceled periods.
+
+#### Invoice automatically
+
+If checked, an invoice for the period will be created automatically according the billing plan parameters. The parameter is available only if the billing status is Pending.
+
+#### Activate only if paid
+
+If unchecked, the subscription always switches to Active at the start of the period. If checked, switching to Active also requires the billing status to be Settled.
+
+When a subscription created from a template, this parameter is automatically checked for the first paid period. This means that the subscription won't be set to Active until the period's billing status is settled (usually meaning that the customer has paid). Following periods will have this parameter disabled.
+
+## Subscription templates
+
+Subscription templates simplify subscription creation by defining reusable configuration parameters.
+
+Access to Subscription Templates is controlled by Roles. Subscription templates are available under: Subscriptions tab > top-right menu > Subscription Templates.
+
+### Parameters
+
+#### Billings plans
+
+The field defines which billings plans will be available for selection. For example, you can offer to select either a 1 month or 1 year billing plan.
+
+#### Trial period
+
+If enabled, created subscriptions will have a trial period at the start.
+
+#### Trial period days
+
+The length of the trial period in days.
+
+#### Fixed term
+
+If enabled, created subscriptions will have a fixed duration. The duration is determined by a unit (month, year, week, or day) and a number.
+
+#### Items
+
+A template must have at least one product added in a line item. Only products marked as *Subscribable* are allowed.
+
+Each line item specifies a quantity. If *Fixed Qty* is checked for a line item, the exact same quantity will be used in a created subscription.
+
+If *Fixed Qty* is not checked, then the line item quantity defined in the template will be multiplied by the quantity set upon subscription creation. For example, if the line item quantity is set to 10 and upon subscription creation the user set a quantity of 3, the result quantity for the item line will be 30. Use case example: A 10 GB storage is given per each seat.
+
+### Template usage
+
+To use a subscription template, go to Subscriptions > top-right menu > Create with Template. Then, select the needed template. After this, the following fields will be shown:
+
+- Billing Plan. Pre-filled if the template has only one plan.
+- Start Date. Pre-filled with the today's date.
+- Trial period. Pre-checked if the template has the trial period is checked for the template.
+- Quantity. Defines quantities of the subscription line items.
+- Currency. If multiple currencies are available in the system.
+
+After filling the form, the page will be redirected to the subscription creation form with pre-filled values. Here, you need to select an Account the subscription is created for. Then, you can save the subscription.
+
+## Updates and proration
+
+To update the line items of an existing subscription, a user can either edit the subscription directly or use the built-in update mechanism. In the latter case, the system automatically creates an invoice, a credit note, or both to prorate the change. The proration will be processed only if there is a Regular period entry with status *Invoiced* or *Completed* and this period is not yet ended.
+
+!!! note
+
+ If a Regular period is completed without an invoice (for example, the company decided to provide the service for free for that period), the proration mechanism is still activated by default. In such cases, avoid issuing an invoice and credit note by setting the update status right away to Completed, or edit the subscription directly bypassing the update process.
+
+ You may still want to prorate the amount in cases when the net amount of the proration is a positive value but avoid crediting the customer when the net amount is negative (to avoid crediting the customer for a service they did not pay for). For this, use the update process but do not issue the credit note if the pre-calculated net amount is negative.
+
+To initiate an update process, in the subscription's detail view, click the plus icon in the Updates panel.
+
+The *Date* field value is pre-set with the today's date. Pick another date if needed. This date is used for proration calculation. The portion of the billed period that falls after this date will be prorated.
+
+Specify the *Billing Action*: Draft or Issue. This defines the status of the invoice and credit note which will be created. If you select Issue, then the following checkboxes will show up:
+
+- Create Payment Request. The system will create the payment request with the amount due.
+- Send Payment Request. The system will send the payment request to the customer.
+- Send Invoice. The system will send the issued invoice to the customer.
+
+Modify the line items of the subscription.
+
+The system previews the three amount values: To Invoice, To Credit, and Net Amount.
+
+Once the update record is saved, the subscription line items are immediately changed according to the line items specified in the update. The line items of the created update cannot be edited. To modify the subscription items again, you need to create a new update.
+
+### Update billing status
+
+The billing status of an update record affects the life cycle of the subscription. An overdue invoice will switch the subscription to the Due billing state and will stop the subscription after the grace period.
+
diff --git a/docs/extensions/sales-pack/suppliers.md b/docs/extensions/sales-pack/suppliers.md
new file mode 100644
index 000000000..8a4732dc2
--- /dev/null
+++ b/docs/extensions/sales-pack/suppliers.md
@@ -0,0 +1,11 @@
+# Suppliers
+
+*As of Sales Pack v2.0.*
+
+Suppliers can be accessed at Products > the top right menu > Suppliers or Purchase Orders > the top right menu > Suppliers. It's also possible add the Suppliers navbar tab.
+
+Access to Suppliers is controlled by Roles.
+
+It's possible to specify Supplier Prices for specific products. There can be multiple prices for the same product: for specific date range or quantity.
+
+Whenever a product is added to a Purchase Order, the system will look up the price in the associated Supplier.
diff --git a/docs/extensions/sales-pack/tax-codes.md b/docs/extensions/sales-pack/tax-codes.md
new file mode 100644
index 000000000..a97d52700
--- /dev/null
+++ b/docs/extensions/sales-pack/tax-codes.md
@@ -0,0 +1,90 @@
+# Tax Codes
+
+*As of Sales Pack v4.0.*
+
+The Tax Codes functionality is the foundation of the tax engine. A tax code is a unique identifier (like *VAT20* or *EXMPT*) that serves two important roles:
+
+- defines tax calculation logic;
+- provides reporting capabilities.
+
+Every document line item must have an associated tax code, even when tax is not applicable (for this, zero-rate tax codes are used).
+
+Tax codes can be enabled or disabled at Administration > Sales Pack Settings > Tax Codes. Having tax codes enabled is recommended.
+
+Access to tax codes is controlled by Roles. Regular users can be granted with edit access. Users that do not have explicit access to the Tax Code scope in their roles, still are able to select tax codes when they create a document.
+
+To manage tax codes go to: Administration > Tax Codes. Here, you can create tax codes.
+
+For a saved document, to view how taxes were applied, click *View Tax Details* from the menu next to the *Edit* button. In case of cash basis taxes, you can view applied taxes from a Payment entry.
+
+### Tax code parameters
+
+#### Status
+
+Indicates whether the tax code is available in the system. Instead of removing tax codes that has been used in transactions, set them Inactive.
+
+#### Selectable
+
+Indicates that the tax code can be selected for line items. Disable this parameter for tax codes that are not meant to be used separately from a composite tax code.
+
+#### Fore Sales
+
+Whether the tax code can be used for sales transactions, such as Quote, Sales Order, and Invoice.
+
+#### For Purchases
+
+Whether the tax code can be used for purchase transactions, such as Purchase Orders and Bills.
+
+#### Type
+
+Available options:
+
+- Percentage. Tax rate is defined by a percentage value.
+- Fixed. A fixed amount tax. For example, $10 tax per each item regardless of the unit price.
+- Composite. Tax code defines multiple nested tax codes. Use this type when multiple taxes must be applied for a product.
+
+#### Rate
+
+A tax rate in percents. Available only for Percentage type.
+
+#### Base
+
+Specifies which value is used as the tax base.
+
+- Net Amount. The amount excluding taxes.
+- Cumulative Total. The net amount plus all previously applied taxes. Has an effect only when the tax code is used in a composite tax.
+
+#### Apply to Proportional Shipping
+
+If enabled, this tax code will be included in proportional shipping tax calculations. You may need to disable this parameter for certain tax codes used in a composite tax.
+
+If the proportional method is not used, this parameter has no effect. The parameter is available only for Percentage type.
+
+#### Included in Price
+
+Whether the tax amount is included in the unit price.
+
+You may need to enable this parameter for taxes like excise. For taxes like VAT or GST, this parameter usually should be disabled.
+
+#### Rounding Level
+
+Defines how tax amounts are rounded.
+
+- Line. Amounts are rounded on each line.
+- Total. Precise line-level amounts are summed and then rounded.
+
+The parameter is available only Percentage type.
+
+#### Items
+
+Available for Composite type.
+
+Tax codes that will be applied when this tax code is used for a line item. An order of taxes matters.
+
+#### Label
+
+An optional label to be shown to customers. This label may be used in a PDF invoice. You may leave the label empty for taxes which are not supposed to be shown to customers.
+
+#### Country
+
+Can be used for reporting.
diff --git a/docs/extensions/sales-pack/taxes.md b/docs/extensions/sales-pack/taxes.md
new file mode 100644
index 000000000..24c30fce4
--- /dev/null
+++ b/docs/extensions/sales-pack/taxes.md
@@ -0,0 +1,174 @@
+# Taxes
+
+*As of Sales Pack v3.0.*
+
+With the Tax feature you can manage taxes, such as VAT, GST, sales tax, excise, and other taxes.
+
+In this article:
+
+* [Tax profiles](#tax-profiles)
+* [Tax classes](#tax-classes)
+* [Tax rules](#tax-rules)
+
+See also:
+
+* [Tax codes](tax-codes.md)
+
+## Tax profiles
+
+!!! note
+
+ Tax Profile was named *Tax* in earlier versions.
+
+A tax profile defines how taxes are applied to a document.
+
+You can access tax profiles at: Products > top-right menu > Tax Profiles. Or use the global search for quick access.
+
+Access to tax profiles is controlled by Roles.
+
+A tax profile can be applied to:
+
+* Quotes
+* Sales orders
+* Invoices
+* Credit notes
+* Return orders
+* Purchase orders
+* Bills
+* Bill credits
+
+Line items added to a document automatically receive the tax rate according to the Tax Profile assigned to the document. It's also possible to re-calculate tax rates for already added items.
+
+Tax profiles can be automatically assigned to new documents using [Tax Rules](#tax-rules).
+
+A tax profile defines:
+
+* Tax code
+* Shipping tax mode
+* Shipping tax code
+* Item rules
+
+If tax codes are not enabled, a tax profile specifies a rate value instead of the tax code.
+
+### Tax code
+
+The Tax Code field defines the standard (default) tax. When a tax profile is selected for a document, all line items will use its default tax code unless a specific item rule applies to the item's product.
+
+### Shipping tax mode
+
+The *Shipping Tax Mode* defines how tax is applied to the shipping cost. Available modes:
+
+* Proportional – Applies tax to shipping proportionally based on the taxes of the items in the document. This is the most common mode.
+* Fixed – A specific tax is applied.
+
+If the shipping tax mode is not specified, no tax will be applied to the shipping cost.
+
+When items on an invoice have different tax rates, the E-invoice will include separate shipping charge entries with their respective VAT rates.
+
+### Shipping tax code
+
+Determines the tax code to apply to the shipping cost. Available only if the shipping tax mode is set to Fixed.
+
+### Item rules
+
+A tax profile can include item rules. Each item rule defines an override tax rate for a specific Tax Class. Item rules are ordered. The first rule that matches is applied, and the subsequent rules are skipped.
+
+!!! example
+
+ A product has a tax class named 'Zero-rated'. A tax item rule maps this tax class to a tax code with a zero rate. Then, every time the product is added to a document line, that tax code will be automatically set.
+
+## Tax classes
+
+Only an administrator can manage tax classes. Regular users can read tax classes if they have access enabled in Roles. Regular users are able to associate products with tax classes provided they have access to the Tax Class scope.
+
+An administrator can access tax classes via: Administration > Tax Classes.
+
+A single product can belong to one or more tax classes. While one class per product is usually sufficient, multiple classes may be necessary when the product's tax treatment differs across jurisdictions.
+
+## Tax rules
+
+!!! note
+
+ Not to be confused with item rules of the tax profile.
+
+Tax rules enable automatic association of a created document with the appropriate Tax Profile.
+
+For sales and purchases separate rule sets are used.
+
+Only an administrator can manage tax rules. An administrator can access tax rules at: Administration > Tax Rules. Purchase rules can be accessed at: Administration > Purchase Tax Rules.
+
+One tax rule defines a Tax Profile and conditions. These conditions are evaluated against the Account record the order is related to.
+
+When an order is created for a specific Account, the Tax Profile is automatically selected according to the evaluated tax rules.
+
+Tax rules are ordered. The first rule that matches is applied, and the subsequent rules are skipped.
+
+A rule with empty conditions is always applied. Such a rule can be placed at the end of the list to act as a default.
+
+Rules can be set as inactive. This is useful, for example, when VAT is charged only after sales exceed a designated threshold. The rule can then be enabled accordingly.
+
+In most cases, rule conditions would check:
+
+* Country – To select the appropriate tax profile for a specific country.
+* Tax Number – If the VAT number is provided, then select the zero-rate tax profile. Reverse charge scenario.
+
+!!! note
+
+ The *Tax Number* field is available in the Account entity type. By default, it's not added to the layout.
+
+### Example
+
+Let's assume our company is based in Germany and sells domestically, within the EU, and worldwide simultaneously.
+
+| Condition | Tax rule to apply |
+|----------------------------------------------------------------------------------|-----------------------------|
+| **Domestic** (same country) | Use seller's local VAT rate |
+| **Intra-EU B2B** (customer is VAT registered) | Reverse charge (0% VAT) |
+| **Intra-EU B2C** (not VAT registered) and total cross-border B2C sales < €10,000 | Use seller's local VAT |
+| **Intra-EU B2C** and threshold exceeded | Use customer's country VAT |
+| **Outside EU** (export) | Exempt (0% VAT) |
+
+We would need to create the following tax profiles:
+
+* Zero – to cover Intra-EU B2B and Outside EU;
+* Reverse charge – to cover all Intra-EU B2B;
+* Germany – to cover Domestic and Intra-EU B2C before threshold exceeded;
+* Separate records for each EU country we are going to sell to (B2C).
+
+For each tax profile, we will create and select a unique tax code.
+
+We would need to create the following tax rules.
+
+1\. Domestic.
+
+This rule will map Accounts from Germany to the *Germany* tax profile. In the rule's conditions, add a condition that checks whether the *Country* is set to Germany.
+
+2\. Intra-EU B2B.
+
+This rule will map Accounts from EU countries with the VAT number to the *Reverse charge* tax profile. In the rule's conditions, add an OR condition with child conditions for each EU country. Also add a condition checking whether the Tax Number is not empty.
+
+!!! note
+
+ You can use a custom field to designate an Account as EU based and set the value with formula. It will make defining the rule conditions simpler.
+
+!!! note
+
+ It may be reasonable to create separate reverse charge tax profile for each country for reporting reasons.
+
+3\. Intra-EU B2C below threshold.
+
+This rule will map Accounts from EU countries without the VAT number to the *Germany* tax profile.
+
+This rule is supposed to be deactivated once total cross-border B2C sales exceeds €10,000.
+
+4\. Separate Intra-EU B2C rules for each EU country.
+
+Each rule will map to a corresponding tax profile of the EU country.
+
+It's important that these rules are placed after the previous rule (the order or rules matters).
+
+5\. Outside EU.
+
+This rule will be the last one. It will map to the *Zero* tax profile. It may not define any condition, acting as a default rule.
+
+It's important that this rule is placed at the end.
diff --git a/docs/extensions/sales-pack/write-offs.md b/docs/extensions/sales-pack/write-offs.md
new file mode 100644
index 000000000..5782b8f97
--- /dev/null
+++ b/docs/extensions/sales-pack/write-offs.md
@@ -0,0 +1,18 @@
+# Write-offs
+
+*As of Sales Pack v4.0.*
+
+Write-offs allow settling an outstanding invoice balance without receiving or issuing a payment. They are commonly used for minor discrepancies, rounding differences, or immaterial amounts deemed uncollectible.
+
+Write-offs are allocated to invoices the same way as payments or credit notes.
+
+!!! warning
+
+ As write-offs do not include line-items, they should not be used when a reduction in tax liability is required.
+ They also should not be used to cancel an entire invoice. In such cases, credit notes should be used instead.
+
+Access to Write-offs is controlled by Roles.
+
+Write-offs are available at: Invoices tab > top-right menu > Write-offs. Or you can use the global search for quick access. An administrator can add the Write-offs tab to the navbar.
+
+You can create a write-off for an invoice from the invoice detail view, from the top-right menu. The outstanding amount will be pre-filled in the write-off's amount field.
diff --git a/docs/extensions/stripe-integration/index.md b/docs/extensions/stripe-integration/index.md
new file mode 100644
index 000000000..a6f3208d0
--- /dev/null
+++ b/docs/extensions/stripe-integration/index.md
@@ -0,0 +1,72 @@
+# Stripe Integration
+
+The integration allows your customers to make one-time payments using Stripe. Available in [extension](https://www.espocrm.com/extensions/stripe-integration/).
+
+The Stripe integration requires:
+
+- [Sales Pack](https://www.espocrm.com/extensions/sales-pack/) extension
+- EspoCRM v9.1 or greater
+
+Check this [article](../sales-pack/payments.md) to learn about the payments feature in Sales Pack.
+
+## Setting up
+
+!!! important
+
+ The integration relies on Stripe's webhooks. Your Espo instance must be accessible to Stripe.
+
+### Create webhooks in Stripe
+
+Go to Stripe Dashboard > Developers > Webhooks.
+
+Click *Add destination*.
+
+Select all the following Checkout events:
+
+* checkout.session.async_payment_failed
+* checkout.session.async_payment_succeeded
+* checkout.session.completed
+* checkout.session.expired
+
+Then, choose the Webhook endpoint, as we are creating a webhook.
+
+Specify the following endpoint URL: `https://your-host/api/v1/Stripe/webhook`. You can obtain the proper URL in Espo under Administration > Payment Channels > Create Payment Channel.
+
+### Create payment channel in Espo
+
+Create a Payment Channel under Administration > Payment Channels, and select *Stripe* in the Provider field. Enter your Stripe keys and the webhook key, which you can obtain from the Stripe Dashboard.
+
+You may name the payment channel *Stripe*.
+
+### Create payment method in Espo
+
+Create a Payment Channel under Administration > Payment Methods, and select the previously created channel. You may name the method *Stripe*.
+
+## Trying out
+
+1. Create a Payment Request, select the created Stripe method, and enter the amount. Set the status to *Pending*.
+2. After the request is created, the payment URL will be generated. You can send this URL to your customer so that they can pay via Stripe.
+3. Once the customer paid, the status of the Payment Request will automatically change to *Paid*.
+4. A Payment entry related to the Payment Request will be created with the status *In Progress*, and will automatically change to *Paid* shortly after (by cron).
+
+## Testing in local environment
+
+As webhooks require your Espo instance being accessible to Stripe, testing the integration in a local environment may need a few tweaks. To test the integration in a local environment, you can use Stripe CLI or a tunnel service (e.g., ngrok).
+
+### Using Stripe CLI
+
+Stripe CLI provides the ability to forward Stripe events to your local webserver. You don't need to create webhooks in the Stripe Dashboard for this (though you will need to create them for production).
+
+Download the [Stripe CLI](https://docs.stripe.com/stripe-cli) tool and run it in the terminal.
+
+Run the command:
+
+```
+stripe listen --forward-to localhost/api/v1/Stripe/webhook
+```
+
+Where *localhost* should be replaced with the actual local address of your Espo instance.
+
+It will print the webhook secret key. Specify this key in the payment channel record in Espo.
+
+Keep the process running while you are testing the integration.
diff --git a/docs/extensions/voip-integration/3cx-integration-setup.md b/docs/extensions/voip-integration/3cx-integration-setup.md
new file mode 100644
index 000000000..b6f7cf222
--- /dev/null
+++ b/docs/extensions/voip-integration/3cx-integration-setup.md
@@ -0,0 +1,80 @@
+# 3CX Integration Setup
+
+3CX integration is available as part of [VoIP Integration extension](https://www.espocrm.com/extensions/voip-integration/). It allows you to integrate EspoCRM with 3CX server and other VoIP providers, read more details [here](https://www.espocrm.com/features/3cx-integration/).
+
+!!! note
+
+ Due to the way 3CX handles call events, the call pop-up in EspoCRM will only appear after the call has ended. This is a limitation of the 3CX PBX platform itself and not of EspoCRM. Once the call is complete, you’ll see the contact information and call details window in CRM as expected.
+
+!!! note
+
+ For the integration to work correctly, EspoCRM instance must be accessible by the 3CX server. The integration operates in Webhook mode, which requires EspoCRM to be reachable over the internet. If your CRM is hosted on a local or private network, or if external access is restricted, the integration will not function.
+
+## How to setup 3CX Integration for an administrator
+
+Fill in the connection details of your 3CX server. To do this, go to the Administration (System panel) > Integrations > VoIP · 3cx.
+
+
+
+* **Name** – name of your connection.
+* **3CX Web Client URL** – URL of your 3CX web client.
+* **Access Key to EspoCRM** – access key to EspoCRM for 3CX server.
+* **Default Country** – the country is used to format phone numbers.
+* **Dial Format for outgoing calls** – a phone number format for outgoing (click-to-call) calls.
+* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed. Use numbers in the following formats: +14844608117 (full number match) or #4844608117# (regular expression).
+* **Permitted Entities** – entities that will be displayed in the popup window and will be used to identify a caller by his phone number.
+* **Apply global ACL for caller lookup** – apply global ACL rules (Administration > Roles) for caller lookup. This information is displayed in the popup window. If unchecked, no ACL restrictions are used.
+* **Hide call popup window** – automatically process call pop-ups without displaying them.
+* **Hide a Lead** – hide a Lead in a call popup when Account / Contact are available.
+* **Display Accounts related to Contacts** – display only Accounts related to Contacts.
+* **Listen recorded calls** – if you want to have possibility to listen recorded calls. This option should also be enabled in your telephony server.
+* **Upload recording?** – enables uploading recordings into EspoCRM.
+* **Automatically save a call** – automatically save incoming/outgoing calls in the system without having to press "Save" button.
+* **Automatically open the caller information** – automatically open the caller information for incoming/outgoing calls.
+* **Quick Create Entities** – entities which can be created through the call popup window.
+
+## How to setup 3CX Integration events
+
+To handle incoming/outgoing calls, download the XML configuration from the side panel in the Administration (System panel) -> VoIP · 3cx, go to the 3CX Management Console -> “Settings” -> “CRM Integration”, click the “+ Add Template” button, and import the downloaded XML configuration.
+
+## How to setup 3CX Integration for users
+
+Each user who wants to use 3CX integration, should setup his access in the User’s Profile, under “VoIP Settings”. Also, the user can change some VoIP settings on this window.
+
+
+
+* **VoIP Server** – your current VoIP server.
+* **Your user extension** – your internal user extension (SIP user) of the 3CX server.
+* **Your VoIP password** – your password of the 3CX server.
+* **Display call notifications** – an option to enable/disable incoming/outgoing call notifications.
+* **Silent notifications** – mute notification sound.
+* **Use internal click-to-call** – an option to enable/disable the internal click-to-call feature. It is a feature to make outgoing calls through the 3CX server. If the checkbox is unchecked, then an external application will handle “tel:” links.
+* **User Dial Context** – Dial Context for a User. If it is empty, a Dial Context of a connector will be used.
+
+## Access control for users
+
+Make sure that your users have the access to the entity 'Calls'.
+
+* [Grant access to Calls](customization.md#grant-access-to-calls)
+
+## Summary and Transcript fields
+
+To access Summary and Transcript fields, you need to drag these fields to the Call layout in EspoCRM. Go to Administration > Layout Manager > Calls and drag the corresponding fields to the layout you need.
+
+## Update 3CX Configuration File
+
+Following the upgrade of the VoIP Integration extension, it is necessary to update the XML Template on the 3CX Server side in order to ensure proper integration.
+
+The steps to update are as follows:
+
+1\. In the EspoCRM instance, go to the Administration > Integrations > VoIP · 3cx and download the latest version of the 3CX XML template.
+
+
+
+2\. Navigate to the 3CX Management Console > Settings > CRM Integration, and delete the existing template.
+
+
+
+3\. Click on the `+ Add Template` button and upload the newly downloaded XML template.
+
+4\. Save the changes.
diff --git a/docs/extensions/voip-integration/asterisk-integration-setup.md b/docs/extensions/voip-integration/asterisk-integration-setup.md
index 7d9590b16..a4a6f6cc8 100644
--- a/docs/extensions/voip-integration/asterisk-integration-setup.md
+++ b/docs/extensions/voip-integration/asterisk-integration-setup.md
@@ -1,26 +1,28 @@
# Asterisk Integration Setup
-VoIP Integration extension allows EspoCRM to integrate with an Asterisk server through Asterisk Manager Interface (AMI), Twilio service and Starface server. For more details about the features, please click [here](https://www.espocrm.com/features/voip-integration/).
+Asterisk integration is available as part of [VoIP Integration extension](https://www.espocrm.com/extensions/voip-integration/). It allows you to integrate EspoCRM with Asterisk server through Asterisk Manager Interface (AMI) and other VoIP providers, read more details [here](https://www.espocrm.com/features/asterisk-integration-setup/).
## Supported Asterisk servers
VoIP Integration extension supports* the following Asterisk servers:
+* Asterisk 22
+* Asterisk 21
+* Asterisk 20
+* Asterisk 19
+* Asterisk 18
* Asterisk 17
* Asterisk 16
* Asterisk 15
* Asterisk 14
* Asterisk 13
-* Asterisk 12
-* Asterisk 11
-* Asterisk 10.
-* Asterisk 1.8
\* these servers were tested with VoIP Integration extension.
## How to setup Asterisk Integration for an administrator
-**Step 1.** Fill in the connection details of your Asterisk server. To do this, go to the Administration (System panel) -> VoIP » Asterisk AMI.
+#### Step 1:
+Fill in the connection details of your Asterisk server. To do this, go to the Administration (System panel) > Integrations > VoIP · Asterisk AMI.

@@ -29,7 +31,6 @@ VoIP Integration extension supports* the following Asterisk servers:
* **Port** – a port for connection through AMI interface.
* **Username** – AMI username.
* **Password** – AMI user password.
-* **Version of the Asterisk server** – a version of your Asterisk server.
* **Protocol** – protocol for connection to Asterisk server (TCP, UDP, TLS).
* **Dialout Channel** – channel format for outgoing calls. It can be “PJSIP/###” (Asterisk 13+) or “SIP/###”, where ### is a user’s extension (internal number). The extension “###” will be substituted automatically depending on the user.
* **Dial Context** – context for dial actions.
@@ -37,21 +38,31 @@ VoIP Integration extension supports* the following Asterisk servers:
* **Read Timeout** – timeout of read events from Asterisk server.
* **Default Country** – the country is used to format phone numbers.
* **Dial Format for outgoing calls** – a phone number format for outgoing (click-to-call) calls.
-* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed.
+* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed. Use numbers in the following formats: +14844608117 (full number match) or #4844608117# (regular expression).
* **Permitted Entities** – entities that will be displayed in popup window and will be used to identify a caller by his phone number.
+* **Apply global ACL for caller lookup** – apply global ACL rules (Administration > Roles) for caller lookup. This information is displayed in the popup window. If unchecked, no ACL restrictions are used.
* **Hide a Lead** – Hide a Lead in a call popup when Account / Contact are available.
* **Display Accounts related to Contacts** – display only Accounts related to Contacts.
* **Automatically save a call** – Automatically save incoming/outgoing calls in the system without having to press "Save" button.
* **Automatically open the caller information** – automatically open the caller information for incoming/outgoing calls.
* **Access Key to EspoCRM** – an access key of EspoCRM to post data from Asterisk server.
* **Listen recorded calls** – possibility to listen recorded calls in EspoCRM.
-* **URL to recorded calls** – a pattern of recorded call URLs.
* **Lines** – a prefix of phone numbers. E.g. UK phone number 702031112233 will be formatted like “7” – a line and “02031112233” – a phone number.
* **Quick Create Entities** – entities which can be created through the call popup window.
* **Active Queue Numbers** – a list of queue phone numbers which should be determined by EspoCRM.
+* **Display a popup only after answering the call** – do not show incoming call popups until the user answers a call.
+* **Experimental features** – test experimental features.
+
+#### Step 2:
+
+Setup a cron job (scheduled task) to handle Asterisk events (incoming/outgoing calls, hangup, etc.). It is very important to set it up to run every minute. The line that needs to be added is displayed in the right section of your Asterisk settings. For linux-based OS, it looks like:
+
+```
+* * * * * cd /var/www/html/espocrm; /usr/bin/php -f command.php voip Asterisk > /dev/null 2>&1
+```
+
+For docker containers, see [here](#setting-up-cron-for-docker-container).
-**Step 2.** Setup a cron job (scheduled task) to handle Asterisk events (incoming/outgoing calls, hangup, etc.). It is very important to set it up to run every minute. The line that needs to be added is displayed in the right section of your Asterisk settings. For linux-based OS, it looks like:
-**\* \* \* \* \* /usr/bin/php -f /var/www/espocrm/voip.php Asterisk > /dev/null 2>&1**
## How to setup Asterisk Integration for users
@@ -67,6 +78,12 @@ Each user who wants to use Asterisk integration, should setup his access in the
* **Use internal click-to-call** – an option to enable/disable the internal click-to-call feature. It is a feature to make outgoing calls through Asterisk server. If the checkbox is unchecked, then an external application will handle “tel:” links.
* **User Dial Context** – Dial Context for a User. If it is empty, a Dial Context of a connector will be used.
+## Access control for users
+
+Make sure that your users have the access to the entity 'Calls'.
+
+* [Grant access to Calls](customization.md#grant-access-to-calls)
+
## Additional phone numbers for users
Each user can add several additional phone numbers to handle incoming calls. They can be added in the User’s Profile.
@@ -75,3 +92,7 @@ Note: Additional phone numbers are used for incoming calls only. Outgoing calls

* **Phone numbers formats:** +442031112233, 00442031112233, 02031112233.
+
+## Setting up cron for Docker container
+
+To display call pop-up windows and ensure the Asterisk provider works correctly in Docker, use either a daemon in the Docker Compose environment or add a cron job. For more information, see [Docker container setup](docker-container.md#asterisk).
diff --git a/docs/extensions/voip-integration/binotel-integration-setup.md b/docs/extensions/voip-integration/binotel-integration-setup.md
index 1f885b160..0780adf8f 100644
--- a/docs/extensions/voip-integration/binotel-integration-setup.md
+++ b/docs/extensions/voip-integration/binotel-integration-setup.md
@@ -1,30 +1,33 @@
# Binotel Integration Setup
-Binotel Integration is available as part of [VoIP Integration extension](https://www.espocrm.com/extensions/voip-integration/). It allows to integrate EspoCRM with Asterisk server through Asterisk Manager Interface (AMI), Starface and Binotel server, read more details [here](https://www.espocrm.com/features/binotel-integration/).
+Binotel integration is available as part of [VoIP Integration extension](https://www.espocrm.com/extensions/voip-integration/). It allows you to integrate EspoCRM with Binotel server and other VoIP providers, read more details [here](https://www.espocrm.com/features/binotel-integration/).
## How to setup Binotel Integration for an administrator
-1. Fill in the connection details of your Binotel server. For this go to the Administration (System panel) -> VoIP » Binotel.
+1\. Fill in the connection details of your Binotel server. For this go to the Administration (System panel) > Integrations > VoIP · Binotel.

* **Name** – name of your Binotel connector.
* **Authorization Key** – authorization Key to the Binotel server.
* **Authorization Secret** – authorization Secret to the Binotel server.
-* **Use SSL** – Use SSL for connection to the server Binotel.
+* **Binotel API Version** – the version of the Binotel API which is used for integration.
* **Access Key** – the key to access to EspoCRM to handle incoming/outgoing calls.
* **Default Country** – The country is used to format phone numbers. E.g. 02011112222 for United Kingdom will be formatted to +442011112222.
* **Dial Format for outgoing calls** – Phone number format for outgoing (click-to-call) calls.
E.g. for "+44 (203) 111-22-33": {COUNTRY_CODE} - "44", {NATIONAL_NUMBER} - "2031112233".
-* **List of ignored numbers** – list of numbers, which will be ignored and popup window will not be displayed.
+* **List of ignored numbers** – list of numbers, which will be ignored and popup window will not be displayed. Use numbers in the following formats: +14844608117 (full number match) or #4844608117# (regular expression).
* **Permitted Entities** – entities that will be displayed in popup window and will be used to identify a caller by his phone number.
+* **Apply global ACL for caller lookup** – apply global ACL rules (Administration > Roles) for caller lookup. This information is displayed in the popup window. If unchecked, no ACL restrictions are used.
* **Hide a Lead** – Hide a Lead in a call popup when Account / Contact are available.
* **Display Accounts related to Contacts** – display an account related to the contact in the popup window.
+* **Automatically save a call** – automatically save incoming/outgoing calls in the system without having to press "Save" button.
* **Automatically open the caller information** – automatically open the caller information for incoming/outgoing calls.
* **Quick Create Entities** – entities which can be created through a call popup.
+* **Experimental features** – test experimental features.
-2. Contact Binotel support to add an URL (see “Post URL” field) to handle incoming/outgoing calls (API CALL Settings and API PUSH):
+2\. Contact Binotel support to add an URL (see “Post URL” field) to handle incoming/outgoing calls (API CALL Settings and API PUSH):
**http://espocrm.local/?entryPoint=Binotel&connector=Binotel&key=hh9v0zr529**
@@ -40,3 +43,9 @@ Each user who uses telephony should setup his user extension in User’s Profile
* **Display call notifications** – if you want to receive incoming/outgoing call notifications.
* **Silent notifications** – mute notification sound.
* **Use internal click-to-call** – switching internal click-to-call possibility. Internal click-to-call is a feature to originate an outgoing call. If the checkbox is unchecked, then will be used an external application to handle tel: links.
+
+## Access control for users
+
+Make sure that your users have the access to the entity 'Calls'.
+
+* [Grant access to Calls](customization.md#grant-access-to-calls)
diff --git a/docs/extensions/voip-integration/customization.md b/docs/extensions/voip-integration/customization.md
index f1d903450..b4ea8d1f0 100644
--- a/docs/extensions/voip-integration/customization.md
+++ b/docs/extensions/voip-integration/customization.md
@@ -3,12 +3,21 @@
In this article:
* [Displaying a call recording](#displaying-a-call-recording)
+* [Grant access to Messages](#grant-access-to-messages)
+* [Grant access to Calls](#grant-access-to-calls)
* [Add click-to-call feature to a custom entity](#add-click-to-call-feature-to-a-custom-entity)
+* [Add custom entities to Permitted Entities](#add-custom-entities-to-permitted-entities)
* [Add custom entities to Quick Create Entities](#add-custom-entities-to-quick-create-entities)
+* [Event information in Permitted / Quick Create Entity](#event-information-in-permitted-quick-create-entity)
* [Adding a call name to a call popup](#adding-a-call-name-to-a-call-popup)
* [Format phone number](#format-phone-number)
* [Call recording for Asterisk](#call-recording-for-asterisk)
-* [Custom call recording URL handler](#custom-call-recording-url-handler)
+* [Adding a custom call recording handler](#custom-call-recording-handler)
+* [Adding a custom ApiClient](#custom-apiclient)
+* [Adding a custom EventListener](#custom-eventlistener)
+* [Adding a custom WebhookHandler](#custom-webhookhandler)
+* [Adding a custom CidManager](#custom-cidmanager)
+* [Adding a custom Call attribute](#custom-call-attribute)
* [Additional info](#additional-info)
@@ -21,6 +30,27 @@ For displaying call recordings in EspoCRM, go to Administration > Layout Manager
After that, clear a local cache (Menu > Clear Local Cache).
+## Grant access to Messages
+
+By default regular users don’t have access to Message entity. Administrator needs to grant access to this entity:
+
+1. Login as Administrator in EspoCRM.
+2. Navigate to the Administration > Roles.
+3. Create / edit a Twilio role.
+4. Grant access to the Message entity.
+
+
+
+By default the Message entity tab should be added into the tab list.
+
+
+
+## Grant access to Calls
+
+Don't forget to give users access to the entity '**Calls**', so that they could make and accept calls. Go to the needed **User** > **Roles**.
+
+Select the role or create a new one. Turn on '**Enabled**' access to the entity '**Calls**' and click '**Save**'.
+
## Add click-to-call feature to a custom entity
To add a click-to-call feature to a custom entity you have to create/edit a file `/custom/Espo/Custom/Resources/metadata/entityDefs/.json`.
@@ -38,14 +68,38 @@ In this file should be defined a phoneNumber field (a field with "type": "phone"
}
```
-Please make sure that your JSON data is correct after changes.
+Make sure that your JSON data is correct after changes.
To take effect, clear a system cache (Administration > Clear Cache) and reload a page in your browser.
+## Add custom entities to Permitted Entities
+
+**Important**: the added entity must be of the `Person` type.
+
+To add some custom entities to Permitted Entities, create/modify the file `/custom/Espo/Custom/Resources/metadata/integrations/.json` with the code:
+
+(e.g. for Asterisk connector it's the file `/custom/Espo/Custom/Resources/metadata/integrations/Asterisk.json`)
+
+```
+{
+ "fields": {
+ "permittedEntities": {
+ "options": [
+ "__APPEND__",
+ ""
+ ]
+ }
+ }
+}
+```
+
+Make sure that your JSON data is correct after changes.
+To take effect, clear a system cache (Administration > Clear Cache) and reload a page in your browser.
+
## Add custom entities to Quick Create Entities
-To add some custom entities to Quick Create Entities, please create/modify the file `/custom/Espo/Custom/Resources/metadata/integrations/.json` with the code:
+To add some custom entities to Quick Create Entities, create/modify the file `/custom/Espo/Custom/Resources/metadata/integrations/.json` with the code:
(e.g. for Asterisk connector it's the file `/custom/Espo/Custom/Resources/metadata/integrations/Asterisk.json`)
@@ -62,18 +116,46 @@ To add some custom entities to Quick Create Entities, please create/modify the f
}
```
-Please make sure that your JSON data is correct after changes.
+Make sure that your JSON data is correct after changes.
To take effect, clear a system cache (Administration > Clear Cache) and reload a page in your browser.
+## Event information in Permitted / Quick Create Entity
+
+There is a way to get event information while creating a `Permitted` / `Quick Create` entity.
+
+For example, if we need to fetch a `phoneNumber` into the `description` field for a **Task** entity:
+
+1\. Add the field in `custom/Espo/Custom/Resources/metadata/entityDefs/Task.json`:
+
+```
+{
+ "fields": {
+ "voipEventData": {
+ "type": "jsonObject",
+ "notStorable": true
+ }
+ }
+}
+```
+
+2\. Make rebuild and grant the [necessary permissions](https://docs.espocrm.com/administration/server-configuration/#permissions).
+
+3\. Add the following formula in `Administration` > `Entity Manager` > `Task` > `Formula` > `Before Save Custom Script`:
+
+```
+$voipEventData = json\encode(voipEventData);
+description = json\retrieve($voipEventData, 'phoneNumber');
+```
+
+In addition to `phoneNumber`, additional data such as `id`, `status`, `type`, `assignedUserId`, etc., can be fetched from `voipEventData`. All data can be viewed after adding the `voipEventData` field to a layout.
## Adding a call name to a call popup
-To display a Call name field in a call popup, please create/modify the file `custom/Espo/Custom/Resources/metadata/app/popupNotifications.json` with the code:
+To display a Call name field in a call popup, create/modify the file `custom/Espo/Custom/Resources/metadata/app/popupNotifications.json` with the code:
```
{
"voipNotification": {
-
"additionalFields": {
"callName" : {
"display": true,
@@ -89,7 +171,7 @@ To display a Call name field in a call popup, please create/modify the file `cus
* default order is 10.
-Please make sure that your JSON data is correct after changes.
+Make sure that your JSON data is correct after changes.
To take effect, clear a system cache (Administration > Clear Cache) and reload a page in your browser.
## Format phone number
@@ -123,18 +205,25 @@ Then go to Administrator panel > Clear cache.
The call recording should be configured on the Asterisk side, the URL of that recording will be saved in EspoCRM.
The setup process:
-1. Configure a call recording on the Asterisk side.
-2. Login to EspoCRM under the administrator and go to the Asterisk connector (Administration > VoIP Settings > Asterisk AMI).
-3. Enable the "Listen recorded calls" option and configure the "URL to recorded calls" field.
+
+1\. Configure a call recording on the Asterisk side.
+
+2\. Login to EspoCRM under the administrator and go to the Asterisk connector (Administration > VoIP Settings > Asterisk AMI).
+
+3\. Enable the "Listen recorded calls" option and configure the "URL to recorded calls" field.
+
Possible parameters:
+
* "{VOIP_UNIQUEID}" - uniqueid of a call;
* "{Y}" - year of a call;
* "{m}" - month of a call;
* "{d}" - day of a call.
+
Example:
If we have a link in a format: "http://11.11.11.11/2019/11/25/1568202771.6.mp3", then the "URL to recorded calls" should be the following:
`http://11.11.11.11/{Y}/{m}/{d}/{VOIP_UNIQUEID}.mp3`
-4. Display a call recording field in a layout of Call entity.
+
+4\. Display a call recording field in a layout of Call entity.
For displaying a call recording field in EspoCRM, go to Administration > Layout Manager > select Calls entity and add the field "Recording" for Detail layout. See the screenshot:
@@ -142,26 +231,126 @@ For displaying a call recording field in EspoCRM, go to Administration > Layout
After that, clear a local cache (Administration > Clear Cache).
-## Custom call recording URL handler
+## Custom call recording handler
-If the standard functionality is not enough for your URL recording, there is a possibility to create a custom call recording URL handler. For this, create a file located at `custom/Espo/Custom/Modules/Voip/Providers/Asterisk/Scripts/Recording.php` with the code:
+If the standard functionality doesn't meet your recording processing needs, you can implement a custom call recording handler. For example, here's how you can customize it for the `Asterisk` connector:
-```
+1\. Create a file located at `custom/Espo/Custom/Modules/Voip/Providers/Asterisk/Recording.php` with the code:
+
+```php
Clear Cache).
+
+## Custom ApiClient
+
+For adding a custom `ApiClient`, create a file located at `custom/Espo/Custom/Modules/Voip/Providers/YOUR_PROVIDER/ApiClient.php` with the code:
+
+```
+ Clear Cache).
+
+## Custom EventListener
+
+For adding a custom `EventListener`, create a file located at `custom/Espo/Custom/Modules/Voip/Providers/YOUR_PROVIDER/EventListener.php` with the code:
+
+```
+ Clear Cache).
+
+## Custom WebhookHandler
+
+For adding a custom `WebhookHandler`, create a file located at `custom/Espo/Custom/Modules/Voip/Providers/YOUR_PROVIDER/WebhookHandler.php` with the code:
+
+```
+ Clear Cache).
+
+
+## Custom CidManager
+
+For adding a custom `CidManager`, create a file located at `custom/Espo/Custom/Modules/Voip/Providers/YOUR_PROVIDER/CidManager.php` with the code:
+
+```
+ Clear Cache).
+
+## Custom Call Attribute
+
+Note: This method is specifically designed to work with 3CX integration only.
+
+To add a custom attribute for the Call entity, create or edit a file located at `custom/Espo/Custom/Resources/metadata/app/voip.json` with the code:
+
+```json
+{
+ "callAttributes": {
+ "3cx": [
+ "__APPEND__",
+ "cAttribute"
+ ]
+ }
+}
+```
+
After saving, clear a local cache (Administration > Clear Cache).
## Additional info
diff --git a/docs/extensions/voip-integration/docker-container.md b/docs/extensions/voip-integration/docker-container.md
new file mode 100644
index 000000000..e642f9796
--- /dev/null
+++ b/docs/extensions/voip-integration/docker-container.md
@@ -0,0 +1,37 @@
+# VoIP configuration for Docker containers
+
+## Asterisk
+
+To display call pop-up windows and ensure the Asterisk provider works correctly in the [Docker](../../administration/installation-by-script.md) instance, you need to use either a daemon in the Docker Compose environment or add a line to the [crontab](../../administration/server-configuration.md#setting-up-crontab). Choose one of these approaches (either the daemon or the crontab line).
+
+### Daemon (recommended)
+
+!!! note
+
+ This configuration is displayed for the [official EspoCRM container](../../administration/docker/installation.md#install-espocrm-with-docker-compose).
+
+Add the following container to your `docker-compose.yml` file:
+
+```yml
+espocrm-daemon-voip:
+ image: espocrm/espocrm:latest
+ container_name: espocrm-daemon-voip
+ volumes:
+ - espocrm:/var/www/html
+ restart: always
+ entrypoint: []
+ command: ["php", "/var/www/html/command.php", "voip", "Asterisk"]
+```
+
+### Crontab line
+
+!!! important
+
+ This line should be added under `root` or other docker user.
+
+```bash
+* * * * * /usr/bin/docker exec --user WEBSERVER_USER -i ESPOCRM_DOCKER-CONTAINER /bin/bash -c "cd /var/www/html; php -f command.php voip Asterisk" > /dev/null 2>&1
+```
+
+Replace `WEBSERVER_USER` with one of the following values: `www-data`, `www`, `apache`, etc., depending on your web server.
+
diff --git a/docs/extensions/voip-integration/iexpbx-integration-setup.md b/docs/extensions/voip-integration/iexpbx-integration-setup.md
new file mode 100644
index 000000000..a3f9670ac
--- /dev/null
+++ b/docs/extensions/voip-integration/iexpbx-integration-setup.md
@@ -0,0 +1,65 @@
+# iexPBX Integration Setup
+
+iexPBX integration is available as part of [VoIP Integration extension](https://www.espocrm.com/extensions/voip-integration/). It allows you to integrate EspoCRM with iexPBX server and other VoIP providers, read more details [here](https://www.espocrm.com/features/iexpbx-integration/).
+
+## How to setup iexPBX Integration for an administrator
+
+#### Step 1:
+
+Fill in the connection details of your iexPBX server. To do this, go to the Administration (System panel) > Integrations > VoIP · iexPBX.
+
+
+
+* **Name** – name of your connection.
+* **Server URL** – URL of your iexPBX server.
+* **API User** – API user of your iexPBX server.
+* **API Secret** – API Secret of your iexPBX server.
+* **Access Key to EspoCRM** – the key to access to EspoCRM to handle incoming/outgoing calls.
+* **Default Country** – the country is used to format phone numbers.
+* **Dial Format for outgoing calls** – a phone number format for outgoing (click-to-call) calls.
+* **Call Recording** – if you want to have possibility to listen recorded calls. This option should also be enabled in your telephony server.
+* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed. Use numbers in the following formats: +14844608117 (full number match) or #4844608117# (regular expression).
+* **Permitted Entities** – entities that will be displayed in the popup window and will be used to identify a caller by his phone number.
+* **Apply global ACL for caller lookup** – apply global ACL rules (Administration > Roles) for caller lookup. This information is displayed in the popup window. If unchecked, no ACL restrictions are used.
+* **Hide a Lead** – hide a Lead in a call popup when Account / Contact are available.
+* **Display Accounts related to Contacts** – display only Accounts related to Contacts.
+* **Automatically save a call** – automatically save incoming/outgoing calls in the system without having to press "Save" button.
+* **Automatically open the caller information** – automatically open the caller information for incoming/outgoing calls.
+* **Quick Create Entities** – entities which can be created through the call popup window.
+* **Experimental features** – test experimental features.
+
+#### Step 2:
+
+Setup webhooks on iexPBX server to handle incoming/outgoing calls. It can be done by login to a web panel of your iexPBX server, go to Settings > API Integrations and define two Webhooks:
+
+##### Call Event Webhook
+
+- Function: `Arama Bilgisi Gönder`
+- Fonksiyon 2: `Tümü`
+- Type: `GET olarak`
+- URL Address: `https://YOUR_ESPOCRM_URL/api/v1/Voip/webhook/IexPBX/YOUR_ACCESS_KEY?chanid={chanid}&src={src}&dst={dst}&type={calltype}`
+
+
+
+##### Call Status Webhook
+
+- Function: `Kapatma Bilgisi Gönder`
+- Fonksiyon 2: `Tümü`
+- Type: `GET olarak`
+- URL Address: `https://YOUR_ESPOCRM_URL/api/v1/Voip/webhook/IexPBX/YOUR_ACCESS_KEY?chanid={chanid}&status={status}&duration={duration}`
+
+
+
+
+## How to setup iexPBX Integration for users
+
+Each user who wants to use iexPBX integration, should setup his access in the User’s Profile, under “VoIP Settings”.
+
+
+
+* **VoIP Server** – select your iexPBX server.
+* **Your user extension** – your internal SIP extension for the iexPBX server (e.g. 101).
+* **Your VoIP password** – your SIP password for your iexPBX server.
+* **Display call notifications** – an option to enable/disable incoming/outgoing call notifications.
+* **Silent notifications** – mute notification sound.
+* **Use internal click-to-call** – an option to enable/disable the internal click-to-call feature. It is a feature to make outgoing calls through the iexPBX server. If the checkbox is unchecked, then an external application will handle “tel:” links.
diff --git a/docs/extensions/voip-integration/overview.md b/docs/extensions/voip-integration/overview.md
new file mode 100644
index 000000000..e15abf33c
--- /dev/null
+++ b/docs/extensions/voip-integration/overview.md
@@ -0,0 +1,18 @@
+# VoIP Integration extension
+
+The VoIP Integration extension allows you to integrate EspoCRM with IP telephony servers/services.
+
+## Supported servers and services
+
+* [3CX PBX](3cx-integration-setup.md)
+* [Twilio service](twilio-integration-setup.md)
+* [Asterisk server](asterisk-integration-setup.md)
+* [Starface server](starface-integration-setup.md)
+* [Binotel service](binotel-integration-setup.md)
+* [iexPBX server](iexpbx-integration-setup.md)
+
+## Additional information
+
+* [Docker](docker-container.md)
+* [Customization](customization.md)
+* [Troubleshooting](troubleshooting.md)
diff --git a/docs/extensions/voip-integration/starface-integration-setup.md b/docs/extensions/voip-integration/starface-integration-setup.md
index 3eb68a262..168507cac 100644
--- a/docs/extensions/voip-integration/starface-integration-setup.md
+++ b/docs/extensions/voip-integration/starface-integration-setup.md
@@ -1,47 +1,54 @@
# Starface Integration Setup
-VoIP Integration extension allows EspoCRM to integrate with an Asterisk server through Asterisk Manager Interface (AMI), Twilio service and Starface server. For more details about the features, please click [here](https://www.espocrm.com/features/voip-integration/).
+Starface integration is available as part of [VoIP Integration extension](https://www.espocrm.com/extensions/voip-integration/). It allows you to integrate EspoCRM with Starface server and other VoIP providers, read more details [here](https://www.espocrm.com/features/starface-integration-setup/).
## Supported Starface servers
VoIP Integration extension supports* the following Starface servers:
-* Starface 6.2
-* Starface 6.3
-* Starface 6.4
-* Starface 6.5
-* Starface 6.6
+* Starface 9.0
+* Starface 8.1
+* Starface 8.0
+* Starface 7.3
+* Starface 7.2
+* Starface 7.1
+* Starface 7.0
* Starface 6.7
+* Starface 6.6
+* Starface 6.5
+* Starface 6.4
+* Starface 6.3
+* Starface 6.2
-\*these servers were tested with VoIP Integration extension.
+\* These servers were tested with the VoIP Integration extension.
## How to setup Starface Integration for an administrator
-1. Fill in the connection details of your Starafce server. To do this, go to the Administration (System panel) -> VoIP » STARFACE.
+Fill in the connection details of your Starface server. To do this, go to the Administration (System panel) > Integrations > VoIP · STARFACE.

* **Name** – name of your connection.
-* **Host** – IP or domain name of your Starface Server.
+* **Host of Starface server** – IP or domain name of your Starface Server.
* **Port** – port for connection by AMI interface.
* **Protocol** – protocol that is used for connection of Starface server (HTTP, HTTPS).
* **Version of your Starface server** – version of your Starface server. This is an important option since Starface 6.4.2 is used a new authorization protocol.
+* **Access Key to EspoCRM** – the key to access to EspoCRM to handle incoming/outgoing calls.
* **Default Country** – the country is used to format phone numbers.
* **Dial Format for outgoing calls** – a phone number format for outgoing (click-to-call) calls.
-* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed.
+* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed. Use numbers in the following formats: +14844608117 (full number match) or #4844608117# (regular expression).
* **Permitted Entities** – entities that will be displayed in the popup window and will be used to identify a caller by his phone number.
+* **Apply global ACL for caller lookup** – apply global ACL rules (Administration > Roles) for caller lookup. This information is displayed in the popup window. If unchecked, no ACL restrictions are used.
* **Hide a Lead** – Hide a Lead in a call popup when Account / Contact are available.
* **Display Accounts related to Contacts** – display only Accounts related to Contacts.
* **Automatically save a call** – Automatically save incoming/outgoing calls in the system without having to press "Save" button.
* **Automatically open the caller information** – automatically open the caller information for incoming/outgoing calls.
* **Quick Create Entities** – entities which can be created through the call popup window.
-
-2. Setup a cron job (scheduled task) to handle Starface Events (incoming/outgoing calls, hangup, etc.). It is very important to set it up to run every minute. The line that needs to be added is displayed in the right block. For linux-based OS, it is:
-**\* \* \* \* \* cd /var/www/html/espocrm; /usr/bin/php -f voip.php Starface > /dev/null 2>&1**
+* **Experimental features** – test experimental features.
## How to setup Starface Integration for users
-Each user who wants to use Starface integration, should setup his access in the User’s Profile, under “VoIP Settings”. Please note that login and password should be to the Starface web interface, not to the SIP credentials. Also, the user can change some VoIP settings on this window.
+Each user who wants to use Starface integration, should setup his access in the User’s Profile, under “VoIP Settings”. Note that login and password should be to the Starface web interface, not to the SIP credentials. Also, the user can change some VoIP settings on this window.

@@ -51,3 +58,10 @@ Each user who wants to use Starface integration, should setup his access in the
* **Display call notifications** – an option to enable/disable incoming/outgoing call notifications.
* **Silent notifications** – mute notification sound.
* **Use internal click-to-call** – an option to enable/disable the internal click-to-call feature. It is a feature to make outgoing calls through the Starface server. If the checkbox is unchecked, then an external application will handle “tel:” links.
+
+## Access control for users
+
+Make sure that your users have the access to the entity 'Calls'.
+
+* [Grant access to Calls](customization.md#grant-access-to-calls)
+
diff --git a/docs/extensions/voip-integration/troubleshooting.md b/docs/extensions/voip-integration/troubleshooting.md
index 234b26438..c8e710c02 100644
--- a/docs/extensions/voip-integration/troubleshooting.md
+++ b/docs/extensions/voip-integration/troubleshooting.md
@@ -5,6 +5,9 @@ In this article:
* [How to report](#how-to-report)
* [VoIP error debug](#voip-error-debug)
* [Asterisk: The popup window is not displayed](#asterisk-the-popup-window-is-not-displayed)
+* [Asterisk: Click to call is not working](#asterisk-click-to-call-is-not-working)
+* [Starface: The popup window is not displayed](#starface-the-popup-window-is-not-displayed)
+* [Twilio: Unable to activate the phone number](#twilio-unable-to-activate-the-phone-number)
## How to report
@@ -14,7 +17,7 @@ In this article:
4. Provide screenshots with:
1. Administration > Integrations > VoIP integration configs;
2. Administration > VoIP Routing > Your VoIP number;
- 3. Defined phone numbers in the user profile (if a user can't make or recieve a call).
+ 3. Defined phone numbers in the user profile (if a user can't make or receive a call).
5. Describe details of this call:
1. Time of the call;
2. Caller phone number;
@@ -22,20 +25,55 @@ In this article:
## VoIP error debug
-1. Enable debug mode as described [here](https://docs.espocrm.com/administration/troubleshooting/#enabling-debug-mode-for-a-logger).
+1. Enable debug mode as described [here](../../administration/troubleshooting.md/#debug-mode).
2. Reproduce an error again.
-3. Get an EspoCRM [log file](https://docs.espocrm.com/administration/troubleshooting/#check-logs) and send it to the support team.
+3. Get an EspoCRM [log file](../../administration/troubleshooting.md/#check-logs) and send it to the support team.
## Asterisk: The popup window is not displayed
-To be able to make / receive calls with the popup window, please follow these steps:
+To be able to make / receive calls with the popup window, check these items:
-1. Configure Asterisk [server](https://www.espocrm.com/features/asterisk-integration-setup/#setup).
+1. If Asterisk server is properly [configured](asterisk-integration-setup.md#step-1).
+2. If cron job is [configured](asterisk-integration-setup.md#step-2).
+3. If internal users are [configured](asterisk-integration-setup.md#how-to-setup-asterisk-integration-for-users). In some cases, Asterisk server doesn't provide internal number, but you can add other user numbers in his [profile](asterisk-integration-setup.md#additional-phone-numbers-for-users).
+4. If your SIP client are running.
-2. Setup a connector [cron job](https://www.espocrm.com/features/asterisk-integration-setup/#cron).
+Now, you can make calls from SIP client or from EspoCRM.
-3. Configure [user internal number](https://www.espocrm.com/features/asterisk-integration-setup/#user-setup). In some cases, Asterisk server doesn't provide internal number, but you can add other user numbers in his [profile](https://www.espocrm.com/features/asterisk-integration-setup/#additional-phone-numbers).
+## Asterisk: Click to call is not working
-4. Run your SIP client.
+VoIP Integration extension is sending a request to Asterisk server when you click on a phone number.
+Make sure the following parameters are correct (Administration > VoIP Settings > VoIP » Asterisk AMI):
+1. `Dialout Channel` - it determines the channel for outgoing calls. It can be "PJSIP/###" (Asterisk 13+) or "SIP/###", where ### is a user’s extension (internal number). The extension "###" will be substituted automatically depending on the user.
-Now, you can make calls from SIP client or from EspoCRM.
+ 
+
+2. `Dial Context` - context of your outgoing calls. The default value of Asterisk server is `from-internal`. If you use some custom extension in your Asterisk server, you have to define it in EspoCRM.
+
+ 
+
+3. `User Dial Context` - each user can define his own Dial Context in his user's profile. Make sure this option is empty or defined correctly.
+
+ 
+
+4. `Dial Format for outgoing calls` - this option may need to be changed depending on the Asterisk server configuration.
+
+
+
+## Starface: The popup window is not displayed
+
+Check the following items to find the cause of the issue:
+
+1. If Starface integration is properly [configured](starface-integration-setup.md).
+2. If internal users are [configured](starface-integration-setup.md#how-to-setup-starface-integration-for-users).
+3. If your SIP client is running.
+4. If your EspoCRM server is available for the Starface server. This is required, because Starface server should send notifications about call events to EspoCRM server.
+5. If your `Site URL` (Administration > Settings) corresponds to the real one.
+
+## Twilio: Unable to activate the phone number
+
+In your [Twilio Console](https://www.twilio.com/console) on the left panel click on United States (US1) (or any other country) > Phone Numbers > Manage > Active Numbers > the number you purchased and in the *Voice and Fax* and *Messaging* sections, set the following settings:
+
+
+
+
diff --git a/docs/extensions/voip-integration/twilio-integration-setup.md b/docs/extensions/voip-integration/twilio-integration-setup.md
index 7dbc5ab15..5b56adc89 100644
--- a/docs/extensions/voip-integration/twilio-integration-setup.md
+++ b/docs/extensions/voip-integration/twilio-integration-setup.md
@@ -1,25 +1,25 @@
# Twilio Integration Setup
-VoIP Integration extension allows EspoCRM to integrate with an Asterisk server through Asterisk Manager Interface (AMI), Twilio service and Starface server. For more details about the features, please click [here](https://www.espocrm.com/features/voip-integration/).
+Twilio integration is available as part of [VoIP Integration extension](https://www.espocrm.com/extensions/voip-integration/). It allows you to integrate EspoCRM with Twilio service and other VoIP providers, read more details [here](https://www.espocrm.com/features/twilio-integration/).
-There are two ways in which you can set up Twillio integration:
+There are two ways in which you can set up Twilio integration:
1. **Call forwarding**. An incoming call from a Twilio number is forwarded to the user’s primary phone number. For outgoing calls EspoCRM creates a connection between the user’s primary phone number and the number called through Twilio service. For more details about how you will be charged for these calls, [click here](https://support.twilio.com/hc/en-us/articles/223132367-How-Much-am-I-Charged-for-Call-Forwarding-with-Twilio).
-2. **Twillio SIP Trunk**. A SIP trunk is a virtual version of a phone line, that isn’t physically connected to a phone company and uses intranet and internal communication systems to access the outside phone lines. More detailed information about Twilio SIP Trunking can be found via the [link](https://www.twilio.com/docs/voice/api/sip-interface).
+2. **Twilio SIP Trunk**. A SIP trunk is a virtual version of a phone line, that isn’t physically connected to a phone company and uses intranet and internal communication systems to access the outside phone lines. More detailed information about Twilio SIP Trunking can be found via the [link](https://www.twilio.com/docs/voice/api/sip-interface).
## How to configure Twilio Integration for an administrator
1. Login to your Twilio account. If you have never used Twilio before, then create the account and purchase a phone number if needed.
2. Login as Administrator in EspoCRM.
-3. Navigate to the Administration > VoIP Settings > VoIP » Twilio.
+3. Navigate to the Administration (System panel) > Integrations > VoIP · Twilio.
4. Tick off Enabled box.
5. Fill in the connection details of your Twilio account.

* **Name** – name of your connection.
-* **Your Account SID** – your Twilio account SID. You can get it at https://www.twilio.com/user/account.
-* **Your Auth Token** – your Twilio Auth Token. You can get it at https://www.twilio.com/user/account.
+* **Your Account SID** – your Twilio account SID. You can get it at https://www.twilio.com/console.
+* **Your Auth Token** – your Twilio Auth Token. You can get it at https://www.twilio.com/console.
* **Record Calls** – an option to enable/disable recording of incoming/outgoing calls.
* **Dial Timeout** – the number of seconds that Twilio will allow the phone to ring before assuming there is no answer.
* **Agent Ringing Timeout** – the waiting limit in seconds to answer the call by the agent, e.g. for an incoming call each agent will get a ringing duration of 20 seconds.
@@ -28,21 +28,25 @@ There are two ways in which you can set up Twillio integration:
* **Default Country** – the country is used to format phone numbers.
* **Dial Format for outgoing calls** – a phone number format for outgoing (click-to-call) calls.
* **Enabled SIP Domains** – the list of enabled Twilio SIP domains which are used in EspoCRM.
-* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed.
+* **List of ignored numbers** – list of numbers which will be ignored. Popup window will not be displayed. Use numbers in the following formats: +14844608117 (full number match) or #4844608117# (regular expression).
* **Permitted Entities** – entities that will be displayed in the popup window and will be used to identify a caller by his phone number.
+* **Apply global ACL for caller lookup** – apply global ACL rules (Administration > Roles) for caller lookup. This information is displayed in the popup window. If unchecked, no ACL restrictions are used.
* **Hide a Lead** – Hide a Lead in a call popup when Account / Contact are available.
* **Display Accounts related to Contacts** – display only Accounts related to Contacts.
* **Automatically save a call** – automatically save incoming/outgoing calls without having to press “Save” button.
* **Automatically open the caller information** – automatically open the caller information for incoming/outgoing calls.
* **Quick Create Entities** – entities which can be created through the call popup window.
+* **Call Transfer Entities** – the list of entities used for call transfer.
+* **Transfer Timeout** – the number of seconds the customer has to wait for an agent to answer the transferred call.
+* **Experimental features** – test experimental features.
## How to configure routing of Twilio phone numbers
-After you have successfully filled in the connection details, EspoCRM will import all active Twilio phone numbers (please wait a few minutes the first time).
+After you have successfully filled in the connection details, EspoCRM will import all active Twilio phone numbers (wait a few minutes the first time).
1. **Configure Routing**
- To configure Twilio phone number routing, please go to Administration > VoIP Routing and select the phone number.
+ To configure Twilio phone number routing, go to Administration > VoIP Trunks and select the phone number.

@@ -57,6 +61,7 @@ After you have successfully filled in the connection details, EspoCRM will impor
* **Voicemail Greeting Text** – a voicemail greeting message. Note: the “Voicemail Greeting Audio” has higher priority.
* **Voicemail Notifications** – Types of notification for a new voicemail message.
* **Farewell at the end of the call**
+* **Display the router's phone number as a caller** – display the office phone number (VoIP Router phone number) as caller.
* **Team Users** – a list of users to configure receiving incoming/outgoing calls, SMS and MMS.
2. **Grant access for Twilio Team members**
@@ -69,12 +74,12 @@ After you have successfully filled in the connection details, EspoCRM will impor
1. Login to your Twilio account.
2. Navigate to the Programmable SMS > Settings > Geo Permissions or just click the link: https://www.twilio.com/console/sms/settings/geo-permissions.
3. Enable needed countries.
-2. [Add access control in EspoCRM](voip-message-access.md#add-access-control-in-espocrm)
+2. [Grant access to Messages](customization.md#grant-access-to-messages)
## How to setup Twilio Integration for users
Each user has to add his phone number which will be used to handle incoming calls. It can be added in the User’s Profile.
-**Note**: If you are using a Twilio SIP, then instead of the phone number, you have to specify the SIP number in the format: “user1@espo.sip.us1.twilio.com”.
+**Note**: If you are using a Twilio SIP, then instead of the phone number, you have to specify the SIP number in the format: “agent1@YOUR_DOMAIN.sip.twilio.com”.

@@ -88,9 +93,15 @@ All other configuration settings should be made by your administrator. The user
* **Silent notifications** – mute notification sound.
* **Use internal click-to-call** – an option to enable/disable the internal click-to-call feature. It is a feature to make outgoing calls through Twilio. If the checkbox is unchecked, then an external application will handle “tel:” links.
+## Access control for users
+
+Make sure that your users have the access to the entity 'Calls'.
+
+* [Grant access to Calls](customization.md#grant-access-to-calls)
+
## How to configure SIP Domains
-1. Configure a SIP domain in Twillio:
+1. Configure a SIP domain in Twilio:
1. Login to your Twilio account.
2. Go to Twilio SIP Domains by clicking in the menu on the left side and select “Programmable Voice” option or just click the link: https://www.twilio.com/console/voice/sip/endpoints.
@@ -115,6 +126,6 @@ All other configuration settings should be made by your administrator. The user
## More Twilio settings for users
-Each user can set “Do Not Disturb” mode for incoming lines. To do it, please go to the home page (click on a logo) and add a “VoIP Settings” dashlet (“+” button).
+Each user can set “Do Not Disturb” mode for incoming lines. To do it, go to the home page (click on a logo) and add a “VoIP Settings” dashlet (“+” button).

diff --git a/docs/extensions/voip-integration/voip-message-access.md b/docs/extensions/voip-integration/voip-message-access.md
deleted file mode 100644
index 9b5e857af..000000000
--- a/docs/extensions/voip-integration/voip-message-access.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Add access control in EspoCRM
-
-By default regular users don’t have access to Message entity. Administrator needs to grant access to this entity:
-
-1. Login as Administrator in EspoCRM.
-2. Navigate to the Administration > Roles.
-3. Create / edit a Twilio role.
-4. Grant access to the Message entity.
-
-
-
-By default the Message entity tab should be added into the tab list.
-
-
diff --git a/docs/extensions/voip-integration/voip.md b/docs/extensions/voip-integration/voip.md
deleted file mode 100644
index 3294d238c..000000000
--- a/docs/extensions/voip-integration/voip.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# VoIP Integration
-
-## Supported servers and services
-
-* [Asterisk server](asterisk-integration-setup.md#asterisk-integration-setup)
-* [Binotel service](binotel-integration-setup.md#binotel-integration-setup)
-* [Starface service](starface-integration-setup.md#starface-integration-setup)
-* [Twilio service](twilio-integration-setup.md#twilio-integration-setup)
-
-
-## Additional information
-
-* [Customization](customization.md)
-* [Troubleshooting](troubleshooting.md)
diff --git a/docs/extensions/zoom-integration/index.md b/docs/extensions/zoom-integration/index.md
new file mode 100644
index 000000000..68861dd11
--- /dev/null
+++ b/docs/extensions/zoom-integration/index.md
@@ -0,0 +1,100 @@
+# Zoom Integration
+
+*Requires EspoCRM v9.0.*
+
+Available in the [Zoom Integration](https://www.espocrm.com/extensions/zoom-integration/) extension.
+
+The Zoom integration allows creating Zoom meetings from Espo.
+
+In this article:
+
+* [How it works](#how-it-works)
+* [Connecting Zoom accounts](#connecting-zoom-accounts)
+* [Setting up](#setting-up)
+* [Usage](#usage)
+
+## How it works
+
+You need to have one general Zoom account (organization account). This account will be connected to Espo. Espo users need to have their Zoom accounts linked to the general Zoom account. The Espo administrator will select which users can use Zoom integration.
+
+When an Espo meeting is pushed to Zoom, it's created in a Zoom account of the user assigned to the meeting. If the user does not have a Zoom account, it won't be possible to push the meeting.
+
+## Connecting Zoom accounts
+
+Connect Zoom accounts of your employees to the organization Zoom account.
+
+To connect a user:
+
+1. Log in to Zoom Admin as an admin.
+2. Go to User Management > Users.
+3. Click Add Users and enter the user's email address.
+4. Check Zoom Meetings Basic for the user.
+5. Send an invitation, and the user must accept it to join your Zoom account.
+
+## Setting up
+
+As an Espo administrator, go to: Administration > Integrations > Zoom. Then, follow the guidelines displayed on the page.
+
+1. Create a General App on the Zoom App Marketplace. Set it as Admin-managed.
+2. Obtain the Client ID and Client Secret.
+3. Copy the Redirect URI from here and add it in the created Zoom app.
+4. Add the required scopes in the Zoom app.
+5. Connect.
+
+Required scopes:
+
+* `meeting:write:meeting:admin`
+* `meeting:update:meeting:admin`
+* `meeting:delete:meeting:admin`
+
+There are Development and Production modes for Zoom apps. They use different credentials. It's recommended to use the Production mode unless for testing purposes.
+
+If you use the Production mode, you will also need to fill in the required fields:
+
+* App Name
+* Developer Contact Information
+* Scope Description
+
+Then, the Zoom App will be marked as *Ready for beta test* in the right panel. Otherwise, you won't be able to connect to a production mode app.
+
+
+!!! note
+
+ There is no need to publish the Zoom App.
+
+
+After connecting to Zoom in Espo, on the same page, select users who are supposed to receive Espo meetings in their Zoom accounts.
+
+The primary email address of a user is used as their Zoom ID by default. You can also specify the Zoom ID for a particular user.
+
+To allow users to push Espo meetings to Zoom, you need to enable the *Zoom Meetings* scope in roles of those users.
+
+
+## Usage
+
+To be able to push a meeting to Zoom, a user needs to have:
+
+* access to the *Zoom Meetings* scope;
+* edit access the meeting.
+
+To push the meeting, click *Push to Zoom* from the dropdown next to the *Edit* button.
+
+Once a Zoom meeting is created, the Join URL field in the Espo meeting will be set to the Zoom's URL.
+
+If you edit an already pushed meeting in Espo, it will be marked as out-of-sync. You can push it again so that it will become synced with Zoom.
+
+If an Espo meeting has status *Not Held*, you can delete the corresponding Zoom meeting by clicking *Delete from Zoom*.
+
+### Join URL
+
+The *Join URL* field is the default Espo field. You can add to the Meeting's layout under: Administration > Entity Manager > Meeting > Layouts > Detail.
+
+When sending an email invitation from Espo, the Join URL will be included in the email body. You can edit the email template under Administration > Template Manager > Invitation · Meeting.
+
+### Meeting scheduler
+
+The Zoom integration is integrated with the [Meeting Scheduler](../meeting-scheduler/index.md). You can specify Zoom as the online location for a specific scheduler.
+
+### Workflows
+
+It's possible to create and delete zoom meetings using a [Workflow](../../administration/workflows.md) rule. Actions are available under *Run Service Action* for a Meeting target.
diff --git a/docs/index.md b/docs/index.md
index 762abb96c..31345f378 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -6,43 +6,64 @@
* [Configuration](administration/server-configuration.md)
* [Apache](administration/apache-server-configuration.md)
* [Nginx](administration/nginx-server-configuration.md)
+ * [IIS](administration/iis-server-configuration.md)
* System
- * [Installation](administration/installation.md)
+ * Installation
+ * [Installation](administration/installation.md)
+ * [Installation by script](administration/installation-by-script.md)
+ * [Installation with Docker](administration/docker/installation.md)
+ * [Installation with Traefik](administration/docker/traefik.md)
+ * [Installation with Caddy](administration/docker/caddy.md)
* [Upgrading](administration/upgrading.md)
- * [Extensions](administration/extensions.md)
- * [Troubleshooting](administration/troubleshooting.md)
- * [Console commands](administration/commands.md)
+ * [Extensions](administration/extensions.md)
* [Jobs](administration/jobs.md)
+ * [Config parameters](administration/config-params.md)
+ * [Log](administration/log.md)
+ * [Console commands](administration/commands.md)
* [WebSocket](administration/websocket.md)
- * [Performance tweaking](administration/performance-tweaking.md)
+* Essentials
+ * [Terms & naming](administration/terms-and-naming.md)
+ * [Troubleshooting](administration/troubleshooting.md)
* [Backup and restore](administration/backup-and-restore.md)
+ * [Performance tweaking](administration/performance-tweaking.md)
* [Moving to another server](administration/moving-to-another-server.md)
- * [Config parameters](administration/config-params.md)
+ * [Security](administration/security.md)
* Customization
* [Entity Manager: entities, fields, relationships](administration/entity-manager.md)
* [Fields](administration/fields.md)
* [Layouts](administration/layout-manager.md)
- * [Dynamic forms](administration/dynamic-logic.md)
-* [Roles management (access control)](administration/roles-management.md)
-* [Email Administration](administration/emails.md)
-* [Formula (calculated fields)](administration/formula.md)
+ * [Dynamic Logic](administration/dynamic-logic.md)
+ * [API Before-Save script](administration/api-before-save-script.md)
+* [Users](administration/users-management.md)
+* [Roles](administration/roles-management.md)
+* [Email administration](administration/emails.md)
+* Formula
+ * [Formula script](administration/formula.md)
+ * [Functions](administration/formula-functions.md)
* [Import](administration/import.md)
* [Portal](administration/portal.md)
+* [Web-to-Lead](administration/web-to-lead.md)
* [Currency](administration/currency.md)
* [Dashboards](administration/dashboards.md)
* Authentication
- * [2-factor authentication](administration/2fa.md)
+ * [2 factor authentication](administration/2fa.md)
+ * [OpenID Connect](administration/oidc.md)
* LDAP
* [Authorization](administration/ldap-authorization.md)
* [Active Directory](administration/ldap-authorization-for-ad.md)
* [OpenLDAP](administration/ldap-authorization-for-openldap.md)
-* Misc
- * [Terms & naming](administration/terms-and-naming.md)
- * [Web-to-Lead](administration/web-to-lead.md)
+* Miscellaneous
* [Webhooks](administration/webhooks.md)
+ * [Passwords](administration/passwords.md)
+ * [Security](administration/security.md)
+ * [Phone numbers](administration/phone-numbers.md)
+ * [Addresses](administration/addresses.md)
* [Maps](administration/maps.md)
* [B2C mode](administration/b2c.md)
* [Multiple assigned users](administration/multiple-assigned-users.md)
+ * [File storage](administration/file-storage.md)
+ * [SMS sending](administration/sms-sending.md)
+ * [App secrets](administration/app-secrets.md)
---
@@ -51,35 +72,65 @@
* Emails
* [General guidelines](user-guide/emails.md)
* [IMAP & SMTP configuration](user-guide/imap-smtp-configuration.md)
- * [Mass Email](user-guide/mass-email.md)
+ * [Mass email](user-guide/mass-email.md)
* [Stream](user-guide/stream.md)
* [Sales management: Leads & Opportunities](user-guide/sales-management.md)
* [Case management](user-guide/case-management.md)
-* [Activities & Calendar](user-guide/activities-and-calendar.md)
-* [Mail Merge (mass snail mailing)](user-guide/mail-merge.md)
-* [Knowledge Base](user-guide/knowledge-base.md)
+* [Activities & calendar](user-guide/activities-and-calendar.md)
+* [Mail merge (mass snail mailing)](user-guide/mail-merge.md)
+* [Knowledge base](user-guide/knowledge-base.md)
* [Documents](user-guide/documents.md)
* [Export](user-guide/export.md)
* [Text search](user-guide/text-search.md)
-* Misc
- * [Printing to PDF](user-guide/printing-to-pdf.md)
+* [Working time calendar](user-guide/working-time-calendar.md)
+* [Printing to PDF](user-guide/printing-to-pdf.md)
+* Miscellaneous
+ * [Shortcut keys](user-guide/shortcuts.md)
* [Markdown syntax](user-guide/markdown.md)
* [Browser support](user-guide/browser-support.md)
* [Data privacy](user-guide/data-privacy.md)
+ * [Complex expressions](user-guide/complex-expressions.md)
+ * [Optimistic concurrency control](user-guide/optimistic-concurrency-control.md)
---
### Extensions
* Advanced Pack
+ * [Overview](extensions/advanced-pack/overview.md)
* [Reports](user-guide/reports.md)
* [Workflows](administration/workflows.md)
* [Business Process Management (BPM)](administration/bpm.md)
* Sales Pack
+ * [Overview](extensions/sales-pack/overview.md)
* [Products](user-guide/products.md)
- * [Quotes](user-guide/quotes.md)
- * [Sales Orders](user-guide/sales-orders.md)
- * [Invoices](user-guide/invoices.md)
+ * [Prices](extensions/sales-pack/prices.md)
+ * Sales
+ * [Quotes](user-guide/quotes.md)
+ * [Sales Orders](user-guide/sales-orders.md)
+ * [Invoices](user-guide/invoices.md)
+ * [Credit Notes](extensions/sales-pack/credit-notes.md)
+ * [Delivery Orders](extensions/sales-pack/delivery-orders.md)
+ * [Return Orders](extensions/sales-pack/return-orders.md)
+ * [Write-offs](extensions/sales-pack/write-offs.md)
+ * [Subscriptions](extensions/sales-pack/subscriptions.md)
+ * Purchases
+ * [Suppliers](extensions/sales-pack/suppliers.md)
+ * [Purchase Orders](extensions/sales-pack/purchase-orders.md)
+ * [Receipt Orders](extensions/sales-pack/receipt-orders.md)
+ * [Bills](extensions/sales-pack/bills.md)
+ * [Bill credits](extensions/sales-pack/bill-credits.md)
+ * [Inventory Management](extensions/sales-pack/inventory-management.md)
+ * [Payments](extensions/sales-pack/payments.md)
+ * [Taxes](extensions/sales-pack/taxes.md)
+ * [Tax codes](extensions/sales-pack/tax-codes.md)
+ * [Issuance locking](extensions/sales-pack/issuance-locking.md)
+ * [Multi-currency](extensions/sales-pack/multi-currency.md)
+ * [Reports](extensions/sales-pack/reports.md)
+* Project Management
+ * [Projects](extensions/project-management/projects.md)
+* Meeting Scheduler
+ * [Meeting Scheduler](extensions/meeting-scheduler/index.md)
* Google Integration
* [Setting-up](extensions/google-integration/setting-up.md)
* [Calendar](extensions/google-integration/calendar.md)
@@ -90,17 +141,32 @@
* [Calendar](extensions/outlook-integration/calendar.md)
* [Contacts](extensions/outlook-integration/contacts.md)
* [Email](extensions/outlook-integration/email.md)
-* VoIP integration
+* VoIP Integration
+ * [Overview](extensions/voip-integration/overview.md)
+ * [3CX PBX](extensions/voip-integration/3cx-integration-setup.md)
+ * [Twilio service](extensions/voip-integration/twilio-integration-setup.md)
* [Asterisk server](extensions/voip-integration/asterisk-integration-setup.md)
+ * [Starface server](extensions/voip-integration/starface-integration-setup.md)
* [Binotel service](extensions/voip-integration/binotel-integration-setup.md)
- * [Starface service](extensions/voip-integration/starface-integration-setup.md)
- * [Twilio service](extensions/voip-integration/twilio-integration-setup.md)
+ * [IexPBX server](extensions/voip-integration/iexpbx-integration-setup.md)
+ * [Docker container](extensions/voip-integration/docker-container.md)
* [Customization](extensions/voip-integration/customization.md)
* [Troubleshooting](extensions/voip-integration/troubleshooting.md)
+* Zoom Integration
+ * [Zoom Integration](extensions/zoom-integration/index.md)
+* Stripe Integration
+ * [Stripe Integration](extensions/stripe-integration/index.md)
+* Export Import
+ * [Overview](extensions/export-import/overview.md)
+ * [Export](extensions/export-import/export.md)
+ * [Import](extensions/export-import/import.md)
+ * [Compare](extensions/export-import/compare.md)
+ * [Run by code](extensions/export-import/run-by-code.md)
+ * [Customization](extensions/export-import/customization.md)
---
### See also
-* [Developer Documentation](development/index.md)
-* [Hints & Tips](https://www.espocrm.com/tips/)
+* [Developer documentation](development/index.md)
+* [Hints & tips](https://www.espocrm.com/tips/)
diff --git a/docs/js/extra.js b/docs/js/extra.js
index 812547844..89b321270 100644
--- a/docs/js/extra.js
+++ b/docs/js/extra.js
@@ -1,8 +1,8 @@
document.addEventListener("DOMContentLoaded", function() {
- loadNavpane();
+ loadNavpanel();
});
-function loadNavpane() {
+function loadNavpanel() {
var width = window.innerWidth;
if (width <= 1200) {
return;
@@ -17,4 +17,4 @@ function loadNavpane() {
toggleEl.checked = true;
}
}
-}
\ No newline at end of file
+}
diff --git a/docs/user-guide/activities-and-calendar.md b/docs/user-guide/activities-and-calendar.md
index 5304923bd..fb0348e0d 100644
--- a/docs/user-guide/activities-and-calendar.md
+++ b/docs/user-guide/activities-and-calendar.md
@@ -1,3 +1,8 @@
+---
+search:
+ boost: 2
+---
+
# Activities & Calendar
There are three types of activities available in EspoCRM by default:
@@ -6,11 +11,11 @@ There are three types of activities available in EspoCRM by default:
* Calls
* Tasks
-Administrator can create a custom entity of Event type. Then at Administration > Settings > Activities it's possible to set this entity type as an Activity and make it available in Calendar.
+An administrator can create a custom entity type of an *Event* type. Then, at Administration > Settings > Activities, it's possible to set this entity type as an *Activity* and make it available in the *Calendar*.
-There is 'My Activities' dashlet showing actual and upcoming activity records related to the current user.
+The *My Activities* dashlet displays current and upcoming activity records associated with the current user.
-Accounts, Contacts, Leads, Opportunities, Cases have the Activities panel on the detail view. Custom entities of Base Plus type have the Activities panel as well.
+Accounts, Contacts, Leads, Opportunities, and Cases have the Activities panel on the detail view. Custom entity type of the *Base Plus* type have the Activities panel as well.
In this article:
@@ -22,39 +27,91 @@ In this article:
### Attendees
-There are 3 types of attendees supported: Users, Contacts, Leads. For each attendee it's possible to specify acceptance status: Accepted, Tentative, Declined.
+There are 3 types of attendees: Users, Contacts, and Leads. For each attendee, it's possible to specify acceptance status: Accepted, Tentative or Declined.
+
+#### Invitations
+
+There is the ability to send **invitation emails** to attendees by clicking the button in the top-right corner. Attendees will be able to set their acceptance status by clicking on a corresponding link in the email.
+
+When an event has status *Not Held*, it's possible to send a cancellation email to attendees. It can be done from the top-right menu on the Meeting (or Call) detail view.
+
+The template for invitation emails can be changed at Administration > Template Manager > Invitation.
+
+Available template placeholders and data values:
+
+* `inviteeName` – a name of the recipient;
+* `recordUrl` – a URL to the Espo meeting record;
+* `acceptLink` – a URL to accept the meeting;
+* `declineLink` – a URL to decline the meeting;
+* `tentativeLink` – a URL to set as tentative;
+* `entityType` – a translated entity type (Meeting or Call);
+* `entityTypeLowerFirst` – a translated entity type starting with a lower case letter (meeting or call);
+* `isUser` – whether the recipient is a User, a boolean value;
+* `dateStartFull` – a meeting start date/time in full format (as of v9.0);
+* `timeZone` – a time zone name applied to date-time placeholder values (as of v9.0).
-There is the ability to send **invitation emails** to attendees by clicking the button in the top-right corner. Attendees will be able to set their acceptance status by clicking on a corresponding link in the email. The template for invitation emails can be changed at Administration > Template Manager > Invitation.
+You can also use Meeting's (or Call's) fields as placeholders.
### Reminders
-There are two types of reminders: Popup (in-app message) and Email. Reminders will be applied to *Assigned User* and users specified in *Users* field.
+There are two types of reminders: Popup and Email. Reminders specified on the form will be applied to the current user, assuming this used is a participant. Other participant will have their default reminders automatically applied.
+
+!!! note
+
+ When creating a Meeting or Call, only the reminder options that will occur in the future are listed. For example, if you create a meeting scheduled to occur in 15 minutes, you won't be able to set a reminder for '1 hour before'. This option won't be available in the list. If you change the Date Start to a later time, the option will appear.
+
+Arbitrary period values can entered in the reminder field by typing a number.
### Default duration
-Default duration can be changed by administrator at Administration > Entity Manager > Meetings / Calls > Fields > Duration > Default. It must be specified in seconds.
+Default duration can be changed by the administrator at Administration > Entity Manager > Meetings / Calls > Fields > Duration > Default. It is specified in seconds.
+
+### Scheduler
+
+The scheduler panel provides the ability to view free & busy time ranges for user attendees when creating or editing an event. Available for Meetings, Calls, and custom entities of the Event type.
+
+The scheduler panel can be added or removed at Administration > Entity Manager > Layouts > {Entity Type} > Bottom Panels.
+
+Which entity types will be taken into account when showing busy time ranges can be configured at Administration > Settings > Free/Busy Entity List.
+
+### Default date
+
+For the Meeting and custom Event entity types, by default, the default values for Date Start and Date End are set to 'now'. You can change it to 'today' (meaning the event will be set as All-Day by default). For this, in the Entity Manager, do the following:
+
+1. Set the default values for the Date Start and Date End fields to 'None'.
+2. Set the default values for the Date Start (all day) and Date End (all day) fields to 'Today'.
+3. Set the default value for the Duration field to 86400.
+4. Set the default value for the Is All-Day field to true (check the checkbox).
## Tasks
-Date Start and Date Due fields are not required. Dates can be specified with or without time parts.
+The Date Start and Date Due fields are not required. Dates can be specified with or without time parts.
### Reminders
-*Reminders* field is hidden if *Date Due* field is empty. It will show up once it's filled in.
+The *Reminders* field is hidden if the *Date Due* field is empty. It will show up once it's filled in.
-### Scheduler
+!!! note
-Available since v5.9.0.
+ When the Date Due does not have a time part, the end of the day will be used as the base time for a reminder.
-Provides the ability to view free & busy time ranges for attendees (users) when scheduling an event. Available for Meetings, Calls and custom entities of Event type.
+Arbitrary period values can entered in the reminder field by typing a number.
-Scheduler panel can be added or removed at Administration > Layout Manager > select needed entity type > Bottom Panels.
+### Collaborators
-What entity types will be taken into account when showing busy time ranges can be configured at Administration > Settings > Free/Busy Entity List.
+*As of v9.0.*
+
+The collaborators feature can be enabled for Tasks at Administration > Entity Manager > Task > Edit.
+
+Users added as collaborators to a Task will have read and stream access, provided their access level, as defined by Roles, is other than no.
+
+When a user creates a Task, they will be automatically added as a collaborator, even if the Task is assigned to another user. The assignee becomes a collaborator too.
+
+The list view filter *Shared* shows Tasks where the current user is a collaborator. The *My Activities* dashlet has a parameter *Include Shared*.
## Calendar
-Calendar displays Meetings, Calls, Tasks. It's also possible to show custom entities of Event type.
+Calendar displays Meetings, Calls, and Tasks. It's also possible to show custom entities of the Event type.
Supported views:
@@ -63,30 +120,37 @@ Supported views:
* Day
* Timeline
-Users can add Calendar on their dashboard.
+Users can also add the Calendar to their dashboard.
-It's possible to view calendar of another user (is you have an access determined by roles). Calendar button is available on the user's detail view.
+It's possible to view the calendar of another user (is you have an access determined by Roles). The *Calendar* button is available on the user's detail view.
### Refreshing calendar
-To refresh calendar items you can click on the date range title at the top in the center.
+To refresh calendar items, you can click on the date range title at the top in the center.
### Shared calendar
Users can create custom shared views that will display events of specific teams.
-Note: User must have a proper *User Permission* set in [Roles](../administration/roles-management.md) to be able to use shared calendars. Set the permission to `team` or `all`.
+!!! note
+
+ A user must have a proper *User Permission* set in [Roles](../administration/roles-management.md) to be able to use shared calendars. Set the permission to *team* or *all* to enable.
+
+!!! note
-Note: Shared view displays events of users of the selected team. It doesn't necessary display events assigned to that team (e.g. event is assigned to the team, but doesn't assigned to any user of that team).
+ The Shared view displays events of users of a selected team. It doesn't necessary display events assigned to that team (e.g. event is assigned to the team, but doesn't assigned to any user of that team).
-Shared view is also available for *Timeline* view. It allows to view events of multiple users.
+The Shared view is also available for the *Timeline* view. It allows you to view events of multiple users.
### Custom entities on calendar
-Administrator can create a custom entity of Event type. Then at Administration > Settings > Activities it's possible to set this entity type as an Activity and make it available in Calendar.
+An administrator can create a custom entity of the Event type. Then, at Administration > Settings > Activities, it's possible to set this entity type as an Activity and make it available in Calendar.
-For custom entities, by default, Assigned User field determines a user who will the record on his/her Calendar. There is a possibility to have [multiple assigned users](../administration/multiple-assigned-users.md).
+For custom entities, by default, the *Assigned User* field determines a user who will see the record on they Calendar. There is the ability to have [multiple assigned users](../administration/multiple-assigned-users.md).
## See also
+* [Working time calendar](working-time-calendar.md)
+* [Calendar & Activities quick tour](https://app.supademo.com/demo/cmj2mit950x3tv3e5ae3xp6fa)
* [How to manage your calendar](https://www.espocrm.com/tips/calendar/)
+* [Meeting scheduler](../extensions/meeting-scheduler/index.md)
diff --git a/docs/user-guide/browser-support.md b/docs/user-guide/browser-support.md
index 9e72d17d8..3228cd811 100644
--- a/docs/user-guide/browser-support.md
+++ b/docs/user-guide/browser-support.md
@@ -1,7 +1,5 @@
# Browser support
-We recommend using the latest versions of Google Chrome or Mozilla Firefox. EspoCRM works the best in these browsers. We regularly test all features in these browsers.
+We recommend using the latest versions of Google Chrome or Mozilla Firefox. We regularly test in these browsers.
Microsoft Edge and Safari are also supported, but there are less guarantees that everything will be working smoothly.
-
-We highly recommend not using Internet Explorer.
diff --git a/docs/user-guide/case-management.md b/docs/user-guide/case-management.md
index b65888a55..1d71a68df 100644
--- a/docs/user-guide/case-management.md
+++ b/docs/user-guide/case-management.md
@@ -4,54 +4,80 @@ In this article:
* [Overview](#overview)
* [Stream](#stream)
-* [Email-to-Case](#email-to-case)
-* [Knowledge Base](#knowledge-base)
-* [Customer Portal](#customer-portal)
-
+* [Email-to-case](#email-to-case)
+* [Knowledge base](#knowledge-base)
+* [Customer portal](#customer-portal)
+* [Access to child records](#access-to-child-records)
+* [Collaborators](#collaborators)
+* [See also](#see-also)
## Overview
-Cases provide the issue tracking ability. It's a principal aspect of customer service in EspoCRM. 'Ticket' term also can be used for cases.
+Cases provide issue-tracking capabilities and a key aspect of customer service in EspoCRM. The term 'ticket' can also be used to refer to Cases.
+
+New Cases are supposed to be created in the following scenarios:
+
+* Manually by CRM users;
+* Manually by users of a customer portal;
+* Through the API (e.g. through a web form;
+* Automatically when a new email comes to a specific mailbox;
+* Automatically by a Workflow rule.
+
+When a new Case is created by a Portal User, it's not assigned to any user. By utilizing the [Workflows](../administration/workflows.md) tool, an administrator can create a rule that will notify certain users about every new Case in the system. Workflows also provide the ability to apply an assignment rule to new cases. *Round-Robin* and *Least-Busy* rules are available. For more complex business flows, it's recommended to utilize the [BPM tool](../administration/bpm.md).
-The Case entity can be associated with one Account and/or with multiple Contacts.
+To prevent overlooking of new Cases, users can add the Case entity type to the *Global Auto-follow* list in the user's Preferences. Then, the user will automatically follow every new Case created in the system they have access to.
-New cases are supposed to be created by the following scenarios:
+The Case entity type can be associated with one Account and/or multiple Contacts. It also can be associated with a Lead record. Note that by default the Lead field is not available in the Detail layout. An administrator can add it at: Administration > Entity Manager > Case > Layouts > Detail.
-* Manually by CRM users
-* Manually by users of the customer portal
-* Through the API (e.g. through the web form)
-* Automatically when a new email came to a specific mailbox
-* Automatically by a Workflow rule
+!!! note
-When the new case is created by a portal user it's not assigned to any user. By utilizing [Workflows](../administration/workflows.md) administrator can create rule that will notify certain users about a new case in the system. Workflows also provide an ability to apply assignment rule to new cases, i.e. *Round-Robin* and *Least-Busy* rules. For more complex business flows it's recommended to utilize [BPM tool](../administration/bpm.md).
+ If a related Contact is not associated with a Portal User, then the customer won't be receiving email notifications about updates in the Stream of te Case. In this scenario, you need to use emails for communication with the customer.
-To prevent overlooking of new cases, users can add Case entity type to the *Global Auto-follow* list at Preferences. Then they will automatically follow every new case.
+!!! tip
-Note: If there is no portal user associated with a linked contact, then the customer won't receive email notifications about updates in the Stream. You need to use emails for communication with the customer.
+ Cases are not necessarily limited to customer service purposes. You can also use them to track non-support-related topics.
## Stream
-Case record has a stream that can be utilized for a communication between customer and service.
+A Case record has a Stream that can be used for communication between the customer and the support team.
+
+CRM users can mark stream posts as *internal*. Such posts are not visible in the customer portal and the customer is notified about them. To make a post internal, click the *lock* icon next to the *Post* button before posting.
+
+## Email-to-case
+
+An administrator can set up a Group Email Account that will create a new Case on each incoming email. For more information, [see here](../administration/emails.md).
+
+Users can create Cases from Emails manually. On the Email detail view, click the dropdown in the top-right corner, then *Create Case*.
+
+When a user wants to send a reply to a customer, they need to make sure that the Case is selected as a *Parent* of the Email that is being composed. This will force automatical addition of the group email address to the *Reply-To* field of the email. Then, when the customer replies on that email, it will be sent to the group email address rather than to the user’s one.
+
+## Knowledge base
+
+Users can relate Knowledge Base Articles to a Case record. See more info about the Knowledge Base [here](knowledge-base.md).
+
+## Customer portal
+
+An administrator can create a [Portal](../administration/portal.md) where customers will be able to create Cases. Permission to create Cases can be granted in a Portal Role.
-CRM users can make *internal posts* that won't be visible in a customer portal. For this, you need to click the lock icon next to *Post* button.
+Since Portal Users automatically follow Cases they have created, they will receive email notifications about new messages in the case's stream. Notifications are sent from the system email account. So when a customer replies to a notification, it will be sent to the system email address. It's also possible to make email replies to go to a Group Email Account. For this, you need to utilize the Workflow tool (or Formula) to make all new cases be automatically linked with the Group Email Account (use the Update Target Record action, set the *Group Email Account* field).
-## Email-to-Case
+Cases marked is *Hidden from Portal* are not available in portals. It can be useful when referencing a Contact is needed but the customer should not have access to the Case. As of v9.0.
-Administrator can set up Group Email Account that will create a new case on each new inbound email. For more information [see here](../administration/emails.md).
+## Access to child records
-Users can create a case from an email manaully. On the email detail view click the dropdown in the top-right corner, then *Create Case*.
+User access to child records of a Case, such as Emails, Meetings and Calls, is not determined by access to the Case record. For example, a Case can be assigned to a User but a related Email is not related to that User resulting in the User not being able to view the Email.
-When a user want to send a reply to the customer, they need to make sure that the case is selected as a *Parent* of the email that is being sent. It will add the group email address to *Reply-To* field of the email. So the customer's reply will be sent to the group address rather than to the user’s one.
+By utilizing the Workflow tool, it's possible to write a rule that will automatically add the Assigned User of a Case to all child records. The same is also possible with the Teams fields.
-## Knowledge Base
+## Collaborators
-Users can relate knowledge base articles to the case record. See more info about knowledge base [here](knowledge-base.md).
+*As of v9.0.0.*
-## Customer Portal
+The collaborators feature can be enabled for Cases at Administration > Entity Manager > Case > Edit. Then, the *Collaborators* field will be automatically created for the Case entity type. You can add this field to the *Side Panel Fields* layout.
-Administrator can create a [portal](../administration/portal.md) where customers will be able to create cases. Permission to create cases can be granted in a portal role.
+Users added as collaborators to a Case will have read and stream access, provided their access level, as defined by Roles, is other than no.
-Since portal users automatically follow cases they created, they will receive email notifications about new messages in the case's stream.
+When a user creates a Case, they will be automatically added as a collaborator, even if the Case is assigned to another user. The assignee becomes a collaborator too.
## See also
diff --git a/docs/user-guide/complex-expressions.md b/docs/user-guide/complex-expressions.md
index 43e625e9d..682b976bb 100644
--- a/docs/user-guide/complex-expressions.md
+++ b/docs/user-guide/complex-expressions.md
@@ -5,7 +5,11 @@ Complex expressions are used to define SQL expressions. Complex expressions are
Where complex expressions can be utilized:
* in report filters;
-* when working with ORM to avoid writing bare SQL (for developers).
+* when working with ORM to avoid writing raw SQL (for developers)
+
+!!! note "Note for developers"
+
+ It's possible to build expressions with `Espo\ORM\Query\Part\Expression` class. See [here](../development/orm.md#complex-expressions).
In this article:
@@ -14,33 +18,51 @@ In this article:
## Functions
-Function names should be in UPPER_CASE. You need to append the **trailing colon** character to a function name. There **should not be any whitespace** between function name and parentheses.
+Function names should be in UPPER_CASE. You need to append a trailing colon character to a function name. There should not be any whitespace between function name and parentheses.
-Examples:
+!!! example "Examples"
-```
-CONCAT:(firstName, ' ', lastName)
-```
+ ```
+ CONCAT:(firstName, ' ', lastName)
+ ```
-```
-IF:(EQUAL:(status, 'Complete'), 'Complete', 'Not Complete')`
-```
+ ```
+ IF:(EQUAL:(status, 'Complete'), 'Complete', 'Not Complete')`
+ ```
Functions:
-* [Flow control](#flow-control)
+* [Conditional](#conditional)
* [Comparison](#comparison)
* [Date & time](#date-time)
* [String](#string)
* [Math](#math)
* [Logical](#logical)
+* [Misc](#misc)
-### Flow control
+### Conditional
#### IF
-E.g. `IF:(a, '1', '0')` – if 'a' is true then return '1'; return '0' otherwise.
+E.g. `IF:(a, '1', '0')` – if *a* is true, then return '1'; return '0' otherwise.
+
+#### SWITCH
+
+*As of v7.4.*
+
+An equivalent of 'CASE WHEN ... THEN ... ELSE ... END'. Arguments on even-numbered positions define 'WHEN' conditions, while following arguments define corresponding 'THEN' values. The last unmatched argument defines 'ELSE'.
+
+E.g. `SWITCH:(EQUAL:(monthNumber, 1), 'Jan', EQUAL:(monthNumber, 2), 'Feb', EQUAL:(monthNumber, 3), 'Mar', 'Other')`.
+
+#### MAP
+
+*As of v7.4.*
+
+An equivalent of 'CASE ... WHEN ... THEN ... ELSE ... END'. Arguments on odd-numbered positions define keys, while following arguments
+define mapped values. The last unmatched argument defines 'ELSE'.
+
+E.g. `MAP:(monthNumber, 1, 'Jan', 2, 'Feb', 3, 'Mar', 'Other')`.
### Comparison
@@ -48,7 +70,7 @@ E.g. `IF:(a, '1', '0')` – if 'a' is true then return '1'; return '0' otherwise
Pattern matching.
-E.g. `LIKE:(name, 'Cloud%'`) will give true for 'name' equal to 'Cloud Basic' and 'Cloud Enterprise'.
+E.g. `LIKE:(name, 'Cloud%'`) will give true when 'name' is equal to 'Cloud Basic' or 'Cloud Enterprise'.
#### NOT_LIKE
@@ -96,7 +118,7 @@ Negation of IS_NULL.
Check whether a value is within a set of values.
-E.g. `IN:(stage, 'Closed Won', 'Closed Lost')` will give true is stage is 'Closed Won' or 'Closed Lost'.
+E.g. `IN:(stage, 'Closed Won', 'Closed Lost')` will return true if stage is 'Closed Won' or 'Closed Lost'.
#### NOT_IN
@@ -116,12 +138,23 @@ E.g. `IFNULL:(name, '')` will return empty string if *name* is NULL.
#### NULLIF
-If the first argument equals the second, it returns NULL, otherwise it returns the
+If the first argument equals the second, returns NULL, otherwise returns the first argument.
E.g. `NULLIF:(name, '')` will return NULL if *name* is empty string.
-### Date & time
+#### GREATEST
+
+*As of v7.4.*
+
+Returns the max value from a list of expressions.
+
+#### LEAST
+*As of v7.4.*
+
+Returns the min value from a list of expressions.
+
+### Date & time
#### MONTH_NUMBER
@@ -149,7 +182,7 @@ Year number.
#### YEAR_X
-Fiscal year number, where X is a number (between 1 and 12) of the fiscal year start. E.g. `YEAR_3`.
+Fiscal year number, where X is a number (between 0 and 11) of the fiscal year start. E.g. `YEAR_3`.
#### HOUR
@@ -169,17 +202,17 @@ Quarter number w/ year. E.g. `2019_1`.
#### QUARTER_X
-Fiscal quarter number, where X is a number (between 1 and 12) of the fiscal year start. E.g. `QUARTER_3`.
+Fiscal quarter number, where X is a number (between 0 and 11) of the fiscal year start. E.g. `QUARTER_3`.
-#### WEEK
+#### WEEK_0
-Week number w/ year.
+Week number w/ a year. Sunday is a first day of week.
-E.g. `2018/4`. Sunday is a first day of week.
+E.g. `2018/4`.
#### WEEK_1
-Week number w/ year. Monday as a first day of week.
+Week number w/ a year. Monday as a first day of week.
#### NOW
@@ -187,7 +220,7 @@ Current date and time.
#### TZ
-Time zone converion.
+Time zone conversion.
E.g. `TZ:(createdAt, -10.5)` will apply -10:30 offset.
@@ -235,6 +268,10 @@ Returns a date part of a date-time value. Available since v6.0.0.
Concatenate. E.g. `CONCAT:(firstName, ' ', lastName)`.
+#### LEFT
+
+Returns a specified number of characters from the left of the string. E.g. `LEFT:(someTextColumn, 1000)`.
+
#### LOWER
Convert to lower case.
@@ -259,16 +296,12 @@ Converts a value to a binary string.
`EQUAL:(BINARY:('test'), 'Test')` returns false.
-Avalilable since v5.7.0.
-
#### REPLACE
Replaces all the occurrences of a substring within a string.
`REPLACE:('haystack', 'needle', 'replaceWith')`
-Available since v6.0.0.
-
### Math
#### ADD
@@ -301,7 +334,7 @@ The smallest integer value greater than or equal to the argument.
#### ROUND
-Round a number to a specified number of decimal places. E.g. `ROUND:(value,2)`.
+Round a number to a specified number of decimal places. E.g. `ROUND:(value, 2)`.
### Logical
@@ -317,10 +350,21 @@ E.g. `AND:(a, b, c)` corresponds to SQL statement `a AND b AND c`.
E.g. `NOT:(a)` corresponds to SQL statement `NOT a`.
+### Misc
+
+#### ANY_VALUE
+
+*As of v9.1.6.*
+
+Obtains an arbitrary row from an aggregated group.
+
+### Custom functions
+
+It is possible to add custom functions. An implementation class name for a custom function should be defined in [metadata](../development/metadata/app-orm.md) by the path app > orm > platforms > {platform} > functionConverterClassNameMap > {function}. The class should implement `Espo\ORM\QueryComposer\Part\FunctionConverter` interface.
## Attribute names
-Attribute names usually are same as a system field names. Fields are listed at Administration > Entity Manager > ... > Fields.
+Attribute names usually are same as system field names. Fields are listed under Administration > Entity Manager > {Entity Type} > Fields.
Attribute names should be in lowerCamelCase.
@@ -333,3 +377,4 @@ Field types having attributes named differently:
Where *field* is the name of the field.
More info about attributes [here](../administration/terms-and-naming.md#attribute).
+
diff --git a/docs/user-guide/data-privacy.md b/docs/user-guide/data-privacy.md
index 8ba761d6c..ae50a0df5 100644
--- a/docs/user-guide/data-privacy.md
+++ b/docs/user-guide/data-privacy.md
@@ -1,12 +1,10 @@
# Data Privacy
-Available since the version 5.2.0.
+EspoCRM provides the ability to view and erase personal data for specific records.
-EspoCRM provides the ability to view and erase personal data for specific records (Contacts, Leads, Accounts).
+In the Entity Manager, an administrator can mark certain fields as those that contain personal data. This option is available for Accounts, Contacts, Leads, and custom entity types of the Person types.
-In Entity Manager administrator can check certain fields as those that can contain personal data. This option is available for Accounts, Contacts, Leads entity types as well as custom entities of the Person types.
-
-By default the following fields are marked as those that can contain personal data.
+By default, the following fields are marked as those that can contain personal data.
Contacts & Leads:
@@ -19,6 +17,6 @@ Accounts:
* Email
-On the detail view of the record in the menu (next to the edit button) there is the item *View Personal Data*. From there it's possible to erase certain fields (only if the user has 'edit' permission).
+To view or erase personal data for a specific record, go to the detail view, then click *View Personal Data* from the dropdown next to the *Edit* button. From there, it's possible to erase certain fields (if the User has edit access).
-Regular uses will have an ability to view/erase personal data only if they have *Data Privacy Permission* (defined by roles).
+Regular uses have the ability to view or erase personal data only if they have *Data Privacy* permission (defined in Roles).
diff --git a/docs/user-guide/documents.md b/docs/user-guide/documents.md
index 5e37fa549..0965d788f 100644
--- a/docs/user-guide/documents.md
+++ b/docs/user-guide/documents.md
@@ -1,12 +1,21 @@
# Documents
-EspoCRM provides the ability to store documents. By default Document entity type has many-to-many relationships with Account, Opportunity, Contact, Lead. Administrator can create relationships with other entity types.
+EspoCRM provides the ability to store documents. By default, the Document entity type has many-to-many relationships with Account, Opportunity, Contact, and Lead. An administrator can create relationships with other entity types.
+
+In this article:
+
+* [Folders](#folders)
+* [Sending in email](#sending-in-email)
+* [Creating from email attachment](#creating-from-email-attachment)
+* [Uploading in attachments](#uploading-in-attachments)
+* [File types](#file-types)
+* [See also](#see-also)
## Folders
-Folders allow to group documents. Document Folders are presented as a hierarchical tree structure. Each folder can contain sub-folders.
+Folders allow to group Documents. Document Folders are presented as a hierarchical tree structure. Each folder can contain sub-folders.
-Document Folder is a separate entity type, hence an access can be controlled by ACL Roles.
+The Document Folder is a separate entity type. Access to it can be controlled by Roles.
## Sending in email
@@ -14,6 +23,16 @@ While composing an email, there is the ability to add a certain document as an a
## Creating from email attachment
-Available since version 5.9.0.
+It's possible to create a Document from an Email attachment. On the Email detail view from the dropdown at top-right corner, click *Create Document*. The email should have at least one attachment to be able to create a Document from it.
+
+## Uploading in attachments
+
+It's possible to upload existing Documents directly in Attachment-Multiple fields. This ability can be enabled for a specific field at: Administration > Entity Manager > {Entity Type} > Fields > {your Attachment-Multiple field}. Add *Documents* to the Source List.
+
+## File types
+
+An administrator can configure allowed file types. Under Administration > Entity Manager > Document > Fields > File, specify allowed file types in the "Accept" parameter.
+
+## See also
-It's possible to create a document from an email attachment. On the email detail view from the dropdown at top-right corner click *Create Document*. The email should have at least one attachment.
+* [Documents quick tour](https://app.supademo.com/demo/cml9ij9ru1tgyvhwzri4tcrc0)
diff --git a/docs/user-guide/emails.md b/docs/user-guide/emails.md
index e3fe684e1..c10066cc5 100644
--- a/docs/user-guide/emails.md
+++ b/docs/user-guide/emails.md
@@ -1,127 +1,214 @@
+---
+search:
+ boost: 3
+---
+
# Guidelines on using emails
-EspoCRM provides the ability to fetch emails from IMAP box. This makes possible to use EspoCRM as an email client along with CRM-specific features.
+EspoCRM is designed to be able to work with emails right from within the system without the necessity to use an email client separately. Though users may still opt to use an email client and have both sent and received emails synced to Espo.
In this article:
* [IMAP accounts](#imap-accounts)
* [SMTP accounts](#smtp-accounts)
-* [Gmail accounts](#gmail-accounts)
* [Working with emails](#working-with-emails)
* [Sending emails](#sending-emails)
* [Email folders](#email-folders)
+* [Group email folders](#group-email-folders)
* [Email filters](#email-filters)
* [Email templates](#email-templates)
+* [Manual import](#manual-import)
+* [See also](#see-also)
## IMAP accounts
-Note: You need to have [cron](../administration/server-configuration.md#setting-up-crontab) properly configured in your system to have inbound emails working.
+*The section concerns email receiving.*
+
+!!! note
+
+ You need to have [cron](../administration/server-configuration.md#setting-up-crontab) properly configured in your system to have inbound emails working.
-User can setup IMAP account on Personal Email Accounts page (Emails tab > top-right menu > Personal Email Accounts).
+A regular user can set up an IMAP account on the Personal Email Accounts page (Emails tab > top-right menu > Personal Email Accounts).
-Specify what folders to monitor in *Monitored Folders* field. By default it's set to INBOX.
+Specify what folders to monitor in *Monitored Folders* field. By default, it's set to INBOX.
-If you use an **external email client** for sending emails, you can add *Sent* folder to monitored ones. Emails sent from the external client will be imported to Espo. Note, that your external client needs to be configured to store sent emails on IMAP server.
+If you use an **external email client** for email sending, you can add *Sent* folder to monitored ones. Emails sent from the external client will be imported to Espo. Note that your external client needs to be configured to store sent emails on the IMAP server.
-*Fetch Since* allows you to choose the date emails should be archived from. Set it to some date prior today if you need to archive old emails.
+*Fetch Since* allows you to choose the date emails should be imported from. Set it to some date prior today if you need to archive old emails.
-There is an ability to specify *Folder* in Personal Email Account. Incoming emails will be put in that folder.
+There is the ability to specify *Folder* in a Personal Email Account. Incoming emails will be put in that Email Folder folder. Note that Emails Folders are personal for users.
+
+For regular users, access to Personal Email Accounts must be allowed in Roles.
## SMTP accounts
-Users can setup SMTP settings in their Personal Email Accounts as well as in Preferences. Personal Email Accounts available at Emails tab > top-right menu > Personal Email Accounts.
+*The section concerns email sending.*
-Administrator also can allow to use the mailn system SMTP account as well as Group Email Accounts (mark as Shared).
+Users can set SMTP settings in their Personal Email Accounts. Personal Email Accounts are available under: Emails tab > top-right menu > Personal Email Accounts.
-Users can have multiple SMTP accounts.
+For regular users, access to Personal Email Accounts must be allowed in Roles.
-Important: Email addresses, user can use to send emails from, must be defined in *Emails* field of *User* record. Only admin can define user's email addresses (by default).
+An administrator can also allow to use the main system SMTP account as well as Group Email Accounts (needs to mark as Shared).
-## Gmail accounts
+Users can have multiple SMTP accounts.
-For connecting your Gmail account (IMAP and SMTP) you have two options:
+!!! important
-1. Enable access for less secure application at your Google account settings.
-2. Use [Google Integration](https://www.espocrm.com/extensions/google-integration/) that provides a secure authentication via Oauth2.
+ Email addresses that user can use to send emails from must be defined in *Emails* field of the *User* record. Only the admin can define user's email addresses (by default).
## Working with emails
-Emails are fetched by cron (in the background) every few minutes (period can specified by Administrator).
-You can see all your emails at Emails tab. There are standard folders Inbox, Sent, Draft emails at the left side.
+Emails are fetched by Cron (in the background) every few minutes (period can specified by the administrator).
+
+A user can see emails on the page accessed through the *Emails* tab.
+
+There are the following default folders available:
+
+* All – all emails in the system the user has access to; the user can see even emails of other users here (if Roles allow);
+* Inbox – incoming emails sent to the user are automatically placed here;
+* Sent – emails sent by the user;
+* Draft – emails composed by the user but not yet sent;
+* Archive – inbox emails that the user explicitly moved to the Archive;
+* Trash – inbox emails that the user explicitly moved to the Trash.
+
+Additionally, there are also user's Email Folders and Group Email Folders listed.
+
+The Email's *Status* field has the following values:
+
+* *Sent* – sent by means of the CRM;
+* *Imported* – fetched from an IMAP account or imported manually;
+* *Draft* – created as a draft and not yet sent.
+
+When a new email comes, the system tries to recognize which record this email belongs to. It can link it with Account, Lead, Opportunity, Case (and also Contact in B2C mode), etc. If it wasn't recognized, then the user can link it manually by filling in the *Parent* field.
+
+If an email came from a new potential client, the user can convert it to a Lead (from the top-right menu).
+
+It's possible to create a Task or Case from an email record (from the top-right menu).
+
+If email addresses (From, To, CC) of the email record are known to the system, it will show the person they are related to (Contact, Lead, User, etc.). If some email address is new, you can create a Contact right from there.
+
+All emails related to a specific record are shown in the History panel of that record. If some email is related, for example, to an opportunity but the opportunity is related to an account, it will be shown both in the opportunity and the account.
+
+When **removing** an email it gets removed from the system entirely, so that it will disappear from their *Inbox*. To prevent this, use *Move to Trash*. An administrator may not grant *delete* access for users to prevent losing emails.
+
+On the list view it's possible to **drag & drop** emails into folders by dragging by a subject link (as of v7.3).
+
+### Inbox
+
+Emails related to a user through the *Users* relationship are referred as their Inbox emails. Only Inbox emails can be moved to Archive, Trash or a personal Email Folder by a user. Only Inbox emails can be marked as read, not read or important by a user.
-*Status* field:
+!!! important
-* *Sent* - was sent via CRM
-* *Archived* – fetched from IMAP account or archived manually
-* *Draft* – email was created as a draft
+ The same Email record can be located in the Inbox of multiple users.
-When the new email comes the system tries to recognize which record this email belongs to. It can link it with Account, Lead, Opportunity, Case (and Contact in B2C mode) etc. If it wasn't recognized, then user can link it manually by filling in *Parent* field.
+An administrator can view and manage users an email is related to by clicking *View Users* action from the dropdown next to the *Edit* button.
-If an email came from a new potential client, user can **convert it to Lead**. Open Email entry and click Create Lead in top-right menu.
+As of v8.5. Regular users can view users an email is related to: Email detail view > dropdown next to *Edit* > View Users. If a user has *edit* access to a particular Email, they can also add other users to the Email so that it will appear in the Inbox of those users. Adding users requires the assignment permission.
-It's also possible to **create Task or Case** from an email record.
+### Concept
-If email addresses (from, to, cc) of the email record are known to the system, it will show the person they are related to (Contact, Lead, User etc). If some email address is new, you can **create contact** right from there.
+Espo does not work exactly like a regular personal email client. Espo is a central place where emails from multiple email accounts are gathered.
-All emails related to specific record are shown in History panel of that record. If some email is related, for example, to opportunity but opportunity is related to the account, it will be shown both in opportunity and account.
+The same email record can appear in the inboxes of multiple users, for example, when they were both recipients of the email. When the same email is imported from multiple email accounts, only one email record will be stored in Espo. Emails are recognized as duplicates by their *Message-ID*.
-When **removing** an email it gets removed from the system entirely, so that it will disappear from their *Inbox*. To prevent this, use *Move to Trash*. Administrator may not grant *delete* access for users to prevent losing emails.
+A user with high privileges can see an email even if it was not addressed to them. This allows the monitoring of subordinates' communication within the organization.
+
+Email folders in Espo are not connected with IMAP folders, there's no two-way sync between them by design.
## Sending emails
-You can compose new email by a few ways:
+You can compose a new email in a few ways:
-* *Compose Email* button on Emails list view;
+* using the *Compose Email* button on the Emails list view;
* replying on another email;
* clicking on an email address of some record;
-* *Compose Email* action of Activities panel.
+* using the *Compose Email* action from the Activities panel on the detail view of a particular record.
+
+There is the ability to select a template for an email you compose.
+
+You can set up the email signature in the Preferences. This signature will be used for all emails you compose.
+
+It's possible to use an **external email client** – the default one on your computer or device. For this, check *Use an external email client* in the Preferences.
+
+### Scheduled send
+
+When composing an email, it's possible to schedule it to be sent at a specific time. The email is saved to Drafts. The scheduled time can be changed after save.
+
+The scheduled send is available from the dropdown menu next to the Send button.
+
+## Email folders
+
+Users can create their personal Email Folders to put some emails in for convenience. To create or edit folders, follow: the Emails list view > dropdown in the top-right corner > Folders. *Skip Notification* means that you won't be notified about incoming emails that get to the specific folder. By utilizing Email Filters, it's possible to put emails in folders automatically by specific criteria.
+
+!!! note
+
+ Email folders in EspoCRM have nothing to do with IMAP folders.
-There is the ability to **select template** of your email.
+## Group email folders
-You can setup **email signature** in Preferences.
+*As of v7.3.*
-It's possible to use an **external email client** (the default one on your computer or device). For this check *Use an external email client* in Preferences.
+Group Email Folders are shared for teams. An administrator can create group email folders and specify which teams have access to a particular folder.
-## Email Folders
+If an email is moved from a group folder to a personal folder or the Inbox, it will unlink the email from that group folder.
-Users can create their own email folders to put some of emails in for convenience. List of available folders is available at Emails page at the left side. To create or edit folders follow Emails > dropdown in top-right corner > Folders. `Skip Notification` means that you won't be notified about incoming emails that fall into the certain folder. By utilizing Email Filters it's possible to put emails in folders automatically by specific criteria.
+There's the ability to automatically put inbound emails imported through a group email account to a specific group folder. It's also possible to move emails matching an email filter to a specific group folder (the filter should be related to a group email account).
-## Email Filters
+Users that have access to a group folder can put there emails that they have edit access to. If an email is located in a group folder, a user does not have edit access to, they won't be able to move that email to another folder.
-Administrator can create global email filters to skip not desirable emails. They are available at Administration > Email Filters.
+The field-level-security (in Roles) can be used to restrict the ability to change (edit) the group folder.
-Regular user can create email filters for their Personal Email Accounts or for their entire inbox. They are available at Emails > dropdown in top-right corner > Filters.
+## Email filters
+
+Administrator can create global Email Filters to skip not desirable emails. They are available at Administration > Email Filters.
+
+Regular user can create Email Filters for their Personal Email Accounts or for their entire inbox. They are available at: Emails > dropdown in top-right corner > Filters.
There are two types of filters:
-* Skip - email will be put in *Trash* or not imported if filter is related to Personal Email Account;
-* Put in Folder - imported emails will be put into specified user's folder automatically.
+* Skip – email will be put in *Trash* or not imported if the filter is related to a Personal Email Account;
+* Put in Folder – imported emails will be put into a specified user's folder automatically.
+
+## Email templates
-## Email Templates
+Email Templates are available at: Emails > dropdown in top-right corner > Email Templates. They can be used both for Mass Email sending and for regular emails. *One-off* checkbox means that the email template is supposed to be used only once, what is usual for email marketing.
-Email templates are available at Emails > dropdown in top-right corner > Email Templates. They can be used both for mass email sending and for regular emails. `One-off` checkbox means that email template supposed to be used only once, what is usual for email marketing.
+It's possible to use placeholders in an email template's body and subject, for example, {Account.name}, {Person.emailAddress}. They will be replaced with values of a Parent record.
-It's possible to use placeholders in email template's body and subject e.g. {Account.name}, {Person.emailAddress}. They will be replaced with values of related records.
+You can use additional reserved placeholders in the template body: `{optOutUrl}` and `{optOutLink}`. Available additional placeholders are listed in a side panel when you compose an email template.
+
+An example of an unsubscribe link for Mass Email:
-You can use additional reserved placeholders in template body: `{optOutUrl}` and `{optOutLink}`.
```
Unsubscribe
```
-This is unsubscribe link for mass email.
The list of available additional placeholders:
-* `{today}` - today's date,
-* `{now}` - current date & time,
-* `{optOutUrl}` - opt-out url (only for mass email),
-* `{optOutLink}` - opt-out link (only for mass email),
-* `{optInUrl}` - opt-in url (only for lead capture confirm opt-in),
-* `{optInLink}` - opt-in link (only for lead capture confirm opt-in).
+* `{today}` – today's date,
+* `{now}` – current date & time,
+* `{optOutUrl}` – opt-out url (only for mass email),
+* `{optOutLink}` – opt-out link (only for mass email),
+* `{optInUrl}` – opt-in url (only for lead capture confirm opt-in),
+* `{optInLink}` – opt-in link (only for lead capture confirm opt-in).
### Handlebars support
-Available since version 5.9.0.
+Email Templates also support the Handlebars templating engine. It's the same template system used for [PDF templates](printing-to-pdf.md#templates) with double-brace placeholders, like `{{name}}`.
+
+The Handlebars engine is only applied when an Email has a non-empty *Parent* field. The regular email template placeholder values are not available for Handlebars helpers.
+
+## Manual import
+
+It's possible to manually import specific emails. For example, if a customer sent an email to an employee's private email address, it may be reasonable to log that email in the CRM manually.
+
+The are two ways of importing emails:
+
+* Archive Email – create an email manually by specifying all fields on a form;
+* Import EML (as of v8.4).
+
+The ability to import emails requires a user to have access to the Import scope (set in Roles).
-Note: This is an expiremental feature.
+## See also
-Email templates also support handlebars. It's the same template system used for PDF templates with double-brace placeholders, like `{{name}}`.
+* [Shortcut keys](https://docs.espocrm.com/user-guide/shortcuts/#emails)
diff --git a/docs/user-guide/export.md b/docs/user-guide/export.md
index 239912462..6a55f6608 100644
--- a/docs/user-guide/export.md
+++ b/docs/user-guide/export.md
@@ -1,9 +1,15 @@
+---
+search:
+ boost: 2
+---
+
# Export
-EspoCRM has the ability to export records to XLSX (Excel) and CSV formats.
+The Export feature allows you to extract record data in XLSX (Spreadsheet) and CSV formats.
* [How to export](#how-to-export)
* [Access control](#access-control)
+* [Parameters](#parameters)
* [CSV delimiter](#csv-delimiter)
* [See also](#see-also)
@@ -31,20 +37,31 @@ You can select specific fields to be exported or check to export all available f
### Step 4
-After clicking Export button the export file will be downloaded.
+After clicking the Export button the export, two scenarios are possible.
+
+* Export will be processed right away and you will receive a prompt to download the file.
+* Export will be processed in idle (if the number of exported records exceeds the specific threshold). A modal dialog will be shown. After the process is finished, you will be able to download the file.
## Access control
-Administrator can disable export function for all non-admin users at Administration > Settings > Disable Export.
+An administrator can disable export function for all non-admin users under Administration > Settings > Disable Export.
+
+Also it's possible to control access to export function via Roles with the *Export Permission* parameter.
+
+## Parameters
+
+### Lite mode
-Also it's possible to control an access to export function via ACL Roles with Export Permission parameter.
+The *Lite* mode consumes much less memory. Recommended if a big number of records is exported.
## CSV delimiter
-Users can specify the delimiter for CSV export at Preferences.
+Users can specify the delimiter for CSV export in their Preferences.
The default delimiter for the system can be changed manually in `data/config.php`, parameter `exportDelimiter`.
## See also
+* [Export feature quick tour](https://app.supademo.com/demo/cmk5pysph1o5ok6skq80atm08)
+* [Export Import extension](../extensions/export-import/overview.md)
* [Import and export tool for quick data migration](https://www.espocrm.com/tips/import-export/)
diff --git a/docs/user-guide/imap-smtp-configuration.md b/docs/user-guide/imap-smtp-configuration.md
index 6ff777ecd..f948ab67f 100644
--- a/docs/user-guide/imap-smtp-configuration.md
+++ b/docs/user-guide/imap-smtp-configuration.md
@@ -4,56 +4,59 @@ In this article:
* [IMAP configuration](#imap-configuration)
* [SMTP configuration](#smtp-configuration)
-* [G Suite account](#setup-for-g-suite-account)
-* [Gmail account](#setup-for-gmail-account)
-* [Outlook account](#setup-for-outlook-account)
-* [Yahoo account](#setup-for-yahoo-account)
-* [Troubleshoot problems](#troubleshoot-problems)
+* [Google Workspace](#google-workspace)
+* [Gmail](#gmail)
+* [Outlook](#outlook)
+* [Yahoo](#yahoo)
## IMAP configuration
-Note: You need to have cron properly configured in your system to have inbound emails working.
+!!! note
-IMAP allows to retrieve your emails from an email client. To setup the IMAP account, do the following steps:
-1. Select *Emails Tab > top-right menu > Personal Email Accounts*.
+ You need to have cron properly configured in your system to have inbound emails working.
+
+IMAP allows you to retrieve your emails from a mail server. To set up an IMAP account, do the following steps:
+
+1. Go to Emails Tab > top-right menu > Personal Email Accounts.
2. Click on *Create Personal Email Account*.
-3. In the *Main* section, specify your *Email Address*. The *Name* of personal email account is generated automatically, but you may change it. *Fetch since* allows to choose the date from which emails should be archived. In case you want to archive old emails, set it to some prior date to the day from which they should be fetched.
+3. In the *Main* section, specify your Email Address. The *Name* of the personal email account is generated automatically, but you can change it. *Fetch since* allows you to choose a date from which emails will be imported. If you want to archive old emails, set it to some past date.

-4. In the *IMAP* section, enter your *Host* name, your *Email Client Username* and *Email Client Password* in the fields shown. Tick of *SLL* for a secure connection. The IMAP *Port* will be generated automatically.
+4. In the *IMAP* section, enter your *Host* name, your *Username* and *Password*. Tick off *SSL* for a secure connection. The IMAP *Port* will be generated automatically.

-5. Specify what folders to monitor in *Monitored Folders* field. By default, it is set to INBOX. If you use some external email client to send emails, you can add Sent folder to archive those emails.
-6. *Put in Folder* field allows to specify the folder in which the incoming emails will be put.
-7. Click on *Test Connection* to check whether everything was specified correctly. If a connection is successful, click *Save* on the top of the page.
+5. Specify what folders to monitor in the *Monitored Folders* field. By default, it is set to INBOX. If you use some external email client to send emails, you can add the Sent folder to archive those emails.
+6. *Put in Folder* field allows you to specify an Espo email folder in which incoming emails will be put.
+7. Click on *Test Connection* to check whether everything was set correctly. If the connection is successful, click *Save*.
## SMTP configuration
-SMTP allows to send email messages out. Users can setup SMTP settings in Preferences as well as in their Personal Email Accounts. An administrator can also allow to use System SMTP (make it shared).
+SMTP is for sending emails. Users can setup SMTP settings their Personal Email Accounts. An administrator can also allow to use the System SMTP (by marking it shared).
-Users can have multiple SMTP accounts. However, email addresses a user can use to send emails from are defined by email addresses of User record.
+Users can have multiple SMTP accounts. However, email addresses a user can use to send emails from are defined by email addresses of the User record (Administration > Users).
-To setup SMTP account, do the following:
+To set up an SMTP account, do the following:
-1. Navigate either to *Personal Email Accounts page (Emails Tab > top-right menu > Personal Email Accounts)* or to *Preferences > SMTP* settings.
-2. Tick off *Use SMTP* box.
-3. Enter your *SMTP Host* name, in SMTP security field select *TLS* for a secure connection. A proper *SMTP Port* will be set automatically.
-4. Tick *SMTP Auth* box and enter your *Email Client Username* and *Email Client Password* in the fields shown.
-5. Click on *Send Test Email* to check whether everything was specified correctly. If the connection is successful, you will receive test email on the specified email address.
+1. Navigate to the *Personal Email Accounts* page: Emails Tab > top-right menu > Personal Email Accounts.
+2. Tick off the *Use SMTP* box.
+3. Enter your *SMTP Host* name, in the SMTP security field select *STARTTLS* or *SSL/TLS* for a secure connection. The proper *SMTP Port* will be set automatically.
+4. Tick off the *SMTP Auth* box and enter your *Username* and *Password*.
+5. Click on the *Send Test Email* button to send a test email to a specified email address.
+6. Save.

-## Setup for G Suite account
+## Google Workspace
1. Sign into your *Google Admin console*.
2. Navigate to *App > G Suite > Gmail > Advanced settings*.
-3. Select the organizational unit in the **rganizations section*.
+3. Select the organizational unit in the *organizations section*.
4. Under the POP and IMAP Access, uncheck the *Disable POP and IMAP access for all users box* checkbox.
-5. Each user has to enable IMAP access as descibed for [Gmail Account](#setup-for-gmail-account).
+5. Each user has to enable IMAP access as described for [Gmail Account](#gmail).
-## Setup for Gmail account
+## Gmail
1. Sign into your *Gmail Account*.
2. Select  > Settings.
@@ -61,55 +64,38 @@ To setup SMTP account, do the following:
4. In the *IMAP access*, select *Enable IMAP*.
5. Click on *Save Changes*.
-Note: There are two ways in which you can setup IMAP and SMTP for Gmail account:
-
-* Use [Google Integration](https://www.espocrm.com/extensions/google-integration/) that provides a secure authentication via Oauth2.
-* Enable [access for less secure application](#for-gmail-accounts) at your Google account settings.
-
-For more information, please follow the [link](https://support.google.com/mail/answer/7126229?hl=en).
-
-## Setup for Outlook account
-
-1. Go to your *Outlook Account*.
-2. Select  > *View all Outlook settings*.
-3. On the navigation panel, select *Mail > Sync email*.
-4. Click *Yes* to enable POP and IMAP access.
-5. Press *Save* button on the top of the page.
-
-
-
-Note: If you have **2FA** enabled for your Microsoft account, you need to create app password and use it in Espo instead of your main password. More info [here](https://support.microsoft.com/en-us/help/12409/microsoft-account-app-passwords-and-two-step-verification).
+!!! note
-## Setup for Yahoo account
+ There are two ways in which you can set up IMAP and SMTP for Gmail account:
-IMAP and SMTP access are enabled by default. All you need is enable the "less secure" access. For more information, please follow these [instructions](#for-yahoo-accounts).
-
-Configuration details are available [here](https://help.yahoo.com/kb/SLN4075.html).
+ * Use the [Google Integration](https://www.espocrm.com/extensions/google-integration/) extension that provides a secure authentication via Oauth2.
+ * Use a generated [App Password](https://support.google.com/accounts/answer/185833). Requires enabling 2-step verification for your Google account.
-## Troubleshoot problems
+For more information, follow the [link](https://support.google.com/mail/answer/7126229?hl=en).
-### Error: Cannot login, user or password wrong
+## Outlook
-#### Step 1. Check the Email Client Username and Email Client Password.
+To be able to connect to Outlook.com or Microsoft 365 email accounts, you need to install the [Outlook Integration](https://www.espocrm.com/extensions/outlook-integration/) extension.
-If you cannot login, make sure you’ve provided the right username and password.
-
-#### Step 2. Allow less secure apps.
+1. Go to your *Outlook Account*.
+2. Open Settings .
+3. On the navigation panel, select *Mail > Forwarding and IMAP*.
+4. *Sign in* if required.
+5. Check *Let devices and apps use IMAP*. Here you can also view your IMAP and SMTP settings.
+6. Click *Save* button.
-Use [Google Integration](https://www.espocrm.com/extensions/google-integration/) that provides a secure authentication via Oauth2, otherwise you have to change your settings to allow less secure apps to access your account.
+!!! important
-#### For Gmail accounts
+ If the STARTTLS encryption method does not work for IMAP, try the SSL/TLS method.
-1. Go to your *Google Account*.
-2. Select *Security* on the navigation panel.
-3. In the *Less secure app access section*, click *Turn on access*.
+## Yahoo
-
+Configuration details are available [here](https://help.yahoo.com/kb/SLN4075.html).
-#### For Yahoo accounts
+## See also
-1. Go to your *Yahoo Account*.
-2. On the navigation panel, select *Account Security*.
-3. At the bottom of the page, click *Allow apps that use less secure sign in*.
+See the articles for specific providers:
-
+* [Gmail](https://support.google.com/accounts/answer/185833)
+* [Yahoo](https://in.help.yahoo.com/kb/SLN15241.html)
+* [Outlook](https://support.microsoft.com/en-us/account-billing/using-app-passwords-with-apps-that-don-t-support-two-step-verification-5896ed9b-4263-e681-128a-a6f2979a7944)
diff --git a/docs/user-guide/invoices.md b/docs/user-guide/invoices.md
index 832a7aeba..163f5520b 100644
--- a/docs/user-guide/invoices.md
+++ b/docs/user-guide/invoices.md
@@ -1,89 +1,228 @@
# Invoices
-Invoices feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/) extension.
+The Invoices feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/) extension.
-Invoice record represents a group of products or services with their quantities and prices.
+An Invoice is a billing document issued to a customer that details the products or services provided, including their quantities, prices, applicable taxes, and the total amount due.
-You can add Invoices panel to Account detail view to be able to see related sales orders. Administration > Layout Manager > Accounts > Relationships.
+You can add the *Invoices* panel to the Account detail view to be able to see related sales orders. Administration > Layout Manager > Accounts > Bottom Panels.
-You can add Invoices panel to Opportunity detail view at Administration > Layout Manager > Opportunities > Relationships.
+You can add the Invoices panel to Opportunity detail view at Administration > Layout Manager > Opportunities > Bottom Panels.
In the article:
* [Converting from Opportunity, Quote or Sales Order](#converting-from-opportunity-quote-or-sales-order)
-* [Total Values Layout](#total-values-layout)
-* [Invoice Items](#invoice-items)
+* [Total values layout](#total-values-layout)
+* [Invoice items](#invoice-items)
+* [Allocations](#allocations)
+* [Payment terms](#payment-terms)
+* [Debit notes](#debit-notes)
+* [Rounding](#rounding)
* [Printing to PDF](#printing-to-pdf)
-* [Sending invoice in email](#sending-invoice-in-email)
+* [Sending in email](#sending-in-email)
* [Automatic numbering](#automatic-numbering)
-* [Default tax](#default-tax)
* [Copying values from product to invoice item](#copying-values-from-product-to-invoice-item)
* [Automation with Workflows or BPM](#automation-with-workflows-or-bpm)
+* [Locking](#locking)
+* [E-Invoicing](#e-invoicing)
## Converting from Opportunity, Quote or Sales Order
-Method 1. Create a new invoice, on the form specify the needed opportunity/quote/sales order. Data will be copied from the opportunity/quote/sales order to the created invoice.
+Method 1. Create a new Invoice, on the form, specify the needed opportunity/quote/sales order. Data will be copied from the opportunity/quote/sales order to the created invoice.
-Method 2. Create a new invoice from Invoices relationship panel on the detail view of the opportunity/quote/sales order.
+Method 2. Create a new Invoice from Invoices relationship panel on the detail view of the opportunity/quote/sales order.
-## Total Values Layout
+## Total values layout
The layout of total value fields (in the bottom on detail view) can be modified at Administration > Layout Manager > Invoices > Bottom Total.
-## Invoice Items
+## Invoice items
-Invoice has a list of items. Each item can represent a certain product or a service with description, quantity, tax rate, list price and unit price fields. It's possible to sort items manually.
+An Invoice has the list of items. Each item can represent a certain product or a service with the description, quantity, tax rate, list price, and unit price fields. It's possible to sort items manually.
-There is an ability to add custom fields for Invoice Item entity using Entity Manager.
+There is the ability to add custom fields for Invoice Item entity type using the Entity Manager.
### Invoice Items Layout
-The layout of invoice items can be modified at Administration > Layout Manager > Invoice Items > List (Item).
+The layout of Invoice Items can be modified at Administration > Layout Manager > Invoice Items > List (Item).
### Discount Rate
-It's possible to specify a discount in percents. To have this ability, administrator should add 'Discount (%)' field to the List (Item) layout.
+It's possible to specify a discount in percents. To have this ability, an administrator should add the *Discount (%)* field to the *List (Item)* layout.
+
+## Allocations
+
+Inbound payments, credit notes, and write-offs can be allocated to an invoice. Allocations reduce the amount due of an invoice.
+
+Applied allocations can be viewed in the Allocations panel of an invoice. To view details of a specific allocation, click View from the dropdown.
+
+## Payment terms
+
+*As of Sales Pack v4.0.*
+
+Payment term profiles can be managed at Administration > Payment Terms Profiles. The default payment term profile can be set at Administration > Sales Pack Settings. This profile will be pre-filled upon invoice creation.
+
+A payment term profile defines items that correspond to payment installments. Each item defines a portion in percents and the number of days. Portions of all items must add up to 100. The number of days is used to calculate the Date Due of the installment by adding the value to the Date Invoiced.
+
+!!! example "Examples"
+
+ - Net 30. Use one item with 100% portion and 30 days.
+ - CIA 25 / Net 20. 25% immediately and the rest after 20 days. Use two items: 25% with 0 days and 75% with 25 days.
+
+Payment installments of a created invoice are available in the Installments panel in the Invoice detail view. The status of each installment updates automatically when a payment is allocated to the invoice. It can be one of the following: Unsettled, Partially Settled, or Settled.
+
+A payment term profile can be assigned for a specific Account. The assigned to an account profile will be used when an invoice is created for that account. Note that the Payment Term Profile field is not added to the Account detail view by default. You need to add it at Administration > Entity Manager > Account > Layouts > Detail.
+
+## Debit notes
+
+*As of Sales Pack v4.0.*
+
+An invoice can be issued as a debit note. In the system, a debit note is an invoice record with the Type field set to *Debit Note*.
+
+A debit note can be created at: Invoices tab > top right menu > Create Debit Note.
+
+By default, debit notes use separate numbering. To use the same numbering, check *Do not use separate numbering for Debit Notes* at Administration > Sales Pack Settings.
+
+To configure the debit note number prefix or change the next number, go to Administration > Entity Manager > Invoice > Fields > Number for Debit Notes (auto-incremented).
+
+In a PDF Template, use `{{type}}` placeholder to print the type of the invoice document: Invoice or Debit Note.
+
+## Rounding
+
+*As of Sales Pack v4.0.*
+
+A rounding can be applied to an invoice. The invoice rounding is mandatory in some countries.
+
+The rounding is applied before the grand total. The rounding method is controlled by a Rounding Profile assigned to the invoice.
+
+Rounding profiles can be managed at Administration > Rounding Profiles. A rounding profile defines a rounding factor.
+
+Rounding factor examples:
+
+- 1 – round to a whole number
+- 0.5 – round to 50 cents
+- 0.01 – round to 1 cent
+
+The default rounding profile can be set at Administration > Sales Pack Settings. This profile will be pre-filled upon invoice creation.
+
+When a credit note is created for an invoice, it inherits the rounding profile from the invoice.
+
+In some cases, when tax-inclusive pricing is used, the discrepancy between the expected amount and the sum of the computed net prices is recorded on the rounding amount line.
## Printing to PDF
-Invoices can be printed to PDF. This action is available in the dropdown next to Edit button on the invoice’s detail view. Then, you will be prompted to select a template. More info about printing to PDF is available [here](printing-to-pdf.md).
+Invoices can be printed to PDF. This action is available in the dropdown next to Edit button on the Invoice detail view. Then, you will be prompted to select a template. More info about printing to PDF is available [here](printing-to-pdf.md).
### Templates
See the documentation [for quote templates](quotes.md#templates).
-## Sending invoice in email
+### Tax number
-Invoice PDF can be send in email as an attachment. Open an invoice record, click the dropdown next to Edit button and then click Email PDF.
+The Sales Pack adds the *Tax Number* field to the Account entity type. Use this field to store VAT numbers. Note that including the VAT number on the invoice is mandatory in many jurisdictions.
-## Automatic numbering
+## Sending in email
-By default, a number field is auto-incremented. You can disable auto-increment at Administration > Entity Manager > Invoice > Fields > number. It's also possible to make the number field read-only.
+An Invoice PDF can be sent in an email as an attachment. Open an invoice record, click the dropdown next to Edit button and then click Email PDF.
-The prefix of the next number, the next number itself and the quantity of digits in the number can be configured at Administration > Entity Manager > Invoice > Fields > numberA.
+The default email template can be set by the administrator: Administration > Sales Pack Settings > Email Templates.
-## Default tax
+To have the Invoice entity selected as the email's parent, the administrator should add the Invoice entity type to the parent type list. Administration > Entity Manager > Email > Fields > Parent > Entity List. As of v3.0.
-You need to have a Tax record created in your CRM. Taxes can be accessed at Quotes list view > dropdown in the top-right corner > Taxes.
+## Automatic numbering
-Administrator can specify a default Tax record at Administration > Entity Manager > Invoices > fields > Tax > Default.
+By default, the *Number* field is auto-incremented. You can disable auto-increment at Administration > Entity Manager > Invoice > Fields > Number. It's also possible to make the number field read-only.
-Note: For older versions of Sales Pack & EspoCRM, you need also to specify the default tax rate value at Administration > Entity Manager > Invoices > fields > Tax Rate > Default.
+The prefix of the next number, the next number itself and the quantity of digits in the number can be configured at Administration > Entity Manager > Invoice > Fields > numberA.
+
+By default, there is no *Name* field on the *Detail* layout. The *Number* is used as a name. You can add the Number field at Administration > Entity Manager > Invoice > Layouts > Detail.
+
+By default, the *Name* field is synced with *Number*. To be able to specify arbitrary names, you need to disable the *Sync with Number* and *Read-only* parameters at Administration > Entity Manager > Invoice > Fields > Name.
## Copying values from product to invoice item
-Field values can be transferred from a product to an invoice item upon product selection. Field names you want to be copied should coincide in Product and Invoice Item enities.
+Field values can be transferred from a product to an invoice item upon product selection. Field names you want to be copied should coincide in Product and Invoice Item entities.
You can select which fields you need to be copied at Administration > Entity Manager > Invoice Item > Fields > Product > Fields to Copy.
## Automation with Workflows or BPM
-The following service actions are available in Workflows and BPM tools:
+The following service actions are available in the Workflows and BPM tools:
* Add Invoice Items
-* Convery Currency
+* Convert Currency
* Send in Email
+## E-Invoicing
+
+*As of Sales Pack v2.4.*
+
+Invoices can be exported to EN 16931 electronic invoices in a UBL format. The following CIUS specifications are supported:
+
+* XRechnung
+* PEPPOL BIS Billing 3.0
+* CIUS-RO e-Factura
+* CIUS-IT
+* CIUS-AT-GOV
+* CIUS-AT-NAT
+* CIUS-ES-FACE
+* NLCIUS
+
+To export an Invoice to a UBL file, click **E-Invoice** from the dropdown menu next to the **Edit** button on the Invoice detail view. The UBL file can be also attached along with a PDF when sending an Invoice in email.
+
+!!! note
+
+ An E-Invoice can exported only if it is valid. It must include certain mandatory fields depending on the specification.
+
+### Settings
+
+E-Invoicing settings are available at Administration > Sales Pack Settings > Electronic Invoicing. Here you can specify the system **Default Format** to prevent the need to select the format each time you are exporting an invoice.
+
+Specify **Seller Information** fields that will be included in electronic invoices. Fields, such as Company Name, Company Address, Electronic Address, VAT Number, etc.
+
+### Account
+
+The Sales Pack adds additional fields to the Account entity type. The following fields of the Account are included in the E-Invoice:
+
+* Tax Number – to store VAT number;
+* Electronic Address Scheme
+* Electronic Address Identifier
+
+Add these fields to the Account's *Detail* layout under: Administration > Entity Manager > Account > Layouts > Detail.
+
+### Invoice
+
+A standard you use may require the Buyer Reference, Purchase Order Reference. The corresponding fields exist in the Invoice entity type, an administrator can add them to the Detail layout.
+
+Additional fields that are mapped to E-Invoice:
+
+* Buyer Reference
+* Purchase Order Reference
+* Note
+
+If you have a requirement to add fields that are not present in Espo out-of-the-box, a developer can implement a custom e-invoice preparator to map custom fields to e-invoice.
+
+### Country codes
+
+The EN 16931 standard requires countries to be represented as ISO 3166-1 alpha-2 codes. But in Espo, the *Address* field allows a country to be an arbitrary string. As of EspoCRM v8.3 it's possible to [map](../administration/addresses.md) country names to ISO 3166-1 alpha-2 codes. This mapping is used when E-Invoices are generated.
+
+Note that it's possible to automatically populate country records with English names.
+
+Example: If you run business from Germany, your customer is also in Germany and you use the word *Germany* when storing the country in Espo, you need to create the *Germany* Address Country record with the *DE* code.
+
+### EN 16931 tax mapping
+
+Tax codes can be mapped to [UNCL5305](https://docs.peppol.eu/poacc/billing/3.0/codelist/UNCL5305/) category code.
+Additionally, a mapping entry can specify a tax class. If the tax class is specified, the mapping will be applied
+to a document items with a product associated with that tax class.
+
+Access mapping at: Administration > EN 16931 Tax Mapping.
+
+## Locking
+
+An Invoice can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Invoice > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
+
## See also
* [Custom calculations for Quote totals](../development/quote-custom-calculations.md)
diff --git a/docs/user-guide/knowledge-base.md b/docs/user-guide/knowledge-base.md
index 394544c19..8775f6ccd 100644
--- a/docs/user-guide/knowledge-base.md
+++ b/docs/user-guide/knowledge-base.md
@@ -1,19 +1,17 @@
# Knowledge Base
-Knowledge Base provides the ability to create articles. Articles are supposed to contain information about products for customers or help for CRM users to improve their productivity.
+The Knowledge Base provides the ability to create articles. Articles may contain information about your products, guidelines for clients, or help for internal users to improve their productivity.
-To make an article available in the portal you need to set its status to 'Published' and select the portal in the *Portals* field. Make sure that the portal role allows an access to Knowledge Base and the navigation menu tab is added in the portal.
+To make an article available in the Portal, you need to set its status to *Published* and select the needed portal in the *Portals* field. Make sure that the Portal Role allows access to the Knowledge Base scope and the navigation menu tab is added in the Portal.
-If you specify *Expiration Date*, then the article will be automatically hidden from the portal on that date.
-
-It's possible to specify a language for an article. The article will be shown only for those portal users which have that language set.
+If you specify the *Expiration Date*, then the article will be automatically hidden from the Portal on that date.
An order in which articles are listed can be manipulated by actions in the dropdown menu of a specific article.
-Knowledge Base articles can be related with Case records, providing a quick access to information from a case record.
+Knowledge Base articles can be associated with Case records. This provides quick access to information from a Case record.
## Categories
Categories allow to group articles. One category can contain multiple sub-categories. Each article can be related to one or multiple categories.
-Knowledge Base Category is a separate entity type, hence an access can be controlled by ACL Roles.
+The Knowledge Base Category is a separate entity type, hence access can be controlled by Roles.
diff --git a/docs/user-guide/mail-merge.md b/docs/user-guide/mail-merge.md
index 61ddd35e5..1cce9a194 100644
--- a/docs/user-guide/mail-merge.md
+++ b/docs/user-guide/mail-merge.md
@@ -1,15 +1,21 @@
# Mail Merge (mass snail mailing)
-1\. You need to have a target list populated with recipients. Target lists can be reached by Campaigns tab > Target Lists button in the top-right corner.
+The Mail Merge feature provides the ability to mass generate snail mails for printing.
-2\. Create a PDF template for an entity type you want to send mails to. If the target list contains records of different entity types (e.g. Contacts and Leads) you need to create templates for each one.
+1\. You need to have a Target List populated with recipients. You can access Target Lists by navigating to the Campaigns tab and clicking the Target Lists button in the top-right corner.
-Note: Administration can create template at Administration > PDF Templates. Templates tab is hidden by default, but can be added by an Administrator.
+2\. Create a PDF Template for an entity type you want to send mails to. If the Target List contains records of different entity types (e.g. both Contacts and Leads) you need to create separate templates for each one.
-3\. Create a campaign of 'Mail' type. Specify the target list for this campaign. Specify the templates you created before.
+!!! note
-4\. On the campaign detail view click on the dropdown next to the *Edit* button and then click *Generate Mail Merge PDF*. Select an entity type and click *Proceed* button.
+ An Administrator can create a template at Administration > PDF Templates. The Templates tab is hidden by default, but can be added by the administrator at Administration > User Interface.
-It will generate a single PDF document for multiple records that you can print.
+3\. Create a campaign of the *Mail* type. Specify the Target List for this Campaign. Specify the templates you created before.
-Note: By default, records with empty *Address* field are skiped.
+4\. On the Campaign detail view, click the dropdown next to the *Edit* button and then click *Generate Mail Merge PDF*. Select an entity type and click *Proceed* button.
+
+It will generate a single PDF document (or multiple PDFs zipped, depending on the used engine) for multiple records that you can print.
+
+!!! note
+
+ By default, records with empty *Address* field are skipped.
diff --git a/docs/user-guide/markdown.md b/docs/user-guide/markdown.md
index c17e283a5..559e0be48 100644
--- a/docs/user-guide/markdown.md
+++ b/docs/user-guide/markdown.md
@@ -1,6 +1,6 @@
# Markdown syntax
-Text fields support markdown syntax.
+Text fields support Markdown syntax.
## Code
```
@@ -86,3 +86,39 @@ some text
___
```
+## Image
+
+```
+
+```
+
+Using an uploaded attachment:
+
+```
+
+```
+
+### Table
+
+```
+| Month | Amount |
+| -------- | -------- |
+| January | $200 |
+| February | $100 |
+```
+
+Alignment:
+
+```
+| Left | Center | Right |
+| -------- | :------: | -------: |
+| January | Good | $200 |
+| February | Normal | $100 |
+```
+
+### Checklist
+
+```
+- [x] Item 1
+- [ ] Item 2
+```
diff --git a/docs/user-guide/mass-email.md b/docs/user-guide/mass-email.md
index a80d37581..acaa6bd4c 100644
--- a/docs/user-guide/mass-email.md
+++ b/docs/user-guide/mass-email.md
@@ -2,111 +2,153 @@
In this article:
+* [Email accounts](#email-accounts)
* [How to send mass email](#how-to-send-mass-email)
-* [Test sending](#test-what-will-be-sent-to-recipients)
-* [Opt-out-link](#opt-out-link)
+* [Test sending](#test-sending)
+* [Opt-out](#opt-out)
* [Tracking URL](#tracking-url)
-* [Target Lists](#target-lists)
-* [Campaign Log](#campaign-log)
+* [Target lists](#target-lists)
+* [Campaign log](#campaign-log)
+* [Bounce emails](#bounce-emails)
+* [Informational emails](#informational-emails)
* [Settings](#settings)
* [Troubleshooting](#troubleshooting)
+## Email accounts
+
+The system email account (the group email account designated as system at Administration > Outbound Emails) is used for mass emails by default. Group email accounts with *Is for Mass Email* checked can also be used. An email account can be selected when creating a Mass Email record.
+
## How to send mass email
-You need to have at least one Target List with target records and Email Template in your crm.
+You need to have at least one **Target List** with target records and an **Email Template** in your CRM.
+
+1. Create a new Campaign of type *Email* or *Newsletter*. Select one or a few target lists in the Target Lists field.
+2. After the Campaign record is created, create a Mass Email for this campaign detail view: click the plus icon in the Mass Email panel. Specify the Date Start (when emails should be sent) and select an email template. Make sure the Status is set to *Pending*.
-1. Create new Campaign with a type `Email` or `Newsletter`. Select one or a few target lists in *Target Lists* field.
-2. After Campaign record is created create Mass Email for this campaign: click plus on Mass Email panel. Specify _Date Start_ - when emails should be sent, and select _Email Template_. Make sure *Status* is set as `Pending`.
+If everything is set up right, emails should go out. They will be sent in portions. You can change the portion size at Administration > Outbound Emails. The administrator can change the **scheduling** at Administration > Scheduled Jobs > Send Mass Emails.
-If everything is setup right emails should go out. They should be sent each hour with portions (you can change portion size in Administration > Outbound Emails). Administrator can change it by updating *&Scheduling* field of 'Check Group Email Accounts' Scheduled Job.
+You can check if emails are sent in the Log panel on the Campaign detail view.
-You can check if emails are sent in Log panel.
+## Test sending
-## Test what will be sent to recipients
+Click the right-side dropdown in a needed record in the Mass Email panel and then click *Send Test*.
-Click right dropdown on the mass email row in _Mass Email_ panel and then click _Send Test_.
+## Opt-out
-## Opt-out link
+The system will append an opt-out link to all sent emails in case it's missing in the email template body. You can use a custom opt-out link in your email template.
-By default the system will append opt-out to all sent emails. But you can use custom one in your Email Template.
+!!! example
-Example:
+ ```html
+ Unsubscribe from the mailing list.
+ ```
-```html
-Unsubscribe from the mailing list.
-```
+An administrator can disable the mandatory opt-out links at Administration > Outbound Emails.
-Administrator can disable mandatory opt-out link being added by system at Administration > Outbound Emails.
+If *Opt-Out Entirely* is checked for a Mass Email, once the recipient clicks on the opt-out link, their email address will be marked as opted out so that marketing emails will never be sent to them, unless the email address is unmarked back. If the parameter is not checked, then the recipient will be marked as opted-out in all Target Lists related to the current Campaign. They still can receive marketing emails when a different Target List is used in another Campaign.
## Tracking URL
-If you want to know that your recipient opened the link from your email, you need to create Tracking URL. Specify any _Name_
- and _URL_ where your link should lead to. Then you will need to paste generated code into your Email Template.
+If you want to know that your recipient opened the link from your email, you need to create a **Tracking URL**. Specify a **Name**
+ and a **URL** where your link should lead to. Then, you need to paste a generated code into your email template.
- Example:
+!!! example
-```html
-Try our demo
-```
+ ```html
+ Try our demo
+ ```
-## Target Lists
+## Target lists
-Target Lists contains the lists of Accounts, Contacts, Leads and Users records.
+Target Lists contain lists of Accounts, Contacts, Leads and Users records. Custom entities of the Person and Company types are supported too.
-Users can populate target lists manually using _Select_ action on the corresponding panel on Target List detail view. There is an ability to make filtering and then select all results of the search.
+Users can populate target lists manually using the *Select* action in the corresponding panel on the Target List detail view. There is the ability to make filtering and then *Select All Results* of the search.
### Populating target lists with Reports
-[Reports](reports.md#syncing-with-target-lists) feature provides an ability to populate target lists with records matching specific criteria.
+The [Reports](reports.md#syncing-with-target-lists) tool provides the ability to populate target lists with records matching specific criteria.
+
+### Excluding target lists
+
+Specify *Excluding Target Lists* to avoid sending mass emails to certain recipients. If there is a record with an email address that matches the email address of an excluded record, it will be excluded as well.
-### Excluding Target Lists
+### Custom entity support
-Specify Excluding Target Lists to avoid sending mass email to certain recipients. If there is a record with the email address that matches the email address of any excluding record, the first record will be excluded as well.
+*[As of v7.1.](https://github.com/espocrm/espocrm/issues/2203)*
-## Campaign Log
+An administrator needs to create a many-to-many relationship between the Target List and the custom entity (of Person or Company type). Then, add the panel to the *Bottom Panels* layout of the Target List entity type.
-In Campaign Log you can see emails that have been sent, opened emails, bounced emails, who opted out, and who clicked the link in the email.
+## Campaign log
+
+In the Campaign Log, you can see emails that have been sent, opened emails, bounced emails, who opted out, and who clicked the link in the email.
* Sent email
-* Links clicked by recipient
+* Links clicked by the recipient
* Recipients who opted out
-* Bounced emails (not delivered to recipient)
-* Emails opened by recipient (disabled by default)
+* Bounced emails (not delivered to the recipient)
+* Emails opened by the recipient (disabled by default)
+
+It's possible create a new Target List (dropdown in the top-right corner on panel) based on records from the log. For example, you can pick only contacts that clicked on a link (tracking URL).
+
+## Bounce emails
+
+A bounce email is an automatic email message from an email system reporting that a sent message has not been delivered.
+
+There are two types of bounced emails: hard and soft. The hard-bounce will mark the recipient email address as invalid so no more emails will be sent to it in future. Soft-bounces will be only logged in the campaign log.
-It's possible to utilize this log by creating Target List (dropdown in the top-right corner on panel) based on records from log. For example, you pick only contacts that clicked on the link (tracking url).
+Bounced emails can be handled only by a *Group Email Account*.
+
+## Informational emails
+
+*As of v9.1.*
+
+Informational emails are not related to marketing. For example, they may provide details about a license update or a notice about scheduled service maintenance.
+
+For sending informational emails, choose the *Informational Email* type when creating a new Campaign.
+
+How it differs from the regular Email type:
+
+* Mass emails are sent to all targets regardless of their opt-out status.
+* Opt-out link is not included.
+* Tracking URLs do not function.
+* Open tracking does not function.
## Settings
-Only for Administrator.
+Only for the administrator.
-Mass Email system parameters available at Administration > Outbound Emails > Mass Email panel.
+Mass Email system parameters are available at Administration > Outbound Emails > Mass Email panel.
-* Max number of emails sent per hour;
-* Disable mandatory opt-out link − by default opt-out link is added even if it's absent in Email Template, you can disable this behaviour;
-* Email Open Tracking − whether to track email opening (not working with most of email providers);
+* Max number of emails sent per hour – to avoid sending rate exceeding; the actual number of emails sent per hour will be always less than this limit; the more often the job is run per hour, the more close to the limit number the number of sent emails will be;
+* Max number of emails sent per batch – how many emails to send per job run per one Mass Email (as of v8.1);
+* Disable mandatory opt-out link − by default opt-out link is added even if it's absent in an Email Template, you can disable this behaviour;
+* Email Open Tracking − whether to track email opening (currently, not working reliably with most email providers);
* Use [VERP](https://en.wikipedia.org/wiki/Variable_envelope_return_path) − for more reliable bounced email precessing.
+Configure how often the sending job is run at: Administration > Scheduled Jobs > Send Mass Emails > Scheduling.
+
## Troubleshooting
-Only for Administrator.
+Only for the administrator.
-#### What to do if emails are not sent out.
+#### What to do if emails are not sent out
1. Check if _Send Test_ works. If doesn't work, then check if system SMTP settings are correct.
2. Check if you have setup cron for your system.
-3. Check if you have 'Send Mass Emails' Scheduled Job and it's 'Active' (Administration > Scheduled Jobs > Send Mass Emails). Check if there is something in the log.
+3. Check if you have *Send Mass Emails* Scheduled Job and it is *Active* (Administration > Scheduled Jobs > Send Mass Emails). Check if there is something in the log.
+#### What if Tracking URLs have wrong URL that does not lead to your CRM
-#### What if Tracking URLs has wrong url that does not lead to your crm.
-
-Check *Site URL* parameter at Administrtion > Settings. The value must be the URL of your EspoCRM, this URL must be accessible externally.
+Check the *Site URL* parameter at Administration > Settings. The value must be the URL of your EspoCRM instance. This URL must be also accessible externally.
#### Bounced emails are not being logged
-Bounced emails can be handled by group email account only. Make sure that you have a group email account that monitors the mailbox bounced emails are sent to.
+Bounced emails can be handled by a Group Email Account only. Make sure that you have a Group Email Account that monitors the mailbox bounced emails are being sent to.
Also some mail server providers can deviate from standards, so bounced emails can be not distinguished.
+Enable *VERP* at Administration > Outbound Emails > Mass Email. This improves bounce recognition significantly. Note that it will work only if your SMTP provider supports VERP.
+
## See also
* [Custom unsubscribe page](../development/campaign-unsubscribe-template.md)
diff --git a/docs/user-guide/optimistic-concurrency-control.md b/docs/user-guide/optimistic-concurrency-control.md
new file mode 100644
index 000000000..b47da4b0c
--- /dev/null
+++ b/docs/user-guide/optimistic-concurrency-control.md
@@ -0,0 +1,21 @@
+# Optimistic Concurrency Control
+
+*As of v7.0.*
+
+Optimistic Concurrency Control prevents data from being overwritten by other users between the time it is fetched and saved.
+
+If a user tries to save a record that has already been modified by another user, a modal dialog will appear, prompting to resolve the conflict. For each changed field, it's possible to choose from the following values:
+
+* Current – the value the user attempted to write;
+* Actual – the value currently stored in the database;
+* Original – the value retrieved before modification.
+
+The conflict won't occur if users modify different fields.
+
+An administrator can enable the Optimistic Concurrency Control for an entity type under Administration > Entity Manager > {Entity Type} > Edit > Optimistic Concurrency Control.
+
+By default, it's enabled for:
+
+* Knowledge Base
+* Email Templates
+* PDF Templates
diff --git a/docs/user-guide/printing-to-pdf.md b/docs/user-guide/printing-to-pdf.md
index 87492f8d2..23543d387 100644
--- a/docs/user-guide/printing-to-pdf.md
+++ b/docs/user-guide/printing-to-pdf.md
@@ -1,24 +1,49 @@
+---
+search:
+ boost: 2
+tags:
+ - pdf
+---
+
# Printing to PDF
-Printing to PDF provides the ability to generate PDF documents with a record data. The document content is defined by Template.
+The Print to PDF feature allows you to generate PDF documents with record data. The document content is defined by a Template.
+
+!!! warning "Important"
+
+ You need to have at least one Template for the entity type of the record you want to print.
+
+In this article:
+
+* [Overview](#overview)
+* [Templates](#templates)
-Important: You need to have at least one Template for the entity type of the record you want to print.
+See also:
+
+* [Quick tour](https://app.supademo.com/demo/cmejvg02x0ly25gz3si01kay7)
+* [International fonts](https://github.com/espocrm/ext-pdf-fonts) (as of v9.4)
+
+## Overview
### Printing single record
-*Print to PDF* is available on the detail view under the dropdown next to the 'Edit' button.
+The *Print to PDF* action is available on the detail view under the dropdown next to the *Edit* button.
### Printing multiple records
-*Print to PDF* is available on the list view as a mass action. You need to select needed records and click Print to PDF from Actions menu. It will generate a single merged PDF file for multiple records.
+*Print to PDF* is available in the list view as a mass action. You need to select needed records and click *Print to PDF* from the *Actions* menu. It will generate a single merged PDF file or multiple PDFs zipped (depending on a used engine) for multiple records.
+
+By default, the maximum number of records is limited to 50. The limit is defined by the config parameter `massPrintPdfMaxCount`.
+
+### Access control
-By default the max number of records is limited to 50. The limit is defined by the config parameter `massPrintPdfMaxCount`.
+Access to PDF printing is controlled by Roles. An administrator can set a *read* access level for the *Template* entity type.
-Note, that page numbering gets reset for each record. You need to use the placeholder `{pageAbsoluteNumber}` to print absolute page numbers in the footer.
+### Engines
-### Access restriction to printing
+PDF documents are generated from HTML code by the use a PDF engine. Out of the box, Espo supports [Dompdf](https://github.com/dompdf/dompdf) engine. [Tcpdf](https://github.com/tecnickcom/TCPDF) engine is available as an [extension](https://github.com/yurikuzn/ext-tcpdf/releases). Dompdf has better CSS support. Tcpdf supports some languages which Dompdf does not.
-Can be achieved by restriction of access to Template entity type.
+The engine can be switched at Administration > Settings > PDF Engine.
## Templates
@@ -31,8 +56,11 @@ Table of content:
* [Page breaking](#page-breaking)
* [Condition checking](#condition-checking)
* [Each iterator](#each-iterator)
+* [Lookup](#lookup)
+* [Expressions](#expressions)
+* [Logical expressions](#logical-expressions)
* [Images](#images)
-* [Date & Time formattng](#date-time-formatting)
+* [Date & time formatting](#date-time-formatting)
* [Number formatting](#number-formatting)
* [Currency symbol](#currency-symbol)
* [Text field](#text-field)
@@ -40,61 +68,85 @@ Table of content:
* [Multi-enum & Array fields](#multi-enum-array-fields)
* [Checklist field](#multi-enum-array-fields)
* [Barcode field](#barcode-field)
-* [Tables](#tables)
* [Raw values](#raw-values)
* [Maps](#maps)
* [Custom helpers](#custom-helpers)
-Available at Administration > PDF Templates.
+Available under Administration > PDF Templates.
-For more precise editing it's recommended to use Code View mode. To switch to Code View click on the button `>`.
+For more precise editing it's recommended to use Code View mode. To switch to Code View click on the button *\>*.
You can print fields of the record as well as fields of related records by utilizing placeholders (Handlebars like) in your template.
-Examples:
+!!! example "Examples"
+
+ * `{{name}}` – Name of the record;
+ * `{{assignedUserName}}` – Assigned User;
+ * `{{account.name}}` – Name of the related account.
+
+!!! note
-* `{{name}}` – Name of the record;
-* `{{assignedUserName}}` – Assigned User;
-* `{{account.name}}` – Name of the related account.
+ If an attribute name coincides with a name of some helper, you can use the following form: `{{this.attributeName}}`.
-Note: If an attribute name coincides with a name of some helper, you can use the following form: `{{this.attributeName}}`.
+You can specify a document title in the *Title* field (as of v7.0). `{$name}` placeholder is available to substitute an entity name.
### Code view
-A code view mode can be enabled by clicking *>* button. It allows to edit raw HTML and make sure a layout is not messed up.
+A code view mode can be enabled by clicking *\>* button. It allows you to edit raw HTML and make sure the layout is not messed up.
+
+When editing a template in the code view and using template helpers, you need to keep the HTML code valid. Otherwise, the markup will break. Follow the guidelines:
+
+1. Do not mix helpers with table tags such as TR, TD. Use the special *iterate* attribute instead.
+2. Avoid helpers inside tags. Bad: `
`. Good: `
`.
### Charset issues
-If some charecters are not displayed in generated PDF files, it usually can be solved by changing a font in a template. For Arabic language use 'AlArabiya' font, for Chinese – 'CID-0 cs'.
+If some characters are not displayed in generated PDF files, it can be usually solved by changing the font in the template. For the Arabic language, use 'AlArabiya' font, for Chinese, use 'CID-0 cs'.
### Access to templates
-Administrator can add Templates tab at Administration > User Interface. An access to templates must be defined in Roles (*Templates* scope).
+An administrator can add the *Templates* tab under Administration > User Interface. Access to templates must be defined in Roles (the *Templates* scope).
### Page numbering
-Placeholders are only available in footer (and header if it's set to be printed on each page).
+Placeholders are only available in footer (and also header if the header is set to be printed on each page).
* `{pageNumber}` – the current number of the page
-* `{totalPageNumber}` – the total number of record (since 5.7.12)
-* `{pageAbsoluteNumber}` – the absolute number of the page, when printing multiple records
### Page breaking
-To add an explicit page break you need to add (since v5.8.0):
+In places where you need to have an explicit page break, add:
```
{{pagebreak}}
```
-For older verseinos (in code view):
+### Condition checking
+
+#### Conditional rendering attribute x-if
+
+*As of v8.4.*
```
-
+
+
+
+
+
+
+
+
```
-### Condition checking
+Helpers:
+
+* if
+* unless
+* ifEqual
+* ifNotEqual
+* equal
+* notEqual
#### if
@@ -102,7 +154,8 @@ For older verseinos (in code view):
{{#if value}}
{{value}}
{{/if}}
-
+```
+```
{{#if value}}
{{value}}
{{else}}
@@ -110,6 +163,16 @@ For older verseinos (in code view):
{{/if}}
```
+```
+{{#if condition1}}
+
+{{else if condition2}}
+
+{{else}}
+
+{{/if}}
+```
+
#### unless
Opposite to *if*.
@@ -118,7 +181,9 @@ Opposite to *if*.
{{#unless value}}
No value
{{/unless}}
+```
+```
{{#unless value}}
No value
{{else}}
@@ -140,6 +205,30 @@ Opposite to *if*.
Opposite to *ifEqual*.
+#### equal
+
+*As of v8.4.*
+
+Returns boolean.
+
+```
+{{#if (equal status 'Active')}}
+ ...
+{{/if}}
+```
+
+#### notEqual
+
+*As of v8.4.*
+
+Returns boolean.
+
+```
+{{#if (notEqual status 'Active')}}
+ ...
+{{/if}}
+```
+
### Each iterator
Looping through a list of items.
@@ -152,25 +241,42 @@ Example:
{{/each}}
```
-Printing tables:
+Array (list):
+
+```
+{{#each array}}
+ {{this}} – item
+ {{@index}} – index
+{{/each}}
+```
+
+Object (map):
```
-{{tableTag}}
- {{#each contacts}}
- {{trTag}}
- {{tdTag}}{{name}}{{/tdTag}}
- {{tdTag}}{{amount}}{{/tdTag}}
-
- {{/trTag}}
- {{/each}}
-{{/tableTag}}
+{{#each map}}
+ {{this}} – item
+ {{@key}} – key
+{{/each}}
```
-`itemList` is an *jsonArray* field (available in Quote, Sales Order, Invoices entity types).
+!!! important
+
+ Using `
` and `
` tags along with `{{#each}}` helper should be avoided as it breaks the markup of the *contenteditable* element. Use the *iterate* attribute instead.
-Note: Using `
` and `
` tags along with `{{#each}}` helper is not recommended, since it breaks a layout of a *contenteditable* element.
+With *iterate* attribute (as of v8.2):
-Displaying certain number of items in one row (since v5.9.2):
+```html
+
+
+
+
{{name}}
+
{{assignedUserName}}
+
+
+
+```
+
+Displaying certain number of items in one row:
```
{{#each contacts}}
@@ -178,17 +284,77 @@ Displaying certain number of items in one row (since v5.9.2):
{{/each}}
```
-Access parent scope:
+!!! important
+
+ The scope is changed inside an iteration block. To access parent scope attributes, use `../`.
+
+Access the parent scope:
```
{{#each contacts}}
- {{../name}}
+ Root record name: {{../name}}
+ Contact name: {{name}}
{{/each}}
```
-### Images
+### Lookup
+
+You can use this helper to access object's and array's items.
-(this way is available since the version 5.8.0)
+In object (map):
+
+```
+{{lookup map key}}
+```
+
+In an array:
+
+```
+{{lookup teamsIds index}}
+```
+
+Link-multiple example:
+
+```
+
{{lookup ../teamsNames this}}
+```
+
+### Expressions
+
+* `{{object.key}}` – lookup in objects;
+* `{{array.[0]}}` – lookup in arrays;
+* `{{~anyTag}}` – remove all previous spacing;
+* `{{anyTag~}}` – remove all next spacing;
+* `{{{helper}}}` – prevent escaping;
+* `{{helper1 (helper2 arg1 arg2) arg2 arg3}}` – sub-expression passed as an argument;
+
+### Logical expressions
+
+*As of 8.4.*
+
+Helpers:
+
+* and
+* or
+* not
+
+To be used in sub-expressions.
+
+Examples:
+
+```
+{{#if (or (equal status 'Draft') (equal status 'Active'))}}
+ ...
+{{/if}}
+```
+
+```
+{{#if (and value1 value2 value3)}}
+ ...
+{{/if}}
+```
+
+### Images
```
{{imageTag imageFieldNameId width=50 height=50}}
@@ -197,7 +363,7 @@ Access parent scope:
* *imageFieldNameId* is a name of image field, concatenated with *Id*
* *width* and *height* can be omitted
-Another way to print images for older versions. Add in code view:
+Another legacy way to print images:
```
@@ -206,9 +372,7 @@ Another way to print images for older versions. Add in code view:
where `imageFieldNameId` – the name of an image field, concatenated with the suffix *Id*.
-### Date & Time formatting
-
-Available since version 5.8.0.
+### Date & time formatting
See info about [date formatting](../administration/date-formatting.md).
@@ -244,31 +408,57 @@ Specific language:
### Number formatting
-To display float numbers w/o fractional part (as integer) use the following expression:
+To display float numbers without a fractional part (as integer), use the following expression:
+
```
{{numberFormat quantity_RAW decimals=0}}
```
-`quantity` is a field name.
+Where `quantity` is a field name.
Custom formatting for currency values:
+
```
{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
```
Value `10000.5` will be printer as `10 000,50`.
+Note that `_RAW` is appended to the field name.
+
### Currency symbol
+A ready value prepared for all currency fields:
+
```
{{amountCurrencySymbol}}
```
+Using a helper (as of v9.3):
+
+```
+{{currencySymbol 'USD'}}
+```
+
+Example for a currency field named *amount*:
+
+```
+{{currencySymbol amountCurrency}}
+```
+
where `amount` is a field name (of *currency* type).
### Text field
-To display text fields (multi-line) use triple braces: ```{{{description}}}```.
+To display text fields (multi-line) use triple braces:
+
+```{{{description}}}```.
+
+Print Markdown (as of v8.1):
+
+```
+{{markdownText fieldName_RAW}}
+```
### Related records
@@ -276,27 +466,32 @@ To display text fields (multi-line) use triple braces: ```{{{description}}}```.
It's possible to loop through a link collection.
-The max number of records is 100. It can be changed with a config parameter *htmlizerLinkLimit*.
+The maximum number of records is 100. It can be changed with a config parameter *htmlizerLinkLimit*.
-Example, printing contact names and roles of an opportunity:
+!!! example
-```
-{{#each contacts}}
- Name: {{name}},
- Role: {{opportunityRole}},
- Contact's Account Type: {{account.type}}
-{{/each}}
-```
+ Printing contact names and roles of an opportunity:
-where `contacts` is a relationship name. You can obtain relationship names at Administraiton > Entity Manager.
+ ```
+ {{#each contacts}}
+ Name: {{name}},
+ Role: {{opportunityRole}},
+ Contact's Account Type: {{account.type}}
+ {{/each}}
+ ```
-Example, printing contact names of an opportunity:
+ Where *contacts* is a relationship name. You can obtain relationship names at Administration > Entity Manager.
-```
-{{#each contactsIds}}
- {{var this ../contactsNames}}
-{{/each}}
-```
+
+!!! example
+
+ Example, printing contact names of an opportunity:
+
+ ```
+ {{#each contactsIds}}
+ {{var this ../contactsNames}}
+ {{/each}}
+ ```
### Multi-enum & Array fields
@@ -310,8 +505,6 @@ Printing selected items:
### Checklist field
-Available since version 5.8.0.
-
```
Option 1: {{checkboxTag fieldName option='Option 1' color='blue'}}
Option 2: {{checkboxTag fieldName option='Option 2' color='blue'}}
@@ -320,13 +513,15 @@ Option 3: {{checkboxTag fieldName option='Option 3' color='blue'}}
### Barcode field
-Available since version 5.8.0.
-
```
-{{barcodeImage barcodeField type='EAN8' width=60 height=30 fontsize=14 text=true padding=0}}
+{{barcodeImage barcodeField_RAW type='EAN8' width=60 height=30 fontsize=14 text=true padding=0}}
```
-`barcodeField` is a name of your field.
+Where *barcodeField* is the name of your barcode field.
+
+Parameters *fontsize*, *text*, and *padding* are supported only in the TCPDF engine.
+
+(TCPDF only)
Available types:
@@ -344,40 +539,19 @@ Available types:
* pharmacode
* QRcode
-
-### Tables
-
-You can use a regular *table* tag or special *tableTag* helper (available since version 5.8.0). The latter way is preferable when using *{{#each}}* helper inside a table.
-
-The following example prints all account's opportunities in a table format.
-
-In code view:
-
-```
-{{#tableTag width="80%" border="0.5pt" cellpadding="4"}}
-{{#each opportunities}}
-{{#trTag}}
- {{#tdTag width="40%"}}{{name}}{{/tdTag}}
- {{#tdTag width="30%"}}{{assignedUserName}}{{/tdTag}}
- {{#tdTag width="30%" align="right"}}{{stage}}{{/tdTag}}
-{{/trTag}}
-{{/each}}
-{{/tableTag}}
-```
-
-where *trTag* is a table row, *tdTag* is a table cell.
-
### Raw values
-To access a raw value of a specific attribute you need to add `_RAW` to the attribute name. The raw value is not formatted value, timezone is UTC for date-time fields.
+To access a raw value of a specific attribute, you need to add a suffix `_RAW` to the attribute name. The raw value is a not formatted value. Raw date-time values are strings with values in the UTC timezone.
-Example (applying another format to the raw value):
+!!! example
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
+ Example (applying another format to the raw value):
+
+ ```
+ {{numberFormat quantity_RAW decimals=0}}
+ ```
-*quantity* is a field name.
+ *quantity* is a field name.
### Maps
@@ -385,4 +559,8 @@ It's possible to print Google Maps image in PDF. See [here](../administration/ma
### Custom helpers
-See [here](../development/template-custom-helper.md).
+See how to create custom helpers [here](../development/template-custom-helper.md).
+
+Helpers can be useful when the same part is used throughout many templates, for example, a header or footer. Printing of such parts can be delegated to a helper.
+
+Helpers can be also used for data formatting.
diff --git a/docs/user-guide/products.md b/docs/user-guide/products.md
index e9b7b7921..4709d85dc 100644
--- a/docs/user-guide/products.md
+++ b/docs/user-guide/products.md
@@ -1,23 +1,116 @@
# Products
-Products feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/).
+The Products feature is available in the [Sales Pack](https://www.espocrm.com/extensions/sales-pack/) extension.
-Product items can be used with Opportunity, Quotes, Sales Orders and Invoices. They are also available for customization in Entity Manager so you can create new relationships between products and other entities.
+Products can be added as line items in Quotes, Sales Orders, Invoices, Credit Notes, Delivery Orders, Receipt Orders, Purchase Orders, and Opportunities.
-A product record has three price fields: *Cost*, *List* and *Unit*. There is the ability to automatically calculate Unit Price using different formulas according to a selected *Pricing Type*.
+The *Product* entity type is available for customization in the Entity Manager. You can add custom fields to the Product as well as custom relationships between the Product and other entity types.
-The product can be marked as *Tax-free*. It will prevent applying the tax rate upon adding the product to a quote, sales order or invoice.
+A product record has 3 price fields: *Cost*, *List* and *Unit*. The list and unit prices are available only if product-level prices are enabled (in settings). There is the ability to automatically calculate the *Unit Price* using different formulas according to a selected *Pricing Type*. Prices can also be defined in Price Books. Note that it’s possible – and often advisable – to define prices exclusively in Price Books while leaving the list and unit price fields in the product record empty.
-
+Products can be associated with Tax Classes, enabling automated tax application based on defined tax rules. Whenever a product is added to a document, the appropriate tax will be applied to the item.
-Products can be added as line items to a Quote record. Product fields can be printed in PDF. More detail [here](quotes.md#templates).
+With the Inventory Management feature enabled, you can track the availability of each product item. The *Is Inventory* field must be checked in the product record to enable inventory tracking.
-## Opportunity line items
+Products can be printed to PDF. See more detail [here](quotes.md#templates).
-Products can be added as line items to an Opportunity record. By default, this feature is disabled. Administrator needs to add *Item List* field to *Detail* layout of Opportunity in Layout Manager. Make the cell full-width wide using minus icon.
+The ability to add products as line items of an Opportunity is disabled by default. An administrator needs to add the *Items* panel under Administration > Entity Manager > Opportunity > Layouts > Bottom panels.
+
+In this article:
+
+* [Categories](#categories)
+* [Variants](#variants)
+* [Properties](#properties)
## Categories
-Each product record can belong to some product category. Product Categories are presented as a hierarchical tree structure. Each category can have sub-categories.
+Each product can be linked to a category. Categories can be arranged in a hierarchical tree structure, where each category may include subcategories.
+
+The Product Category is a separate entity type. Access to it is controlled by Roles.
+
+
+
+## Variants
+
+*As of Sales Pack v2.0.*
+
+### Product Attributes
+
+Before being able to create products with variants, you need to create some Product Attributes. Product attributes are available under: Products > the top-right menu > Product Attributes.
+
+Every product attribute is supposed to have a specific set of options. Add needed options on the Product Attribute detail view.
+
+Examples of attributes with their options:
+
+* Size – XS, S, M, L, XL
+* Color – Red, Blue, White, Black
+
+### Template Products
+
+A Template Product serves as a root for variants. Product variants inherit properties of its template, some properties can be overridden in variants.
+
+To create a product with variants you need to create a template product. Click **Create Product** from the **Products** page, select *Template* **Type**. Then, in the **Template** tab, add needed attributes. For every attribute, select options needed options. Then **Save** the Product.
+
+After that, you need to generate variants. From the template product detail view, open the **Variants** tab in the bottom, click **Generate**. It will generate all possible combinations according to attributes and options of the product template.
+
+You can remove variants that you don't need. E.g. a Red shirt is not produced in the XS size, hence, you need to remove the XS-Red variant.
+
+You can re-generate variants. It will create all missing combinations.
+
+!!! important
+
+ Once a product variant is references somewhere in the system (e.g. in a sales order), you should not remove that variant. Otherwise, after you re-generate it, it will be a different product record with a different ID.
+
+ For the same reason, it's not recommended to add additional attributes to product templates, variants of which are already referenced.
+
+### Miscellaneous
+
+When you select a template product (e.g. in a Quote), a modal dialog will appear prompting to select a specific variant.
+
+Inventory quantity is tracked on the variant level. When viewing the quantity of a Template product, the sum of all variants will be shown.
+
+An Inventory Number cannot be associated with a Product Template. It should be associated with a specific Variant.
+
+It's possible to specify Product fields that should be **synced** between Template and Variants. Administration > Entity Manager > Products > Edit > Variant sync fields. These fields will be read-only in Variants. Whenever the field value is changed in the Template, it will be automatically copied to the Variants. By default, the *Status* field is selected as synced.
+
+## Properties
+
+A product can marked as Sellable, Purchaable, or Subscribable.
+
+### Item Type
+
+*As of v4.0.*
+
+Two options are available: Goods or Services. If Goods is selected, the product can be used in deliveries, receipts, and transfers, and it allows inventory tracking.
+
+### Allow Fractional Quantity
+
+If enabled, it will be possible to use fractional quantity values for a product.
+
+### Track Inventory
+
+Available if the *Inventory Transactions* feature is enabled in the system. If the *Track Inventory* parameter is disabled in a product, its quantity won't be tracked.
+
+Note: In the earlier versions this parameter was called *Is Inventory*.
+
+### Inventory Number Type
+
+Can be empty, Batch or Serial. See more about inventory numbers [here](../extensions/sales-pack/inventory-management.md#inventory-numbers).
+
+### Removal strategy
+
+Available if *Inventory Number Type* is not empty. Determines how Inventory Numbers will be sorted when a user picks a number for a delivery or transfer order.
+
+Available options:
+
+* FIFO – first in, first out; sorted by *Incoming Date* in ascending order;
+* FEFO – first expired, first out; sorted by *Expiration Date* in ascending order;
+* LIFO – last in, first out; sorted by *Incoming Date* in descending order.
+
+### Expiration Days
+
+Available if *Inventory Number Type* is not empty. A number of days that is automatically added to the current date to determine an *Expiration Date* of an Inventory Number when the number is created in the system. Note that the Expiration Date then can be changed by a user.
+
+### Tax Classes
-Product Category is a separate entity type, hence the access can be controlled by ACL.
+Tax classes allow the system to automatically select an appropriate Tax Code for a product. For example, a product can have a tax class named 'Zero-rated'. A tax item rule will map this tax class to a tax code with a zero rate. Then, every time the product is added to a document line, that tax code will be automatically set.
diff --git a/docs/user-guide/quotes.md b/docs/user-guide/quotes.md
index 2f5aa60c6..0152910fe 100644
--- a/docs/user-guide/quotes.md
+++ b/docs/user-guide/quotes.md
@@ -1,37 +1,37 @@
# Quotes
-Quotes feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/).
+The Quotes feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/).
-Quote is a specific group of products or services with their quantities and prices that you quote to customers.
+A quote is a formal pricing document that outlines specific products or services, along with their quantities and associated prices, offered to a customer.
-Quote has a relationship with Opportunity. You can add `Quotes` panel to Opportunity detail view at Administration > Layout Manager > Opportunities > Relationships. When creating a new quote linked to an opportunity it transfers opportunity items to the quote.
+The Quote entity type has a relationship with Opportunity type. You can add the *Quotes* panel to the Opportunity detail view at Administration > Layout Manager > Opportunities > Bottom Panels. When creating a new quote linked to an opportunity, it transfers opportunity items to the quote.
-You can add Quotes panel to Account's detail view to be able to see related quotes: Administration > Layout Manager > Accounts > Relationships.
+You can add the Quotes panel to the Account detail view to be able to see related quotes: Administration > Layout Manager > Accounts > Bottom Panels.
In the article:
* [Converting from Opportunity](#converting-from-opportunity)
* [Generating Sales Orders and Invoices from Quote](#generating-sales-orders-and-invoices-from-quote)
-* [Total Values Layout](#total-values-layout)
+* [Total values layout](#total-values-layout)
* [Quote Items](#quote-items)
* [Printing to PDF](#printing-to-pdf)
-* [Sending quote in email](#sending-quote-in-email)
+* [Sending in email](#sending-in-email)
* [Automatic numbering](#automatic-numbering)
-* [Default tax](#default-tax)
* [Copying values from product to quote item](#copying-values-from-product-to-quote-item)
+* [Locking](#locking)
* [Automation with Workflows or BPM](#automation-with-workflows-or-bpm)
## Converting from Opportunity
-Method 1. Create a new quote, on the form specify a needed opportunity. Data will be copied from the opportunity to the created quote.
+Method 1. Create a new quote, on the form, specify a needed opportunity. Data will be copied from the opportunity to the created quote.
-Method 2. Create a new quote from Quotes relationship panel on the detail view of the opportunity. Note: Administrator needs to add the panel in layout manager.
+Method 2. Create a new quote from Quotes relationship panel on the detail view of the opportunity. Note: The administrator needs to add the panel in the Layout Manager.
## Generating Sales Orders and Invoices from Quote
-You are able to create Sales Order and Invoice from the existing Quote.
+You are able to create a Sales Order and an Invoice from an existing Quote.
-Method 1. Create a new sales order or invoice, on the form specify the needed quote. Data will be copied from the quote to the created sales order or invoice.
+Method 1. Create a new sales order or invoice, on the form, specify the needed quote. Data will be copied from the quote to the created sales order or invoice.
Method 2. Create a new sales order or invoice from the corresponding relationship panel on Quote detail view.
@@ -41,29 +41,29 @@ The layout of total value fields (in the bottom on detail view) can be modified
## Quote Items
-Quote has a list of items. Each item can represent a certain product or a service with description, quantity, tax rate, list price and unit price fields. It's possible to sort items manually.
+A Quote has a list of items. Each item can represent a certain product or a service with description, quantity, tax rate, list price, and unit price fields. It's possible to sort items manually.
-There is an ability to add custom fields for Quote Item entity using Entity Manager.
+There is the ability to add custom fields for the Quote Item entity type using the Entity Manager.
-### Quote Items Layout
+### Quote Items layout
The layout of quote items can be modified at Administration > Layout Manager > Quote Items > List (Item).
### Discount Rate
-It's possible to specify a discount in percents. To have this ability, administrator should add 'Discount (%)' field to the List (Item) layout.
+It's possible to specify a discount in percents. To have this ability, the administrator should add the *Discount (%)* field to the *List (Item)* layout.
## Printing to PDF
-Quotes can be printed to PDF. This action is available in the dropdown next to Edit button on the quote’s detail view. Then you will be prompted to select Template. More info about printing to PDF is available [here](printing-to-pdf.md).
+Quotes can be printed to PDF. This action is available in the dropdown next to Edit button on the quote’s detail view. Then, you will be prompted to select a Template. More info about printing to PDF is available [here](printing-to-pdf.md).
### Templates
-An example template is available by default. You can create new templates (Quotes list view > top-right dropdown menu > Templates) as well as edit the existing ones.
+An example template is available by default. You can create new templates (Quotes list view > top-right dropdown menu > Templates) as well as edit existing ones.
-For more precise editing, it's recommended to use Code View mode.
+For more precise template editing, you can use the Code View mode.
-You can print fields of Quote record as well as fields of related records by utilizing placeholders in your template.
+You can print fields ofa Quote record as well as fields of related records by utilizing placeholders in your template.
Examples:
@@ -83,10 +83,24 @@ Examples:
`{{product.color}}`.
-The length and color are custom fields of Product entity in examples.
+In examples, the length and color are custom fields of the Product entity type.
Looping through quote items:
+```
+
+
{{order}}
+
{{name}}
+
{{quantity}}
+
{{product.weight}}
+
{{listPrice}}
+
{{unitPrice}}
+
{{amount}}
+
+```
+
+Or:
+
```
{{order}}
@@ -104,29 +118,34 @@ It's possible to print image fields:
```
```
-where `imageId` – the name of custom image field, concatenated with the suffix `Id`.
+
+Where `imageId` – the name of the custom image field concatenated with the suffix `Id`.
For product line item:
+
```
```
-To display float numbers (like quantity, unitPrice etc.) w/o fractional part (as integer), use the following expression:
+To display float numbers (like quantity, unitPrice etc.) without a fractional part (as integer), use the following expression:
+
```
{{numberFormat quantity_RAW decimals=0}}
```
-Custom formatting for currency values (since version 4.8.3):
+Custom formatting for currency values:
+
```
{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
```
+
Value `10000.5` will be printer as `10 000,50`.
To display text fields (multiline), use triple braces: `{{{description}}}`.
#### Quote Items attributes
-You can use these attributes in a template inside the loop `{{#each itemList}}`:
+You can use these attributes in a template inside the loop `{{#each itemList}}` or `
`:
* name
* quantity
@@ -142,31 +161,36 @@ You can use these attributes in a template inside the loop `{{#each itemList}}`:
All fields can be found at Administration > Entity Manager > Quote Items > Fields.
+## Sending in email
+
+A Quote PDF can be sent in an email as an attachment. Open a quote record, click the dropdown next to Edit button, and then click Email PDF.
-## Sending quote in email
+The default email template can be set by the administrator: Administration > Sales Pack Settings > Email Templates.
-Quote PDF can be send in email as an attachment. Open a quote record, click the dropdown next to Edit button and then click Email PDF.
+To have the Quote entity selected as the email's parent, the administrator should add the Quote entity type to the parent type list. Administration > Entity Manager > Email > Fields > Parent > Entity List. As of v3.0.
## Automatic numbering
-By default, a number field is auto-incremented. You can disable auto-increment at Administration > Entity Manager > Quote > Fields > number. It's also possible to make the number field read-only.
+By default, the *Number* field is auto-incremented. You can disable auto-increment at Administration > Entity Manager > Quote > Fields > number. It's also possible to make the number field read-only.
The prefix of the next number, the next number itself and the quantity of digits in the number can be configured at Administration > Entity Manager > Quote > Fields > numberA.
-## Default tax
+By default, there is no *Name* field on the *Detail* layout. The *Number* is used as a name. You can add the Number field at Administration > Entity Manager > Quote > Layouts > Detail.
-You need to have a Tax record created in your CRM. Taxes can be accessed at Quotes list view > dropdown in the top-right corner > Taxes.
-
-Administrator can specify a default Tax record at Administration > Entity Manager > Quote > fields > Tax > Default.
-
-Note: For older versions of Sales Pack & EspoCRM, you need also to specify the default tax rate value at Administration > Entity Manager > Quote > fields > Tax Rate > Default.
+By default, the *Name* field is synced with *Number*. To be able to specify arbitrary names, you need to disable the *Sync with Number* and *Read-only* parameters at Administration > Entity Manager > Quote > Fields > Name.
## Copying values from product to quote item
-Field values can be transferred from a product to a quote item upon product selection. Field names you want to be copied should coincide in Product and Quote Item enities.
+Field values can be transferred from a product to a quote item upon product selection. Field names you want to be copied should coincide in Product and Quote Item entity type.
You can select which fields you need to be copied at Administration > Entity Manager > Quote Item > Fields > Product > Fields to Copy.
+## Locking
+
+A Quote can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Quote > Edit.
+
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
+
## Automation with Workflows or BPM
The following service actions are available in Workflows and BPM tools:
diff --git a/docs/user-guide/reports.md b/docs/user-guide/reports.md
index f1a9665ba..378ff1038 100644
--- a/docs/user-guide/reports.md
+++ b/docs/user-guide/reports.md
@@ -1,114 +1,168 @@
+---
+search:
+ boost: 2
+---
+
# Reports
-Reports feature is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
+The Reports feature is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/). It provides the analytic capabilities and two additional functionalities: report panels and custom list view filters.
+
+There are three types of reports:
-There are two types of reports: List and Grid.
+* List
+* Grid
+* Joint Grid
In this article:
* [List reports](#list-reports)
* [Grid reports](#grid-reports)
* [Joint Grid reports](#joint-grid-reports)
-* [Filters](#filters_1)
+* [Filters](#filters)
* [Displaying on dashboard](#displaying-on-dashboard)
* [Email sending](#email-sending)
* [Printing to PDF](#printing-to-pdf)
* [Syncing with Target Lists](#syncing-with-target-lists)
* [List view filters based on reports](#report-filters)
* [Reports panels](#report-panels)
+* [Portal access](#portal-access)
+* [Formula functions](#formula-functions)
See also:
* [Complex expressions](complex-expressions.md)
+* [Quick tour](https://app.supademo.com/demo/cmca8j4uc1gy18qszrhdt68jy)
## List Reports
-List report displays the list of records that meet the specified criteria.
+A List report displays the list of records that meet the specified criteria.
-To create a new list report, click on *Reports* tab and then click *Create Report* button. Choose needed Entity Type, then click *Create* button at *List Report* section.
+To create a new list report, click on the *Reports* tab and then click the *Create Report* button. Then, select the entity type to which your report will apply.
-At *Columns* field, pick the fields you would like to be displayed. Below, you can specify display parameters for every column:
+In the *Columns* field, select the fields you would like to have displayed in the report. Underneath, you can configure how each column is displayed with the following parameters:
* Width – width in percents;
-* Align – left or right;
-* Link – a value will be displayed as a link leading to the record detail view;
-* Export Only – a column won't be displayed in report results on UI, but it will be available in export;
-* Not Sortable – a column cannot be ordered by, some fields are not available for sorting.
+* Align – how to align data: left or right;
+* Link – value will be displayed as a link leading to the record detail view;
+* Export Only – the column won't be displayed in report results on the UI, but it will be available in export;
+* Not Sortable – the column cannot be ordered by, some fields are not available for sorting;
+* Hidden – the column will be hidden but can be optionally shown in the report result view.
-Choose the needed sorting at *List Order* field.
+Choose the needed sorting in the *List Order* field.
-At _Filters_ section, you can specify criteria that determines what records will be listed in your report. You can use logical operators 'OR' and 'AND' here.
+In the *Filters* section, you can specify criteria that determine what records will be included in your report. You can use logical operators 'OR' and 'AND' here.
-*Runtime Filters* allow you to specify different filters before you run the report.
+*Runtime Filters* lets you narrow down the results each time you run the report, without needing to edit the report itself. It's useful when the report structure stays the same, but you want to change the criteria dynamically – like choosing a specific date range, customer, or status before generating the results.
-You can **export** list report results to XLSX (Excel) and CSV formats.
+You can *export* list report results to XLSX (spreadsheet) and CSV formats.
-The example of list report results:
+An example of list report results:

-Additional features where list reports can be utilized:
+Where list reports can be also utilized:
* Scheduled workflows – to do some scheduled actions over records that met criteria specified by a list report.
* Scheduled BPM processes – to start BPM processes for records that met some criteria.
-* Sync with target lists – to add records that met some criteria to target lists, more info [below](#syncing-with-target-lists).
+* Sync with target lists – to add records that met some criteria to target lists, more info [below](#syncing-with-target-lists).
* List view filters – to filter records on the list view according to the criteria specified in the list report, more info [below](#report-filters).
* Panels on the detail view – to display related records that met some criteria on the side panel, more info [below](#report-panels).
* Applying assignment rule – to assign records that met specific criteria by workflow or BPM.
+### Results view
+
+The results view can be accessed under: Report detail view > Results View button (top-right corner). Here, the report is displayed in full width. You can show or hide specific columns as well as resize them.
## Grid Reports
-Grid reports show summarized values, can be grouped by one or two fields and displayed as a chart.
+Grid reports display summarized values, can be grouped by one or two fields, and support chart visualization.
+
+To create a new grid report, click on the *Reports* tab and then click the *Create Report* button. Then, select the entity type to which your report will apply.
-To create a new grid report, click on *Reports* tab and then click *Create Report* button. Choose needed Entity Type, then click *Create* button at *Grid Report* section.
+When choosing the *Entity Type* for a grid report, consider the following. The *Entity Type* should contain the field that data will be aggregated by. For example, if you need to sum by the opportunity amount, choose the Opportunity entity type. If you need to aggregate by fields from different entity types, consider creating separate grid reports for each entity type and then use a Joint Report to join them into one.
-The example of grid report results that shows revenue grouped by User:
+An example of grid report results showing revenue grouped by a user:

+!!! tip
+
+ When dealing with long tables with many columns, you can use Shift + Mouse Wheel to scroll horizontally. It can also be helpful to use the Result View, which displays the report data in full width.
+
### Group By
-At *Group By* field, pick one or two fields you want your report data be grouped by. It's possible to apply grouping by year, month, week, and day for date fields. If you group by two fields your report will be considered as three-dimensional.
+In the *Group By* field, pick one or two fields you want your report data be grouped by. For date fields, it's possible to apply grouping by year, quarter, month, week, and day. If you leave the Group By field empty, the report will not apply any grouping.
-You can leave *Group By* field empty.
+There is the ability to craft a [complex expression](complex-expressions.md) for grouping. Complex expressions are internally translated into SQL statements. Complex expressions offer various use cases. For instance, the MAP function can be used to group data by region rather than by country.
-There is the ability to specify a custom complex expression (with functions) for grouping. The complex expression is translated into SQL statement. More info about complex expressions is available [here](complex-expressions.md).
+Example:
+
+```
+MAP:(
+ account.billingAddressCountry,
+ 'United States', 'United States',
+ 'Germany', 'Europe',
+ 'France', 'Europe',
+ 'Italy', 'Europe',
+ 'Other'
+)
+```
+
+A report grouped by two fields is called *two-dimensional*.
+
+The results table for two-dimensional Grid reports can be displayed in two modes:
+
+- Regular – columns represent the first grouping field, and rows represent the second grouping field.
+- Normalized – unpivoted (flattened), with both grouping fields displayed in rows.
### Columns
-At *Columns* field, select one or more aggregate functions applied to a specific field.
+In the *Columns* field, select one or more **aggregate** functions applied to a specific field.
Functions:
* COUNT – number of records;
* SUM – summation, applied to Currency, Int and Float fields;
-* MIN – mimimal value;
+* MIN – minimal value;
* MAX – maximal value;
* AVG – average value.
-If the report is grouped by a link field then it's possible to add fields from the linked record w/o aggregate functions. The example is the report for Opportunities grouped by Campaign with Campaign.Budget column.
+If a report is grouped by a link field, then it's possible to include fields from the linked record without an aggregate function applied to it. In the example below, the report for Opportunities with grouping by Campaign with Campaign.Budget column included.
+
+It's possible to add **non-aggregated columns**. In this case, records will be displayed for each group. Note that if your report deals with a big number of records, it can run much slower.
+
+Non-grouping grid report with non-aggregated columns:
+
+
+
+Grouping grid report with non-aggregated columns:
+
+
+
+There is the ability to craft [complex expressions](complex-expressions.md) for columns. Complex expressions are internally translated into SQL statements.
### Order by
-*Order by* field defines how report data will be sorted.
+The *Order By* field defines how the report results will be sorted.
-### Filters
+### Filters section
-At *Filters* section, you can specify criteria to limit data displayed in the report results. You can use logical operators 'OR' and 'AND' here. More info [below](#filters_1).
+In the *Filters* section, you can specify criteria to limit data displayed in the report results. You can use logical operators 'OR' and 'AND' here. See more info [below](#filters).
-### Runtime Filters
+### Runtime filters
-*Runtime Filters* allow you to specify different filters before you run the report.
+*Runtime Filters* lets you narrow down the results each time you run the report, without needing to edit the report itself.
-Note: Specifying the runtime filter can be also useful for dashlets and report panels.
+!!! note
+
+ Specifying a runtime filter can be also useful for dashlets and report panels. It allows you to have filters applied to a particular dashlet or panel.
### Charts
-Grid report allows displaying results in a chart form.
+Grid report allows displaying results in chart form.
-There are following chart types available:
+There are the following chart types available:
* Bar (Horizontal);
* Bar (Vertical);
@@ -135,31 +189,45 @@ Pie:
### Export
-It's possible to export grid report results to XLSX (Excel) and CSV formats. Charts are exported to XLSX.
+It's possible to export grid report results to XLSX (spreadsheet) and CSV formats. Both a results table and chart are exported to XLSX.
+
+!!! important
+
+ If a Grid report contains non-aggregated columns, the chart is not printed on the spreadsheet.
+
+### Access
+
+By checking *Apply access control*, the report result will not include records that the current user does not have access to.
+
+If a regular user does not have edit access to the *Apply access control* field (via field level security in Roles), all reports they create will have the *Apply access control* automatically checked.
## Joint Grid reports
-Available since Advanced Pack v2.2.0.
+Joint Grid reports combine multiple Grid reports. A combined report can bring together data from reports that target different entity types.
+
+Grid reports selected for a Joint report must use either one grouping field or none.
-Joint Grid reports combine multiple grid reports of different entity types. Sub-reports must be grouped by 1 or 0 fields.
+If you need to aggregate by fields from different entity types, consider creating separate Grid reports for each entity type and then use the Joint report type to combine them into one.
Some usage examples:
* Lead count / Contact count;
* Revenue by month / Campaign Budget by month;
-* Revenu by user / Lead count by User.
+* Revenue by user / Lead count by User.
-You can create a new Joint Grid report from the dropdown menu in the top-right corner on the Reports list view.
+You can create a new Joint Grid report from the dropdown menu in the top-right corner in the Reports list view.
-Runtime filters are not supported in joint reports. Only regular filters (specified in each sub-report) can be used.
+Colors of chart columns are determined by chart colors set in the respective sub-reports.
-For charts, colors of columns must be specified in sub-reports.
+Runtime filters are not supported in Joint reports. Only regular filters specified in each sub-report can be used.
+
+Non-aggregate columns are not supported in Joint reports.
## Filters
### Field filter
-Field filters are simple to use. They allow to filter by specific fields of a target entity type as well as fields of related records. E.g. you can filter Opportunities by a field of Account entity type.
+Field filters are simple to use. They allow to filter by specific fields of a target entity type as well as fields of related records. For example, you can filter Opportunities by a field of the Account entity type.

@@ -177,14 +245,14 @@ AND means that all conditions in the group must be met.
NOT IN provides the ability to filter records that don't meet specified criteria. E.g. listing accounts that don't have any opportunity with 'Closed Won' or 'Closed Lost' status.
-Note: It's recommended to avoid using NOT IN group when possible, by using filters 'Not Equals', 'None of', etc. instead. NOT IN group uses a sub-query that can negatively affect a report performance in some cases.
+!!! note
+
+ It's recommended to avoid using NOT IN group when possible, by using filters 'Not Equals', 'None of', etc. instead. NOT IN group uses a sub-query that can negatively affect report performance in some cases.

### IN group
-Note: Available in since EspoCRM v5.6.0 and Advanced Pack v2.1.0.
-
IN is similar to AND group but utilizes a sub-query.
The example of usage: Filtering accounts that have opportunities of both 'Closed Won' and 'Negotiation' stages.
@@ -193,30 +261,47 @@ The example of usage: Filtering accounts that have opportunities of both 'Closed
### Complex Expression
-For more advanced use. You can apply function for certain database column and compare it with the result of [formula](../administration/formula.md) expression.
+For more advanced use. You can apply a database function to a certain database column and compare it with a result calculated by a [formula](../administration/formula.md) expression.
-Note: If you need to compare just with a simple string value you should put it into single quotes `'some string'`.
+!!! note
-Note: Functions intended to interact with the entity record will not work here because the formula is not applied to a specific record.
+ If you need to compare just with a simple string value you should put it into single quotes `'some string'`.
-Applying function to attribute and comparing with the result of formula:
+!!! note
+
+ Formula functions intended to interact with the entity record will not work here because the formula is not applied to a specific record.
+
+Applying function to a column and comparing with a result of formula:

-Comparing the result of custom complex expression & the result of formula:
+Comparing the result of the custom complex expression and the result of the formula expression:

-
-* Complex expression is translated into SQL statement and becomes a part of SQL query.
-* Formula is executed by PHP and the result value is substituted into SQL query.
-* Comparison operator is substituted into SQL query between complex expression statement and formula result value.
+* Complex expression is translated into an SQL statement and becomes a part of an SQL query.
+* Formula is executed before running the report and the result value is substituted into an SQL query.
+* Comparison operator is substituted into an SQL query between the complex expression statement and the formula result value.
More info about complex expressions is available [here](complex-expressions.md).
+!!! example
+
+ Filter record that were created after less than 12 month from the creation of a related account. For example, it can be used to show sales only from new customers.
+
+ ```
+ LESS_THAN:(
+ TIMESTAMPDIFF_MONTH:(
+ account.createdAt,
+ createdAt
+ ),
+ 12
+ )
+ ```
+
### Having group
-Having group provides an ability to filter records with using aggregate functions COUNT, SUM, MAX, MIN, AVG.
+The Having group provides the ability to filter records with using aggregate functions COUNT, SUM, MAX, MIN, AVG.
Some use cases:
@@ -225,29 +310,43 @@ Some use cases:
## Displaying on dashboard
-You can display any report on dashboard. In order to do it, you need to add Report dashlet and then pick the needed report at the dashlet options.
+You can display any report on the dashboard. In order to do it, you need to add the Report dashlet to the dashboard and then pick the needed report from the dashlet options.
+
+For grid reports it's possible to display:
+
+* Chart
+* Chart & Total
+* Total
+* Table
-Grid reports can be displayed as a chart, a chart with totals or only totals.
+For list reports it's possible to display:
-List reports can be displayed as a list or a total number of records.
+* List
+* Total (number or records)
+
+For list reports, you can either display the list or records or only the total number of records.
+
+Dashlet with only totals displayed:
+
+
## Email sending
-It's possible to make the system send report results to certain users on a regular basis according to specified time. This must be configured for certain reports individually.
+It's possible to set up the system send report results to certain users on a regular basis according to specified time. This must be configured for certain reports individually.
-The Max number of records that can be sent in an email by default is 3000. You can increase it by adding a parameter to data/config.php: `'reportSendingListMaxCount' => 5000`.
+The Max number of records that can be sent in an email by default is set to 3000. You can increase it by adding the parameter to data/config.php: `'reportSendingListMaxCount' => 5000`.
## Printing to PDF
-Available since Advanced Pack v2.5.0, compatible with EspoCRM v5.8.0 and later.
+!!! note
-Note: A user needs to have access to *Template* scope (set in Roles).
+ A user needs to have access to the *Template* scope in Roles.
-Note: You need to have at least one PDF Template for Report entity type. The template can be created at Administration > PDF Templates.
+ You need to have at least one PDF Template record for the Report entity type. The template can be created at Administration > PDF Templates.
-To print a report: on the report detail view on *Report* panel, from the dropdown next to *Edit* button, click *Print to PDF*.
+To print a Report: on the Report detail view on the *Report* panel, from the dropdown next to the *Edit* button, click *Print to PDF*.
-In PDF table, `{{reportTable}}` is used to print a report results table.
+In a PDF template, `{{reportTable}}` helper is used to print a report results table.
Example:
@@ -262,36 +361,83 @@ Available attributes:
* cellpadding;
* fontSize;
* color – a text color;
-* flip – to flip table, true or false.
+* flip – to flip table, true or false;
+* width – a table width, a CSS parameter (as of v3.1).
## Syncing with Target Lists
-It's possible to have target lists synced with list report results. It's convenient for mass email when you would like to send emails only to contacts that meet some criteria at the moment of sending. This feature is available on the detail view of any target list at *Sync with Reports* panel.
+It's possible to have target lists synced with list report results. It's convenient for mass email when you would like to send emails only to contacts that meet some criteria at the moment of sending. This feature is available in the detail view of any target list in the *Sync with Reports* panel.
+
+## Report filters
+
+The Report Filters feature allows you to create custom primary filters for list views. These filters can also be used in specific formula functions.
+
+An administrator can create custom list view filters based on specific reports. Available under: Administration > Report Filters. It's possible to specify teams that will have access to the filter.
+
+!!! note
-## Report Filters
+ The layout, that is specified in the report, is not applied to the list view when the filter is selected.
-Report Filters are the list view filters based on reports.
+
-Administrator can create custom list view filters based on specific reports. Available at: Administration > Report Filters. It's possible to specify teams that will have access to the filter.
+Report filters can utilized in *Record List* dashlets (as a primary filter).
-Note: The layout, that is specified in the report, is not applied to the list view when the filter is selected.
+Report filters can be utilized in [formula functions](../administration/formula.md#filter):
-## Report Panels
+* `record\count`
+* `record\findOne`
+* `record\findRelatedOne`
+* `record\findRelatedMany`
+* `entity\sumRelated`
+* `entity\countRelated`
-Report Panels are the detail view panels showing report results.
+## Report panels
-Administrator can create custom side and bottom panels for the detail view of the specific entity type. It's possible to specify teams that will have access to the panel.
+The Report Panels feature allows you to create custom detail view panels that display report results.
+
+An administrator can create custom side and bottom panels for the detail view of the specific entity type. It's possible to specify teams that will have access to the panel.
Both Grid and List reports can be used.
-It's possible to display only total amount on the report panel.
+For grid reports it's possible to display:
+
+* Chart
+* Chart & Total
+* Total
+* Table (as of v2.7.0)
+
+For list reports it's possible to display:
+
+* List
+* Total (number or records)
+
+The order of side panels can be customized under: Administration > Entity Manager > {Entity Type} > Layouts > Side Panels (Detail).
+
+The order of bottom panels can be customized under: Administration > Entity Manager > {Entity Type} > Layouts > Bottom Panels.
+
+The report panel displays results related to the record that is viewed. The first found relationship is used. If a report has an appropriate runtime filter, then it will be used to filter report results. The runtime filter must be a field of a Link, Link-multiple or Link-parent type. "For example, if a report is for Opportunity and has a runtime filter Account, that filter will be automatically applied when the report panel is added to the Account detail view.
+
+## Portal access
+
+Specific reports can be allowed for specific portals. For this, you need to add the portal in the *Portals* field of the Report. The Portal Role assigned to the portal should have defined access to the *Reports* scope with the *Read* action set to *all*.
+
+It's possible to add a report dashlet to the portal dashboard.
+
+!!! note
+
+ For grid reports which are meant be available in the portal, it's usually reasonable to enable [Apply ACL](#access).
+
+## Formula functions
+
+### report\export
-The order of side panels can be customized at Layout Manager > Side Panels (Detail).
+`report\export(REPORT_ID, [USER_ID])`
-The order of side panels can be customized at Layout Manager > Bottom Panels (since v5.9.0).
+*As of v3.6.*
-The report panel shows results related to the record that is viewed. The first found relationship is used. If the report has an appropriate runtime filter, then it will be used to restrict results. The runtime filter must be a field of link, link-multiple or link-parent type.
+Generates an XLSX export file and returns an attachment ID. An optional USER_ID allows you to apply access restrictions for a specific user. Note that generated attachments have the role `Export File`, hence they will be automatically deleted by the cleanup job. To prevent deletion, you can change the role to `Attachment`.
## See also
* [Complex expressions](complex-expressions.md)
+* [Billing transactions](https://www.espocrm.com/blog/tutorial-billing-transactions/)
diff --git a/docs/user-guide/sales-management.md b/docs/user-guide/sales-management.md
index 6a01f29c4..dbc172b4d 100644
--- a/docs/user-guide/sales-management.md
+++ b/docs/user-guide/sales-management.md
@@ -4,36 +4,52 @@ In this article:
* [Leads](#leads)
* [Opportunities](#opportunities)
+* [Accounts](#accounts)
* [Currency](#currency)
* [Sales analytics](#sales-analytics)
+* [See also](#see-also)
## Leads
-A Lead represents a person or organization that currently is not a customer, but has a potential to be. Creating a new lead record usually is a first step of the sale process. As more information about the lead is gathered it's supposed that lead will be converted into a Account, Contact and Opportunity.
+A Lead represents a person or organization that is not currently a customer but has the potential to be. Creating a new Lead record is usually the first step in the sale process. As more information about the Lead is gathered, the Lead is expected to be converted into an Account, Contact, and/or Opportunity.
-New leads are supposed to be created by the following scenarios:
+New Leads are typically created in the following scenarios:
-* Manually by CRM users;
-* Through the API (e.g. through the web form);
-* Automatically by a Workflow rule.
+* manually by CRM users;
+* through the API (e.g. through a web form);
+* automatically by a Workflow rule.
-By utilizing [Workflows](../administration/workflows.md) administrator can set up the system to apply a specific assignment rule to new leads, i.e. *Round-Robin* and *Least-Busy* rules. For more complex business flows it's recommended to utilize [BPM tool](../administration/bpm.md).
+By utilizing the [Workflows](../administration/workflows.md) tool, an administrator can set up the system to apply a specific assignment rule to new Leads. *Round-Robin* and *Least-Busy* rules are available. For more complex business flows, it's recommended to utilize the [BPM tool](../administration/bpm.md).
-To prevent overlooking of new leads, users can add *Lead* entity type to the *Global Auto-follow* list at Preferences. Then they will automatically follow every new lead.
+Users can also create a Lead from an Email – from the top-right dropdown menu.
+
+To prevent overlooking of new Leads, users can add the *Lead* entity type to the *Global Auto-follow* list in Preferences. Then, they will automatically follow every new Lead created in the system they have access to.
+
+It may be useful to enable the Kanban view for Leads. It can be enabled under: Administration > Entity Manager > Lead > Edit > Kanban View.
+
+Leads can be added to Target Lists, which is useful for marketing purposes
### Converting
-To convert the lead, you need to click *Convert* button on the lead detail view. Then you can check to what record types you want to convert: Account, Contact, Opportunity.
+To convert a Lead, you need to click *Convert* button on the Lead detail view. Then, you can check to what record types you want to convert: Account, Contact, and/or Opportunity.
+
+A converted Lead won't be removed from the system. It will have status *Converted*, records it was converted to, will be available in the *Converted To* panel on the right.
-Converted lead won't be removed from the system. It will have status *Converted*, records it was converted to, will be available on *Converted To* panel on the right.
+Note that Leads cannot be converted to Accounts if the system is set to the B2C mode.
## Opportunities
-An opportunity represents a potential or closed deal. Opportunity with *Closed Won* stage are taken into account in sales revenue calculation (dashlets & reports).
+An Opportunity represents a potential deal or closed sale.
+
+!!! note
+
+ Opportunities with the *Closed Won* stage are taken into account in the default sales dashlets. Using Opportunities to calculate revenue is an option that may be suitable for small businesses.
+
+For Opportunities, the Kanban view is enabled by default. Users can switch between the List and Kanban views.
### Stage
-Following opportunity stages are available by default:
+The following opportunity stages are available by default:
* Prospecting
* Qualification
@@ -42,19 +58,38 @@ Following opportunity stages are available by default:
* Closed Won
* Closed Lost
-Administrator can define custom stages depending on business flow of the company: Administration > Entity Manager > Opportunity > Fields > Stage. It's also possible to define custom probabilities for each stage.
+An administrator can define custom stages depending on the business workflow of the company: Administration > Entity Manager > Opportunity > Fields > Stage. It's also possible to define custom probability values for each stage.
### Probability
-Opportunity probability is an estimated percentage chance that the sale will be won. *Closed Won* status has 100% probability, *Closed Lost* – zero. Other stages has their default probabilities. Probabilities can be utilized in revenue forecasting.
+The Opportunity probability is an estimated percentage chance that the sale will be won. The *Closed Won* status has a 100% probability, the *Closed Lost* – zero. Other stages has their specific probabilities between 0% and 100%. The probabilities can be modified in the Entity Manager.
+
+!!! note
+
+ Probabilities can be utilized in revenue forecasting.
+
+## Accounts
+
+Accounts play a central role in EspoCRM. They represent companies and organizations your business works with.
+
+An Account has relationships with the following records:
+
+- Contacts
+- Opportunities
+- Cases
+- Documents
+
+Users can subscribe to a particular Account record to see updates that concern that Account.
+
+Account records can be added to Target Lists, which you can use for marketing purposes or for organizing your data.
## Currency
-Administrator can define available currencies and their rates at Administration > Currency.
+An administrator can define available currencies and their rates at Administration > Currency.
-It's possible to convert currency of existing opportunities:
+It's possible to convert currency of existing Opportunities:
-* on the list view: select needed records and then click *Convert Currency* in the *Actions* dropdown,
+* on the list view: select needed records and then click *Convert Currency* in the *Actions* dropdown;
* on the detail view: click the dropdown next to the *Edit* button, then *Convert Currency*.
## Sales analytics
@@ -66,11 +101,11 @@ The following charts are available on the dashboard by default:
* Opportunities by Stage
* Sales Pipeline
-By utilizing [Reports tool](reports.md) it's possible to view sales statistics based on specific criteria. Report charts can be displayed on the dashboard.
+By utilizing the [Reports tool](reports.md), it's possible to view sales statistics based on specific criteria. Report charts can be displayed on the dashboard.
### Revenue forecast
-Available with Reports from Adavanced Pack.
+Available with Reports from Advanced Pack.
1. Create a new grid report for Opportunity entity type.
2. Add 'MONTH: Close Date' to Group By field.
@@ -78,10 +113,13 @@ Available with Reports from Adavanced Pack.
4. Add 'Close Date' to Runtime Filters field.
5. Select 'Bar (vertical)' chart type.
-This report will show revenue forecast based on probabilities of opportunities.
+This report will show the revenue forecast based on probabilities of Opportunities.
-Users, who have an access to this report, will be able to add it on their dashboards.
+Users who have access to this report will be able to add it on their dashboards.
## See also
+* [Quick tour on Leads](https://app.supademo.com/demo/cmhc0w8ns14v6fatilwlycmjn)
+* [Quick tour on Opportunities](https://app.supademo.com/demo/cmhkj43rn1k3xu1hm0zxfmhb6)
+* [Quick tour on Accounts](https://app.supademo.com/demo/cmhxas59c35xb17y0s8mr6co6)
* [Who are leads? Lead conversion in 3 steps](https://www.espocrm.com/tips/lead-conversion/)
diff --git a/docs/user-guide/sales-orders.md b/docs/user-guide/sales-orders.md
index 7285e9b7d..f2d311f8a 100644
--- a/docs/user-guide/sales-orders.md
+++ b/docs/user-guide/sales-orders.md
@@ -1,12 +1,12 @@
# Sales Orders
-Sales Orders feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/) extension.
+The Sales Orders feature is available in [Sales Pack](https://www.espocrm.com/extensions/sales-pack/) extension.
-Sales Order represents a group of products or services with their quantities and prices.
+A Sales Order is a document representing a confirmed customer order, and contains a group of products or services with their quantities and prices.
-You can add Sales Orders panel to Account detail view to be able to see related sales orders. Administration > Layout Manager > Accounts > Relationships.
+You can add the Sales Orders panel to the Account detail view to be able to see related sales orders. At Administration > Layout Manager > Accounts > Bottom Panels.
-You can add Sales Orders panel to Opportunity detail view at Administration > Layout Manager > Opportunities > Relationships.
+You can add the Sales Orders panel to the Opportunity detail view at Administration > Layout Manager > Opportunities > Bottom Panels.
In the article:
@@ -14,26 +14,27 @@ In the article:
* [Generating Invoices from Sales Order](#generating-invoices-from-sales-order)
* [Total Values Layout](#total-values-layout)
* [Sales Order Items](#sales-order-items)
+* [Delivery](#delivery)
* [Printing to PDF](#printing-to-pdf)
-* [Sending sales order in email](#sending-sales-order-in-email)
+* [Sending in email](#sending-in-email)
* [Automatic numbering](#automatic-numbering)
-* [Default tax](#default-tax)
* [Copying values from product to sales order item](#copying-values-from-product-to-sales-order-item)
+* [Locking](#locking)
* [Automation with Workflows or BPM](#automation-with-workflows-or-bpm)
## Converting from Opportunity or Quote
-Method 1. Create a new sales order, on the form specify needed opportunity or quote. Data will be copied from the opportunity/quote to the created sales order.
+Method 1. Create a new sales order. On the form, select an opportunity or a quote. Data will be copied from the opportunity/quote to the created sales order.
-Method 2. Create a new sales order from Sales Orders relationship panel on the detail view of the opportunity/quote.
+Method 2. Create a new sales order from the Sales Orders relationship panel on the detail view of the opportunity/quote.
## Generating Invoices from Sales Order
-You are able to create Invoices from the existing Sales Order record.
+You are able to create Invoices from an existing Sales Order record.
-Method 1. Create a new invoice, on the form specify a needed sales order. Data will be copied from the sales order to the created invoice.
+Method 1. Create a new invoice. On the form, select a needed sales order. Data will be copied from the sales order to the created invoice.
-Method 2. Create a new invoice from Invoices relationship panel on the detail view of the sales order record.
+Method 2. Create a new invoice from the Invoices relationship panel on the detail view of the sales order record.
## Total Values Layout
@@ -41,56 +42,66 @@ The layout of total value fields (in the bottom on detail view) can be modified
## Sales Order Items
-Sales Order has a list of items. Each item can represent a certain product or a service with description, quantity, tax rate, list price and unit price fields. It's possible to sort items manually.
+A Sales Order has the list of items. Each item can represent a certain product or a service with description, quantity, tax rate, list price, and unit price fields. It's possible to sort items manually.
-There is an ability to add custom fields for Sales Order Item entity using Entity Manager.
+There is the ability to add custom fields to the Sales Order Item entity type using the Entity Manager.
### Sales Order Items Layout
-The layout of sales order items can be modified at Administration > Layout Manager > Sales Order Items > List (Item).
+The layout of Sales Order Items can be modified at Administration > Layout Manager > Sales Order Items > List (Item).
### Discount Rate
-It's possible to specify a discount in percents. To have this ability, administrator should add 'Discount (%)' field to the List (Item) layout.
+It's possible to specify a discount in percents. To have this ability, an administrator should add the *Discount (%)* field to the *List (Item)* layout.
+
+## Delivery
+
+A Delivery Order can be created from a Sales Order. A button in the top-right corner will appear when the Sales Order is eligible for delivery. The Sales Order must have at least one Product of *Goods* product type to have the ability to create a delivery.
## Printing to PDF
-Sales Orders can be printed to PDF. This action is available in the dropdown next to Edit button on the sales order’s detail view. Then, you will be prompted to select a template. More info about printing to PDF is available [here](printing-to-pdf.md).
+Sales Orders can be printed to PDF. This action is available in the dropdown next to the Edit button on the sales order’s detail view. Then, you will be prompted to select a template. More info about printing to PDF is available [here](printing-to-pdf.md).
### Templates
See the documentation [for quote templates](quotes.md#templates).
-## Sending sales order in email
+## Sending in email
+
+A Sales Order PDF can be send in an email as an attachment. Open a sales order record, click the dropdown next to the Edit button and then click Email PDF.
+
+The default email template can be set by the administrator: Administration > Sales Pack Settings > Email Templates.
-Sales Order PDF can be send in email as an attachment. Open a sales order record, click the dropdown next to Edit button and then click Email PDF.
+To have the Sales Order entity selected as the email's parent, the administrator should add the Sales Order entity type to the parent type list. Administration > Entity Manager > Email > Fields > Parent > Entity List. As of v3.0.
## Automatic numbering
-By default a number field is auto-incremented. You can disable auto-increment at Administration > Entity Manager > Sales Order > Fields > number. It's also possible to make the number field read-only.
+By default, the *Number* field is auto-incremented. You can disable auto-increment at Administration > Entity Manager > Sales Order > Fields > number. It's also possible to make the number field read-only.
The prefix of the next number, the next number itself and the quantity of digits in the number can be configured at Administration > Entity Manager > Sales Order > Fields > numberA.
-## Default tax
+By default, there is no *Name* field on the *Detail* layout. The *Number* is used as a name. You can add the Number field at Administration > Entity Manager > Sales Order > Layouts > Detail.
-You need to have a Tax record created in your CRM. Taxes can be accessed at Quotes list view > dropdown in the top-right corner > Taxes.
+By default, the *Name* field is synced with *Number*. To be able to specify arbitrary names, you need to disable the *Sync with Number* and *Read-only* parameters at Administration > Entity Manager > Sales Order > Fields > Name.
-Administrator can specify a default Tax record at Administration > Entity Manager > Sales Order > fields > Tax > Default.
+## Copying values from product to sales order item
-Note: For older versions of Sales Pack & EspoCRM, you need also to specify the default tax rate value at Administration > Entity Manager > Sales Order > fields > Tax Rate > Default.
+Field values can be transferred from a product to a sales order item upon product selection. Field names you want to be copied should coincide in the Product and the Sales Order Item entity types.
-## Copying values from product to sales order item
+You can select which fields you need to be copied: Administration > Entity Manager > Sales Order Item > Fields > Product > Fields to Copy.
+
+## Locking
-Field values can be transferred from a product to a sales order item upon product selection. Field names you want to be copied should coincide in Product and Sales Order Item enities.
+A Sales Order can be locked if it's completed or canceled. When a record is locked, a specific fields become read-only. An administrator can configure the field list at: Administration > Entity Manager > Sales Order > Edit.
-You can select which fields you need to be copied at Administration > Entity Manager > Sales Order Item > Fields > Product > Fields to Copy.
+If the settings parameter *Forbid order unlocking* is checked, once a record is locked, it can be unlocked only by an administrator.
## Automation with Workflows or BPM
The following service actions are available in Workflows and BPM tools:
* Add Sales Order Items
-* Convery Currency
+* Convert Currency
* Send in Email
## See also
diff --git a/docs/user-guide/shortcuts.md b/docs/user-guide/shortcuts.md
new file mode 100644
index 000000000..477e135a3
--- /dev/null
+++ b/docs/user-guide/shortcuts.md
@@ -0,0 +1,67 @@
+# Shortcut keys
+
+*As of v7.2.*
+
+!!! note
+
+ On Mac OS, the CMD key (⌘) is the equivalent of the Ctrl.
+
+## General
+
+* `Ctrl + Middle-Click` – open a record in a quick view modal (when applied on a record link);
+
+## Record list
+
+* `Ctrl + Enter` – apply search filter;
+* `Ctrl + Space` – create new record;
+* `Ctrl + /` – focus on search-bar;
+* `Ctrl + <` – previous primary filter;
+* `Ctrl + >` – next primary filter;
+* `Ctrl + Arrow Left` – previous page;
+* `Ctrl + Arrow Right` – next page;
+
+!!! note "Tip"
+
+ A combination `Ctrl + Middle-Click` (on a record link) followed by `Ctrl + Space` can be used for quick edit.
+
+## Record detail
+
+* `Ctrl + Space` – switch to edit;
+* `Ctrl + \` – switch through tabs;
+* `Ctrl + Arrow Left` – previous record;
+* `Ctrl + Arrow Right` – next record;
+
+## Record edit
+
+* `Ctrl + Enter` – save and exit;
+* `Esc` – cancel;
+* `Ctrl + S` – save and continue editing;
+* `Ctrl + Alt + Enter` – save and create new (from the create view);
+
+## Calendar
+
+* `Arrow Left` – previous range;
+* `Arrow Right` – next range;
+* `Home` – move to today;
+* `Minus` – zoom out (timeline);
+* `Plus` – zoom in (timeline);
+* `1..6` – switch between view modes, refresh if the current mode;
+* `Ctrl + Space` – create event;
+
+## Image preview
+
+* `Arrow Left` – previous image;
+* `Arrow Right` – next image;
+
+## Emails
+
+* `Ctrl + Delete` – move selected emails to Trash;
+* `Ctrl + Backspace` – move selected emails to Archive (as of v8.3);
+* `Ctrl + I` – mark selected emails as Important or Not Important;
+* `Ctrl + M` – move selected emails to a specific folder;
+* `Ctrl + Q` – mark all emails as read; mark selected emails as read (as of v9.0);
+
+## Text formatting
+
+* `Ctrl + B` – bold;
+* `Ctrl + I` – italic;
diff --git a/docs/user-guide/stream.md b/docs/user-guide/stream.md
index 13bcbc75d..df801998c 100644
--- a/docs/user-guide/stream.md
+++ b/docs/user-guide/stream.md
@@ -1,48 +1,98 @@
# Stream
-Stream in EspoCRM is a feed where you can see updates and new additions for records you follow. You are also can post messages to the own stream and to stream of another users.
+Stream in EspoCRM is a feed where you can see posts and updates of records you follow. You can also post messages to your own Stream and to the Stream of other Users.
-By default the following entity types have the stream: Accounts, Contacts, Leads, Opportunities, Cases, Tasks. Administrators can **enable** or **disable** stream for a certain entity type in [Entity Manager](../administration/entity-manager.md).
-
-There are two types of stream in EspoCRM: record stream and user stream.
+By default, the following entity types have the Stream enabled: Accounts, Contacts, Leads, Opportunities, Cases, Meetings, and Tasks. An administrator can enable or disable the Stream for a certain entity type under Administration > Entity Manager > {Entity Type} > Edit.
## Record Stream
-The *Stream* panel is available on the record detail view at the bottom. Posts, updates and new additions related to the current record are displayed here.
+The *Stream* panel is available on the record detail view in the bottom. Posts and updates related to the record are displayed here. Each entry in the stream is represented by a *Note* entity.
+
+An administrator can move the Stream panel down so that it will appear under other panels or put the panel into a tab. This can be done at Administration > Entity Manager > {Entity Type} > Layouts > Bottom Panels.
+
+Stream posts can be pinned. A user needs to have *edit* access to a record to be able to pin or unpin Stream posts.
+
+### Access
-It's possible to **move the stream panel down** so that it will appear under other panels. Administrator can do it at Administration > Layout Manager > select entity type > Bottom panels (since v5.9.0).
+Access to the Stream is controlled by Roles and can be configured per entity type. For example, it's possible to configure that users have access to the Stream of records related to their team.
+
+With the [Collaborators](../administration/roles-management.md#collaborators) feature enabled, users who are record collaborators can access the Stream of the record, provided their access level, as defined by Roles, is other than *no*.
## User Stream
-Users can see their stream in the Stream dashlet as well as under Stream tab. Users also can see stream of another users in the user's detail view, if they have access that is controlled by *User Permission* field in Roles.
+Users can view their own Stream in the *Stream* dashlet as well on the separate Stream page.
+
+Users can see Stream of another users on the user's detail view if they have access defined by the *User Permission* in Roles. In the user's Stream, you can see posts and updates of records that the user follows. You can also see posts addressed to that user.
-In the user stream you can see posts and updates of records that the user follows. You can also see posts addressed to the user.
+It's possible to view all activity for a specific user. It will display all notes that either created directly by the user or created as a result of that users' actions. Available from the dropdown menu on the Stream panel on the User's detail view. As of v8.2.
## Notifications
-You will receive notifications about updates in your stream that were done by another users.
+A user receives notifications about new stream entries in followed records.
## Posts
-You can create post related to a certain record. You are also able to attach multiple files and images to the post. Images can be pasted from the clipboard.
+You can create a post related to a certain record. You are also able to attach multiple files and images to a post. Images can be pasted from the clipboard.
### Mentions
-If you want to mention somebody in your post, you need to type `@` symbol and start to type user's name. The user you has mentioned in your post will be notified about it.
+If you want to mention somebody in your post, you need to type `@` symbol and start typing the user's name. The user you have mentioned in your post will be notified.
+
+!!! note
+
+ The user who was mentioned in the post needs to have access to the Stream of the record where they were mentioned. Otherwise, the user won't receive a notification about the post.
+
+!!! note
+
+ The user needs to have a proper *Mention Permission* (set in Roles) to be able to mention a specific user. If the assignment permission is set to `no`, then the user won't be able to mention anyone. If set to `team`, then they will be able to mention only users of their teams. If set to `all`, then they will be able to mention anyone. Portal users are not able to mention users.
+
+### Attachments
+
+Users can attach files stream posts.
+
+An administrator can configure the *Attachments* field at Administration > Entity Manager > Note > Fields > attachments (as of v7.2). The following parameters are available:
-Note: The user who was mentioned in the post, needs to have an access to stream of the record where they were mentioned. Otherwise, the user won't receive the notification about the post.
+* Source list – by adding Documents, it enables the ability to attach Documents to stream posts directly;
+* Max file size;
+* Accept – which file types to accept.
-Note: The user needs to have a proper *Assignment Permission* (set in roles) to be able to mention a specific user. If the assignment permission is set to `no`, then the user won't be able to mention anybody. If set to `team`, then they will be able to mention only users of their team (or teams). If set to `all`, then will be able to mention anybody.
+### Quote reply
+
+*As of v9.0.*
+
+By clicking 'Quote Reply' on a stream post, it will paste quoted contents into the text field. If a part of a post is selected, only the selected part will be quoted.
## Posts to users
-Users can create post to certain users, to certain teams, to all users and to self. Access for this ability is controlled by *Assignment Permission* field in Roles.
+Users can create posts to certain Users, to certain Teams, to all Users and to self. Access for this feature is controlled by the *Message Permission* in Roles.
+
+You can post to Users:
+
+* from the *Stream* dashlet;
+* in the *Stream* panel on the user's detail view.
## Filtering
-You can filter what to show in a stream: *All*, *Posts* or *Updates*. Filters are availble in the dropdown in to top-right corner of the panel.
+You can filter what to show in the Stream: *All*, *Posts* or *Updates*. Filters are available in the dropdown in to top-right corner of the panel.
+
+## Global Stream
+
+*As of v8.2.*
+
+The Global Stream is available on a separate page where users can see all Stream notes, not only related to records they follow. Users can perform search: by specific fields or by a text filter. Notes that user don't have access to are not listed.
+
+The Global Stream can be useful when you need to search for a specific post. The full-text search is applied when using the text filter.
+
+Access to the Global Stream is controlled by Roles.
+
+The separate navbar Global Stream tab is available. It can be also reached from the Stream page.
+
+!!! note
+
+ If a user does not have *all* access level for all entity types, there are possible scenarios leading to an empty or not complete result list being displayed. It's a server load optimization measure when it would take too much of resources to find the first records the user has access to. Consider adding some search filters in such cases.
## See also
+* [Stream quick tour](https://app.supademo.com/demo/cmkvg6g2n2z4p12hh6xvxp6nf)
* [Activity Stream – Keep up with changes](https://www.espocrm.com/tips/activity-stream/)
* [Following records in EspoCRM](https://www.espocrm.com/tips/follow-records/)
diff --git a/docs/user-guide/text-search.md b/docs/user-guide/text-search.md
index 4843b6c39..04df9bf38 100644
--- a/docs/user-guide/text-search.md
+++ b/docs/user-guide/text-search.md
@@ -8,48 +8,62 @@ In this article:
See also:
-* [Seach types in EspoCRM: What you should know](https://www.espocrm.com/tips/search-types/)
+* [Search types in EspoCRM: What you should know](https://www.espocrm.com/tips/search-types/)
## List view text search
-On the record list view it's possible to perform text search.
+On the record list view, it's possible to perform text search.
-The field list, which is used in filtering, can be configured at Administration > Entity Manager > Edit specific entity type > Text Filter Fields.
+The field list which is used in filtering can be configured under: Administration > Entity Manager > {Entity Type} > Edit > Text Filter Fields.
-It's possible to use the wildcard `*`.
+It's possible to use a wildcard `*`.

-There is an option to use 'contains' operator for varchar fields by default. Parameter is available at Administration > Settings. Note, that it can affect performance.
+There is an option to force the system to use the 'contains' operator for Varchar fields by default. Parameter is available under Administration > Settings. Note that it can affect performance.
+
+To disable previous search suggestions, uncheck the checkbox at Preferences > Misc > Disable text filter storing.
## Global search
-Global Search performs a search in multiple entity types simultaneously.
+The Global Search performs search in multiple entity types simultaneously.
-The list of entity types used in Global Search can be configured at Administration > Settings > Global Search Entity List.
+The list of entity types used in the Global Search can be configured under Administration > Settings > Global Search Entity List.
-The field list which is used in filtering can be configured at Administration > Entity Manager > Edit specific entity type > Text Filter Fields.
+The field list which is used in filtering can be configured under Administration > Entity Manager > {Entity Type} > Edit > Text Filter Fields.

## Full-text search
-Provides an ability to perform a much faster and comprehensive text search.
+Full-text search provides the ability to perform much faster and comprehensive text search. The full-text is performed at the database level.
+
+The full-text search can be enabled for a specific entity type under Administration > Entity Manager > {Entity Type} > Edit > Full-text search.
+
+After enabling full-text-search, running rebuild is required. If you have many records, it's recommended to run rebuild from CLI: `php rebuild.php`.
+
+In Global Search, the full-text search is always applied (for entity types with enabled full-text search).
+
+The full-text search is also applied when you search in the list view. Though it can be skipped for some search queries. Yet, it's possible to force a full-text usage by prepending `ft:` to your search query.
+
+The following operators are available:
+
+* `+` – A leading plus sign indicates that this word must be present.
+* `-` – A leading minus sign indicates that this word must not be present.
+* *no operator* – The word is optional, but the rows that contain it are rated higher.
+* `*` – The truncation (or wildcard) operator. Appended to the word to be affected.
+* `"` – A phrase enclosed within double quotes must be contained literally, as it was typed.
-Full-text search can be enabled for a specified entity type at Administration > Entity Manager > Edit specific entity type > Full-text search. Running rebuild is required. Run from CLI: `php rebuild.php`.
+### Minimum word length
-Full-text search is always applied in Global Search (for entity types with enabled full-text search).
+The MySQL option `ft_min_word_len` defines a minimum word length available for full-text search. By default, it's set to `4`. You might want to set it to `3` to be able to search shorter words.
-Full-text search is also applied when you search in the list view. Though it can be skipped for some search queries. Yet, it's possible to force a full-text usage by prepending `ft:` to the search query.
+If you change this parameter in MySQL, you also need to run rebuild in Espo.
-For InnoDB tables the following operators are available:
+### Stopwords
-* `+` A leading plus sign indicates that this word must be present.
-* `-` A leading minus sign indicates that this word must not be present.
-* (no operator) The word is optional, but the rows that contain it are rated higher.
-* `*` The truncation (or wildcard) operator. Appended to the word to be affected.
-* `"` A phrase enclosed within double quotes must be contained literally, as it was typed.
+[MySQL](https://dev.mysql.com/doc/refman/8.0/en/fulltext-stopwords.html) and [MariaDB](https://mariadb.com/docs/server/ha-and-performance/optimization-and-tuning/optimization-and-indexes/full-text-indexes/full-text-index-stopwords) have the list of stopwords that are ignored by full-text search.
-Note: MySQL option *ft_min_word_len* defines min word length available for full-text search. By default it's 4. If you change this paramater, you need also to set EspoCRM *fullTextSearchMinLength* parameter at data/config.php: `'fullTextSearchMinLength' => 3`.
+### Autocomplete
-Note: MySQL has a blacklist of words that are not available for full-text search. E.g. *test*, *hello*.
+When Full-text search is enabled, autocomplete in link fields may not show suggestions until you type a full word. To have suggestions work for word parts, you can enable the parameter that will append the wildcard operator automatically for autocompletion queries. Administration > Settings > Append wildcard in quick search.
diff --git a/docs/user-guide/working-time-calendar.md b/docs/user-guide/working-time-calendar.md
new file mode 100644
index 000000000..b3ea2b6a3
--- /dev/null
+++ b/docs/user-guide/working-time-calendar.md
@@ -0,0 +1,72 @@
+# Working Time Calendar
+
+*As of v7.3.*
+
+The Working Time feature allows you to define working and non-working days for users, teams, and the entire organization. It provides a weekly schedule with customizable hours per weekday, supports exceptions for special working days (such as weekends or days with adjusted hours), and allows marking holidays or leaves.
+
+Features:
+
+* Week schedule (weekdays can have different schedule);
+* Working day exceptions (e.g. working weekends, days with a non-standard schedule);
+* Non-working day exceptions (leaves, holidays, etc.).
+
+Admin users and regular users who have access to the Working Time Calendar scope can manage Working Time Calendars.
+
+Working Time Calendars can be accessed under:
+
+* Calendar page > top-right dropdown menu > Working Time Calendars;
+* Administration > Working Time Calendars (in the Data panel).
+
+A working Time Calendar record can be:
+
+* Selected as a system default (Administration > System > Working Time Calendar);
+* Selected for a team – will apply to users who have that team set in the *Default Team*;
+* Selected for a specific user.
+
+A Working Time Calendar record defines:
+
+* Time zone;
+* Workday schedule (working time ranges);
+* Week schedule (what weekdays are working, every weekday can have a different schedule).
+
+A Working Time Exception record applies custom working time for a specific day range for specific users or for a whole calendar. It can define non-working days or working days with a custom time schedule.
+
+!!! note
+
+ In Exceptions, the Date End is inclusive.
+
+Examples:
+
+* Holidays for a whole team. Create an Exception record related to the Working Time Calendar with the type *Non-working*.
+* A leave for a specific user (employee). Create an Exception record related to the User (through the *Users* field) with the type *Non-working*.
+* A working Saturday. Create a one-day Exception with the type *Working*.
+* A working day with a shortened time schedule. Create a one-day Exception with the type *Working*, with a custom *Schedule*.
+
+Non-working days have a different background color on the Calendar:
+
+
+
+Non-working timeslots:
+
+
+
+The Timeline displays non-working ranges with a different background color:
+
+
+
+## Formula functions
+
+The following formula functions are available.
+
+* `ext\workingTime\addWorkingDays(DATE, DAYS)` – adds working days, the result will be a date-time pointing at the beginning of the day (`00:00`) in a corresponding time zone;
+* `ext\workingTime\findClosestWorkingTime(DATE)` – finds the beginning of the next closest working time slot;
+* `ext\workingTime\getSummedWorkingHours(FROM, TO)` – get a total number of working hours between two dates;
+* `ext\workingTime\getWorkingDays(FROM, TO)` – get a number of working days between two dates;
+* `ext\workingTime\hasWorkingTime(FROM, TO)` – whether a date range contains any working time;
+* `ext\workingTime\isWorkingDay(DATE_OR_DATETIME)` – whether a date falls into a working day.
+
+Functions can be applied for the default calendar, user calendar, or team calendar. An entity type ( `'User'` or `'Team'`) and an entity ID can be passed to all workingTime functions as the last two arguments. For example, `ext\workingTime\isWorkingDay(dateStart', 'User', assignedUserId)`.
+
+## See also
+
+* [Quick tour](https://app.supademo.com/demo/cmj9rq2v70sm3f6zpxmxq1npw)
diff --git a/i18n/bn_BD/administration/apache-server-configuration.md b/i18n/bn_BD/administration/apache-server-configuration.md
deleted file mode 100644
index c29c94446..000000000
--- a/i18n/bn_BD/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# EspoCRM এর জন্য Apache সার্ভার কনফিগারেশন
-
-এই নির্দেশাবলী থেকে সম্পূরক Server Configuration](server-configuration.md) গাইডলাইন। দয়া করে মনে রাখবেন এখানে তালিকাভুক্ত সমস্ত কনফিগারেশন সেটিংস উবুন্টু সার্ভারে তৈরি করা হয়েছে।
-
-## পিএইচপির প্রয়োজনীয়তা
-
-সমস্ত প্রয়োজনীয় লাইব্রেরিগুলি ইনস্টল করতে, এই কমান্ডগুলি একটি টার্মিনালে চালান:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## সমস্যাটি সমাধান করা “API Error: EspoCRM API is unavailable”:
-
-প্রয়োজনীয় পদক্ষেপ নিন। সমস্যাটি সমাধান করা হলে প্রতিটি পদক্ষেপের পরে পরীক্ষা করুন।
-
-### 1. Apache- তে "mod_rewrite" সমর্থন সক্ষম করুন
-
-"Mod_rewrite" সক্ষম করতে, টার্মিনালে এই কমান্ডগুলি চালনা করুন:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. সমর্থন সক্ষম করুন .htaccess
-
-.htaccess সমর্থন সক্ষম করতে, সার্ভার কনফিগারেশন যোগ/সম্পাদনা করুন Settings /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf বা /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-পরে, এই কমান্ডটি একটি টার্মিনালে চালান:
-
-```
-sudo service apache2 restart
-```
-
-### 3. RewriteBase পাথ যোগ করুন
-
-একটি ফাইল /ESPOCRM_DIRECTORY/api/v1/.htaccess খুলুন এবং নিম্নলিখিত লাইন প্রতিস্থাপন করুন:
-
-```
-# RewriteBase /
-```
-
-সাথে
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-যেখানে REQUEST_URI URL এর একটি অংশ, যেমন "http://example.com/espocrm/" এর জন্য, REQUEST_URI "espocrm"
-
-
-## HTTP AUTHORIZATION সমর্থন সক্ষম করুন (শুধুমাত্র FastCGI এর জন্য)।
-
-FastCGI ডিফল্ট হিসাবে HTTP AUTHORIZATION সমর্থন করে না যদি আপনি FastCGI ব্যবহার করেন তবে নিম্নলিখিত কোডগুলি যুক্ত করে আপনার VirtualHost অথবা /etc/apache2/apache2.conf (httpd.conf) এ এটি সক্রিয় করতে হবে:
-
-Fcgid মডিউল জন্য:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Fcgid মডিউল জন্য:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-বর্তমানে যে মডিউলটি ব্যবহৃত হচ্ছে তা পরীক্ষা করতে, এই কমান্ডটি চালান এবং মডিউল খুঁজুন:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/bn_BD/administration/b2c.md b/i18n/bn_BD/administration/b2c.md
deleted file mode 100644
index f31aa5962..000000000
--- a/i18n/bn_BD/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#B2C (ব্যবসা-থেকে-ক্লায়েন্ট) জন্য EspoCRM কনফিগার করা
-
-ডিফল্ট হিসাবে EspoCRM B2B ব্যবসা ব্যবহারের জন্য কনফিগার করা হয়। কিন্তু আপনি সহজেই এটি B2C জন্য সেটআপ করতে পারেন।
-
-* পরিবর্তন করুন `b2cMode` তে আপনার কনফিগ ফাইল `data/config.php`. সংস্করণ 4.3.0 থেকে এটি কনফিগার করা যেতে পারে। Administration > Seetings.
-* অপসারণ *Account* ন্যাভিগেশন মেনু থেকে ইটারফেস (Administration > User Interface).
-* অপসারণ *Account* আপনার লেআউটগুলির ক্ষেত্রগুলি (Administation > Layout Manager).
-* একটি অ্যাক্সেস অক্ষম করুন *Account* আপনার সব ভূমিকারসব পিতা বা মাতা ক্ষেত্রগুলির পিকলিস্টগুলি থেকে অ্যাকাউন্ট সরান জন্য সুযোগ (Administration > Roles).
-* সব পিতা বা মাতা ক্ষেত্রগুলির পিকলিস্টগুলি থেকে অ্যাকাউন্ট সরান (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
diff --git a/i18n/bn_BD/administration/backup-and-restore.md b/i18n/bn_BD/administration/backup-and-restore.md
deleted file mode 100644
index 79aa3385a..000000000
--- a/i18n/bn_BD/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# ব্যাকআপ এবং পুনঃস্থাপন
-
-## কিভাবে নিজে EspoCRM ব্যাকআপ করবেন
-
-EspoCRM ফাইল এবং ডাটাবেস ডেটা নিয়ে গঠিত। EspoCRM এর একটি সম্পূর্ণ ব্যাকআপ তৈরি করার জন্য এই সমস্ত ডেটা প্রয়োজন। এখানে উবুন্টু সার্ভারের সাথে মাইএসকিউএল কিভাবে কাজ করে তার নির্দেশনা।
-
-### Step 1. ব্যাকআপ ফাইল
-
-ইনস্টল করা EspoCRM এর ডকুমেন্টের বিষয়বস্তু সংরক্ষণ করুন। উবুন্টুর জন্য ডিফল্ট পাথ হয় `/var/www/html`. আপনি এই পাথ ব্যাবহার করতে পারেন:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Step 2. ব্যাকআপ ডাটাবেস
-
-আপনার সমস্ত ডেটা ব্যাকআপ করতে, আপনাকে ডাটাবেস নাম এবং অ্যাক্সেস শংসাপত্রগুলি জানতে হবে। আপনি কনফিগারেশন ফাইলে ডাটাবেস নামটি খুঁজে পেতে পারেন `/ESPOCRM_DIRECTORY/data/config.php` অধীন অধ্যায় `database`. আপনি এই কমান্ড ব্যবহার করে আপনার ডাটাবেস ব্যাকআপ করতে পারেন:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Step 3. ব্যাকআপ অনুলিপি করুন
-
-এখানেই শেষ. এখন, আপনি তৈরি ব্যাকআপ একটি নিরাপদ স্থানে কপি করতে হবে।
-
-
-## একটি স্ক্রিপ্ট এর সঙ্গে EspoCRM ব্যাকআপ করবেন কিভাবে
-
-আপনি সমস্ত প্রয়োজনীয় তথ্য ব্যাকআপ করার জন্য একটি স্ক্রিপ্ট ব্যবহার করতে পারেন। SSH এর মাধ্যমে লগইন করুন এবং কমান্ডগুলি চালান (উবুন্টু সার্ভারে পরীক্ষিত)।
-
-### একটি স্ক্রিপ্ট ডাউনলোড করুন
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### স্ক্রিপ্ট চালান
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-কোথায়:
- * `PATH_TO_ESPOCRM`EspoCRM ডিরেক্টরিটি ইনস্টল করার একটি পথ.
- * `BACKUP_PATH` ব্যাকআপ ডিরেক্টরি একটি পথ.
-
-উবুন্টু সার্ভারের জন্য এটি হল:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-দ্রষ্টব্য: যদি আপনার মাইএসকিউএল ব্যবহারকারীকে আপনার ডাটাবেস ডাম্প করার জন্য প্রয়োজনীয় অধিকার না থাকে, তাহলে আপনাকে অন্য মাইএসকিউএল ব্যবহারকারীর শংসাপত্রগুলি প্রবেশ করতে প্রমান করা হবে।
-
-সফল নির্মাণের পরে, আপনি তৈরি ব্যাকআপ একটি পাথ পাবেন।
-
-## ব্যাকআপ থেকে EspoCRM পুনরুদ্ধার করুন
-
-আপনি উপরে বর্ণিত হিসাবে তৈরি ব্যাকআপ থেকে EspoCRM পুনরুদ্ধার করতে পারেন।
-
-### Step 1. ব্যাকআপ ফাইলগুলি আনআর্কাইভ করুন
-
-আর্কাইভ ফাইলগুলিতে, আপনি আর্কাইভ ম্যানেজার ব্যবহার করতে পারেন বা নিম্নোক্ত কমান্ডটি চালাতে পারেন। ফাইলগুলি ওয়েব-সার্ভারের ডিরেক্টরির মধ্যে স্থাপন করা প্রয়োজন।
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-কোথায়:
- * `/var/www/html` is a web-server directory.
-
-### Step 2. প্রয়োজনীয় অনুমতিগুলি সেট করুন
-
-ফাইলগুলির একটি ওয়েব সার্ভার ব্যবহারকারীর মালিকানা থাকা উচিত এবং সঠিক অনুমতি আছে। এই নির্দেশ অনুসরণ করে প্রয়োজনীয় অনুমতি সেট করুন:[www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### Step 3. ডাটাবেস ডাম্প আমদানি করুন
-
-ডেটাবেস ডাম্প একই ব্যবহারকারীর শংসাপত্রের সাথে একই ডাটাবেসে আমদানি করা উচিত, অন্যথায় কনফিগারেশন ফাইলের সংশোধন করা উচিত `ESPOCRM_DIRECTORY/data/config.php`. ডাম্প থেকে আপনার ডাটাবেস আমদানি করতে, টার্মিনালে নীচের কমান্ডটি চালান:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Step 4. চেক/কনফিগার করুন crontab
-
-আপনার crontab সঠিকভাবে কনফিগার করা হয় কিনা তা পরীক্ষা করুন। নীচের কমান্ডটি চালান এবং চেক করুন যদি এস্পোসিআরএম সঠিক পথে থাকে:
-
-```bash
-sudo crontab -l -u www-data
-```
-কোথায়:
- * `www-data` is your web-server user.
-
-যদি আপনি কোনও পরিবর্তন করতে চান তবে এই কমান্ডটি ব্যবহার করুন:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-EspoCRM জন্য crontab কনফিগার সম্পর্কে আরো বিবরণ এখানে বর্ণিত আছে [www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
diff --git a/i18n/bn_BD/administration/bpm.md b/i18n/bn_BD/administration/bpm.md
deleted file mode 100644
index e68401258..000000000
--- a/i18n/bn_BD/administration/bpm.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# ব্যবসা প্রক্রিয়া ম্যানেজমেন্ট
-
-ব্যবসায় প্রক্রিয়া ব্যবস্থাপনা (BPM) টুল EspoCRM- এ ব্যবসায়িক প্রক্রিয়ার মডেল এবং স্বয়ংক্রিয় করার ক্ষমতা প্রদান করে। এটি একটি ইঞ্জিন বিপিএমএন 2.0 স্ট্যাণ্ডার্ড বর্ণিত ব্যবসা প্রক্রিয়া নির্বাহ। BPM সরঞ্জাম পাওয়া যায় [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) extension.
-
-
-
-### ওয়ার্কফ্লা টুল থেকে পার্থক্য
-
-ওয়ার্কফ্লো টুলটি সহজ ব্যবসা নিয়মগুলির অটোমেশন, W/O ক্রমবর্ধমান প্রবাহের আইটেমগুলির জন্য নির্ধারিত হয়, যখন প্রফ্রাইনটি গ্রাফিকালি প্রদর্শন করার প্রয়োজন নেই।
-
-বি.পি.এম টুল আরও জটিল ব্যবসা প্রবাহের উদ্দেশ্যে হয়, যেখানে ডাইভারজিং এবং কনভারজিং ফ্লো, এক্সিকিউশন বিলম্ব, ইউজার ইন্টারঅ্যাকশন থাকতে পারে। একটি ফ্লোচার্ট ভিউ একটি মানুষের জন্য ব্যবসায়িক প্রক্রিয়া আরও বোধগম্য করে তোলে, একটি লগ প্রক্রিয়া কিভাবে অনুষ্ঠিত হয়েছিল তা দেখতে পারবেন।
-
-## প্রক্রিয়া ফ্লোচার্টগুলি
-
-ফ্লোচার্ট প্রক্রিয়া লিঙ্কটি প্রশাসনের প্যানেল থেকে পাওয়া যায়। এটি ন্যাভিগেশন প্যানেলের একটি ট্যাবে যোগ করা যাবে।
-
-ফ্লোচার্ট ব্যবসার প্রক্রিয়া মডেলিং জন্য উদ্দেশ্যে করা হয়। প্রশাসক ফ্লোচার্টগুলি তৈরি এবং সম্পাদনা করতে পারেন। নিয়মিত ব্যবহারকারীরা কেবলমাত্র ফ্লোচার্টগুলি দেখতে পারেন।
-
-প্রতিটি ফ্লোচার্টের নির্দিষ্ট সত্তা টাইপ আছে (টার্গেট প্রকার ক্ষেত্র)। ফ্লোচার্ট ভবিষ্যতে প্রক্রিয়াকরণগুলির বাস্তবায়ন নির্ধারণ করে। এটি ফ্লোচার্ট উপাদান এবং উপাদানগুলির মধ্যে সংযোগগুলি অন্তর্ভুক্ত করে।
-
-যদি প্রক্রিয়া ফ্লোচার্টটি অনির্বাচিত হয় তবে 'Is Active' ক্ষেত্র তারপর এটি উদাহরণ প্রক্রিয়া আরম্ভ হবে না.
-
-একটি নির্দিষ্ট ফ্লোচার্ট উপাদানের বিবরণ এবং প্যারামিটারগুলি দেখানোর জন্য আপনাকে এটি ক্লিক করতে হবে। সম্পাদনা মোডে আপনি প্যারামিটার সম্পাদনা করতে সক্ষম হবেন।
-
-## প্রক্রিয়া
-
-প্রক্রিয়াগুলি প্রশাসনের প্যানেল থেকে পাওয়া যায়। সংযোগটিও নেভিগেশন প্যানেলের একটি ট্যাবে যোগ করা যেতে পারে।
-
-প্রক্রিয়া ব্যবসায়িক প্রক্রিয়ার উদাহরণ উপস্থাপন করে। এটি শুরু যখন এটি অবস্থা পায় 'Started'. প্রক্রিয়া শেষ হলে এটি অবস্থা পায় 'Ended'. প্রসেসটি এমন একটি ব্যবহারকারীর দ্বারা বন্ধ করা যায় যা প্রসেসটি সম্পাদনা করার অ্যাক্সেস আছে। এটি ম্যানুয়ালি বন্ধ হলে এটি অবস্থা পায়'Stopped'।
-
-প্রক্রিয়াটি ফ্লোচার্ট অনুযায়ী কার্যকর করা হয়। প্রক্রিয়াটি শুরু হওয়ার পরে প্রক্রিয়াটির ফ্লোচার্ট পরিবর্তন করা যাবে না।
-
-প্রক্রিয়াটি দায়বদ্ধভাবে একক লক্ষ্যের রেকর্ডের সাথে সম্পর্কিত।
-
-প্রক্রিয়াগুলি স্বয়ংক্রিয়ভাবে শুরু হতে পারে (নির্দিষ্ট শর্ত বা নির্ধারিত সময়ে) বা ম্যানুয়ালি (যেখানে ফ্লোচার্টে অন্তত একটি স্টার্ট ইভেন্ট আছে)। প্রক্রিয়াটি শুরু করতে ব্যবহারকারীকে ক্লিক করতে হবে'Start Process'প্রসেস তালিকা বোতাম।
-
-## ফ্লোচার্ট এলিমেন্টস
-
-### ঘটনাবলী
-
-চেনাশোনাগুলি হিসাবে একটি ফ্লোচার্টে ইভেন্টগুলি প্রদর্শিত হয়
-
-#### ইভেন্ট শুরু করুন
-
-প্যারামিটার নেই এটি প্রক্রিয়া একটি শুরু বিন্দু। স্টার্ট ইভেন্টটি এমন ব্যবহারকারীর দ্বারা শুরু করা যেতে পারে যা প্রসেস তৈরির অ্যাক্সেস আছে। ব্যবহারকারীকে ক্লিক করতে হবে 'Start Process' প্রসেস তালিকায় বোতাম.
-
-#### শর্তসাপেক্ষ স্টার্ট ইভেন্ট
-
-প্রক্রিয়া শুরু একটি বিন্দু। নির্দিষ্ট শর্ত পূরণ করা হয় যখন এটা স্বয়ংক্রিয়ভাবে ট্রিগার হতে অনুমিত হয়। ট্রিগার দুটি ধরনের আছে:'After record created', 'After record saved'.
-
-#### টাইমার স্টার্ট ইভেন্ট
-
-প্রক্রিয়া শুরু একটি বিন্দু। এটি নির্ধারণের মাধ্যমে প্রসেস আরম্ভ করে। আপনি প্রসেস শুরু করার জন্য ক্রসব্লব নোটিএনে নির্ধারিত লিস্ট প্রতিবেদনগুলি নির্দিষ্ট করতে হবে।
-
-#### শর্তসাপেক্ষ ইন্টারমিডিয়েট ইভেন্ট
-
-নির্দিষ্ট মাপকাঠি পূরণ করা হয় না হওয়া পর্যন্ত এই ঘটনাটি প্রবাহ বন্ধ করে দেয়।
-
-#### টাইমার ইন্টারমিডিয়েট ইভেন্ট
-
-এই ইভেন্ট প্রবাহ বন্ধ এবং ইভেন্ট এর পরামিতি দ্বারা নির্দিষ্ট হিসাবে যতক্ষণ অপেক্ষা করছে।
-
-আরো জটিল টাইমার সেটিংসের জন্য আপনি ব্যবহার করতে পারেন [formula](formula.md). সূত্র স্ক্রিপ্টগুলি তারিখ-সময় মান (UTC টাইমজোনে) ফেরত দিতে হবে। একবার এই সময় আসে প্রবাহ পরের উপাদান এগিয়ে যেতে হবে।সূত্র ফাংশনটি ভবিষ্যতে একটি নির্দিষ্ট সময় টাইমার সেট করা সম্ভব, উদাহরণস্বরূপ। পরের কাজ দিবসের শুরুতে
-
-ব্যবহার করে datetime\closest সূত্র ফাংশনটি ভবিষ্যতে একটি নির্দিষ্ট সময় টাইমার সেট করা সম্ভব, উদাহরণস্বরূপ। পরের কাজ দিবসের শুরুতে।
-
-#### শেষ ইভেন্ট
-
-বর্তমান প্রবাহ শেষ। এটা সমান্তরাল মধ্যে চলমান প্রবাহ শেষ না। প্রবাহ সমাপ্তি ঘটনা পৌঁছেছে এবং সমান্তরালে চলমান কোন কিছু নেই তারপর প্রক্রিয়া শেষ হয়।
-
-#### শেষ ইভেন্ট বন্ধ করুন
-
-সব প্রবাহ শেষ প্রক্রিয়া পরবর্তীকালে শেষ হয়
-
-### গেটওয়েস
-
-গেটওয়ে হীরা হিসাবে প্রদর্শিত হয়।
-
-#### এক্সক্লুসিভ গেটওয়ে
-
-প্রবাহ বিভাজক বা একত্রিত করতে পারেন
-
-ডাইভারজিংয়ের ক্ষেত্রে এটি একটি একক প্রবাহ (পথ) সংজ্ঞায়িত করে যা নির্দিষ্ট মাপকাঠি অনুসারে নির্বাচিত হবে। প্রথম পরিমাপের শর্ত প্রবাহ নির্ধারণ করে, পরবর্তী শর্তগুলি বাদ দেওয়া হয়। ডিফল্ট প্রবাহ নির্দিষ্ট করার একটি ক্ষমতা আছে। ডিফল্ট প্রবাহ নির্বাচন করা হয় যদি কোনও পূরণ শর্ত নেই। ডিফল্ট প্রবাহ একটি স্ল্যাশ চিহ্ন দিয়ে চিহ্নিত করা হয়।
-
-একটি ডাইভারজিং সমেত গেটওয়ে দ্বারা উত্পন্ন সমান্তরাল প্রবাহগুলিকে একত্রিত করার জন্য যদি প্রয়োজন হয় তাহলে আপনাকে একটি সংযোজক সমন্বিত প্রবেশপথ ব্যবহার করতে হবে। এটি সমস্ত ইনকামিং প্রবাহের জন্য অপেক্ষা করবে এবং তারপর বহির্মুখী উপাদানটি চালিয়ে যাবে।
-
-
-
-
-
-#### সমেত গেটওয়ে
-
-প্রবাহ বিভাজক বা একত্রিত করতে পারেন
-
-প্রতিটি প্রবাহের মানদণ্ড কার্যকর করার উপর নির্ভর করে ডাইভারজিংয়ের ক্ষেত্রে এটি এক বা একাধিক সমান্তরাল প্রবাহ (পাথ) নির্দেশ করতে পারে। ডিফল্ট প্রবাহ নির্বাচন করা হয় যদি কোনও পূরণ শর্ত নেই। ডিফল্ট প্রবাহ একটি স্ল্যাশ চিহ্ন দিয়ে চিহ্নিত করা হয়।
-
-একটি ডাইভারজিং সমেত গেটওয়ে দ্বারা উত্পন্ন সমান্তরাল প্রবাহগুলিকে একত্রিত করার জন্য যদি প্রয়োজন হয় তাহলে আপনাকে একটি সংযোজক সমন্বিত প্রবেশপথ ব্যবহার করতে হবে। এটি সমস্ত ইনকামিং প্রবাহের জন্য অপেক্ষা করবে এবং তারপর বহির্মুখী উপাদানটি চালিয়ে যাবে।
-
-
-
-দ্রষ্টব্য: Diverging এবং গেটওয়ে converging সমতুল্য হতে হবে।
-
-দ্রষ্টব্য: যদি সমান্তরাল প্রবাহ এক কারণে কিছু কারণে শেষ হয়েছে, তাহলে গেটওয়ে ডুভারিং প্রক্রিয়া করা হবে না। প্রক্রিয়া ব্লক করা হবে। এমন একটি ফ্লোচার্ট ডিজাইন এড়িয়ে চলুন যা এমন পরিস্থিতি নিয়ে আসতে পারে।
-
-#### সমান্তরাল গেটওয়ে
-
-প্রবাহ বিভাজক বা একত্রিত করতে পারেন
-
-ডাইভারজিংয়ের ক্ষেত্রে এটি একাধিক সমান্তরাল প্রবাহে প্রবাহিত হয়। এই গেটওয়ে টাইপ জন্য কোন প্যারামিটার আছে।
-
-সমস্ত ইনকামিং প্রবাহ আসা পর্যন্ত এবং এটি পরবর্তী বহির্মুখী উপাদান অবধি চলতে না হওয়া পর্যন্ত এটি converging ক্ষেত্রে অপেক্ষা।
-
-
-
-দ্রষ্টব্য: Diverging এবং গেটওয়ে converging সমতুল্য হতে হবে।
-
-দ্রষ্টব্য: যদি সমান্তরাল প্রবাহ এক কারণে কিছু কারণে শেষ হয়েছে, তাহলে গেটওয়ে ডুভারিং প্রক্রিয়া করা হবে না। প্রক্রিয়া ব্লক করা হবে। এমন একটি ফ্লোচার্ট ডিজাইন এড়িয়ে চলুন যা এমন পরিস্থিতি নিয়ে আসতে পারে।
-
-#### ইভেন্ট ভিত্তিক গেটওয়ে
-
-শুধুমাত্র প্রবাহ বিচ্ছিন্ন করতে পারেন।
-
-এটি বহির্মুখী ঘটনাগুলির সূত্রপাত না হওয়া পর্যন্ত এটি প্রবাহ বন্ধ করে দেয়। উত্তেজিত ইভেন্ট একক প্রবাহ নির্ধারণ করে। অন্যান্য আউটগোয়িং ইভেন্টগুলি বাতিল হয়ে যায়।
-
-শুধুমাত্র অন্তর্বর্তী অনুষ্ঠান বহির্বিভাগের ক্রম প্রবাহের অন্য প্রান্তে হতে পারে।
-
-
-
-### ক্রিয়াকলাপ
-
-ক্রিয়াকলাপগুলি গোলাকার আয়তক্ষেত্র হিসাবে প্রদর্শিত হয়।
-
-#### কার্য
-
-টাস্কগুলি ক্রিয়াগুলিকে অনুসরণ করতে পারে:
-
-* রেকর্ড তৈরি করুন - কোনো সত্তা টাইপের নতুন রেকর্ড তৈরি করে;
-* সম্পর্কিত রেকর্ড তৈরি করুন - লক্ষ্য রেকর্ড সম্পর্কিত নতুন রেকর্ড তৈরি করে;
-* আপডেট টার্গেট রেকর্ড;
-* আপডেট সম্পর্কিত রেকর্ড - লক্ষ্য রেকর্ড সম্পর্কিত রেকর্ড বা রেকর্ড আপডেট;
-* আপডেট তৈরি করা রেকর্ড - বর্তমান প্রক্রিয়ায় তৈরি যে কোনো রেকর্ডের নির্দিষ্ট ক্ষেত্রের আপডেট;
-* আপডেট প্রক্রিয়া রেকর্ড - নির্দিষ্ট ব্যবহারকারী বা দলের প্রসেস বরাদ্দ করতে ব্যবহার করা যেতে পারে;
-* অন্য রেকর্ড লিঙ্ক - একটি নির্দিষ্ট রেকর্ড সঙ্গে লক্ষ্য রেকর্ড লিঙ্ক;
-* অন্য রেকর্ড থেকে আনলিঙ্ক - নির্দিষ্ট রেকর্ড থেকে লক্ষ্য রেকর্ড লঙ্ঘন;
-* বরাদ্দকরণ নিয়ম প্রয়োগ করুন - টার্গেটের রেকর্ড নির্দিষ্ট করে, প্রসেস রেকর্ড বা নির্দিষ্ট নিয়ম অনুযায়ী প্রক্রিয়া দ্বারা তৈরি কোন রেকর্ড;
-* বিজ্ঞপ্তি তৈরি করুন - নির্দিষ্ট ব্যবহারকারীদের জন্য অ্যাপ্লিকেশন বিজ্ঞপ্তি তৈরি করে;
-* অনুসরণ করুন - বিশেষ ব্যবহারকারী লক্ষ্য রেকর্ড অনুসরণ করে, প্রসেস রেকর্ড বা প্রক্রিয়া দ্বারা তৈরি কোন রেকর্ড;
-* চালান সার্ভিস অ্যাকশন - কাস্টম সেবা কর্মগুলি ডেভেলপারদের দ্বারা বাস্তবায়িত করে।
-
-টাস্কের জন্য উপলব্ধ কর্মগুলি ওয়ার্কফ্লো বৈশিষ্ট্য হিসাবে প্রায় একই। সম্পর্কে আরো বিস্তারিত দেখুন [workflow's actions](workflows.md#actions).
-
-#### বার্তা প্রেরণ কার্য
-
-নির্দিষ্ট প্রাপককে ইমেল বার্তা পাঠায়
-
-#### ব্যবহারকারী টাস্ক
-
-ব্যবহারকারীর মিথস্ক্রিয়া একটি নমনীয় ক্ষমতা প্রদান করে। এটি কার্যকরী না হওয়া পর্যন্ত ব্যবহারকারী (সুনির্দিষ্টভাবে বা নিয়োগের নিয়মের দ্বারা নির্দিষ্ট করা হয়) টাস্ককে সংশোধন করে। পদ্ধতি ব্যবহারকারী টাস্ক রেকর্ড সিস্টেমের মধ্যে তৈরি করা হবে। ডিফল্টরূপে তিনটি অ্যাকশন প্রকার রয়েছে: অনুমোদন, পর্যালোচনা, সম্পন্ন করুন।
-
-* টাইপ অনুমোদন ব্যবহারকারী 'অনুমোদন' এবং 'প্রত্যাখ্যান' মধ্যে নির্বাচন করতে প্রয়োজন।
-* রিভিউ টাইপ কেবল একটি বিকল্প দেয়: 'পর্যালোচনা'।
-* সম্পূর্ণ উপায়ে দুটি বিকল্প রয়েছে: 'সমাপ্ত' এবং 'ব্যর্থ'।
-
-
-তৈরি করা প্রসেস ইউজার টাস্ক রেকর্ডে নির্ধারিত ইউজার ইন-অ্যাপের বিজ্ঞপ্তি পাবেন। প্রশাসক ইমেল বিজ্ঞপ্তিগুলি সক্ষম করতে পারেন।
-
-ব্যবহারকারীরা তাদের ড্যাশবোর্ডে প্রসেস ইউজার টাস্ক ড্যাশলেট যোগ করতে পারেন তাদের প্রকৃত প্রসেস ব্যবহারকারী কাজ দেখতে।
-
-It's possible to read the resolution of the passed user task within diverging gateways or conditional events, making ramification in the process flow.
-
-#### স্ক্রিপ্ট টাস্ক
-
-মধ্যে স্ক্রিপ্ট সঞ্চালন ভাষা [espo-formula](formula.md)। সমস্ত সেট ভেরিয়েবল সঞ্চিত এবং (`$variableName`) প্রসেসের মধ্যে উপলব্ধ হবে।
-
-### ফ্লো
-
-#### ক্রম ফ্লো
-
-একটি কঠিন তীর হিসাবে প্রতিনিধিত্ব। ক্রিয়া নির্দেশ করে যা প্রক্রিয়া উপাদানগুলি কার্যকর করা হবে।
-
-## পরিবেশ
-
-শর্তসাপেক্ষ ইভেন্টগুলি, একচেটিয়া এবং সমেত দ্বিমাত্রিক গেটওয়েগুলির প্রক্রিয়াগুলির প্রবাহকে নির্ধারণ করে.
-
-UI এর মাধ্যমে নিম্নোক্ত রেকর্ডের জন্য শর্তগুলি পরীক্ষা করার ক্ষমতা রয়েছে:
-
-* লক্ষ্য রেকর্ড;
-* অনেকগুলি থেকে এক এবং শিশুদের-থেকে-পিতামাতার সম্পর্কের মাধ্যমে লক্ষ্য সম্পর্কিত রেকর্ড;
-* কর্মের মাধ্যমে প্রক্রিয়া দ্বারা তৈরি রেকর্ড;
-* ব্যবহারকারী টাস্ক রেকর্ড, যা রেজল্যুশন পরীক্ষা করতে পারবেন।
-
-শর্তগুলি সংজ্ঞায়িত করাও সম্ভব [Espo-formula](formula.md) ভাষাতে।
-
-BPM সরঞ্জামের শর্তগুলি ওয়ার্কফ্লো বৈশিষ্ট্য হিসাবে একই। সম্পর্কে আরো বিস্তারিত দেখুন [workflow's conditions](workflows.md#conditions).
-
-## উদাহরণ
-
-### উদাহরণ 1
-
-
-
-### উদাহরণ 2
-
-
-
-### উদাহরণ 3
-
-
diff --git a/i18n/bn_BD/administration/dynamic-logic.md b/i18n/bn_BD/administration/dynamic-logic.md
deleted file mode 100644
index 6226d88bd..000000000
--- a/i18n/bn_BD/administration/dynamic-logic.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# ডায়নামিক লজিক (ডাইনামিক ফরম)
-
-ডাইনামিক লজিক বৈশিষ্ট্য ব্যবহার করে ফরমগুলির ডায়নামিক আচরণটি অর্জন করা যায়। ডায়নামিক লজিক প্যারামিটার প্রতিটি ক্ষেত্রে উপলব্ধ। যখন আপনি একটি ক্ষেত্র সম্পাদনা বা তৈরি করেন তখন প্যারামিটারগুলিকে এনটিটি ম্যানেজারে পাওয়া যায়।
-
-ডায়নামিক লজিকের নির্দিষ্ট ক্ষেত্রগুলি দৃশ্যমান, প্রয়োজনীয় বা শুধুমাত্র পঠনযোগ্য করে তুলতে কন্ডিশনে সংজ্ঞায়িত করতে পারবেন। ফর্ম পরিবর্তন হবে অখন তথ্য স্বয়ংক্রিয়ভাবে পরীক্ষা করা হবে।
-
-Enum, Array এবং Multi-Enum ক্ষেত্রগুলির ক্ষেত্রে যেগুলি শর্ত পূরণ করা হয় তার উপর নির্ভর করে ক্ষেত্রের জন্য উপলব্ধ বিভিন্ন সেটের বিকল্পগুলি নির্ধারণ করা সম্ভব।
-
-শর্তাবলী ব্যবহারকারী ইন্টারফেসের মাধ্যমে কনফিগার করা হয়, কোন কোডিং প্রয়োজন নেই।
diff --git a/i18n/bn_BD/administration/emails.md b/i18n/bn_BD/administration/emails.md
deleted file mode 100644
index aeb77f9fc..000000000
--- a/i18n/bn_BD/administration/emails.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# ইমেইল
-
-> গুরুবপূর্ণ। [Cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) ইমেইলে আনলিমিটেড কাজের জন্য আপনার সিস্টেমে কনফিগার করা উচিত। আপনি আপনার EspoCRM এ তথ্য পেতে পারেন Administration > Scheduled Jobs এ।
-
-## সংক্ষিপ্ত বিবরণ
-
-EspoCRM এর IMAP মেইলবক্সগুলি নিরীক্ষণ করার একটি ক্ষমতা রয়েছে। ইমেল দুটি উপায়ে সংরক্ষণ করা যায়: গোষ্ঠী ইমেইল অ্যাকাউন্টগুলি এবং ব্যক্তিগত ইমেইল অ্যাকাউন্টগুলি। গোষ্ঠী ইনবাউন্ড অ্যাকাউন্টগুলি গোষ্ঠী মেলবক্সের জন্য নির্ধারিত: সর্বাধিক সাধারণ ক্ষেত্রে একটি সমর্থন বাক্স। ব্যক্তিগত ইমেইল অ্যাকাউন্টগুলি ব্যবহারকারীদের ব্যক্তিগত মেইলবক্সগুলির জন্য নির্ধারিত।
-
-একটি ইমেল আসছে যখন সিস্টেমটি যথাযথ রেকর্ডের সাথে লিঙ্ক করার চেষ্টা করে (অ্যাকাউন্ট, লিড, সুযোগ, কেস)। ব্যবহারকারীরা যে রেকর্ড অনুসরণ করে তারা সিস্টেমে একটি নতুন ইমেইল সম্পর্কে বিজ্ঞপ্তি পাবেন, এমনকি যদি তারা TO বা CC তে না থাকে
-
-## গ্রুপ ইমেইল অ্যাকাউন্টসমুহ
-
-শুধুমাত্র অ্যাডমিনিস্ট্রেটর গ্রুপ ইমেল অ্যাকাউন্ট স্থাপন করতে পারেন। গোষ্ঠী ইমেল অ্যাকাউন্টগুলি ইমেল গ্রহণ ও প্রেরণের জন্য উভয়ই ব্যবহার করা যেতে পারে। গ্রুপ অ্যাকাউন্ট থেকে ইমেল পাঠানো 4.9.0 সংস্করণ থেকে উপলব্ধ করা হয়েছে।
-
-টিমের ক্ষেত্র নির্ধারণ করে যে কোন দলগুলিকে ই-মেইল হিসেবে নিয়োগ করা হবে।
-
-যদি গ্রুপের ইমেইল একাউন্টে SMTP থাকে এবং এটি ভাগ করে নেওয়া হিসাবে পরীক্ষা করা হয় তাহলে একটি অ্যাক্সেস গ্রুপ ইমেল অ্যাকাউন্টের অনুমতির মাধ্যমে ভূমিকা দ্বারা নিয়ন্ত্রিত হবে। টিম ক্ষেত্র ব্যবহার করা হবে যদি অনুমতি স্তর 'Team' হিসাবে সেট করা হয়
-
-সিস্টেমে ইনকামিং ইমেলগুলি জন্য একটি স্বয়ংক্রিয় উত্তর পাঠাতে একটি ক্ষমতা আছে।
-
-## Email-to-Case
-
-সিস্টেমটি আগত গোষ্ঠী ইমেলগুলি থেকে কেস তৈরি করার একটি বিকল্প আছে।
-এই বৈশিষ্ট্য সমর্থন দল জন্য উদ্দেশ্যে করা হয়
-এই পদ্ধতি অনুযায়ী নির্দিষ্ট দল থেকে ব্যবহারকারীদের ক্ষেত্রে বিতরণ করা যায়:
-`direct assignment`, `round-robin` এবং `less-busy`.
-থ্রেডে শুধুমাত্র প্রথম ইমেল একটি নতুন কেস তৈরি করে।
-প্রতি পরবর্তী একটি বিদ্যমান ক্ষেত্রে রেকর্ডের সাথে সংযুক্ত হবে এবং তার স্ট্রিম প্যানেলে প্রদর্শিত হবে।
-
-যখন ব্যবহারকারীরা গ্রাহকের কাছে একটি উত্তর পাঠাতে চান তখন তাদের নিশ্চিত করতে হবে যে এই মামলাটিকে ইমেলের একটি পিতা বা মাতা হিসেবে নির্বাচিত করা হয়েছে যা পাঠানো হচ্ছে। এটি ব্যবহারকারীর নিজের পরিবর্তে গ্রাহকের ইমেইল অ্যাড্রেস এর ঠিকানা সরবরাহ করবে।
-
-## ব্যক্তিগত ইমেল অ্যাকাউন্টসমুহ
-
-ব্যবহারকারীরা তাদের নিজস্ব ইমেল অ্যাকাউন্টগুলি সেট আপ করতে পারেন যা নিরীক্ষণ করা প্রয়োজন। Emails > Top Right Dropdown Menu > Personal Email Accounts. অ্যাডমিনিস্ট্রেটর ব্যবহারকারীদের ইমেল অ্যাকাউন্টগুলি পরিচালনা করতে পারেন।
-
-## ইমেল ফিল্টারসমুহ
-
-এই নির্দিষ্ট মানদণ্ড অনুযায়ী আগত ইমেলগুলির ফিল্টারের অনুমতি দেয়। উদাহরণস্বরূপ যদি আপনি EspoCRM এ আমদানি করার জন্য কিছু অ্যাপ্লিকেশন দ্বারা পাঠানো বিজ্ঞপ্তি বার্তাগুলি না চান তবে EspoCRM তাদের তৈরি করতে ফিল্টার তৈরি করতে পারেন।
-
-অ্যাডমিন সমস্ত ইমেইল অ্যাকাউন্টে প্রয়োগ করা গ্লোবাল ফিল্টার তৈরি করতে পারে। ব্যবহারকারীরা নিজের ব্যক্তিগত ইমেইল একাউন্ট এবং সমগ্র ইনবক্সের জন্য ফিল্টারগুলি তৈরি করতে পারে।
diff --git a/i18n/bn_BD/administration/entity-manager.md b/i18n/bn_BD/administration/entity-manager.md
deleted file mode 100644
index a964ce15e..000000000
--- a/i18n/bn_BD/administration/entity-manager.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# সত্তা ম্যানেজার
-
-এডিটি ম্যানেজার প্রশাসন প্যানেলে পাওয়া যায়। এটি আপনার EspoCRM ইনস্ট্যান্সটি অত্যন্ত কাস্টমাইজ করার একটি ক্ষমতা প্রদান করে। আপনি নিম্নলিখিত করতে সক্ষম:
-
-* নতুন ধরনের সত্তা যোগ করুন
-* বিদ্যমান প্রকারের উপাদানগুলি কাস্টমাইজ করুন: লেবেলগুলি পরিবর্তন করুন, তালিকার দর্শনতে ডিফল্ট ক্রম, সক্রিয় বা স্ট্রীম অক্ষম করুন।
-* ক্ষেত্র কনফিগার করুন: নতুন যুক্ত করুন, বিদ্যমানগুলি কাস্টমাইজ করুন।
-* সম্পর্কগুলি কনফিগার করুন: নতুন যুক্ত করুন, বিদ্যমান লোকেদের লেবেলগুলি পরিবর্তন করুন।
-
-## নতুন সত্তা তৈরি করুন
-
-ক্লিক করুন `Create Entity`এনটিটি ম্যানেজার পৃষ্ঠায় বোতাম। নাম, লেবেল এবং প্রকার নির্দিষ্ট করুন। আপনি যদি নির্বাচন করেন `Person` টাইপ করুন, আপনার সত্তাটির ইমেল, ফোন, প্রথম নাম, সর্বশেষ নাম এবং অভিবাদন ক্ষেত্র থাকবে। কার্যদর্শন `Stream` যদি আপনি আপনার সত্তা স্ট্রিম প্যানেল এবং ব্যবহারকারীদের এই ধরনের সত্ত্বা অনুসরণ করতে সক্ষম হতে চান।
-
-প্রকার:
-
-* Base - নাম, মৌলিক ব্যবহারকারী, টিম, বিবরণ মত মৌলিক ক্ষেত্রের সাথে খালি সত্তা।
-* Base Plus - ব্যাস কিন্তু ক্রিয়াকলাপ সহ, ইতিহাস, টাস্ক প্যানেল (4.3.0 থেকে পাওয়া যায়)।
-* Event - তারিখ শুরু, তারিখ শেষ, স্থিতিকাল, প্যারেন্ট, স্থিতি ক্ষেত্র। ক্যালেন্ডার এবং ক্রিয়াকলাপের প্যানেলে উপলব্ধ (4.3.0 থেকে,এ অবশ্যই সক্রিয় থাকতে হবে Administration > Settings).
-* Person - ইমেল, ফোন, প্রথম নাম, শেষ নাম, অভিবাদন, ঠিকানা ক্ষেত্র। ক্রিয়াকলাপ, ইতিহাস, টাস্ক প্যানেল
-* Company - ইমেল, ফোন, বিলিং ঠিকানা, জাহাজীকরণ ঠিকানা ক্ষেত্র। ক্রিয়াকলাপ, ইতিহাস, টাস্ক প্যানেল
-
-## বিদ্যমান সত্তা আপডেট করুন
-
-আপনি যদি একটি নির্দিষ্ট সত্তাতে `সম্পাদনা` লিঙ্ক ক্লিক করেন তবে আপনি সেই সত্তাটির কিছু পরামিতি পরিবর্তন করতে সক্ষম হবেন।
-
-* Labels - সত্তা এর একবচন এবং বহুবচন নাম।
-* ডিফল্ট ক্রম রেকর্ড তালিকা দর্শনে দ্বারা সাজানো হয়।
-* Stream - স্ট্রীট বৈশিষ্ট্য এই সত্তা জন্য সক্ষম করা হয় কিনা।
-* Disabled - আপনার সিস্টেমে এই সত্তাটির প্রয়োজন হবে না তা পরীক্ষা করুন।
-* Text Filter Fields - মূল পাঠ্য ফিল্টার এবং গ্লোবাল অনুসন্ধানের জন্য কোন ক্ষেত্রগুলি অনুসন্ধান করা যায়
-
-
-## ক্ষেত্রসমূহ
-
-ক্লিক করে `Fields`লিঙ্কটি আপনাকে একটি পৃথক পৃষ্ঠাতে সরানো হবে। সেখানে আপনি নতুন ক্ষেত্র তৈরি করতে সক্ষম হবেন বা বিদ্যমানদের আপডেট করতে পারবেন। নিম্নলিখিত ধরনের ক্ষেত্র এনটিটি ম্যানেজারে পাওয়া যায়:
-
-* Address - রাস্তার ঠিকানা, শহর, রাজ্য, ডাক কোড এবং দেশ;
-* Array - মানগুলির তালিকা, একাধিক মূল্য নির্বাচন করার ক্ষমতা (কোনও ভাল বিকল্প যদি আপনি এই ক্ষেত্রটি অনুসন্ধান করতে না চান); ব্যবহারকারী নির্দিষ্ট না হলে ব্যবহারকারীরা তাদের নিজস্ব মান যোগ করতে পারেন।
-* Attachment Multiple- একাধিক ফাইল সংযুক্তি;
-* Auto-increment - শুধুমাত্র উত্পন্ন সংখ্যা পড়ুন;
-* Boolean - চেকবক্স, সত্য বা মিথ্যা;
-* Currency - মুদ্রার মানের জন্য;
-* Date;
-* DateTime;
-* Enum - নির্বাচন বাক্স, শুধুমাত্র একটি মান নির্বাচন করার ক্ষমতা;
-* File - এক ফাইল আপলোড;
-* Float - একটি দশমিক অংশ সঙ্গে সংখ্যা;
-* Foreign - সংশ্লিষ্ট সত্তা একটি ক্ষেত্র;
-* Image - একটি প্রাকদর্শন সঙ্গে ইমেজ ফাইল আপলোড;
-* Integer - সম্পূর্ণ নম্বর;
-* Number - একটি সম্ভাব্য উপসর্গ এবং একটি নির্দিষ্ট দৈর্ঘ্যের সাথে স্ট্রিং টাইপের স্বতঃবৃদ্ধি সংখ্যা;
-* Multi-enum - মানগুলির তালিকা, একাধিক মান নির্বাচন করার ক্ষমতা (যদি আপনি এই ক্ষেত্রটি অনুসন্ধান করতে চান তবে ভাল বিকল্প না), তবে অ্যারের মতই কিন্তু নিখুঁত।
-* Text - পাঠ্য এলাকা, দীর্ঘ multiline গ্রন্থে জন্য;
-* Url - লিঙ্কের জন্য;
-* Varchar - সংক্ষিপ্ত লেখা;
-* Wysiwyg - টেক্সট ফরম্যাটের অনুরূপ, পাঠ্য ফর্ম্যাট করার ক্ষমতা।
-
-প্যারামিটার:
-* Required - ক্ষেত্রের ভর্তি বাধ্যতামূলক হয় কিনা।
-* Default Value - ক্ষেত্রের মান নতুন রেকর্ড তৈরি উপর সেট।
-* Audited - ক্ষেত্র আপডেটগুলি লগ ইন করা হবে স্ট্রিম
-
-**নোট**: আপনি নতুন ক্ষেত্র যোগ করার পরে আপনি এই ক্ষেত্রটি রাখা প্রয়োজন [layouts](layout-manager.md) (Administration > Layout Manager).
-
-### ডায়নামিক লজিক
-
-ফরমগুলি গতিশীল করতে একটি ক্ষমতা প্রদান করে। নির্দিষ্ট ক্ষেত্রগুলি দৃশ্যমান, প্রয়োজনীয় বা শুধুমাত্র পঠনযোগ্য করে তুলতে অবস্থার সংজ্ঞায়িত করা সম্ভব। ফর্ম পরিবর্তন যখন তথ্য স্বয়ংক্রিয়ভাবে পরীক্ষা করা হবে।
-
-Enum, Array এবং Multi Enum ক্ষেত্রগুলির জন্য ক্ষেত্রের জন্য উপলব্ধ বিভিন্ন সেট বিকল্পগুলি সংজ্ঞায়িত করা সম্ভব হয় যা কোন শর্ত পূরণ করা হয় তার উপর নির্ভর করে।
-
-
-## সম্পর্ক
-
-আপনি আউট অফ বাক্স এবং কাস্টম সত্তা উভয় মধ্যে নতুন সম্পর্ক তৈরি করতে পারেন। 3 উপলব্ধ সম্পর্ক ধরন আছে:
-
-* One-to-Many: আপনি এই সম্পর্ক তৈরি করেছেন পরে আপনি ডান সত্তা বিস্তারিত লেআউট একটি লিঙ্ক ক্ষেত্র স্থাপন এবং বাম সত্তা সম্পর্ক প্যানেল যোগ করতে পারেন।
-* Many-to-One: এক-টু-অনের মতোই কিন্তু বিপরীতভাবে;
-* Many-to-Many: উভয় পক্ষের সম্পর্ক প্যানেল।
-
-প্যারামিটার 'Link Multiple Field' মানে যে ক্ষেত্রের `linkMultiple` সম্পর্কের সাথে টাইপ তৈরি করা হবে। আপনি লেআউট এ যেমন একটি ক্ষেত্র স্থাপন করতে পারেন। সম্পর্কিত রেকর্ড দ্রুত picking জন্য এটি সুবিধাজনক। এটি একটি ভাল বিকল্প না হলে আপনার সম্পর্ক বিস্তারিত তালিকা স্ক্রিন লোড হ্রাস করতে পারেন যা সংযুক্ত লিঙ্ক অনেক আছে উদ্দেশ্যে করা হয়।
-
-যদি প্যারামিটার 'Audited' চেক করা হয় তাহলে সম্পর্কের আপডেটগুলি লগ ইন করা হবে স্ট্রিম।
-
diff --git a/i18n/bn_BD/administration/extensions.md b/i18n/bn_BD/administration/extensions.md
deleted file mode 100644
index 0feff5d76..000000000
--- a/i18n/bn_BD/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# এক্সটেনশানগুলি পরিচালনা করুন
-
-## কিভাবে একটি এক্সটেনশান ইনস্টল করতে হয়
-
-EspoCRM এক্সটেনশন (যেমন উন্নত প্যাক, ভিওআইপি ইন্টিগ্রেশন) ইনস্টল করার জন্য:
-
-1. একজন অ্যাাডমিনিসট্রেটর হিসাবে লগইন করুন।
-2. যান Administration > Extensions.
-3. আপনার এক্সটেনশন প্যাকেজ (জিপ ফাইলে) আপলোড করুন।
-4. ইনস্টল করুন বোতাম ক্লিক করুন।
-
-
-## কিভাবে একটি এক্সটেনশন আপগ্রেড করতে হয়
-
-একটি নতুন সংস্করণে একটি ইতিমধ্যে ইনস্টল এক্সটেনশন (উদাঃ উন্নত প্যাক, ভিওআইপি ইন্টিগ্রেশন) আপগ্রেড করার জন্য:
-
-1. প্রয়োজনীয় এক্সটেনশনটি নতুন সংস্করনে ডাউনলোড করুন
-2. একজন অ্যাাডমিনিসট্রেটর হিসাবে লগইন করুন।
-3. যান Administration > Extensions.
-4. ইতিমধ্যে ইনস্টল সংস্করণ আনইনস্টল ছাড়া আপনার নতুন এক্সটেনশন প্যাকেজ (জিপ ফাইল) আপলোড করুন।
-5. ইনস্টল করুন বোতাম ক্লিক করুন।
-
-
-## কিভাবে একটি এক্সটেনশন আনইনস্টল করতে হয়
-
-একটি ইনস্টল করা এক্সটেনশন আনইনস্টল করার ধাপ:
-
-1. একজন অ্যাাডমিনিসট্রেটর হিসাবে লগইন করুন।
-2. যান Administration > Extensions.
-3. উপলব্ধ এক্সটেনশনগুলির তালিকায় প্রয়োজনীয় এক্সটেনশান খুঁজুন।
-4. আনইনস্টল বোতামটি ক্লিক করুন।
-
-
-## কিভাবে একটি এক্সটেনশন মুছে ফেলতে হয়
-
-যখন একটি এক্সটেনশানটি আনইনস্টল করা হয় তখন এটি সিস্টেমটিতে এখনও উপলব্ধ। এটি সম্পূর্ণভাবে মুছে ফেলা হতে পারে। একটি এক্সটেনশন মুছে ফেলার ধাপ:
-
-1. একজন অ্যাাডমিনিসট্রেটর হিসাবে লগইন করুন।
-2. যান Administration > Extensions.
-3. উপলব্ধ এক্সটেনশনগুলির তালিকায় প্রয়োজনীয় এক্সটেনশান খুঁজুন।
-4. রিমুভ বোতামটি ক্লিক করুন।
diff --git a/i18n/bn_BD/administration/formula.md b/i18n/bn_BD/administration/formula.md
deleted file mode 100644
index c6f4b8a48..000000000
--- a/i18n/bn_BD/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# গণনাকৃত ক্ষেত্র (সূত্র)
-
-সত্তা ব্যবস্থাপকের মধ্যে নির্দিষ্ট সত্তা টাইপের জন্য স্ক্রিপ্ট (সূত্র) নির্ধারণ করা সম্ভব। রেকর্ড সংরক্ষিত হবার আগে এই স্ক্রিপ্ট সঞ্চালিত হবে।
-এটি গণনা থেকে প্রাপ্ত মানের সাথে নির্দিষ্ট ক্ষেত্রগুলি (বৈশিষ্ট্য) স্বয়ংক্রিয়ভাবে সেট করার একটি ক্ষমতা প্রদান করে।
-
-সূত্র সম্পাদনা করতে অনুসরণ করুন Administration > Entity Manager > dropdown menu at the right on the row of needed entity > Formula.
-আপনাকে ক্ষেত্র সেট করতে প্রয়োজন হতে পারে, গণনা করা অনুমিত হয়, এনটাইটীটি ম্যানেজার মাধ্যমে শুধুমাত্র পড়ুন।
-
-
-
-## বাক্য গঠন
-
-EspoCRM সূত্র এই বৈশিষ্ট্যটির জন্য বিশেষভাবে পরিকল্পিত সহজ ভাষায় লেখা হয়।
-
-অপারেটর আছে, ফাংশন গুণাবলী এবং মান সূত্র ব্যবহার করা যেতে পারে। অক্ষর দ্বারা বিভাজিত এক্সপ্রেশনকে বিভক্ত করা আবশ্যক`;`.
-
-### অপারেটরসমুহ
-
-* `=` - অ্যাসাইনমেন্ট।
-* `||` - লজিকাল অর,
-* `&&` - লজিকাল অ্যান্ড,
-* `!` - লজিকাল নট,
-* `+`- সাংখ্যিক যোগিকরন,
-* `-` - সাংখ্যিক বিয়োগীকরন,
-* `*` - সাংখ্যিক গুনন,
-* `/` - সাংখ্যিক বিভক্তিকরন,
-* `%` - সাংখ্যিক মডিউল,
-* `==` - তুলনীয় সমান,
-* `!=` - তুলনীয় সমান না,
-* `>` - তুলনীয় অপেক্ষাক্রিত বৃহত্তর,
-* `<` - তুলনীয় কম,
-* `>=` - তুলনীয় বড় বা সমান,
-* `<=` - তুলনীয় কম বা সমান.
-
-অপারেটরদের অগ্রাধিকার:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### বৈশিষ্ট্যাবলী
-
-বৈশিষ্ট্য লক্ষ্য সত্তা এর ক্ষেত্র মান প্রতিনিধিত্ব করে। প্লাস বাটন ক্লিক করে আপনি উপলব্ধ বৈশিষ্ট্যগুলি সন্নিবেশ করতে পারেন।
-
-নিম্নোক্ত বিন্যাসের সাথে সম্পর্কিত সংস্থার বৈশিষ্ট্যগুলি অ্যাক্সেস করা সম্ভব `linkName.attributeName`.
-
-
-### ফাংশনসমুহ
-
-ফাংশন ব্যবহারের বিন্যাস: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Out-of-the-box ফাংশন নীচের তালিকাভুক্ত করা হয়।
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` যদি শর্ত পূরণ করা হয় তবে CONSEQUENT করুন। যদি না - তারপর আলাদাভাবে করুন।
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` যদি শর্ত পূরণ করা হয় তবে CONSEQUENT করুন। যদি না হয় - কিছুই করবেন না।
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` দুই বা ততোধিক স্ট্রিংগুলি সমন্বয় করে।
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` START অবস্থান এবং LENGTH দ্বারা একটি STRING থেকে অক্ষর এক্সট্র্যাক্ট করে।
-
-যদি LENGTH বাদ দেওয়া হয়, তবে START থেকে শুরু হওয়া STRING এর শেষ পর্যন্ত শুরু হওয়া সাবস্ট্রিংটি ফেরত দেওয়া হবে।
-
-যদি LENGTH নেতিবাচক হয়, তাহলে অনেক অক্ষর STRING শেষে শেষ হবে।
-
-#### string\\trim
-`string\trim(STRING)` STRING এর প্রারম্ভে এবং শেষে থেকে রেখাচিত্রমালা স্ট্রিপগুলি।
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` নিম্ন ক্ষেত্রের অক্ষরে রূপান্তর করে। (সংস্করণ 5.0.0 থেকে)।
-
-#### string\\upperCase
-`string\upperCase(STRING)` ঊর্ধ্ব ক্ষেত্রের অক্ষরে রূপান্তর করে। (সংস্করণ 5.0.0 থেকে)।
-
-#### datetime\\today
-`datetime\today()` আজকের তারিখে ফেরত।
-
-#### datetime\now
-`datetime\now()` বর্তমান ডেটটাইম রিটার্ন করে।
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` অ্যাপ্লিকেশন সেটিংস অনুযায়ী স্ট্রিং ফর্ম্যাট করা তারিখ বা ডেটাটাইম VALUE রূপান্তর করে। টাইমজোন এবং FORMAT বাদ দেওয়া যাবে। যদি টাইমজোন বাদ দেওয়া হয় তাহলে ডিফল্ট টাইম জোনটি ব্যবহার করা হবে। যদি FORMAT বাদ দেওয়া হয় তবে ডিফল্ট বিন্যাসটি ব্যবহার করা হবে।
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Returns date of the month (1-31). `0` যদি VALUE খালি থাকে। যদি TIMEZONE বাদ দেওয়া হয় তাহলে সিস্টেম টাইমজোন ব্যবহার করা হয়। (সংস্করণ 4.7.0 থেকে)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Returns month (1-12). `0` যদি VALUE খালি থাকে। যদি TIMEZONE বাদ দেওয়া হয় তাহলে সিস্টেম টাইমজোন ব্যবহার করা হয়। (সংস্করণ 4.7.0 থেকে)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Returns year. `0` যদি VALUE খালি থাকে। যদি TIMEZONE বাদ দেওয়া হয় তাহলে সিস্টেম টাইমজোন ব্যবহার করা হয়। (সংস্করণ 4.7.0 থেকে)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Returns hour (0-23). `-1` যদি VALUE খালি থাকে। যদি TIMEZONE বাদ দেওয়া হয় তাহলে সিস্টেম টাইমজোন ব্যবহার করা হয়। (সংস্করণ 4.7.0 থেকে)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Returns minute (0-59). `-1` যদি VALUE খালি থাকে। যদি TIMEZONE বাদ দেওয়া হয় তাহলে সিস্টেম টাইমজোন ব্যবহার করা হয়। (সংস্করণ 4.7.0 থেকে)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Returns day of the week (0-6). `-1` যদি VALUE খালি থাকে। `0` - রবিবারের জন্য যদি TIMEZONE বাদ দেওয়া হয় তাহলে সিস্টেম টাইমজোন ব্যবহার করা হয়। (সংস্করণ 4.7.3 থেকে)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Returns difference between two dates or datetimes. INTERVAL_TYPE can be 'years', 'months', 'days', 'hours', 'minutes'. Returns `null` if failure. Result will be negative if VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` DATTIME VALUE এর MINUTES যোগ করে MINUTES ঋণাত্মক হতে পারে।
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` DATTIME VALUE এ HOURS যোগ করে HOURS নেতিবাচক হতে পারে।
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` তারিখ বা datetime VALUE যোগ করে DAYS নেতিবাচক হতে পারে।
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` WEEKS তারিখ বা তারিখ সময় VALUE যোগ করে WEEKS নেতিবাচক হতে পারে।
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` তারিখ বা ডেটটাইম VALUE এর জন্য MONTHS যোগ করে MONTHS নেতিবাচক হতে পারে।
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` তারিখ বা ডেটটাইম VALUE এর জন্য YEARS জুড়েছে YEARS নেতিবাচক হতে পারে।
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` পাস করা আর্গুমেন্টগুলির উপর ভিত্তি করে VALUE- এর নিকটতম তারিখ বা ডেটাটাইম ফেরত দেয়। (সংস্করণ 5.0.0 থেকে)
-
-TYPE নিম্নলিখিত মানগুলির মধ্যে একটি হতে পারে: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. TARGET একটি পূর্ণসংখ্যা মান বা একটি স্ট্রিং মান। IS_PAST অতীতের নিকটতম খুঁজে পেতে মানে যদি টাইমজোন বাদ দেওয়া হয় তাহলে ডিফল্ট টাইমজোন ব্যবহার করা হয়।
-
-উদাহরণ:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` 20:00 সময় সঙ্গে ভবিষ্যতে নিকটতম datetime মান ফিরে আসবে।
-
-`datetime\closest('2017-11-20', 'date', 1, true)` ফিরে আসবে `2017-11-01`, মাসের প্রথম দিন।
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` পরের সোমবার ফিরে আসবে (দিনের শুরুতে)।
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` একটি নির্দিষ্ট বিন্যাস বা ডিফল্ট অ্যাপ্লিকেশন সেটিংস অনুসারে স্ট্রিং ফর্ম্যাট করা সাংখ্যিক VALUE রূপান্তর করে। যদি DECIMALS, DECIMAL_MARK বা THOUSAND_SEPARATOR তারপর সিস্টেম ডিফল্টগুলি ব্যবহার করা হয়
-
-উদাহরণ:
-
-`number\format(2.666667, 2)` - ফলাফল 2.67;
-
-`number\format(1000, 2)` - ফলাফল 1,000.00;
-
-`number\format(10.1, 0)` - ফলাফল 10.
-
-
-#### number\abs
-`number\abs(VALUE)` পরম মান যদি সংখ্যাটি সাংখ্যিক না হয় তবে উল্লিখিত হয়।
-
-#### number\round
-`number\round(VALUE, PRECISION)` নির্ধারিত PRECISION (দশমিক বিন্দুর পরে সংখ্যা সংখ্যা) এর মানের মান পূরণ করে। PRECISIONও নেগেটিভ বা শূন্য (ডিফল্ট) হতে পারে।
-
-#### number\floor
-`number\floor(VALUE)` প্রয়োজনীয় সর্বনিম্ন মান পরে নীচের সর্বনিম্ন পূর্ণসংখ্যা মান ফেরত দেয় (সংস্করণ 4.9.0 থেকে)
-
-#### number\ceil
-`number\ceil(VALUE)` যদি প্রয়োজন হয় তাহলে সর্বোচ্চ মানের পূর্ণসংখ্যা মান ফেরত পাঠায়। (সংস্করণ 4.9.0 থেকে)
-
-#### entity\isNew
-`entity\isNew()` যদি সত্তাটি নতুন (তৈরি করা হয়) এবং মিথ্যা না হলে (সত্যিকারের আপডেট করা হয়) সত্যিকারের সত্য প্রদান করে।
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` সত্তা এর ATTRIBUTE পরিবর্তন করা হয়, তাহলে TRUE প্রদান করে।
-
-উদাহরণ:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` TRUE ফেরত আসে যদি সত্তাটির ATTRIBUTE পরিবর্তন না হয়।
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` অ্যাট্রিবিউট যা সেট করা হয়েছিল যখন টার্গেট সত্তা ডাটাবেস থেকে আনা হয়েছিল। এটি সংশোধন করার আগে।
-
-উদাহরণ:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` একাধিক ক্ষেত্র লিঙ্ক আইডি যোগ করুন। উদাহরণ স্বরূপ, যোগ করুন 'someTeamId' থেকে 'teams'ক্ষেত্র।
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` আইডি তালিকা যুক্ত করে (সংস্করণ 4.8.3 থেকে)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` লিংক একাধিক ক্ষেত্রের নির্দিষ্ট আইডি নির্দিষ্ট কিনা তা পরীক্ষা করে।
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` লিঙ্ক একাধিক ক্ষেত্র থেকে একটি নির্দিষ্ট আইডি মুছে ফেলে।
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` লক্ষ্য সত্তাটি LINK এবং ID দ্বারা উপস্থাপিত অন্য সত্তাটির সাথে সম্পর্কিত কিনা তা পরীক্ষা করে।
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` বর্তমান ব্যবহারকারীর ATTRIBUTE প্রদান করে।
-
-#### list
-`list(VALUE-1, ... VALUE-N)` অ্যারে ফেরত আসে (সংস্করণ 4.7.0 থেকে)।
-
-#### array\includes
-`array\includes(LIST, VALUE)` যদি তালিকাতে VALUE অন্তর্ভুক্ত থাকে তবে সত্য প্রদান করে অ্যারে এবং মাল্টি-Enum ক্ষেত্রগুলির জন্য ব্যবহার করা যেতে পারে। (সংস্করণ 4.7.0 থেকে)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` একটি অ্যারের শেষে এক বা একাধিক উপাদান যোগ করে এবং নতুন অ্যারে ফেরৎ। (সংস্করণ 5.0.0 থেকে)
-
-#### array\length
-`array\length(LIST)` LIST- এ উপাদানগুলির সংখ্যা গণনা দেয় (সংস্করণ 4.8.1 থেকে)
-
-
-### ভ্যালু
-
-* স্ট্রিংস। উদাহরণস্বরূপ 'some string';
-* পূর্ণ সংখ্যা উদাহরণস্বরূপ 1, 100, 40300.
-* ফ্ল্যাট সংখ্যা। E.g. 5.2.
-
-### ভেরিয়েবল
-
-সূত্র মধ্যে কাস্টম ভেরিয়েবল সংজ্ঞায়িত করা সম্ভব।
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## উদাহরণ
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## ওয়ার্কফ্লো মধ্যে সূত্র ব্যবহার
-
-আপনি ওয়ার্কফ্লো শর্ত এবং কর্মের সূত্র ব্যবহার করতে পারেন। দেখুন [workflows documentation](workflows.md) আরও তথ্যের জন্য।
diff --git a/i18n/bn_BD/administration/import.md b/i18n/bn_BD/administration/import.md
deleted file mode 100644
index 704730c3f..000000000
--- a/i18n/bn_BD/administration/import.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# আমদানি
-
-আমদানি শুধুমাত্র অ্যাডমিন ব্যবহারকারীদের জন্য অ্যাক্সেসযোগ্য। Administration > Import. আপনি শুধুমাত্র CSV ফাইল থেকে আমদানি করতে সক্ষম।
-
-## ধাপ 1
-
-আপনি যে ধরনের রেকর্ডগুলি আমদানি করতে চান তা নির্বাচন করুন (এনট্টিটি প্রকার ক্ষেত্র)।
-একটি CSV ফাইল নির্বাচন করুন। একটি ফাইলের সাথে ফরম্যাট করা উচিত `UTF-8`।
-সিলেক্ট করুন `What to do?`। উপলব্ধ বিকল্প: 'Create Only', 'Create & Update', 'Update Only'.
-
-* `Create Only` - এটি নির্বাচন করুন যদি আপনি চান যে রেকর্ডটি কেবলমাত্র তৈরি করা হয়।
-* `Create & Update` - রেকর্ড তৈরি করা হবে কিন্তু যদি ক্ষেত্র মান মান মেলে রেকর্ড খুঁজে পাওয়া যাবে এটি আপডেট করা হবে। আপনি Step 2_ এ কি ক্ষেত্রগুলির সাথে মেলে তা পরীক্ষা করতে সক্ষম হবেন।
-* `Update only` - শুধুমাত্র মান মান পূরণের রেকর্ডগুলি পাওয়া যাবে এটি আপডেট হবে।
-
-একবার আপনি একটি সিএসভি ফাইল নির্বাচন করে দেখতে পারবেন পূর্বরূপ প্যানেলে কীভাবে পার্স করা উচিত। আপনি বৈশিষ্ট্য পরিবর্তন যখন পূর্বরূপ আপডেট করা হবে।
-
-* `Header Row` - CSV ফাইলে ক্ষেত্রের নাম দিয়ে প্রথম সারি আছে কি না।
-* `Execute in idle` - যদি আপনি আমদানি করার জন্য রেকর্ডের একটি বড় গুচ্ছ আছে সুপারিশ। আমদানি ক্রন দ্বারা প্রক্রিয়া করা হবে। আমদানির প্রক্রিয়া শেষ হলে স্থিতিটি 'Complete' -এ সেট করা হবে।
-* `Skip searching for duplicates` - এটি আমদানি রানটাইম কমিয়ে দিবে।
-
-পদক্ষেপ 2_ এ এগিয়ে যাওয়ার জন্য _Next_ বোতাম ক্লিক করুন
-
-
-
-## ধাপ ২
-
-ক্ষেত্রের ম্যাপিং সেটআপ করুন: ক্ষেত্রগুলি সিএসভি ফাইলের কলামের সাথে সম্পর্কিত। আপনি এখানে প্রয়োজনীয় কলামগুলি ত্যাগ করতে পারবেন না।
-'Create & Update' এবং 'Update only' এর ক্ষেত্রে আপনি যাতে ক্ষেত্রগুলি চেক করতে চান সেগুলি যাতে আপডেট হওয়া উচিত তা পাওয়া যাবে।
-ডিফল্ট মান যোগ করুন আপনি সেট করতে চান নতুন এবং আপডেট রেকর্ড চান। উদাহরণস্বরূপ আপনি সীমাবদ্ধ ব্যবহারকারী বা টিম ক্ষেত্রগুলি নির্দিষ্ট করতে পারেন।
-
-আমদানি সম্পন্ন হওয়ার পর আপনি তৈরি করা রেকর্ডগুলি ফিরিয়ে নিতে সক্ষম হবেন, প্রতিলিপি এবং আপডেট করা রেকর্ডগুলি দেখতে পাবেন। ডুপ্লিকেট মানে সিস্টেমের অনুরূপ রেকর্ড ছিল। আপনি একবারে সমস্ত আমদানি করা সদৃশগুলি সরাতে পারেন। দ্রষ্টব্য: পূর্বাবস্থায় ফেরা আপডেটগুলি রেকর্ডের সাথে কাজ করে না।
-
-এগিয়ে যাওয়ার জন্য _ আমদানি করুন _ বোতামটি ক্লিক করুন একটি আমদানি প্রক্রিয়া সম্পন্ন হওয়ার আগে এটি কিছু সময় লাগতে পারে। যদি আপনি একটি বড় গুচ্ছ রেকর্ড আমদানি করতে চান (আপনার সার্ভার কনফিগারেশন উপর নির্ভর করে, সাধারণত যদি 200 রেকর্ডের বেশি) আপনি যে php পরামিতি নিশ্চিত করতে প্রয়োজন`set_time_limit` যথেষ্ট বড়।
-
-
-
-## লক্ষ্য তালিকাতে কিভাবে আমদানি করতে হয়
-
-যখন আপনি পরিচিতিগুলি আমদানি করেন, লেড বা অ্যাকাউন্টগুলি আপনি কিছু টার্গেট তালিকায় যুক্ত করতে পারেন। ধাপ 2 এ আপনাকে লক্ষ্য তালিকার ক্ষেত্র যোগ করতে হবে `Default Values` প্যানেল এবং একটি প্রয়োজনীয় টার্গেট তালিকা রেকর্ড নির্বাচন করুন। আপনি আরও ব্যবহার করতে পারেন`Update only` or `Create & Update` একটি লক্ষ্য তালিকায় বিদ্যমান লক্ষ্য যোগ করার জন্য আমদানি।
diff --git a/i18n/bn_BD/administration/installation.md b/i18n/bn_BD/administration/installation.md
deleted file mode 100644
index 0b82ac5b0..000000000
--- a/i18n/bn_BD/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# ইন্সট্যালেশন
-
-### আবশ্যকতা
-EspoCRM বেশিরভাগ হোস্টিং প্রদানকারীদের উপর চালান করে। প্রয়োজনীয়তা নিম্নলিখিত অন্তর্ভুক্ত করুন:
-
-* পিএইচপি 5.6 বা পিএইচপি এর সর্বশেষ সংস্করণ সক্রিয় পিডোর, json, জিডি লাইব্রেরি, এমক্রিপ্ট এক্সটেনশন (ডিফল্টরূপে সাধারণত সক্রিয়);
-* মাইএসকিউএল 5.5.3 বা উচ্চতর।
-
-দেখুন [সার্ভার কনফিগারেশন](server-configuration.md) আরও তথ্যের জন্য নিবন্ধ
-
-### 1. EspoCRM ইনস্টলেশন প্যাকেজটি ডাউনলোড করুন
-EspoCRM অনুসরণের সর্বশেষ সংস্করণটি পেতে [ডাউনলোড পৃষ্ঠা](http://www.espocrm.com/download/) লিঙ্ক।
-
-### 2. আপনার সার্ভারে EspoCRM ফাইল আপলোড করুন
-
-একবার ডাউনলোড শেষ হলে, আপনার ওয়েব সার্ভারে প্যাকেজ আপলোড করুন।
-এটি আপলোড করতে আপনি এসএসএইচ, এফটিপি বা হোস্টিং প্রশাসন প্যানেল ব্যবহার করতে পারেন।
-আপনার পাবলিক ওয়েব সার্ভার ডিরেক্টরি (যেমন, `public_html`, `www`, ইত্যাদি)।
-
-_Note: FTP এর জন্য, আপনার ওয়েব সার্ভারে আপলোড করার আগে আপনাকে আর্কাইভটি বের করতে হবে।_
-
-### 3. EspoCRM ব্যবহার করার জন্য একটি মাইএসকিউএল ডাটাবেস তৈরি করুন
-
-আপনার হোস্টিং প্রশাসন প্যানেলে যান, বা SSH তে, এবং এস্পোসিআরএম এর জন্য একটি নতুন ডাটাবেস এবং ব্যবহারকারী তৈরি করুন (যেমন, `MySQL Databases` সিপ্যানেল এ)।
-
-### 4. EspoCRM ইনস্টলেশন প্রক্রিয়া চালান
-
-এখন, আপনার ওয়েব ব্রাউজার খুলুন, এবং EspoCRM ফাইলগুলির সাথে URL এ যান (যেমন, `http://yourdomain.com/espo`)।
-
-আপনি এই পর্দা দেখতে হলে, আপনি একটি "Permission denied" ত্রুটি আছে
-সুতরাং, আপনি প্রদর্শিত কমান্ডটি দ্বারা SSH মাধ্যমে টার্মিনালে চালানো প্রয়োজন, বা সঠিক অনুমতি সেট।
-এটি ডিরেক্টরের জন্য 755, ফাইলের জন্য 644, এবং 775 এর জন্য হওয়া উচিত `data` ডিরেক্টরিতে।
-এছাড়াও নিশ্চিত করুন যে আপনার সঠিক _owner_ এবং _group_ রয়েছে
-
-
-
-আপনি যদি নীচের পর্দাটি দেখতে পান, অনুমতি সঠিক এবং আপনি EspoCRM ইনস্টল করতে শুরু করতে পারেন।
-
-
-
-এই পৃষ্ঠাতে, আপনি লাইসেন্স চুক্তিটি পড়তে ও গ্রহণ করতে পারেন।
-
-
-
-আপনার নতুন তৈরি মাইএসকিউএল ডাটাবেসের বিস্তারিত লিখুন।
-
-
-
-প্রশাসক EspoCRM ব্যবহারকারী নাম এবং পাসওয়ার্ড লিখুন।
-
-
-
-এই পৃষ্ঠায় আপনি EspoCRM এর ডিফল্ট সেটিংস সেট করতে পারেন, যেমন তারিখ এবং সময় বিন্যাস, টাইমজোন, কারেন্সি এবং অন্যান্য।
-
-
-
-আউটগোয়িং ইমেইলের জন্য এসএমটিপি সেটিংস প্রবেশ করুন, যদি আপনি ইমেল প্রেরণ করার ক্ষমতা থাকতে চান
-এই ধাপটি _Next_ বোতাম ক্লিক করে এড়িয়ে যেতে পারে।
-ইনস্টলেশনের পরে এই সমস্ত বিকল্পগুলি EspoCRM- এ যোগ করা / পরিবর্তিত হতে পারে।
-
-
-
-অভিনন্দন! ইনস্টলেশন সম্পূর্ণ।
-আপনার সিস্টেম দ্বারা চালানো শি্ডডট টাস্ক সেট আপ শেষ জিনিস। এটি চলমান দ্বারা সম্পন্ন করা যেতে পারে `crontab -e` উইন্ডোজ সিস্টেমে linux cli এবং _Windows Tasks Scheduler_ এ।
-
-
-
-আমরা আশা করি আপনি EspoCRM এ কাজ উপভোগ করতে করবেন।
-
-
-
-
-
-
-
diff --git a/i18n/bn_BD/administration/layout-manager.md b/i18n/bn_BD/administration/layout-manager.md
deleted file mode 100644
index bd58afa8c..000000000
--- a/i18n/bn_BD/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# লেআউট ম্যানেজার
-
-লেআউট ম্যানেজার অ্যাডমিনিস্ট্রেটর প্যানেলে উপলব্ধ। বিস্তৃত বিবরণ, সম্পাদন, তালিকার দৃশ্য এবং অনুসন্ধান ফিল্টার এবং গণ-আপডেট ফর্মগুলির ক্ষেত্রগুলি কাস্টমাইজ করার ক্ষমতা প্রদান করে।
-
-## তালিকা
-
-তালিকা দেখুন জন্য প্রধান বিন্যাস। কলাম এবং তাদের পরামিতি নির্ধারণ করে।
-
-
-
-কলামগুলর জন্য উপলব্ধ প্যারামিটার নীচে তালিকাভুক্ত করা হয়।
-
-### প্রস্থ (%)
-
-কলামের প্রস্থ শতাংশ, খালি মানে স্বয়ং-প্রস্থ।
-
-### লিংক
-
-যদি চেক করা হয় তবে ক্ষেত্রটি রেকর্ডের বিস্তারিত দৃশ্যের একটি লিঙ্ক হিসাবে প্রদর্শিত হবে। সাধারণত নাম ক্ষেত্রগুলির জন্য ব্যবহার করা হয়
-
-### বাছাইযোগ্য না
-
-কলাম সাজানোর ক্ষমতা অক্ষম করে।
-
-### শ্রেণীবদ্ধ করা
-
-কলামটি বাম বা ডানদিকে সন্নিবেশ করান।
-
-## বিস্তারিত
-
-বিস্তারিত ভিউ এবং সম্পাদনা প্রদর্শনের জন্য প্রধান বিন্যাস প্যানেল, সারি এবং ঘর নির্ধারণ করে কোষগুলি ক্ষেত্রগুলি ধারণ করে।
-
-সারিটি দুটি কক্ষ বা একক কক্ষ ধারণ করতে পারে যা সারির পূর্ণ প্রস্থে সম্প্রসারিত হয়। আপনি একটি নতুন সারি যোগ করার প্রয়োজন একটি প্রসারিত সেল সঙ্গে সারি যোগ করুন এবং কোনো সেল নেভিগেশন একটি সাইন চিহ্ন ক্লিক করুন।
-
-
-
-## তালিকা (ছোট)
-
-সম্পর্ক প্যানেল জন্য তালিকা বিন্যাস। এছাড়াও অন্যান্য স্থানে ব্যবহার করা যেতে পারে যেখানে এটি সংকীর্ণ দৃশ্যের তালিকা প্রদর্শনযোগ্য।
-
-## বিস্তারিত (ছোট)
-
-দ্রুত তৈরি, দ্রুত ভিউ এবং দ্রুত সম্পাদনা ফর্মগুলির বিস্তারিত বিবরণ।
-
-## অনুসন্ধান ফিল্টার
-
-তালিকায় দেখুন উপলব্ধ ক্ষেত্রের তালিকা দ্বারা অনুসন্ধান।
-
-## গণ আপডেট
-
-গণ আপডেট ফর্ম পাওয়া ক্ষেত্রের তালিকা।
-
-## সম্পর্ক প্যানেল
-
-নীচের অংশে বিস্তারিত দৃশ্যের উপর প্রদর্শিত সম্পর্ক প্যানেলের তালিকা। প্যানেল পুনরায় আদেশ করা যেতে পারে স্টাইলের প্যারামিটারের সাথে প্যানেলের রং নির্ধারণ করা সম্ভব।
-
-## সাইড প্যানেলস
-
-বিস্তারিত জন্য সাইড প্যানেল, সম্পাদনা, বিস্তারিত ছোট, ছোট আকার সম্পাদনা করুন প্যানেল তালিকা গোপন বা পুনরায় অর্ডার করার ক্ষমতা প্রদান করে ক্রিয়াকলাপ, ইতিহাস, কার্য এবং অন্যান্য। প্যানেলগুলি শৈলী প্যারামিটার দ্বারা রঙিন করা যায়।
-
-## অতিরিক্ত লেআউটসমুহ
-
-কিছু সত্তা ধরনের অতিরিক্ত লেআউট ধারণ করে: লিড রূপান্তর, অ্যাকাউন্টের জন্য তালিকা।
diff --git a/i18n/bn_BD/administration/ldap-authorization-for-ad.md b/i18n/bn_BD/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index acd5c7220..000000000
--- a/i18n/bn_BD/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# সক্রিয় ডিরেক্টরি জন্য LDAP অনুমোদন
-
-সক্রিয় ডিরেক্টরি সার্ভারের কনফিগারেশন LDAP অনুমোদনের উদাহরণ। কনফিগারেশন LDAP অনুমোদনের সম্পূর্ণ গাইড বর্ণিত হল [এখানে](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/bn_BD/administration/ldap-authorization-for-openldap.md b/i18n/bn_BD/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 6bd6eacbb..000000000
--- a/i18n/bn_BD/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# OpenLDAP এর জন্য LDAP অনুমোদন
-
-OpenLDAP সার্ভারের কনফিগারেশন LDAP অনুমোদনের উদাহরণস্বরূপ কনফিগারেশন LDAP অনুমোদনের সম্পূর্ণ গাইডে বর্ণিত হল [এখানে](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/bn_BD/administration/ldap-authorization.md b/i18n/bn_BD/administration/ldap-authorization.md
deleted file mode 100644
index 18c984242..000000000
--- a/i18n/bn_BD/administration/ldap-authorization.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# Ldap অনুমোদন
-
-এই গাইডে, আমরা EspoCRM এর জন্য LDAP অনুমোদন কীভাবে কনফিগার করব তা দেখাবো। চলুন যাই.
-
-আপনার LDAP সার্ভারে যান এবং EspoCRM ব্যবহারকারীদের জন্য একটি বেস DN তৈরি করুন
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-ব্যবহারকারীদের DN এ অ্যাক্সেস থাকতে হবে আমাদের এমন একটি সিস্টেম ব্যবহারকারী তৈরি করতে হবে (“cn=espo-users,ou=users,dc=espo,dc=local”)। সুতরাং, এই সিস্টেম ব্যবহারকারীর জন্য পূর্ণ DN হবে
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-এখন, আমরা EspoCRM অ্যাক্সেস করতে LDAP ব্যবহারকারীকে যুক্ত করতে পারি। উদাহরন, ব্যবহারকারীর নাম দিয়ে Espo টেস্টার “tester” ভেতরে “cn=espo-users,ou=users,dc=espo,dc=local” DN। দয়া করে নোট করুন: EspoCRM এর জন্য এই লগইন ফরম্যাট ব্যবহার করতে সক্ষম করতে আপনাকে নির্দিষ্ট করতে হবে “ব্যবহারকারীর নাম অ্যাট্রিবিউট” এবং “বেস DN” অপশানসমূহ।
-
-তারপর, অ্যাডমিনিস্ট্রেটর প্যানেলে EspoCRM প্রমাণীকরণ সেটিংসে যান, নির্বাচন করুন `LDAP` পদ্ধতি এবং বিস্তারিত LDAP পূরণ করুন:
-
-
-
-* Host – LDAP আইপি বা হোস্ট নাম।
-* Port – সংযোগ পোর্ট।
-* Auth – LDAP সার্ভারের জন্য প্রমাণপত্রাদি অ্যাক্সেস করুন:
- * Full User DN – সম্পূর্ণ সিস্টেম ব্যবহারকারী DN যা অনুমতি দেয় অন্যান্য ব্যবহারকারীদের অনুসন্ধান করতে।
- * Password – LDAP সার্ভার অ্যাক্সেস পাসওয়ার্ড।
-* Security – SSL বা TLS প্রোটোকল।
-* Username Attribute – ব্যবহারকারীর সনাক্তকরণের বৈশিষ্ট্য সক্রিয় ডিরেক্টরি জন্য এটি হতে পারে “userPrincipalName” বা “sAMAccountName”.
-* Account Canonical Form – আপনার অ্যাকাউন্ট ক্যানোনিকাল ফর্ম টাইপ। 4 বিকল্প আছে:
- * Dn – বিন্যাসে ফর্ম `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – ফর্ম `tester`.
- * Backslash – ফর্ম `COMPANY\tester`.
- * Principal – ফর্ম `tester@company.com`.
-* Bind Requires Dn – যদি DN ফর্মের ইউজারনেম ফর্ম্যাট করার প্রয়োজন হয়।
-* Base Dn – ডিফল্ট বেস DN যা ব্যবহারকারীদের অনুসন্ধানের জন্য ব্যবহৃত হয়।
-* User Login Filter – ফিল্টার যা ব্যবহারকারীদের EspoCRM ব্যবহার করতে সক্ষম সীমাবদ্ধ করতে পারবেন। উদাহরণস্বরূপ `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – ডোমেন যা অনুমোদন LDAP সার্ভারের জন্য ব্যবহৃত হয়।
-* Account Domain Name Short – LDAP সার্ভার অনুমোদনের জন্য ব্যবহৃত ছোট ডোমেন।
-* Try Username Split – ডোমেনের সাথে একটি ইউজারনেম বিভক্ত করার বিকল্প।
-* Opt Referrals – if রেফারেলগুলি LDAP ক্লায়েন্টের সাথে অনুসরণ করা উচিত।
-* Create User in EspoCRM – এই বিকল্পটি EspoCRM এ LDAP থেকে একটি ব্যবহারকারী তৈরি করতে সক্ষম করে।
- * User First Name Attribute – LDAP অ্যাট্রিবিউট যা ব্যবহারকারী প্রথম নামটি নির্ধারণ করতে ব্যবহৃত হয়।
- * User Last Name Attribute – LDAP অ্যাট্রিবিউট যা ব্যবহারকারীর নামটি নির্ধারণ করতে ব্যবহৃত হয়।
- * User Title Attribute – LDAP অ্যাট্রিবিউট যা ব্যবহারকারীর শিরোনাম নির্ধারণ করতে ব্যবহৃত হয়।
- * User Email Address Attribute – LDAP অ্যাট্রিবিউট যা ব্যবহারকারীর ইমেইল অ্যাড্রেস নির্ধারণ করতে ব্যবহৃত হয়।
- * User Phone Number Attribute – LDAP অ্যাট্রিবিউট যা ব্যবহারকারীর ফোন নম্বর নির্ধারণ করতে ব্যবহৃত হয়।
-
-এখন, লগইন পৃষ্ঠাতে যান এবং ব্যবহারকারীর শংসাপত্রগুলি প্রবেশ করুন।
-
-
-
-ব্যবহারকারী প্রমাণিত হয়েছে এবং স্বয়ংক্রিয়ভাবে EspoCRM এ তৈরি করা হয়েছে।
-
-##আপনার সার্ভারের উপর ভিত্তি করে কনফিগারেশন নির্দেশাবলী:
-* [সক্রিয় ডিরেক্টরি সার্ভার](ldap-authorization-for-ad.md)
-* [OpenLDAP সার্ভার](ldap-authorization-for-openldap.md)
-
-LDAP কনফিগার করার বিষয়ে আরো তথ্য আপনি এগুলি পড়তে পারেন [Zend\Ldap লাইব্রেরি](https://zendframework.github.io/zend-ldap/intro/) পৃষ্ঠা, EspoCRM এই লাইব্রেরি ব্যবহার করে।
-
diff --git a/i18n/bn_BD/administration/maps.md b/i18n/bn_BD/administration/maps.md
deleted file mode 100644
index e0cb22bbe..000000000
--- a/i18n/bn_BD/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# মানচিত্র
-
-## একটি ঠিকানা ক্ষেত্রের উপর ভিত্তি করে মানচিত্রটি কীভাবে দেখানো হবে
-
-প্রতিটি ঠিকানা ক্ষেত্রের সংশ্লিষ্ট মানচিত্র ক্ষেত্র আছে। আপনার সমস্ত প্রয়োজনীয়তা বিস্তারিত বিন্যাস এটি করা হয়। এটি Google মানচিত্র পরিষেবা ব্যবহার করে।
-
-`অ্যাাডমিনিসট্রেটর > লেআউট ম্যানেজার > সত্তা নির্বাচন করুন (অ্যাকাউন্ট, যোগাযোগ, লিড বা কাস্টম এক) > বিস্তারিত > ড্র্যাগ এবং ড্রপ ম্যাপ ক্ষেত্র।`
-
-মাইনাস চিহ্ন ব্যবহার করে ঘরের চৌকাঠটি তৈরি করুন।
-
-আপনি আপনার ক্ষেত্রের উচ্চতা কনফিগার করতে পারেন।
-
-`অ্যাাডমিনিসট্রেটর > সত্তা ম্যানেজার > সত্তা নির্বাচন করুন > ক্ষেত্রসমুহ > মানচিত্রের ক্ষেত্রটি খুঁজুন এবং এটিতে ক্লিক করুন > উচ্চতা সম্পাদনা করুন এবং সংরক্ষণ করুন।`
-
-## Api চাবি
-
-EspoCRM সংস্করণ 4.2.0 থেকে আপনি গুগল ম্যাপস ব্যবহার করার জন্য Api কী নির্দিষ্ট করতে হবে (অ্যাাডমিনিসট্রেটর > ইন্টিগ্রেশন > Google Maps)।
-
diff --git a/i18n/bn_BD/administration/moving-to-another-server.md b/i18n/bn_BD/administration/moving-to-another-server.md
deleted file mode 100644
index a56570a68..000000000
--- a/i18n/bn_BD/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# EspoCRM অন্য সার্ভারে সরানো হচ্ছে
-
-অন্য সার্ভারে EspoCRM সরানোর জন্য এই পদক্ষেপগুলি অনুসরণ করুন:
-
-### পদক্ষেপ 1. ব্যাকআপ ফাইল
-
-একটি ফাইল ম্যানেজার খুলুন বা SSH এর মাধ্যমে লগইন করুন EspoCRM ডাইরেক্টরি থেকে সমস্ত উপলব্ধ ফাইল আর্কাইভ করুন আরো বিস্তারিত: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### পদক্ষেপ 2. ব্যাকআপ আপনার ডাটাবেস
-
-ডেটাবেস (MySQL, MariaDB) -এ সংরক্ষিত ডাটা ব্যাকআপ করা উচিত। এই সুপারিশটি অনুসরণ করুন: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### পদক্ষেপ 3. অন্য সার্ভারে ফাইল এবং ডাটাবেস ব্যাকআপ কপি
-
-একটি নতুন সার্ভারে ফাইল এবং আপনার ডাটাবেসের ব্যাকআপ কপি।
-
-### পদক্ষেপ 4. আনআর্কাইভ ব্যাকআপ ফাইল
-
-ব্যাকআপ ফাইলগুলি আনআর্কাইভ করতে, আপনি আর্কাইভ ম্যানেজার বা এই নির্দেশনাটি ব্যবহার করতে পারেন: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-দ্রষ্টব্য: ফাইলগুলি ওয়েব-সার্ভারের ডিরেক্টরির মধ্যে স্থাপন করা প্রয়োজন।
-
-### পদক্ষেপ 5. একটি সার্ভার কনফিগার করুন
-
-এখানে সুপারিশগুলির উপর ভিত্তি করে একটি নতুন সার্ভার কনফিগার করুন: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### পদক্ষেপ 6. সঠিক অনুমতি
-
-প্রয়োজনীয় অনুমতি এবং ফাইল মালিক সেট করুন, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### পদক্ষেপ 7. আপনার ডাটাবেস ব্যাকআপ আমদানি করুন
-
-প্রথমত, আপনাকে একটি MySQL ব্যবহারকারীর সাথে একটি নতুন ডাটাবেস তৈরি করতে হবে। ব্যাকআপ থেকে আপনার ডাটাবেস আমদানি করতে, instuction অনুসরণ করুন: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### পদক্ষেপ 8. সঠিক EspoCRM কনফিগারেশন
-
-সার্ভার সফলভাবে আমদানি এবং কনফিগার করার পরে, ফাইলের EspoCRM কনফিগারেশন সঠিক করুন `ESPOCRM_DIRECTORY/data/config.php`:
-
- * ডাটাবেস সংযোগ সেটিংস:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - যদি আপনার ডোমেন নাম (URL) পরিবর্তিত হয়:
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * ডিফল্ট ফাইল মালিক (শুধুমাত্র যদি ভিন্ন হয়):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- যেখানে `www-data` আপনার ওয়েব-সার্ভার ব্যবহারকারী।
-
-### ধাপ 9. একটি ক্রনট্যাব সেটআপ করুন
-
-একটি ক্রনট্যাব সেটআপ করুন, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-দ্রষ্টব্য: এটি আপনার ওয়েব সার্ভার ব্যবহারকারীর অধীনে কনফিগার করা উচিত।
-
-এখানেই শেষ. এখন, আপনার EspoCRM একটি নতুন সার্ভারে চলছে।
diff --git a/i18n/bn_BD/administration/nginx-server-configuration.md b/i18n/bn_BD/administration/nginx-server-configuration.md
deleted file mode 100644
index 3b45c03fd..000000000
--- a/i18n/bn_BD/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# EspoCRM এর জন্য Nginx সার্ভার কনফিগারেশন
-
-এই নির্দেশাবলী থেকে সম্পূরক [সার্ভার কনফিগারেশন](server-configuration.md) গাইডলাইন। দয়া করে মনে রাখবেন এখানে তালিকাভুক্ত সমস্ত কনফিগারেশন সেটিংস উবুন্টু সার্ভারে তৈরি করা হয়েছে।
-
-## PHP প্রয়োজনীয়তা
-
-সমস্ত প্রয়োজনীয় লাইব্রেরিগুলি ইনস্টল করতে, এই কমান্ডগুলি একটি টার্মিনালে চালান:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## সমস্যাটি সমাধান করা "API ত্রুটি: EspoCRM API অনুপলব্ধ":
-
-প্রয়োজনীয় পদক্ষেপ নিন। সমস্যাটি সমাধান করা হলে প্রতিটি পদক্ষেপের পরে পরীক্ষা করুন।
-
-### 1. Nginx সার্ভারে পুনরায় লেখা নিয়মগুলি সক্ষম করুন
-
-আপনার Nginx সার্ভার ব্লক কনফিগার ফাইল এই কোডটি যোগ করুন (/etc/nginx/sites-available/YOUR_SITE) ভিতরে “server” ব্লক:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-আপনার যদি এই ফাইল না থাকে, তবে আপনাকে এটি তৈরি করতে হবে। এই জন্য একটি টার্মিনাল খুলুন এবং কমান্ডটি চালান:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-এবং উপরে তালিকাভুক্ত কোড যোগ করুন। Nginx- এ নতুন ভার্চুয়াল হোস্ট কনফিগার করার বিষয়ে আরো তথ্যের জন্য, দয়া করে এটি পড়ুন [ গাইডলাইন](nginx-virtual-host.md).
-
-সবকিছু ঠিক আছে কিনা তা পরীক্ষা করতে টার্মিনালে এই কমান্ডটি চালান:
-
-```
-sudo nginx -t
-```
-
-যদি তাই হয়, nginx সার্ভার পুনরায় আরম্ভ করার জন্য কমান্ডটি চালান:
-
-```
-sudo service nginx restart
-```
-
-### 2. RewriteBase পাথ যোগ করুন
-
-একটি ফাইল খুলুন /ESPOCRM_DIRECTORY/api/v1/.htaccess এবং নিম্নলিখিত লাইন প্রতিস্থাপন করুন:
-
-```
-# RewriteBase /
-```
-সাথে
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-যেখানে REQUEST_URI এর একটি URL অংশ, যেমন “http://example.com/espocrm/” জন্য, REQUEST_URI হয় “espocrm”.
diff --git a/i18n/bn_BD/administration/nginx-virtual-host.md b/i18n/bn_BD/administration/nginx-virtual-host.md
deleted file mode 100644
index 760293978..000000000
--- a/i18n/bn_BD/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# EspoCRM- এর জন্য Nginx- এ একটি ভার্চুয়াল হোস্ট কনফিগার
-
-এই গাইডে আমরা উবুন্টু সার্ভারে EspoCRM জন্য Nginx একটি ভার্চুয়াল হোস্ট কনফিগার কিভাবে দেখাতে হবে।
-
-## একটি সার্ভার ব্লক ফাইল তৈরি করুন
-
-এই ফাইল তৈরি করতে, একটি টার্মিনাল খুলুন এবং কমান্ডটি চালান:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-এখন, এই ফাইলটি খুলুন (/etc/nginx/sites-available/espocrm.conf) এবং নীচের মুদ্রিত বিন্যাস অনুসরণ কোড সংশোধন করুন (কিছু সেটিংস আপনার কনফিগারেশন উপর ভিত্তি করে পৃথক হতে পারে):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## এই সার্ভার ব্লক সক্ষম করুন
-
-একটি সাংকেতিক লিঙ্ক তৈরি করুন:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-সবকিছু ঠিক আছে কিনা তা পরীক্ষা করতে এই কমান্ডটি চালান:
-
-```
-sudo nginx -t
-```
-
-এবং Nginx সার্ভার পুনরায় আরম্ভ করুন:
-
-```
-sudo service nginx restart
-```
-
-## আপনার স্থানীয় হোস্ট কনফিগার করুন (ঐচ্ছিক, শুধুমাত্র একটি স্থানীয় ডোমেইনের জন্য)
-
-আপনি যদি একটি স্থানীয় ডোমেন যোগ করেন, তাহলে আপনাকে এটি আপনার স্থানীয় কম্পিউটারে (সার্ভারে নয়) কনফিগার করতে হবে। উবুন্টুর জন্য, ফাইলটি খুলুন `/etc/hosts` এবং লাইন যোগ করুন:
-
-```
-192.168.1.1 espocrm.local # specify the IP address of your Nginx server
-```
-
-উইন্ডোজের জন্য, এইগুলি অনুসরণ করুন [নির্দেশাবলী](http://support.microsoft.com/kb/923947)।
diff --git a/i18n/bn_BD/administration/portal.md b/i18n/bn_BD/administration/portal.md
deleted file mode 100644
index 05630d5f8..000000000
--- a/i18n/bn_BD/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# পোর্টাল
-
-পোর্টাল আপনার গ্রাহকদের এবং অংশীদারদের জন্য নির্দিষ্ট CRM ডেটা এবং ফাংশন অ্যাক্সেস করার একটি ক্ষমতা প্রদান করে। অ্যাাডমিনিসট্রেটর একাধিক পোর্টাল তৈরি করতে পারেন। প্রতিটি পোর্টালের নিজস্ব সেটিংস, ড্যাশলবোর্ড, ব্যবহারকারী তালিকা, অ্যাক্সেস কন্ট্রোল সেটিংস থাকতে পারে।
-
-পোর্টাল তৈরি করতে ফলো অ্যাাডমিনিসট্রেটর > পোর্টাল, পোর্টাল তৈরি করুন বোতাম ক্লিক করুন।
-
-* `Is Active`. যদি চেক না এমন পোর্টাল অন্য কারো জন্য উপলব্ধ হবে না।
-* `Is Default`. যে পোর্টাল ছোট URL দ্বারা উপলব্ধ হবে মানে: http(s)://YOUR_ESPO_URL/portal.
-* `Roles`. পোর্টাল লগ ইন ব্যবহারকারীদের জন্য প্রয়োগ করা হবে এক বা একাধিক পোর্টাল ভূমিকা নির্দিষ্ট করুন। পোর্টাল ভূমিকা সম্পর্কে আরও তথ্য নীচের হয়।
-* `Tab List`. ট্যাব যা ন্যাভিগেশন বার দেখানো হবে।
-* `Dashboard Layout`. ড্যাশলেটগুলি নির্দিষ্ট করুন যা পোর্টালের হোম পৃষ্ঠায় প্রদর্শিত হবে। উল্লেখ্য যে পোর্টাল ব্যবহারকারীরা তাদের ড্যাশবোর্ড কনফিগার করতে পারে না।
-* `URL`. কেবল পঠন পড়ুন যা আপনি লিঙ্ক প্রদর্শন অ্যাক্সেস করতে পারেন পোর্টাল এর সাথে।
-
-## পোর্টাল ব্যবহারকারী
-
-অ্যাাডমিনিসট্রেটর তৈরি করতে পারেন পোর্টাল ব্যবহারকারীদের।
-
-1. অ্যাাডমিনিসট্রেটর > ব্যবহারকারী.
-2. ব্যবহারকারী তৈরির পাশে ক্লিক করুন ডান ড্রপডাউন।
-3. পোর্টাল ব্যবহারকারী তৈরি করুন ক্লিক করুন
-4. পোর্টাল ব্যবহারকারীর সাথে যোগাযোগ করুন নির্বাচন করুন।
-5. ফর্ম পূরণ করুন এবং সংরক্ষণ করুন ক্লিক করুন।
-
-পোর্টাল ব্যবহারকারীকে যে পোর্টাল অ্যাক্সেস করতে সক্ষম হতে পোর্টাল রেকর্ড সংযুক্ত করা উচিত।
-
-## পোর্টাল ভূমিকা
-
-পোর্টাল ভূমিকা EspoCRM মধ্যে নিয়মিত ভূমিকা অনুরূপ কিন্তু কয়েক পার্থক্য এর সঙ্গে।
-
-* `not-set` স্তর একটি প্রবেশাধিকার অস্বীকার করে।
-* `own` স্তর মানে ব্যবহারকারীর দ্বারা রেকর্ড তৈরি করা হয়। উদাহরণস্বরূপ পোর্টাল ব্যবহারকারী কিছু মামলা জারি এবং এই ক্ষেত্রে এই ব্যবহারকারীর মালিকানাধীন।
-* `account` স্তর মানে হল যে পোর্টাল ব্যবহারকারীর সাথে সম্পর্কিত অ্যাকাউন্টের সাথে সম্পর্কিত রেকর্ড সম্পর্কিত।
-* `contact` স্তরের মানে হল যে পোর্টাল ব্যবহারকারীর সাথে সম্পর্কিত যোগাযোগ সম্পর্কিত রেকর্ডটি সংশ্লিষ্ট।
-
-বরাদ্দ ব্যবহারকারী এবং টিম ক্ষেত্র শুধুমাত্র পোর্টাল ব্যবহারকারীদের জন্য পড়ানো হয়।
-
-### উদাহরণ
-
-`পোর্টাল ব্যবহারকারীদের ক্ষেত্রে তৈরি করতে সক্ষম হওয়া উচিত, তাদের অ্যাকাউন্টের সাথে সম্পর্কিত ক্ষেত্রে দেখুন; তারা জ্ঞান বেস দেখতে সক্ষম হওয়া উচিত।`
-
-1. পোর্টাল ভূমিকা ফর্ম তৈরি করুন (অ্যাাডমিনিসট্রেটর > পোর্টাল ভূমিকা > ভুমিকা তৈরি) খুলুন.
-2. মামলার অ্যাক্সেস সক্ষম করুন, সেট করুন: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. জ্ঞান বেস অ্যাক্সেস সক্ষম করুন, সেট করুন `create - no, read - account, edit - no, delete - no`.
-4. আপনার পোর্টাল রেকর্ড সম্পাদনা করুন (অ্যাাডমিনিসট্রেটর > পোর্টাল)। ভূমিকা ক্ষেত্রের মধ্যে আপনার পোর্টাল ভূমিকা নির্বাচন করুন এবং তারপর সংরক্ষণ করুন।
-
-## পোর্টালে অ্যাক্সেস
-
-আপনি পোর্টাল রেকর্ডের 'URL' ক্ষেত্রের মধ্যে আপনার পোর্টালের জন্য url খুঁজে পেতে পারেন। এছাড়াও বিভিন্ন url দ্বারা অ্যাক্সেস করতে সক্ষম সার্ভার কনফিগারেশন সরঞ্জাম (যেমন mod_rewrite) ব্যবহার করা সম্ভব। এই ক্ষেত্রে আপনাকে 'কাস্টম URL' ক্ষেত্রটি পূরণ করতে হবে।
-
-### Apache সার্ভারের জন্য কাস্টম URL দ্বারা পোর্টাল অ্যাক্সেস করুন
-
-কাস্টম URL: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### মোড পুনর্লিখন নিয়ম
-
-তে পোর্টাল রেকর্ড আইডি নির্দিষ্ট করুন `{PORTAL_ID}` এর পরিবর্তে। পোর্টাল রেকর্ড আইডি আপনার ওয়েব ব্রাউজারের অ্যাড্রেস বারে পাওয়া যাবে যখন আপনি পোর্টাল রেকর্ডের বিস্তারিত বিবরণ খুলবেন। যেমন: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 একটি পোর্টাল নিবন্ধন আইডি হয়।
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/bn_BD/administration/roles-management.md b/i18n/bn_BD/administration/roles-management.md
deleted file mode 100644
index bad01982b..000000000
--- a/i18n/bn_BD/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# ভূমিকা ব্যবস্থাপনা
-
-## সংক্ষিপ্ত বিবরণ
-
-আপনাকে ভূমিকাগুলি ব্যবহার করতে হব কিছু ব্যবহারকারীদের অ্যাক্সেস সীমাবদ্ধ করার জন্যে। প্রশাসক প্রশাসন প্যানেলের ভূমিকা পরিচালনা করতে পারেন। প্রত্যেকটি ভূমিকা নির্দিষ্ট এলাকার (স্কোপগুলি) অ্যাক্সেস নির্ধারণ করে যা ব্যবহারকারীদের কাছে সেই ভূমিকাটির মালিক হয়।
-
-একাধিক ভূমিকা থাকতে পারে এক ব্যবহারকারীর। যারা ভূমিকা একটি নির্দিষ্ট ব্যবহারকারী (ব্যবহারকারীর প্রবেশের ক্ষেত্রে 'Roles' ক্ষেত্র) এবং/অথবা ব্যবহারকারীর অন্তর্গত টিমগুলি থেকে উত্তরাধিকার লাভের জন্য নির্বাচিত হতে পারে।
-
-যদি কোনো ব্যবহারকারীর একাধিক ভূমিকা থাকে তবে তাদের একত্রীকরণ করা হবে যাতে অনুমোদিত নীতির একটি উচ্চতর অগ্রাধিকার থাকবে। যে প্রশাসক সহজেই এবং flexibly অ্যাক্সেস স্তরের নিয়ন্ত্রণ পরিচালনা করতে পারবেন
-
-ব্যবহারকারীর বিস্তারিত ভিউতে 'অ্যাক্সেস' বোতামটি ক্লিক করার মাধ্যমে কোন নির্দিষ্ট ব্যবহারকারীকে অনুমতি দেওয়া হয় তা দেখতে পাওয়া সম্ভব।
-
-
-
-## উদাহরন
-
-উদাহরণস্বরূপ, ব্যবহারকারী 'Sales' দলের অন্তর্গত সেই দলের একক ভূমিকা 'Salesman' তাই এই দলের সকল ব্যবহারকারী 'Salesman' ভূমিকা পাবেন।
-
-‘Salesman’ ভূমিকা নিম্নলিখিত উপায় সংজ্ঞায়িত করা হয়:
-
-লিড:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-সুযোগ:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-ব্যবহারকারীরা কেবলমাত্র সেইগুলি এবং সুযোগগুলি পড়তে সক্ষম হবে যা 'সেলস ডিপার্টমেন্ট' টিম ('টিমস' ক্ষেত্র) এর অন্তর্গত।
-ব্যবহারকারী কেবলমাত্র সেইগুলি এবং সুযোগগুলি সম্পাদনা করতে সক্ষম হবে যা তাদের নিযুক্ত করা হয় বা তাদের তৈরি করা হয়েছে।
-ব্যবহারকারীরা কোনও লিড বা সুযোগ সরাতে সক্ষম হবে না।
-
-আমরা একটি নির্দিষ্ট ব্যবহারকারীর আরো অধিকার দিতে চাই যারা কোম্পানির বিক্রয় পরিচালকের পদমর্যাদা রাখে। এই 'কর্মচারী' থেকে 'বিক্রয়' দল থেকে সমস্ত রেকর্ড / সম্পাদনা / মুছে ফেলার ক্ষমতা থাকতে হবে। ব্যবহারকারী আমাদের 'সেলস' দলের অন্তর্গত হওয়া উচিত। কিন্তু আমাদের নতুন ভূমিকা 'সেলস ম্যানেজার' তৈরি করতে হবে এবং 'রোলস' ক্ষেত্রে এই ব্যবহারকারীর জন্য এই ভূমিকাটি নির্বাচন করুন।
-.
-
-'সেলস ম্যানেজার' ভূমিকা নিম্নলিখিত পদ্ধতি সংজ্ঞায়িত করা হয়:
-
-লিড:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-সুযোগ:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-আমাদের ব্যবহারকারী ম্যানেজার সকল বিক্রয় এবং সুযোগগুলি 'বিক্রয়' দল থেকে সক্ষম করতে সক্ষম হবে।
-
-## বিশেষ অনুমতিগুলি
-
-### নিয়োগের অনুমতি
-
-অন্য ব্যবহারকারী এবং/অথবা দলগুলিকে রেকর্ড পুনঃনির্ধারণ করার ক্ষমতা সীমিত করার জন্য এই প্যারামিটারটি সেট করুন। `team` - তারপর এটি শুধুমাত্র নিজের দলের (ব্যবহারকারীদের) ব্যবহারকারীদের জন্য বরাদ্দ করা সম্ভব হবে। If `no` - ব্যবহারকারীরা সব সময়ে পুনরায় স্থানান্তর করতে পারবে না।
-
-এটি ব্যবহারকারীকে অন্য ব্যবহারকারী/দলগুলির স্ট্রিম করতে পোস্ট করতে সক্ষম কিনা তা সংজ্ঞায়িত করে।
-
-### ব্যবহারকারীর অনুমতি
-
-ব্যবহারকারীদের ক্রিয়াকলাপ, ক্যালেন্ডার এবং অন্যান্য ব্যবহারকারীদের স্ট্রিম দেখতে ব্যবহারকারীদের জন্য একটি ক্ষমতা সীমিত করার অনুমতি দেয়।
-
-### পোর্টাল অনুমতি
-
-পোর্টাল তথ্য অ্যাক্সেস, পোর্টাল ব্যবহারকারীদের বার্তা পোস্ট করার ক্ষমতা নির্ধারণ করে।
-
-### গ্রুপ ইমেল অ্যাকাউন্ট অনুমতি
-
-গ্রুপ ইমেল অ্যাকাউন্টগুলিতে একটি অ্যাক্সেস নির্ধারণ করে, গোষ্ঠী SMTP থেকে ইমেল পাঠানোর একটি ক্ষমতা।
-
-### রপ্তানি অনুমতি
-
-ব্যবহারকারীদের রেকর্ডগুলি রপ্তানি করার ক্ষমতা রয়েছে কিনা তা পরিস্কার করে। (সংস্করণ 4.9.0 থেকে)
-
-## ডিফল্ট দ্বারা অনুমতি
-
-ডিফল্টরূপে (যদি কোনও প্রয়োগ না থাকে) ব্যবহারকারীরা সমস্ত রেকর্ডগুলি পড়তে ও সম্পাদনা করতে পারেন। কিন্তু যারা তাদের তৈরি করেছেন তাদের ছাড়াও তারা মুছে যাবে না এবং একই সময়ে তারা নিয়োগ করা হয়।
-
-Administration>Settings এ 'ACL কঠোর মোড' সক্ষম করে ডিফল্টভাবে প্রয়োগ করা একটি অ্যাক্সেস সীমাবদ্ধ করার ক্ষমতা আছে।
-
-## ক্ষেত্রের স্তর নিরাপত্তা
-
-একটি নির্দিষ্ট ক্ষেত্রগুলির জন্য অ্যাক্সেস নিয়ন্ত্রণ করতে অনুমতি দেয়।
-
-ডিফল্ট ব্যবহারকারীর দ্বারা সমস্ত ক্ষেত্রগুলি পড়তে পারে যদি কেউ রেকর্ডটি পড়তে পারে। যদি কেউ রেকর্ডটি সম্পাদনা করতে পারে তবে ব্যবহারকারী কোনও ক্ষেত্র সম্পাদনা করতে পারেন। আপনি ক্ষেত্র স্তর নিরাপত্তা ব্যবহার করে নির্দিষ্ট ক্ষেত্রগুলিতে অ্যাক্সেস সীমাবদ্ধ করতে পারেন।
-
-ক্ষেত্রের স্তর অধ্যায় একটি ভূমিকা রেকর্ড দেখতে সম্পাদনা করুন নির্দিষ্ট বৈশিষ্ট্যের পাশে প্লাস আইকন তারপর প্রয়োজনীয় ক্ষেত্র নির্বাচন করুন। তারপর আপনি জন্য অ্যাক্সেসের স্তর নির্দিষ্ট করতে সক্ষম হবে `read` এবং `edit` কর্ম। বিকল্প আছে: `yes` and `no`।
-
-
diff --git a/i18n/bn_BD/administration/server-configuration.md b/i18n/bn_BD/administration/server-configuration.md
deleted file mode 100644
index a98e22f20..000000000
--- a/i18n/bn_BD/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# EspoCRM এর জন্য সার্ভার কনফিগারেশন
-
-EspoCRM ইনস্টল করা যেতে পারে Apache ([নির্দেশাবলী](apache-server-configuration.md)), Nginx ([নির্দেশাবলী](nginx-server-configuration.md)), অথবা IIS সার্ভার সমর্থন PHP সংস্করণ 5.6 বা বৃহত্তর এবং MySQL সংস্করণ 5.1 বা বৃহত্তর।
-
-## কনফিগারেশন সুপারিশগুলি
-
-### PHP এর প্রয়োজনীয়তা
-
-EspoCRM এর প্রয়োজন PHP 5.6 বা তার চেয়েও বেশি, নিম্নোক্ত এক্সটেনশনগুলি সক্ষম করে:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – PHP তে অ্যাক্সেস করতে MySQL;
-* [JSON](http://php.net/manual/en/book.json.php) – রিসোর্স এই বিন্যাস ব্যবহার করে (মেটাডেটা, লেআউট, ভাষা এবং অন্যান্য);
-* [GD](http://php.net/manual/en/book.image.php) – ইমেজ ম্যানুপুলেট করতে;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – সর্বোচ্চ সুরক্ষা নিশ্চিত করতে;
-* [Zip](http://php.net/manual/en/book.zip.php) – EspoCRM আপগ্রেড এবং এক্সটেনশান ইনস্টল করতে সক্ষম হতে;
-* [IMAP](http://php.net/manual/en/book.imap.php) – EspoCRM- এ মেলবক্সগুলি নিরীক্ষণ করতে;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-এছাড়াও [mailparse](https://pecl.php.net/package/mailparse) pecl এক্সটেনশন ইনস্টল করার সুপারিশ করা হয়েছে। ই-মেইল ফিচার ফিচারটি মসৃণ করার জন্য এটি প্রয়োজন।
-
-php.ini সেটিংস:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### MySQL এর আবশ্যকতা
-
-EspoCRM সমর্থন করে MySQL সংস্করণ 5.1 বা এর বেশি ।
-এই কোন বিশেষ অদ্ভুততা হয়। সমস্ত ডিফল্ট সেটিংস EspoCRM এর জন্য ভাল।
-
-## ইউনিক্স-ভিত্তিক সিস্টেমগুলির জন্য প্রয়োজনীয় অনুমতিসমুহ
-
-ফাইল এবং ডিরেক্টরিগুলির নিম্নলিখিত অনুমতি থাকা উচিত:
-
-* `/data`, `/custom`, `/client/custom` – সব ফাইল, ডিরেক্টরি এবং সাবডিরেক্টরি (ফাইলের জন্য 664, ডিরেক্টরীগুলির জন্য 775, সব সাবডিরেক্টরি এবং ফাইল সহ) লিখনযোগ্য হওয়া উচিত;
-* `/application/Espo/Modules`, `/client/modules` – বর্তমান ডিরেক্টরিতে লিখনযোগ্য (বর্তমান ডিরেক্টরি জন্য 775, ফাইলের জন্য 644, ডিরেক্টরি এবং subdirectories জন্য 755);
-* অন্যান্য সকল ফাইল এবং ডিরেক্টরিগুলি পড়তে হবে (ফাইলগুলির জন্য 644, ডিরেক্টরিগুলির জন্য 755)।
-
-অনুমতিগুলি সেট করতে, টার্মিনালে এই কমান্ডগুলি চালান:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-সমস্ত ফাইল মালিকানাধীন এবং ওয়েব সার্ভার প্রক্রিয়ার দ্বারা গ্রুপ মালিকানাধীন থাকা উচিত। এটি “www-data”, “daemon”, “apache”, “www”, ইত্যাদি হতে পারে।
-দ্রষ্টব্য: বিটমনি স্ট্যাকে, ফাইলগুলি "daemon" ব্যবহারকারীর মালিকানাধীন এবং গোষ্ঠীভুক্ত হওয়া উচিত।
-দ্রষ্টব্য: শেয়ার হোস্টগুলিতে, আপনার ব্যবহারকারী অ্যাকাউন্টের মালিকানাধীন এবং গোষ্ঠী-মালিকানা থাকা উচিত।
-
-মালিক এবং গ্রুপ-মালিক সেট করতে, টার্মিনালে এই কমান্ডগুলি চালান:
-
-```
-cd
-chown -R : .;
-```
-
-## একটি crontab সেটআপ করুন
-
-একটি UNIX সিস্টেমের মধ্যে একটি ক্রসট্যাব স্থাপন করতে, নিম্নলিখিত পদক্ষেপগুলি গ্রহণ করুন:
-
-* 1. আপনার EspoCRM উদাহরণের জন্য অ্যাডমিনিস্ট্রেটর হিসাবে লগইন করুন।
-* 2. অ্যাডমিনিস্ট্রেটিভ প্যানেলে নির্ধারিত চাকরির বিভাগে যান (Menu > Administration > Scheduled Jobs) এবং crontab এর জন্য স্ট্রিং কপি করুন। এটি এর মত মনে হচ্ছে:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. একটি টার্মিনাল খুলুন এবং এই কমান্ডটি চালান:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER নিম্নলিখিত “www”, “www-data”, “apache”, ইত্যাদি হতে পারে (আপনার ওয়েব সার্ভারে নির্ভর করে)।
-* 4. কপি করা স্ট্রিংটি পেস্ট করুন (ধাপ ২ থেকে) এবং crontab ফাইলটি সংরক্ষণ করুন (Ctrl+O, তারপর Ctrl+X ন্যানো সম্পাদকের জন্য).
-
-## আপনার সার্ভারের উপর ভিত্তি করে কনফিগারেশন এর নির্দেশাবলী:
-
-* [Apache সার্ভার কনফিগারেশন](apache-server-configuration.md).
-* [Nginx সার্ভার কনফিগারেশন](nginx-server-configuration.md).
diff --git a/i18n/bn_BD/administration/troubleshooting.md b/i18n/bn_BD/administration/troubleshooting.md
deleted file mode 100644
index 9acaff124..000000000
--- a/i18n/bn_BD/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# সমস্যা সমাধান
-
-## লগ চেক করুন
-
-সমস্যাটি খুঁজে বের করতে, আপনাকে ত্রুটিযুক্ত লগ ফাইলগুলি পরীক্ষা করতে হবে।
-
-#### EspoCRM ত্রুটি লগ
-
-EspoCRM লগ অবস্থিত `/logs/*.log` এ এবং কিছু ত্রুটি তথ্য রয়েছে।
-
-#### আপাচি ত্রুটি লগ
-
-উবুন্টু সার্ভারের জন্য একটি এ্যাপাচি ত্রুটি লগ অবস্থিত `/var/log/apache2/error.log` এ এবং সকল ত্রুটি তথ্য রয়েছে। লগ ফাইলসমুহের অবস্থান অন্যান্য সিস্টেমে ভিন্ন হতে পারে।
-
-## ডিবাগিং মোড সক্ষম করুন
-
-ডিবাগিং মোডটি সক্ষম করতে, ইনস্টল করা EspoCRM ডাইরেক্টরিতে যান, `data/config.php` ফাইলটি খুলুন এবং মান পরিবর্তন করুন:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-to
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## নির্ধারিত চাকরি কাজ করছে না
-
-#### সমস্যা #1: আপনার crontab কনফিগার করা নেই
-
-1. আপনার সার্ভার SSH এর মাধ্যমে লগইন করুন।
-
-2. এই পদক্ষেপগুলি অনুসরণ করে আপনার crontab কনফিগার করুন: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-বিঃদ্রঃ Crontab ওয়েব-সার্ভার ব্যবহারকারীর অধীনে কনফিগার করা উচিত, যেমন `crontab -e -u www-data`।
-
-3. কিছুক্ষণের জন্য অপেক্ষা করুন এবং নির্ধারিত চাকরিগুলি পরীক্ষা করুন যে কোনও কাজ সম্পাদন করা হয়েছে কি না (একটি লগ প্যানেল দেখুন)।
-
-#### সমস্যা #2 Crontab কনফিগার করা হয়েছে, কিন্তু নির্ধারিত চাকরি কাজ করছে না
-
-ক্রোন চলার সময় কোন ত্রুটি নেই তা নিশ্চিত করতে টার্মিনালে ক্রন কমান্ড চালানোর চেষ্টা করুন:
-
-1. আপনার সার্ভার SSH এর মাধ্যমে লগইন করুন।
-
-2. EspoCRM ইনস্টল করা আছে এমন ডিরেক্টরিতে যান। উদাহরণস্বরূপ, `/var/www/html/espocrm` ডিরেক্টরির জন্য কমান্ডটি হল:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Crontab কমান্ডটি চালান:
-
-```bash
-php cron.php
-```
-
-বিঃদ্রঃ এটি ওয়েব সার্ভার ব্যবহারকারীর অধীনে কার্যকর করা উচিত। যদি আপনি রুট হিসাবে লগ ইন করেন তবে এই কমান্ডটি হওয়া উচিত (যেমন উবুন্টু):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-যেখানে `www-data` হল একটি ওয়েব-সার্ভার ব্যবহারকারী।
-
-4. যদি কোন ত্রুটি না থাকে, তাহলে কোনও চাকরী কার্যকর করা হবে কিনা তা দেখতে নির্ধারিত চাকরি পরীক্ষা করুন (একটি লগ প্যানেল দেখুন)।
-
-## EspoCRM আপডেটের পরেও লোড হচ্ছে না
-
-এই কিছু শেয়ার হোস্টিং এর উপর কখনও কখনও ঘটতে পারে।
-
-ফাইলের অনুমতি পরীক্ষা করুন:
-/index.php
-/api/v1/index.php
-
-তাদের অবশ্যই 644 হতে হবে। যদি তাদের কোনও ফাইলের 664 অনুমতি থাকে তবে আপনাকে 644 এ পরিবর্তন করতে হবে। আপনার হোস্টিং কন্ট্রোল প্যানেল অথবা chmod কমান্ড ব্যবহার করুন।
-
-```
-chmod 644 /path/to/file
-```
-ফাইল অনুমতি সম্পর্কে আরো তথ্য: [এখানে](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/bn_BD/administration/upgrading.md b/i18n/bn_BD/administration/upgrading.md
deleted file mode 100644
index c49604f31..000000000
--- a/i18n/bn_BD/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# EspoCRM আপগ্রেড কিভাবে করবেন
-
-EspoCRM নিম্নলিখিত পদক্ষেপগুলি দ্বারা সর্বশেষ সংস্করণে আপগ্রেড করা যেতে পারে:
-
-### ধাপ 1. আপনার বর্তমান সংস্করণ চেক করুন
-
-আপনার বর্তমান সংস্করণ চেক করতে যান প্রশাসন> আপগ্রেড পৃষ্ঠা।
-
-### ধাপ 2. প্রয়োজনীয় আপগ্রেড প্যাকেজ ডাউনলোড করুন
-
-আপগ্রেড পাতায় যান https://www.espocrm.com/download/upgrades/ এবং আপনার বর্তমান সংস্করণ উপর ভিত্তি করে প্রয়োজনীয় প্যাকেজ ডাউনলোড করুন।
-
-### ধাপ 3. একটি ব্যাকআপ তৈরি করুন (ঐচ্ছিক)
-
-আপগ্রেড করার আগে আপনার EspoCRM ফাইল এবং ডেটা ব্যাকআপ তৈরি করুন। অনুসরণ করুন [এইসব নির্দেশাবলী](https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md) এটি সম্পন্ন করতে।
-
-### ধাপ 4. আপগ্রেড প্রক্রিয়া
-
-প্রশাসন> আপগ্রেড এ যান। একটি আপগ্রেড প্যাকেজ দ্বারা আপলোড এবং ইনস্টল করুন।
-
-আপনি মেনুতে> সম্পর্কে সর্বশেষ সংস্করণটি আছে কি না তা পরীক্ষা করতে পারেন।
-
-## CLI এর মাধ্যমে আপগ্রেড করুন
-
-আপনি কমান্ড লাইন ইন্টারফেসের মাধ্যমে আপগ্রেড করতে পারেন। আপনি EspoCRM রুট ডিরেক্টরি থেকে নিম্নলিখিত কমান্ড চালানোর প্রয়োজন:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/bn_BD/administration/workflows.md b/i18n/bn_BD/administration/workflows.md
deleted file mode 100644
index 4e8971b9d..000000000
--- a/i18n/bn_BD/administration/workflows.md
+++ /dev/null
@@ -1,145 +0,0 @@
-# ওয়ার্কফ্লো
-
-ওয়ার্কফ্লো বৈশিষ্ট্য পাওয়া যায় এখানে [উন্নত প্যাক](https://www.espocrm.com/extensions/advanced-pack/)।
-
-ওয়ার্কফ্লো আপনার ব্যবসা প্রক্রিয়াটি একটি সহজ উপায় স্বয়ংক্রিয় করে। আপনি প্রশাসন প্যানেল এ এটি খুঁজে পেতে পারেন। একটি ওয়ার্কফ্লো নিয়ম তৈরি করতে আপনাকে সংজ্ঞায়িত করতে হবে:
-
-* টার্গেট সত্তা - কোন সত্তা টাইপে ওয়ার্কফ্লো প্রয়োগ করা হয়;
-* ট্রিগার টাইপ - যখন কর্মক্ষেত্রটি চালিত হবে;
-* শর্ত - কর্মক্ষেত্রটি ট্রিগার করার জন্য শর্ত পূরণ করা প্রয়োজন;
-* ক্রিয়াকলাপ - যদি কর্মক্ষেত্রটি প্রবর্তিত হয় তবে কি করতে হবে।
-
-
-## ট্রিগার টাইপসমুহ
-
-### রেকর্ড তৈরির পরে
-
-একটি নতুন রেকর্ড তৈরি করা হয় শুধুমাত্র যখন ট্রিগার। যদি নির্দিষ্ট শর্ত পূরণ করা হয় তাহলে কর্মগুলি কার্যকর করা হবে।
-
-### রেকর্ড সংরক্ষিত পরে
-
-একটি নতুন রেকর্ড তৈরি বা একটি বিদ্যমান রেকর্ড আপডেট করা হয় যখন ট্রিগার। যদি নির্দিষ্ট শর্ত পূরণ করা হয় তাহলে কর্মগুলি কার্যকর করা হবে।
-
-এই ধরনের ট্রিগারের সঙ্গে কর্মপ্রবাহ নিয়মের জন্য এটি একটি ক্ষেত্র আছে কিনা পরীক্ষা কর যা কিছু ক্ষেত্র ছিল একটি সাধারণ অভ্যাস 'changed'। উদাহরণস্বরূপ যদি কেস এর অবস্থা পরিবর্তিত হয় তবে কিছু কর্ম সঞ্চালন।
-
-### তালিকাভুক্ত
-
-নির্ধারিত সময়সূচী অনুযায়ী ট্রিগার। আপনি প্রতি সপ্তাহে চালানোর জন্য এটি সেটআপ করতে পারেন, ইত্যাদি। একটি নির্দিষ্ট তালিকা প্রতিবেদন দ্বারা ফিরে রেকর্ডের জন্য কর্ম প্রয়োগ করা হবে। তাই আপনাকে একটি তালিকা প্রতিবেদন তৈরি করতে হবে।
-
-একটি ক্রনট্যাব অনুকরণে নির্ধারণ নির্ধারণ করা হয়।
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### অনুক্রমিতাসংবন্ধীয়
-
-ব্যবহৃত খুব কমই। অন্য কর্মপ্রবাহ দ্বারা চালিত হতে অনুমিত একটি জটিল যুক্তি তৈরি করার ক্ষমতা প্রদান করে।
-
-নোট: অনুক্রমিক ওয়ার্কফ্লো জন্য এটি ব্যবহার করার জন্য সুপারিশ করা হয় [BPM টুল](bpm.md) বরং একটি ওয়ার্কফ্লো বৈশিষ্ট্য তুলনায়।
-
-## শর্তসমুহ
-
-আপনি ওয়ার্কফ্লো ট্রিগার ট্রিগার পূরণ করতে হবে শর্ত নির্দিষ্ট করতে পারেন। শর্তাবলী নির্দিষ্ট করা যেতে পারে এমন দুটি উপায় আছে: UI শর্ত বিন্যাসকারী এবং সূত্র দিয়ে।
-
-### UI শর্ত বিন্যাসকারী
-
-কিছু উপলব্ধ শর্তের ধরন:
-
-* _equals_ - ক্ষেত্র একটি নির্দিষ্ট মান বা অন্য ক্ষেত্রের একটি মান সমান;
-* _was equal_ - কর্মফল প্রবাহিত হওয়ার আগে ক্ষেত্রটি একটি নির্দিষ্ট মান সমান ছিল;
-* _not equals_ - ক্ষেত্র একটি নির্দিষ্ট মান বা অন্য ক্ষেত্রের মান সমান নয়;
-* _was not equal_ - কর্মফল প্রবাহিত হওয়ার পূর্বে ক্ষেত্র নির্দিষ্ট মানের সমান নয়;
-* _empty_ - ক্ষেত্রের মান খালি;
-* _not empty_ - ক্ষেত্রের মান খালি নয়;
-* _changed_ - ক্ষেত্র পরিবর্তন করা হয়েছিল;
-* _not changed_ - ক্ষেত্র পরিবর্তিত হয় নি।
-
-### সূত্র শর্তাবলী
-
-সূত্র কোন জটিলতার অবস্থার সংজ্ঞায়িত করার একটি ক্ষমতা প্রদান করে। সূত্র সিনট্যাক্স অনুসরণ পড়ার জন্য [এই নিবন্ধটি](formula.md).
-
-নোট: কোনও হওয়া উচিত নয় `;` সীমাবদ্ধ সূত্র কোড ব্যবহৃত যখন এটি একটি শর্ত নির্ধারণ করে।
-
-## ক্রিয়াকলাপ
-
-### ইমেইল পাঠান
-
-সিস্টেম একটি নির্দিষ্ট ইমেইল টেমপ্লেট ব্যবহার করে একটি ইমেল পাঠাতে হবে। একটি প্রাপকের ইমেল ঠিকানাটি টার্গেট রেকর্ড, কোনও সম্পর্কিত রেকর্ড, বর্তমান ব্যবহারকারী, অনুগামী, দল ব্যবহারকারী বা নির্দিষ্ট করা থেকে নেওয়া যেতে পারে। একটি নির্দিষ্ট ব্যবধানের জন্য ইমেল অবিলম্বে পাঠানো বা বিলম্বিত হতে পারে।
-
-### রেকর্ড তৈরি করুন
-
-সিস্টেম কোন সত্তা টাইপ নতুন রেকর্ড তৈরি করবে। যদি লক্ষ্য রেকর্ডের মধ্যে একটি সম্পর্ক থাকে এবং রেকর্ড তৈরি করা হয় তবে এটি রেকর্ডগুলির সাথে সম্পর্কযুক্ত হতে পারে।
-
-ক্ষেত্রগুলি গণনা করার জন্য সূত্র সংজ্ঞায়িত করার একটি ক্ষমতা আছে।
-
-### সম্পর্কিত রেকর্ড তৈরি করুন
-
-সিস্টেম লক্ষ্য রেকর্ড সম্পর্কিত রেকর্ড তৈরি করবে। ক্ষেত্রগুলির গণনা করার জন্য সূত্র সংজ্ঞায়িত করা সম্ভব।
-
-### আপডেট লক্ষ্য রেকর্ড
-
-লক্ষ্য রেকর্ড নির্দিষ্ট ক্ষেত্রের পরিবর্তনের অনুমতি দেয়। ক্ষেত্রগুলির গণনা করার জন্য সূত্র সংজ্ঞায়িত করা সম্ভব।
-
-যদি আপনি লিঙ্ক-মাল্টিপল ফিল্ডে নতুন আইটেম যোগ করতে চান তবে বিদ্যমান ডাটা (যেমন টিমগুলি) খুলতে আপনাকে সূত্র ফাংশন ব্যবহার করতে হবে entity\addLinkMultipleId। উদাহরণ: `entity\addLinkMultipleId('teams', 'teamId')`।
-
-### আপডেট সম্পর্কিত রেকর্ড
-
-সম্পর্কিত রেকর্ড বা রেকর্ড নির্দিষ্ট ক্ষেত্রের পরিবর্তনের অনুমতি দেয়। ক্ষেত্রগুলির গণনা করার জন্য সূত্র সংজ্ঞায়িত করা সম্ভব।
-
-### অন্য রেকর্ড সঙ্গে লিঙ্ক
-
-অন্য নির্দিষ্ট সত্তা সঙ্গে লক্ষ্য সত্তা সঙ্গে সম্পর্কযুক্ত। উদাহরণস্বরূপ রেকর্ডে নির্দিষ্ট দল যোগ করে।
-
-### অন্য রেকর্ডের সঙ্গে আনলিঙ্ক
-
-অন্য একটি নির্দিষ্ট সত্তা থেকে লক্ষ্য সত্তা সম্পর্কিত না। উদাহরণস্বরূপ রেকর্ড থেকে একটি নির্দিষ্ট দলের অপসারণ।
-
-### নিয়োগ নীতি প্রয়োগ করুন
-
-বিতরণ নিয়ম দ্বারা ব্যবহারকারীর লক্ষ্য রেকর্ড বরাদ্দ করুন। দুটি উপলব্ধ নিয়ম আছে: রাউন্ড-রবিন এবং লিস্ট-ব্যস্ত।
-
-* Round-Robin - ব্যবহারকারীদের উপরে থেকে একটি তালিকা (টিম) নীচে এবং তারপর আবার শুরু শুরু হয়।
-* Least-Busy - ব্যবহারকারী যারা কম নির্ধারিত রেকর্ড আছে নিয়োগ জন্য নির্বাচিত হবে।
-
-_List Report_ - নিখরচায় ব্যস্ত বিতরণের জন্য নির্দিষ্ট রেকর্ডের সংখ্যা গণনা করার জন্য কোন রেকর্ডগুলি বিবেচনা করা হবে। উদাহরণস্বরূপ ক্ষেত্রে আমরা সক্রিয় অবস্থা সঙ্গে শুধুমাত্র রেকর্ড নেওয়া প্রয়োজন।
-
-### বিজ্ঞপ্তি তৈরি করুন
-
-বার্তা সহ নির্দিষ্ট ব্যবহারকারীদের অবহিত করুন বার্তা টেমপ্লেটে স্থানধারক ব্যবহার করা সম্ভব: {সত্তা} - লক্ষ্য রেকর্ড, {ব্যবহারকারী} - বর্তমান ব্যবহারকারী।
-
-### অনুসরণ করুন
-
-নির্দিষ্ট ব্যবহারকারীদের লক্ষ্য সত্তা বা একটি নির্দিষ্ট সম্পর্কিত সত্তা অনুসরণ করার জন্য বাহিনী।
-
-### আরেকটি ওয়ার্কফ্লো ট্রিগার
-
-অনুক্রমিক ওয়ার্কফ্লো করতে অনুমতি দেয়। শর্ত দ্বারা কর্মক্ষেত্র শাখা করা সম্ভব: আপনি যে ওয়ার্কফ্লোতে বর্ণিত বিভিন্ন শর্তগুলির সাথে দুটি ওয়ার্কফ্লো ট্রিগার করতে কার্যপ্রবাহ স্থাপন করতে পারেন।
-
-ক্রমবর্ধমান কার্যপ্রবাহ কার্যকর করা বিলম্ব করা সম্ভব। ক্রমবর্ধমান ওয়ার্কফ্লো মধ্যে আপনি শর্ত সংজ্ঞায়িত করতে পারেন স্পেসিফিক ক্ষেত্র পরিবর্তন করা হয়েছে কিনা তা পরীক্ষা করে যেহেতু মূল কর্মক্ষেত্র দ্বারা ট্রিগার ছিল using _Changed_ and _Was Equal_ condition types।
-
-নোট: অনুক্রমিক ওয়ার্কফ্লো জন্য এটি ব্যবহার করার জন্য সুপারিশ করা হয় [BPM tool](bpm.md) বরং একটি ওয়ার্কফ্লো বৈশিষ্ট্য তুলনায়।
-
-### সার্ভিস অ্যাকশন চালান
-
-নির্দিষ্ট পরিষেবা স্ক্রিপ্ট চালানোর অনুমতি দেয়। ডিফল্টরূপে নিম্নলিখিত কর্মগুলি উপলব্ধ আছে:
-
-* আমন্ত্রণ পাঠান - মিটিং/কলের জন্য;
-* উদ্ধৃতি আইটেম যোগ করুন - উদ্ধারচিহ্ন এর জন্য।
-
-বিকাশকারীরা তাদের নিজস্ব কর্মকাণ্ডগুলি লিখতে পারে। দেখুন [আরো বিস্তারিত](../development/workflow-service-actions.md).
-
-## কর্মে সূত্র ব্যবহার করে
-
-রেকর্ড তৈরি, আপডেট লক্ষ্য রেকর্ড, সম্পর্কিত রেকর্ড তৈরি, আপডেট সম্পর্কিত রেকর্ড জন্য ক্ষেত্র গণনা সূত্র সংজ্ঞায়িত করা সম্ভব। শেষ দুটি জন্য, লক্ষ্য সত্তা বৈশিষ্ট্য অ্যাক্সেস আপনি ফাংশন ব্যবহার করা উচিত `targetEntity\attribute`। কর্মক্ষেত্রের আগে সেট করা লক্ষ্য সত্তাটির বৈশিষ্ট্যাবলী অ্যাক্সেস করতে ফাংশন ব্যবহার করা হয়েছিল `targetEntity\attributeFetched`।
-
-উদাহরণ:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/ceb_PH/README.md b/i18n/ceb_PH/README.md
deleted file mode 100644
index 836fc6971..000000000
--- a/i18n/ceb_PH/README.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Dokumentasyon para sa EspoCRM
-
-### Administrasyon
-* [Konpigyurasyon para sa Server](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/server-configuration.md)
- * [Apache](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/apache-server-configuration.md)
- * [Nginx](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/nginx-server-configuration.md)
-* [Pag-instalar](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/installation.md)
-* [Pag-upgrade](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/upgrading.md)
-* [Pagdumala sa mga Role (pagkontrol sa akses)](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/roles-management.md)
-* [Mga Email](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/emails.md)
-* Customization
- * [Entity Manager: mga entity, field, relationship](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/entity-manager.md)
- * [Layout Manager](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/layout-manager.md)
- * [Mga Ekstensyon](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/extensions.md)
- * [Mga Dynamic form](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/dynamic-logic.md)
-* Awtomasyon
- * [Business Process Management (BPM)](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/bpm.md)
- * [Mga Workflow](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/workflows.md)
- * [Mga Calculated Field (Formula)](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/formula.md)
-* [Data Import](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/import.md)
-* [Portal](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/portal.md)
-* [Awtorisasyon sa LDAP](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/ldap-authorization.md)
- * [Active Directory](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/ldap-authorization-for-ad.md)
- * [OpenLDAP](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/ldap-authorization-for-openldap.md)
-* [Troubleshooting](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/troubleshooting.md)
-* Misc
- * [Mga Map](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/maps.md)
- * [B2C nga mode](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/b2c.md)
- * [Pag-backup ug pag-restore](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/backup-and-restore.md)
- * [Pagbalhin ngadto sa lain nga server](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/administration/moving-to-another-server.md)
-
-
-### Giya para sa Tiggamit
-* [Mga Email](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/emails.md)
-* [Stream](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/stream.md)
-* [Pagdumala sa mga Sales](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/sales-management.md)
-* [Pagdumala sa mga Case](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/case-management.md)
-* [Mga aktbidad og Kalendaryo](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/activities-and-calendar.md)
-* [Binulto nga Email](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/mass-email.md)
-* [Mga Report](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/reports.md)
-* [Mga Quote](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/quotes.md)
-* Misc
- * [Pag-print ngadto sa PDF](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/printing-to-pdf.md)
- * [Markdown nga syntax](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/markdown.md)
- * [Suporta sa mga browser](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/user-guide/browser-support.md)
-
-### Development
-* [API](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/api.md)
-* [ORM: Unsaon pagdumala sa mga entity](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/orm.md)
-* [Metadata](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/metadata.md)
-* [Mga Custom view](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/custom-views.md)
-* [Pag-link sa daghan nga field ngadto sa primary nga rekord](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/link-multiple-with-primary.md)
-* [Mga extension package](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/extension-packages.md)
-* [Mga Hook](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/hooks.md)
-* [Paghimo og custom scheduled nga trabahoon](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/scheduled-job.md)
-* [Pagpatin-aw sa mga bag-ong punsyon para sa Formula](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/new-function-in-formula.md)
-* [Custom na field type](https://github.com/espocrm/documentation/blob/master/i18n/ceb_PH/development/custom-field-type.md)
-
-
-[Ang dokumentasyon nga naa sa website](https://www.espocrm.com/documentation/)
diff --git a/i18n/ceb_PH/administration/apache-server-configuration.md b/i18n/ceb_PH/administration/apache-server-configuration.md
deleted file mode 100644
index 3642d856b..000000000
--- a/i18n/ceb_PH/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Mga konpigyurasyon sa Apache nga server para sa EspoCRM
-
-Ang kining mga pag-giya kay pang-puno ra sa [Server Configuration](server-configuration.md) nga mga guideline. Palihug hinumdumi nga ang mga lista sa setting sa kani nga konpigyurasyon kay gihimo sa Ubuntu nga server
-
-## Mga gikinahanglan sa PHP
-
-Para ma install ang tanan gikinahanglan nga mga library, ipadagan ni ang command sa imohang terminal.
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Pag-ayo sa isyo nga “API Error: EspoCRM API is unavailable”:
-
-Himoa ra ang mga gikinahanglan nga mga lakang. Pagkahuman sa paghimo, susiha og balik kong nasolbad naba an problema.
-
-### 1. E-enable ang suporta sa “mod_rewrite” ni Apache
-
-Para ma tugotan ang "mod_rewrite," ipadagan ni na mga sugo gikan sa terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. E-enable ang .htaccess support
-
-Para ma-enable ang .htaccess support, pun-e o usba ang Server Configuration Settings /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf or /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Pagkahuman, ipadagan ni nga command gikan sa terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Pun-e ang RewriteBase nga path
-
-Ablihi ang file /ESPOCRM_DIRECTORY/api/v1/.htaccess ug ilisi ang musunod nga linya:
-
-```
-# RewriteBase /
-```
-
-og
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-kung asa ang REQUEST_URI kay parte sa URL, e.g. for “http://example.com/espocrm/”, REQUEST_URI kay "espocrm".
-
-## E-enable ang HTTP AUTHORIZATION nga suporta (para lang sa FastCGI).
-
-Ang FastCGI kay wala nagsuporta sa HTTP AUTHORIZATION. Kung mugamit ka og FastCGI, gikinahanglan nimo e-enable nimo ni sa imohang VirtualHost o sa /etc/apache2/apache2.conf (httpd.conf) punan sa musunod nga code:
-
-Para sa Fgid nga module:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-For FastCgi module:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Para tanawon kong unsa nga module ang gigamit karon, ipadagan ni ang command ug pangitaa ang module:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/ceb_PH/administration/b2c.md b/i18n/ceb_PH/administration/b2c.md
deleted file mode 100644
index 3903f2540..000000000
--- a/i18n/ceb_PH/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#Pagusab sa EspoCRM para sa B2C (Business-to-Client)
-
-Ang EspoCRM kay naka-configure para gamiton alang sa B2B nga mga negosyo. Pero pwede usab kini e-setup para sa B2C.
-
-* Usba ang `b2cMode` para mahimong true sa config nga file `data/config.php`. Gikan sa version 4.3.0, pwede nimo ning usbon sa Administration > Seetings.
-* Tangtanga ang *Account* tab giakn sa navigation menu (Administration > User Interface).
-* Tangtanga ang *Account* nga mga field gikan sa mga layout (Administation > Layout Manager).
-* E-disable ang pa-agi sa pagsulod sa *Account* nga scope para sa tanang papel (Administration > Roles).
-* Tangtanga ang Account gikan sa mga picklist sa tanang parent nga mga field (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
diff --git a/i18n/ceb_PH/administration/backup-and-restore.md b/i18n/ceb_PH/administration/backup-and-restore.md
deleted file mode 100644
index 6fbb653e2..000000000
--- a/i18n/ceb_PH/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Pagbackup og ang Pagbalik
-
-## Unsaon pag manomanog backup sa EspoCRM
-
-Ang EspoCRM kay usa ka grupo ka mga files og database nga data. Anga kaning nga mga data kay gikinahanglan para makabackup sa EspoCRM. Kani ang mga paggiya kung unsaon ni pagbuhat sa Ubuntu nga server gamit ang MySQL.
-
-### Step 1. Pag-backup sa mga file
-
-Paghimo og archive nga directory sa tanang mga sulod sa nakainstolar na nga EspoCRM. Sa Ubuntu, ang default nga path kay `/var/www/html`. Pwede ni nimo gamiton nga command:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Step 2. Pag-backup sa database
-
-Para e-backup ang tanan nimo nga data, gikinahanglan nga kamao ka sa pangalan og access credentials sa imohang database. Pwede nimong makit-an ang pangalan sa database sa konpigurasyon nga file `/ESPOCRM_DIRECTORY/data/config.php` ubos sa `database` nga section. Pwede nimong gamiton ang command sa ubos para mabackup ang database.
-
-```bash
-mysqldump --user=IMOHANG_USER --password=IMOHANG_PASSWORD PANGALAN_SA_IMOHANG_DATABASE > "db.sql"
-```
-
-### Step 3. Pagkopya sa backup
-
-Mao na to tanan. Karon, gikinahanglan nimo kopyahon ang nahimong backup ngadto padulong sa luwas nga dapit.
-
-
-## Unsaon pag pag-backup sa EspoCRM gamit ang script
-
-Pwede ka mugamit og script para e-backup ang tanan gikinahanglan nga data. Pag-login gamit ang SSH ug ipadagan ang musunod nga mga command (na testigan na kini sa Ubuntu server).
-
-### Pag-download sa usa ka script
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Pagpadagan sa script
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-kung asa
- * `PATH_TO_ESPOCRM` kay ang path nga padulong sa naka-instolar na nga EspoCRM directory.
- * `BACKUP_PATH` kay ang path nga padulong sa backup nga directory.
-
-Para sa mga Ubuntu na server kini kay:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Timan-e: Nga kong ang imong MySQL user kay walay katungod nga maglabay sa imohang database, pangayoan ka og credentials sa imohang laing MySQL nga user.
-
-Pagkahuman sa pagbuhat, makadawat ka og path padulong sa nahimo nimong backup.
-
-## Pagbalik sa EspoCRM gikan sa backup
-
-Pwede nimong ibalik ang EspoCRM gikan sa backup mura sa gihulagway sa taas.
-
-### Step 1. Pag-unarchive sa mga backup nga file
-
-Para e-unarchive ang mga files, pwede kang mugamit og Archive Manager o ipadagan ang mga command sa ubos. Ang mga file kay gikinahanglan ilisan og mga web-server nga directory.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-kung asa:
- * `/var/www/html` kay usa ka web-server nga directory.
-
-### Step 2. Pag-set sa mga gikinahanglan nga pagtugod
-
-Ang mga file kay gikinahanglan gitag-iya sa usa ka web-server nga user and naay mga saktong pagtugot. Palihug e-set ang mga gikinahanglan nga mga [permission](server-configuration.md#mga-gikinahanlang-permiso-para-sa-mga-unix-based-nga-mga-sistema) gamit ang kaning mga pag-giya.
-
-### Step 3. Pag-import sa database dump
-
-Ang database dump kay gikinahanglan e-import padulong sa parehas nga database gamit ang parehas nga mga credentials, kung dili ang mga pagusab kay gikinahanglan usbon sulod sa konpigurasyon nga file `ESPOCRM_DIRECTORY/data/config.php`. Para e-import ang database gikan sa dump, ipadagan ang mga command sa ubos gikan sa terminal:
-
-```bash
-mysql --user=IMOHANG_USER_SA_DATABASE --password=IMOHANG_DATABASE_PASSWORD PANGALAN_SA_IMOHANG_DATABASE < db.sql
-```
-
-### Step 4. Tan-awon/Usbon ang crontab
-
-Susiha kung sakto ang konpigyurason sa crontab. Ipadagan ang command sa ubos og susiha kung sakto ang path padulong sa EspoCRM:
-
-```bash
-sudo crontab -l -u www-data
-```
-kung asa:
- * `www-data` kay ang imohang web-server.
-
-Kung naa kay mga pag-usab, gamita ni ang command sa ubos:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Ang uban pang mga detalye aron sa pagusab sa [crontab](server-configuration.md#pag-setup-og-crontab) kay makita sa.
diff --git a/i18n/ceb_PH/administration/bpm.md b/i18n/ceb_PH/administration/bpm.md
deleted file mode 100644
index 6f9bffd51..000000000
--- a/i18n/ceb_PH/administration/bpm.md
+++ /dev/null
@@ -1,209 +0,0 @@
-# Business Process Management
-
-Ang Business Process Management (BPM) nga tool kay naghatag og abilidad nga mumodel og mu-awtomeyt sa mga proseso sa negosyo sa EspoCRM. Usa kini ka makina nga maoy mubuhat sa mga proseso sa negosyo nga gihulagway sa BPMN 2.0 nga standard. Ang BPM nga tool kay makita sa [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) nga ekstensyon.
-
-
-
-### Kalainan gikan sa Workflows nga tool
-
-Ang Workflows nga tool kay gituyo para mu-awtomeyt sa mga yano ra nga mga balaod sa negosyo, nga walay sequential flow nga mga item, kung kanus-a wala gikinahanglan ang pagdisplay sa flow nga pina-grapikal.
-
-Ang BPM tool gihimo para sa mga komplikado nga mga proseso sa negosyo, kung asa naay pwede natipon o nagbuwag nga mga proseso, ulahi nga eksekusyon, o mga inter-aksyon sa user. Ang flowchart view kay himoon ang mga proseso sa negosyo nga sayon sabton sa usa ka tao, ang log kay mutugot sa pagpakita kung giunsa ang proseso pagbuhat.
-
-## Mga Flowchart sa mga Proseso
-
-Ang link para iproseso ang mga flowchart kay makit-an sa administrasyon nga panel. Pwede usab kini ipuno sa nabigasyon nga panel isip usa ka tab.
-
-Ang mga flowchart kay gituyo para pag-model sa mga proseso sa negosyo. Ang administrador kay makahimo og makausab sa mga flowchart. Ang mga regular nga user kay pwede ra maka tan-aw sa mga flowchart.
-
-Ang kada flowchart kay naay espisipiko nga tipo sa entity (Target Type field). Ang flow chart mudetermina sa pagpadagan sa mga musunod nga proseso na mga instance. Gilangkuban kini sa mga flowchart na elemento og mga koneksyon tali sa mga elemento.
-
-Kung ang flowchart nga proseso kay naay wala nga nacheck nga 'Is Active' nga field, dili kini sugdan ang pagsugod sa proseso.
-
-Para ipakita ang mga detalye ug mga parameter para sa usa ka flowchart nga element, kinahanglan nimo e-klik kini. Sa edit nga mode, pwede nimong usbon ang mga parameter.
-
-## Mga Proseso
-
-Ang mga proseso kay maanaa gikan sa administrasyon nga panel. Ang link kay pwede usab kini ipuno sa nabigasyon nga panel isip usa ka tab.
-
-Ang mga proseso kay nagrepresentar sa mga proseso sa usa ka negosyo. Kung sugdan kini, ang status kay mausab ngadto sa 'Started'. Kung ang proseso kay mahuman na, ang status kay mausab ngadto sa 'Ended'. Ang proseso kay pwede usab hunongon ug manomano sa usa ka user nga naay pagtugot nga muusab sa proseso. Kung gi manomano kinig hunong, ang status niini kay usbon ngadto sa 'Stopped'.
-
-Ang proseso kay himoon base sa flowchart. Ang Flowchart sa proseso kay dili pwede nga usbon inig human ug sugod.
-
-Ang usa ka proseso kay olbigado nga naay relasyon sa usa ra ka target nga record.
-
-Ang mga proseso kay pwede sugdan ug ditso nga awtomatik (kung naa mga espesipiko nga mga kondisyon o gikan sa paghimo og iskedyul). Para sa manomano nga pagsugod sa proseso, ang user kay gikinahanglan nga mu klik sa 'Start Process' nga pindutanan sa lista nga view sa mga proseso.
-
-## Mga Flowchart nga Elemento
-
-### Mga Event
-
-Ang mga Event kay gi display sa flowchart isip ka mga lingin.
-
-#### Sugod nga Event
-
-Wala kini mga parameter. Kini kay ang sugod nga punto sa proseso. Ang Sugod nga Event kay pwede sugdan nga manomano sa usa ka user nga naay pagtugot para muhimo og mga proseso. Ang user kay gikinahanglan nga muklik sa 'Start Process' nga pindutanan sa mga lista nga view sa mga proseso.
-
-#### Kondisyonal nga Sugod nga Event
-
-Kini kay ang sugod nga punto sa proseso. Kini kay dapat unta sugdan dayon awtomatikali kung ang mga kondisyon kay naabot. Naay duha ka mga tipo sa mga trigger: 'After record created', 'After record saved'.
-
-#### Timer nga Sugod nga Event
-
-Kini kay ang sugod nga punto sa proseso. Sugdan niini ang mga proseso ginamit ang pag-eskedyul. Gikinahanglan nimo nga pahinganlan ang report nga lista nga mubalik sa mga rekord para sa pagsgugod sa mga proseso ug pag-eskedyul sa sud sa crontab nga notation.
-
-#### Kondisyonal nga Intermediate nga Event
-
-Ang kini nga event kay hunongon ang flow hangtod nga maabot ang mga kondisyon nga gitakda.
-
-#### Timer nga Intermediate nga Event
-
-Ang kani nga event kay muhunong sa flow ug maghuwat kung gitakda kini sa parameter sa event.
-
-Para sa mga mas komplikado pa nga mga setting, pwede gamiton ang [formula](formula.md). Anga mga formula nga mga script kay dapat mubalik og Date-Time nga value (sa UTC nga timezone). Kung muabot na ang oras niini, ang flow kay sundan sa sunod nga elemento.
-
-Sa paggamit og datetime\closest nga formula nga function, pwede na iset ang timer sa espisipiko nga oras sa umaabot, e.g. ang sugod sa adlaw sa ugma nga naay trabaho.
-
-#### Katapusan nga Event
-
-Undagon ang karon nga flow. Dili niya undagon ang mga flow nga nagdagan in parallel. Kung ang flow kay naabot na sa kataposan nga event ug wala nay laing nagdagan pa in parallel, taposon niini ang proseso.
-
-#### Terminate nga Kataposan nga Event
-
-Muundang sa tanan nga mga flow. Ang proseso kay ulahing undangon.
-
-### Mga Gateway
-
-Ang mga gateway kay ipakita isip mga diamond.
-
-#### Eksklusibo nga Gateway
-
-Pwede mubuwag o magtipon sa mga flow.
-
-Sa kaso nga kini mag buwag, muhimo kini og usa ka nag-inusara nga flow (nga path) nga pilion sa nase sa gitakda nga mga kondisyon. Ang unang naabot nga kondisyon kay mudetermina sa flow, ang sunod nga mga kondisyon kay pangtangtangon. Naa kini abilidad nga mutakda kong unsa ang default nga flow. Ang default nga flow kay pilion kong walay mga kondisyon nga naabot. Ang default nga flow kay markahan og slash nga sign.
-
-Sa kaso nga magtipon, mu idirekta ra niini ang flow ngado sa outgoing nga elemento. Dili hinoon kini babagan pagkahuman sa pag-abot sa flow, mao ang mga parallel nga mga flow kay dili matipon ngadto sa usa ka nag-inusara nga flow.
-
-
-
-
-
-#### Inklusibo nga Gateway
-
-Pwede mubuwag og mutipon sa mga flow.
-
-Sa kaso nga mubuwag, pwede ni siya idirekta sa usa o mas daghan pa nga mga parallel nga flow (nga path), depende kung naabot ang mga kondisyon sa tagsa tagsa ka mga flow. Ang default nga flow kay pilion kung walay kondisyon nga naabot. Ang default nga flow kay markahan og slash nga sign.
-
-Kung gikinahanglan nga itipon ang mga parallel nga mga flow nga nahimo sa pag buwag sa mga inklusibo nga mga gateway, gikinahanglan nimo nga gamiton ang nagtipon nga inklusibo nga gateway. Maghuwat kinig para sa tanang mga padulong nga mga flow ug mupadayon sa mga mubiya nga mga elemento.
-
-
-
-Timan-e: Dapat ibalanse ang mga magbuwag o mga magtipon nga mga flow.
-
-Timan-e: Kung ang usa ka parallel nga flow kay maundang tungod sa usa ka rason, ang magbuwag nga gateway kay dili na maproseso. Ang proseso kay pugngan. Likaye ang disenyo sa flowchart nga pwede mahitabo ni nga sitwasyon.
-
-#### Parallel nga Gateway
-
-Pwede mubuwag o mutipon sa mga flow.
-
-Kung pananglit magbuwag, iyang tungaon ang flow ngadto sa makadaghan nga parallel nga mga flow. Walay paramter para sa kani nga tipo sa gateway.
-
-Sa kaso nga magtipon, maghuwat kini hangtod ang tanan padulong nga mga flow kay maabot ug dayon mupadayon kini ngadto sa sunod nga elemento.
-
-
-
-Timan-e: Ang magbuwag og magtipon nga mga gateway kay dapat balansehon.
-
-Note: If one of parallel flows has been ended for some reason then diverging gateway will never be processed. The process will be blocked. Avoid a flowchart design that can bring about such a situation.
-
-Timan-e: Kung ang usa ka parallel nga flow kay maundang tungod sa usa ka rason, ang magbuwag nga gateway kay dili na maproseso. Ang proseso kay pugngan. Likaye ang disenyo sa flowchart nga pwede mahitabo ni nga sitwasyon.
-
-#### Gateway nga Gibase sa Event
-
-Pwede ra magbuwag sa mga flow.
-
-Hunongon niini ang flow hangtod ang tanang nagpadayon nga mga event kay masugdan. Ang mga nasugdan nga event kay mudeterminar sa nag-inusara nga flow. Ang uban nga nagpadayon nga event kay e-reject.
-
-Ang mga intermediate ra nga event ang pwede nga naa sa pikas nga bahin sa mga nagpadayon nga mga sequence flow.
-
-
-
-### Mga Aktibidad
-
-Ang mga aktibidad kay ipakita isip mga rektanggulo.
-
-#### Tahas
-
-Ang tahas kay pwede muhimo aning mga aksyon:
-
-* Paghimo og Rekord - muhimo og bag-o nga record sa bisan unsa nga klase nga entity;
-* Paghimo og Related nga Rekord - muhimo og bago nga record nga naay relasyon sa gitarget nga rekord;
-* Pag-update sa Target nga Rekord;
-* Pag-update sa Related nga Rekord - mu-update sa record o mga record nga naay relasyon sa gitarget nga rekord;
-* Pag-update sa Nahimo na nga Record - mu-update sa espisipiko nga record nga field sa bisan unsang record nga nahimo sa proseso karon;
-* Pag-udate sa Process na Record - pwede gamiton para mu-assign sa proseso sa espisipiko nga user o grupo;
-* Pag-link ngadto sa Lain nga Record - mu-link sa gitarget nga rekord ngadto sa gitakda nga record;
-* Pag-unlink gikan sa Lahi nga Record - mu-unlink sa gitarget nga record gikan sa gitakda nga rekord;
-* Pag-assign sa Assignment nga Rule - mu-assign sa gitarget nga rekord, sa proseso nga rekord, o bisan unsang klase nga rekord nga gihimo sa proseso base sa gitakda nga kondisyon;
-* Paghimo og Notipikasyon - muhimo og in-app nga notipikasyon para sa gitakda nga mga user;
-* Himoong Followed - himoon ang usa ka gitakda nga user nga musunod sa usa ka gitarget nga rekord, sa proseso nga rekord, o bisan unsa nga rekord nga ginama sa proseso;
-* Pagdagan sa Serbisyo nga Aksyon - mupadagan sa kustom nga serbisyo nga aksyon nga giimplementar sa mga debeloper.
-
-Ang mga aksyon nga pwede himoon sa usa ka tahas kay halos parehas ra sa Workflow nga feature. Tanawa ang uban pa nga mga detalye kabahin sa [aksyon sa workflow](workflows.md#mga-aksyon).
-
-#### Pagpadala og Mensahe nga Tahas
-
-Mupadala og email nga mensahe ngado sa usa ka espisipiko nga mudawat.
-
-#### Tahas nga User
-
-Muhatag og flexible nga abilidad nga user interaksyon. Hunoongon niini ang pagbuhat hangtod ang user (giklaro og takda o gikan sa assignment nga balaod) muhuman sa tahas. Ang Process User Task nga rekord kay himoon sa sistema. Naay tulo nga mga klase nga aksyon: Approve, Review, Accomplish.
-
-* Ang Approve nga tipo kay nanginahanglan sa user nga mupili tali sa 'Approved' ug 'Declined'.
-* Ang Review nga tipo kay muhatag lang og usa ka opsyon: 'Reviewed'.
-* Ang Accomplish nga tipo kay naay duha ka opsyon: 'Completed' and 'Failed'.
-
-Ang user nga na-assignan sa sa mga nahimo nga Process User Task nga rekord kay makadawat og in-app nga notipikasyon. Ang administrador kay pwede usab mutugot sa mga email nga notipikasyon.
-
-Ang mga user kay pwede usab makadungag og Process User Tasks nga dashlet sa ilahang mga dashboard para makita ang mga proseso nga user nga task.
-
-Pwede sad basahon ang resolusyon sa gipasa nga user task sa sulod sa nagbuwag nga mga gateway o mga kondisyonal nga mga event, nga mupamatuud sa proseso nga flow.
-
-#### Script nga Tahas
-
-Mu-eksikyut sa script sa sulod sa [espo-formula](formula.md) nga pinulongan. Ang tanang mga giset nga variable (`$variableName`) kay hiposon ug mahimong makuha sulod sa proseso.
-
-### Mga Flow
-
-#### Sequence nga Flow
-
-Girepresanta isip usa ka solid nga udyong o arrow. Mupakita sa order kung asa ang mga proseso na elemento kay i-eksikyut.
-
-## Mga Kondisyon
-
-Ang mga kondisyonal nga event, eksklusibo og inklusibo nga mga magbuwag nga gateway kay naay mga kondisyon nga mudeterminar sa flow sa mga proseso.
-
-Sa UI, naay abilidad nga tanawon ang mga kondisyon sa mga musunod nga mga rekor:
-
-* Gitarget nga rekord;
-* Mga rekord nga naay relasyon sa gitarget nga rekord pinaagi sa many-to-one ug children-to-parent nga mga relasyon;
-* Ang mga rekord nga nahimo sa proseso gikan sa mga tahas.
-* Ang mga tahas sa user nga rekord, nga pwede mupakita ug mupasusi sa mga resolusyon.
-
-Posible usab nga muhimo og mga kondisyon sulod sa [Espo-formula](formula.md) nga pinulongan.
-
-Ang mga kondisyon sa BPM too kay parehas ra sa Workflow nga feature. Tanawa ang mga detalye bahin sa [mga kondisyon sa workflow](workflows.md#mga-kondisyon).
-
-## Mga Example
-
-### Example 1
-
-
-
-### Example 2
-
-
-
-### Example 3
-
-
diff --git a/i18n/ceb_PH/administration/dynamic-logic.md b/i18n/ceb_PH/administration/dynamic-logic.md
deleted file mode 100644
index 61213c1d1..000000000
--- a/i18n/ceb_PH/administration/dynamic-logic.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Dynamic nga Lohiko (mga dynamic nga form)
-
-Ang dynamic nga linihokan sa mga form kay makab-otan pinaagi sa pag-gamit sa Dynamic Logic Feature. Ang Dynamic Logic nga mga parametro kay makit-an sa tanan mga field. Ang mga parametro kay naa makit-an sa Entity Manager kung mu-edit o muhimo ka ug usa ka field.
-
-Ang Dynamic Logic kay mutugot nga muhimo og mga kondisyon nga muhimong visible, required, o read only sa ubang mga field. Ang mga kondisyon kay awtomatik nga susihon kung ang datos sa sulod sa form kay nausab.
-
-Conditions are configured through user interface, no coding required.
-Ang mga kondisyon kay gikonpigyura gamit ang user interface, wala nay gikinahanglan nga pag-code.
diff --git a/i18n/ceb_PH/administration/email-fetching.md b/i18n/ceb_PH/administration/email-fetching.md
deleted file mode 100644
index 890f311db..000000000
--- a/i18n/ceb_PH/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Mga Email
-
-Ang kani nga dokumento kay gibalhin [diri](emails.md).
diff --git a/i18n/ceb_PH/administration/emails.md b/i18n/ceb_PH/administration/emails.md
deleted file mode 100644
index 92cf8eb89..000000000
--- a/i18n/ceb_PH/administration/emails.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Mga Email
-
-> Importante. Ang [Cron](server-configuration.md#pag-setup-og-crontab) kay gikinahanglan gikonpigyur sa inyohang sistema para mugana ang pagkuha sa email. Makit-an ni nimo nga inpormasyon sa imohang EspoCRM sa Administration > Scheduled Jobs.
-
-## Kinatibuk-an
-
-Ang EspoCRM kay naay abilidad nga mumonitor sa mga IMAP na mga mailbox. Ang email kay pwede ma-archive sa 2 ka pamaagiL Group Email Accounts ug Personal Email Accounts.
-Ang Group Inbound Accounts kay gituyo para sa mga grupo nga mga mailbox: ang pinaka komon nga kaso kay ang usa ka suporta na box. Ang Personal Email Accounts kay gituyo para sa personal nga mga mailbox sa user.
-
-Sa pagabot sa email, ang sistema kay suwayan og pagkonektar sa mga saktong record (Accounts, Lead, Opportunity, Case). Ang mga user nga nagsunod ana nga mga record kay makadawat og notipikasyon bahin sa bagong email nga naabot sa sistema, bisan pa wala sila gibutang sa To or CC.
-
-## Group Email Accounts
-
-Ang administrado ra ang maka himo og Group Email nga mga account. Ang mga Group Email Account kay pwede magamit para pagdawat og pagpadala og mga email. Ang pagpadala og email gikan sa group nga mga account kay naa na gikan sa 4.9.0 nga version.
-
-Ang Teams nga field kay nag determina kung asa nga team e-assign ang email.
-
-Kung ang group email account kay naay SMTP ug gicheck na ni nga shared, ang pag-akses ani kay mahimong ikontrol sa mga Role sa Group Email Account nga pagtugot. Ang Teams nga field kay gamiton kung ang lebel sa pagtugot kay 'team'.
-
-Naay abilidad ang sistema nga musend og awtomatik nga tubag kong naay padulong nga email.
-
-## Email-ngadto-Kaso
-
-Naay opsyon para ang sistema muhimo og cases para sa mga padulong nga group email.
-Ang kani nga bahin kay gituyo para sa pagsuporta sa mga team. Ang mga kaso kay pwede ibahin ngadto sa lain laing mga user para sa espesipiko nga mga team gamit ang kani nga mga pamaagi: `direct assignment`, `round-robin` and `less-busy`. Ang una ra nga email sa thread ang muhimo og bago nga kaso. Anga sumusunod nga mga email kay e-konektar sa nahimo na nga kaso ug ipakita kini sa Stream nga panel.
-
-Kung ang user kay gusto mupadala og tubag ngadto sa kustomer, gikinahanglan nila siguradohon nga ang kaso kay gipili para mahimong ginikanan sa email nga gipadala. Himoon ni nga ang ang tubag sa customer kay ipadala sa group email nga address kay sa sa email sa user.
-
-## Personal nga mga Email Account
-
-Users can setup their own email accounts that need to be monitored. Emails > Top Right Dropdown Menu > Personal Email Accounts. Administrator also can manage users' email accounts.
-
-Ang mga user kay makasetup og ilahang kaugalingong mga count nga gikinahanglang obserbahan. Top Right Dropdown Menu > Personal Email Accounts. Ang administrador kay pwede makadumala sa mga email account sa user.
-
-## Mga Email Filter
-
-Kini kay musala sa mga padulong nga mga email sumala sa ilahang mga espesipiko nga mga kriterya. E.g. kun dili ka ganahan makadawat og mga notipikasyon nga mga mensahe gikan sa ubang mga applikasyon para ma-import padulong sa EspoCRM, pwede ka magbuhat ug filter para laktodan kini sa EspoCRM.
-
-Ang admin kay makahimo og global nga mga filter, para ma-gamit sa tanang mga email account. Ang mga user kay pwede nga muhimo og mga filter para sa ilahang personal nga email account para sa kinatibuk-ang inbox.
diff --git a/i18n/ceb_PH/administration/entity-manager.md b/i18n/ceb_PH/administration/entity-manager.md
deleted file mode 100644
index 454b3f485..000000000
--- a/i18n/ceb_PH/administration/entity-manager.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Entity Manager
-
-Ang Entity Manager kay makit-an sa Administration Panel. Muhatag kini og abilidad nga i-customize sa bisan unsa nimong gusto ang imohang EspoCRM instance. Pwede nimo buhaton ang mga musunod:
-
-* Pagpuno og bag-o nga mga klase nga entity.
-* I-customize ang mga nahimo nang mga klase sa entity: usbon ang mga label, mga default order sa list view, i-enable o i-disable ang stream.
-* I-configure ang mga field: pagdugang og bag-o, pagcustomize sa mga nahimo na.
-* I-configure ang mga relationship: pagdugang og bag-o, pag-usab og mga label sa mga nahimo na.
-
-## Paghimo og bag-go nga entity
-
-I-click ang `Create Entity` nga pindutanan sa Entity Manager nga page. I-specify ang pangalan, mga label, og tipo. Kung mupili ka sa `Person` nga tipo, ang imong entity kay mabutangan og Email, Phone, First Name, Last Name ug Salutation nga mga field. I-check ang `Stream` kung gusto nimo nga ang imong entity kay mabutangan og stream panel ug ang mga user nga mamahimong mu-Follow sa mga entity nga in-ani og klase.
-
-Mga Tipo:
-
-* Base - blangko nga entity nga naa ray mga basic nga mga field parehas sa Name, Assigned User, Teams, Description.
-* Base Plus - mura rag Base pero naay mga Activities, History, Tasks panels (naa na kini sukad pa sa 4.3.0).
-* Event - Date Start, Date End, Duration, Parent, Status fields. Makita ni sa Calendar ug Activities panel (sukad pa sa 4.3.0, gikinahanglan nga ni i-enable sa Administration > Settings).
-* Person - Email, Phone, First Name, Last Name, Salutation, Address fields. Activities, History, Tasks panels.
-* Company - Email, Phone, Billing Address, Shipping Address fields. Activities, History, Tasks panels.
-
-## I-update ang nahimo na nga entity
-
-Kung imong i-click ang `Edit` nga link sa usa ka entity, pwede nimong usbon ang ubang mga parameter sa kadto nga entity.
-
-* Labels - singular ug plural nga pangalan sa entity.
-* Ang mga default order nga rekord kay han-ayon didto sa mga list view.
-* Stream - kung ang Stream feature kay na-enable para sa kani nga entity.
-* Disabled - i-check kung dili nimo ganahan ni nga entity nga maanaa sa imohang sistema.
-* Text Filter Fields - unsa nga mga field ka mangita para sa main text filter ug global search.
-
-
-## Mga Field
-
-Sa pag-click sa `Fields` nga link, ibalhin ka sa lahi nga page. Didto, mamahimo kang muhimo og bag-o nga mga field o mu-update sa mga nahimo na. Ang mga musunod nga mga klase sa mga field kay makita didto sa Entity Manager:
-
-* Address - adres nga naay dalan, siyudad, estado, postal code ug nasod;
-* Array - lista sa mga value, nga naay abilidad nga mupili og daghan nga mga value (dili ni nindot nga opsyon kung gikinahanglan nimo mangita sa kani nga field); ang mga user kay pwede ra makadungag og ilahang kaugalingong mga value kung ang opsyon kay wala gi-specify.
-* Attachment Multiple - daghang mga file attachment;
-* Auto-increment - numero nga gi-generate ug mabasa ra;
-* Boolean - checkbox, true o false;
-* Currency - para sa mga currency nga value;
-* Date;
-* DateTime;
-* Enum - selectbox, nga naay abilidad nga mupili og usa ra ka value;
-* File - mu-upload og usa ka file;
-* Float - numero nga naay decimal nga parte;
-* Foreign - usa ka field nga naay related nga entity;
-* Image - mu-upload og image file nga naay preview;
-* Integer - mga whole number;
-* Number - usa ka auto-incrementing nga numero nga usa ka klase ka string nga posible naay prefix ug hitas-on;
-* Multi-enum - lista sa mga value, nga naay abilidad nga mupili og daghan nga mga value (dili ni nindot nga opsyon kung nanginahanglan kang mangita sa kani nga field), parehas ra sa Array pero mas nindot pa.
-* Text - text area, para sa mga tag-as nga multiline text;
-* Url - para sa mga link;
-* Varchar - mugbo nga text;
-* Wysiwyg - parehas ra sa Textfield, nga naay abilidad nga mu-format og text.
-
-Mga Parameter:
-* Required - kung diin ang pagbutang og entry ani nga field kay gikinahanglan.
-* Default Value - Value sa kani nga field nga gi-set paghimo ani nga bag-o nga rekord.
-* Audited - mga update ani nga field kay i-log sa Stream.
-
-**Timan-e**: Inig human nimo og puno og bago nga field, gikinahanglan nimo nga ibutang ang kini nga field sa [layouts](layout-manager.md) (Administration > Layout Manager).
-
-### Dynamic nga Lohiko
-
-Muhatag og abilidad nga muhimo sa mga form ngadto sa pagka-dynamic. Posible nga ma-takda ang mga kondisyon para himoong visible, required, o read-only ang mga field. Ang mga kondisyon kay i-check automatically kung ang data sa form kay nausab.
-
-Para sa Enum, Array ug Multi Enum nga mga field, posible nga i-define ang nakalainlaing mga set sa opsyon nga mahimong available para sa field depende kung unsa nga kondisyon ang natuman.
-
-
-## Mga Relationship
-
-Pwede kang muhimo og bag-o nga mga relationship tali sa out-of-box ug custom nga mga entity. Naay 3 ka pwede nga pilian nga mga relationship type:
-
-* One-to-Many: pagkahuman nimo og himo ani nga relationship, pwede nimong ibutang ang link nga field ngadto sa detail layout sa tuo nga entity og magpuno og relationship panel sa wala nga entity;
-* Many-to-One: parehas ra sa One-to-Many pero bali;
-* Many-to-Many: mga relationship panel nga naa sa duha ka kilid.
-
-Ang parameter nga 'Link Multiple Field' kay nagpasabot nga ang field nga `linkMultiple` type kay himoon dungan sa relationship. Pwede nimong ibutang ang kana nga field sa layout. Sayon kini para sa mga dinalidali nga pagkuha ug mga related nga mga rekord. Dili ni maayo nga opsyon kung ang imohang relationship kay gihimo nga naay daghang gi-link nga mga record nga makahinay sa pag-load sa detail view nga screen.
-
-Kung ang parameter nga 'Audited' kay nacheck, ang mga update sa relationship kay i-log sa Stream.
\ No newline at end of file
diff --git a/i18n/ceb_PH/administration/extensions.md b/i18n/ceb_PH/administration/extensions.md
deleted file mode 100644
index 06e50e8e0..000000000
--- a/i18n/ceb_PH/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Pagdumala sa mga Extension
-
-## Unsaon pag-instolar sa extension
-
-Para mag instol EspoCRM nga extension (e.g. Advanced Pack, VoIP Integration):
-
-1. Login nga ikaw ang administrador.
-2. Adto sa Administration > Extensions.
-3. I-upload ang imohang extension nga package (zip file).
-4. E-click ang Install nga pindotanan.
-
-
-## Unsaon pag-upgrade sa extension
-
-Para e-upgrade ang nakainstolar na nga extension (e.g. Advanced Pack, VoIP integration) ngadto sa bag-o nga bersyon:
-
-1. I-download ang bago nga bersyon sa gikinahanglan nga extension
-2. Login nga ikaw ang administrador.
-3. Adto sa Administration > Extensions.
-4. I-upload ang imohang extension nga package (zip file) nga dili tangtangon ang nakainstolar na nga extension.
-5. E-click ang Install nga pindotanan.
-
-
-## Unsaon pag-uninstall sa usa ka extension
-
-Mga lakang para ma-uninstall ang naka instolar na nga extension:
-
-1. Login nga ikaw ang administrador.
-2. Adto sa Administration > Extensions.
-3. Pangitaa ang gikinahanglan nga extension sa lista sa mga extension.
-4. E-click ang Uninstall nga pindotanan.
-
-
-## Unsaon pag-tangtang sa usa ka extension
-
-Kung wala na nakainstolar ang usa ka extension, makit-an pa kini sa sistema. Pero pwede kini tangtangon. Ang mga lakang sa pagtangtang sa extension:
-
-1. Login nga ikaw ang administrador.
-2. Adto sa Administration > Extensions.
-3. Pangitaa ang gikinahanglan nga extension sa lista sa mga extension.
-4. E-click ang Remove nga pindotanan.
diff --git a/i18n/ceb_PH/administration/formula.md b/i18n/ceb_PH/administration/formula.md
deleted file mode 100644
index 71fb8747d..000000000
--- a/i18n/ceb_PH/administration/formula.md
+++ /dev/null
@@ -1,269 +0,0 @@
-# Mga Calculated Field (Formula)
-
-Sa entity manager, posible ka mu-define og script (formula) para sa episipiko nga entity type. Ang script kay i-execute matag higayon una masave ang rekord.
-Muhatag kinig abilidad nga automatic nga mutakda og mga values nga gikuha gikan sa pagkalkula ngadto sa espisipiko nga mga field (attributes).
-
-Para mu-edit ug formula sunda ang Administration > Entity Manager > dropdown menu sa tuong bahin sa row sa gikinahanglan nga entity > Formula.
-
-Pwede usab nga manginahanglan ka mutakda sa mga field, kadto untang mga gikalkula, Read-only via Entity Manager.
-
-
-## Syntax
-
-Ang EspoCRM formula kay gisuwat sa simple nga pinulongan nga gidisenyo para sa kani nga feature.
-
-Naay mga operator, mga function attribute ug mga value nga pwedeng magamit sa formula. Ang mga gibuwag nga mga expression kay gikinahanglan e-delimit gamit ang karakter nga `;`.
-
-### Mga Operator
-
-* `=` - assignment.
-* `||` - lohikal nga OR,
-* `&&` - lohikal nga AND,
-* `!` - lohikal nga NOT,
-* `+`- numero nga summation,
-* `-` - numero nga subtraction,
-* `*` - numero nga multiplication,
-* `/` - numero nga division,
-* `%` - numero nga modulo,
-* `==` - parehong pagtandi,
-* `!=` - di parehong pagtandi,
-* `>` - mas labaw pa nga pagtandi,
-* `<` - mas gamay pa nga pagtandi,
-* `>=` - parehos o mas labaw pa nga pagtandi,
-* `<=` - parehos o mas gamay pa nga pagtandi.
-
-Prayoridad sa mga operator:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Mga Attribute
-
-Ang mga attribute kay nagrepresentar sa mga field value sa gitarget nga entity. Pwede kang magdungag og mga wala pa na gamit nga mga attribute pinaagi sa pag click sa plus nga pindotanan.
-
-Posible i-access ang mga attribute sa mga nalambigit sa mga entity gamit ang musunod nga format `linkName.attributeName`.
-
-
-### Mga Function
-
-Ang format sa paggamit sa function: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Ang mga out-of-the-box nga function kay gilista sa ubos.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` Kung ang CONDITION kay natuman na buhata ang CONSEQUENT. Kung wala -- buhata ang ALTERNATIVE.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` Kung ang CONDITION kay natuman na buhata ang CONSEQUENT. Kung wala -- wala kay buhaton.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Sumpayon ang duha o mas labaw pa nga mga string.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Kuhaon ang mga character gikan sa STRING pinaagi sa START nga posisyon og LENGTH.
-
-Kung wala nabutangan ang LENGTH, ang substring nga nagsugod gikan sa START hangtod sa kataposan sa STRING ang iuli.
-
-Kung ang LENGTH kay negative, mao sad ang hidaghanon sa mga karakter nga tangtangon sa kataposan sa STRING.
-
-#### string\\trim
-`string\trim(STRING)` Tangtangon ang mga whitespace gikan sa sinugdanan ngadto sa kataposan sa STRING.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Himoon ang mga letra ngadto sa lower case. (ngadto pa sa version 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Himoon ang mga letra ngadto sa case. (ngadto pa sa version 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Mubalik sa datetime karon.
-
-#### datetime\now
-`datetime\now()` Mubalik sa datetime karon dayon.
-
-#### datetime\format
-
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Usbon ang date o datetime nga VALUE ngadto sa usa ka string nga giformat basi sa mga application setting. Ang TIMEZONE ug FORMAT kay pwede ra dili butangan. Kung ang TIMEZONE kay wala butangi og value, ang default nga time zone ang gamiton. Kung ang FORMAT kay wala butangi og value, ang default nga format ang gamiton.
-
-#### datetime\date
-
-`datetime\date(VALUE, [TIMEZONE])` Muuli og adlaw sa buwan (1-31). `0` kung ang VALUE kay wala butangi. Kung ang TIMEZONE kay wala butangi og value, ang timezone sa sistema ang gamiton. (ngadto pa sa version 4.7.0)
-
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Muuli og buwan (1-12). `0` kung ang VALUE kay wala butangi. Kung ang TIMEZONE kay wala butangi og value, ang timezone sa sistema ang gamiton. (ngadto pa sa version 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Muuli og tuig. `0` kung ang VALUE kay wala butangi. Kung ang TIMEZONE kay wala butangi og value, ang timezone sa sistema ang gamiton. (ngadto pa sa version 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Muuli og oras (0-23). `1` kung ang VALUE kay wala butangi. Kung ang TIMEZONE kay wala butangi og value, ang timezone sa sistema ang gamiton. (ngadto pa sa version 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Muuli og minuto (0-59). `-1` kung ang VALUE kay wala butangi. Kung ang TIMEZONE kay wala butangi og value, ang timezone sa sistema ang gamiton. (ngadto pa sa version 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Muuli og adlaw sa semana (0-6). `-1` kung ang VALUE kay wala butangi. `0` - para sa Domingo. Kung ang TIMEZONE kay wala butangi og value, ang timezone sa sistema ang gamiton. (ngadto pa sa version 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Muuli sa diperensiya sa duha ka date or datetime. INTERVAL_TYPE kay mamahimong 'years', 'months', 'days', 'hours', 'minutes'. Muuli og `null` kung wala nigana. Ang resulta kay negative kung ang VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Mudugang og MINUTES ngadto sa datetime nga VALUE. Ang MINUTES kay pwede negative.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Mudugang og HOURS ngadto sa datetime nga VALUE. Ang HOURS kay pwede negative.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Mudugang og DAYS ngadto sa date o datetime nga VALUE. Ang DAYS kay pwede negative.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Mudugang og WEEKS ngadto sa date o datetime nga VALUE. Ang WEEKS kay pwede negative.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Mudugang og MONTHS ngadto sa date o datetime nga VALUE. Ang MONTHS kay pwede negative.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Mudugang og YEARS ngadto sa date o datetime nga VALUE. Ang YEARS kay pwede negative.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` Muuli sa pinakaduol nga date o datetime sa VALUE base sa gipasa nga mga argumento. (ngadto pa sa version 5.0.0)
-
-Ang TYPE kay pwede mamahimong bisan asa ani nga mga musunod nga value: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. Ang TARGET kay usa ka integer nga value o usa ka string nga value. IS_PAST means to find closest in the past. If TIMEZONE is omitted then default timezone is used.
-
-Mga Example:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Muuli sa pinakaduol nga datetime value sa umaabot gamit ang 20:00 nga oras.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Muuli og `2017-11-01`, ang unang adlaw sa buwan.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Muuli sa sunod nga lunes (ang sinugdanan sa adlaw).
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Muilis og numeric nga VALUE ngadto sa string formatted nga gibase sa episipiko nga format o default nga application setting. Kung DECIMALS, DECIMAL_MARK, o THOUSAND_SEPARATOR, ang mga default sa sistema ang gamiton.
-
-Mga Example:
-
-`number\format(2.666667, 2)` - Ang result kay 2.67;
-
-`number\format(1000, 2)` - Ang result kay 1,000.00;
-
-`number\format(10.1, 0)` - Ang result kay 10.
-
-
-#### number\abs
-`number\abs(VALUE)` Absolute nga value. Muuli og null kong dili numero ang VALUE.
-
-#### number\round
-`number\round(VALUE, PRECISION)` Muuli og mga rounded nga value sa VALUE nga gipilian ug PRECISION (hidaghanon sa mga numero pagkahuman sa decimal point). Ang PRECISION kay pwede usab kini ma negative o zero (ang default);
-
-#### number\floor
-`number\floor(VALUE)` Muuli og sunod nga pinakaubos nga integer value pinaagi sa pag round down sa value kong gikinahanglan. (ngadto pa sa version 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` Muuli sa sunod nga pinakataas nga integer value pinaagi sa pag round up sa value kong gikinahanglan. (ngadto pa sa version 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Muuli og TRUE kung ang entity kay bago (gihimo pa) ug FALSE kong dili (giupdate pa).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Muuli og TRUE kung ang ATTRIBUTE sa entity kay nausab.
-
-Example:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Muuli og TRUE kung ang ATTRIBUTE sa entity kay wala nausab.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Ang attribute nga giset sa kadtong gikuha pa gikan sa database ang gitarget nga entity. Sa wala pa kini giusab.
-
-Example:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Mudugang ug ID ngadto sa Link Multiple field. Panaglitan, dungagan og 'someTeamId' ang 'teams' nga field.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Mudugang ug lista sa mga id. (ngadto pa sa version 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Mucheck kung ang Link Multiple nga field kay naay espisipiko nga ID.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Mutangtang sa espisipiko nga ID gikan sa Link Multiple nga field.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Mucheck kong ang gitarget nga entity kay naay relasyon ngadto sa laing entity nga gireprestar sa LINK og ID.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Muuli og ATTRIBUTE sa current nga user.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Muuli og array. (ngadto pa sa version 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Muuli og true kung ang LIST naay sulod nga VALUE. Pwede ni gamiton para sa Array ug Multi-Enum nga field. (ngadto pa sa version 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Mudugang ug usa o mas labaw pa nga mga elemento ngadto sa kataposan sa array ug muuli og bago nga array. (ngadto pa sa version 5.0.0)
-
-#### array\length
-`array\length(LIST)` Muuli og ihap sa pila ka elemento sa LIST. (ngadto pa sa version 4.8.1)
-
-### Mga Value
-
-* Mga String. E.g. 'some string';
-* Mga Integer nga numero. E.g. 1, 100, 40300.
-* Mga Float nga numero. E.g. 5.2.
-
-### Mga Variable
-
-Posible nga mu-define og custom nga mga variable sa formula.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Mga Example
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Pag-gamit sa Formula sa Mga Workflow
-
-Pwede gamiton ang formula ngadto sa mga workflow kondisyon og aksyon. Tanawa ang [workflows nga dokumentasyon](workflows.md#using-formula-in-actions) para sa dugang pa nga impormasyon.
diff --git a/i18n/ceb_PH/administration/import.md b/i18n/ceb_PH/administration/import.md
deleted file mode 100644
index f6b167469..000000000
--- a/i18n/ceb_PH/administration/import.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Import
-
-Ang import kay ma-access ra sa mga admin nga user. Administration > Import. Pwede kang mu-import ra gikan sa CSV nga mga file.
-
-## Step 1
-
-Pili kung unsa nga type nga mga rekord ang imohang gikinahanglan nga i-import (Entity Type field).
-Pili ug CSV file Ang file kay gikinahanglan nga giformat gamit ang `UTF-8`.
-Pili og `What to do?`. Mga pwede nga mga opsyon: 'Create Only', 'Create & Update', 'Update Only'.
-
-* `Create Only` - pilia ni kung gusto nimong rekord ra ang mahimo.
-* `Create & Update` - ang mga rekord kay himoon pero kung ang rekord nga nagkaparehas og mga field value kay makit-an, i-update kini. Pwede nimong e-check kung unsa nga mga field ang i-match by sa _Step 2_.
-* `Update only` - ang mga rekord ra nga naay nagkaparehang mga field value ang makitan ug i-update.
-
-Kung nakapili naka og csv nga file, pwede naka makakita kung unsaon ni pag parse sa Preview panel. Kung usbon nimo ang mga property, ang preview kay ma-update.
-
-* `Header Row` - depende kong ang CSV file naay unga nga row nga naay mga field name.
-* `Execute in idle` - girekomenda kini kung naa kay daghan nga rekord nga gusto nimong i-import. Ang import kay iproseso gamit ang cron. Ang status kay i-set ngadto sa 'Complete' kung ang proseso sa pag-import kay nahuman na.
-* `Skip searching for duplicates` - muminus kini sa import runtime.
-
-I-click ang _Next_ nga pindutanan para musunod ngadto sa _Step 2_.
-
-
-
-## Step 2
-
-I-setup ang field mapping: kung unsaon pag correspond sa field sa mga column ngadto sa csv file.
-Sa kaso nga 'Create & Update' ug 'Update only', gikinahanglan ra ka mucheck sa mga field kung asa ang mga rekord nga gikinahanglang ma-update kay makit-an.
-Pagdungag ug mga default value nga imohang ganahan iset sa mga bag-o o bag-ong giupdate nga mga rekord. E.g. pwede nimong i-specify ang Assigned User o Teams nga mga field.
-
-Pagkahuman sa pag-import, pwede na nimong i-revert ang mga nahimo nang mga rekord, mutan-aw sa mga nagkadoble ug mga na-update nga rekord. Kung nagkadoble, nagpasabot kini nga naay parehas nga rekord sa sistema. Pwede nimong tangtangon ang tanan imported nga mga duplicate sa makausa ra. Timan-e: Ang Revert kay dili mugana sa mga na-update nga mga rekord.
-
-I-click ang _Run Import_ nga pindutanan para magpadayon. Mukaon kini og pila ka oras usa ang import kay mahuman. Kung gusto nimo nga muimport og dagko nga mga rekord (depende ni sa imohang server configuration, kasagaran kung dako pa sa 200 ka mga rekord), gikinahanglan nimo nga siguradohon nga ang php parameter nga `set_time_limit` nga sakto ra sa hidak-on.
-
-
-
-## Unsaon pag-import ngadto sa Target List
-
-Kung mu-import kag Contacts, Leads o Accounts, pwede nimong ipuno ni sa ubang mga target list. Sa step 2, gikinahanglan nimong ipuno ang Target List nga field sa `Default Values` panel ug pilion ang gikinahanglan nga target list rekord. Pwede usab nimo gamiton ang `Update only` o `Create & Update` nga import para dungagan og mga dugang pa nga mga target ngadto sa target list.
diff --git a/i18n/ceb_PH/administration/installation.md b/i18n/ceb_PH/administration/installation.md
deleted file mode 100644
index a1a935d7f..000000000
--- a/i18n/ceb_PH/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Pag-install
-
-### Mga Requirement
-Ang EspoCRM mudagan ra sa kasagarang mga hosting provider. Ang mga requirement kay naglangkob sa mga musunod:
-
-* PHP 5.6 o ang pinakabag-o nga version sa PHP nga gi-enable ang pdo, json, GD library, mga mcrypt extension (kasagaran kay gienable nani by default);
-* MySQL 5.5.3 o mas taas pa.
-
-Tanawa ang [Server Configuration](server-configuration.md) para sa dugang pa nga impormasyon.
-
-### 1. I-download ang EspoCRM nga installation package
-Para makuha ang pinakabag-o nga version sa EspoCRM, adto sa [download page](http://www.espocrm.com/download/) nga link.
-
-### 2. I-upload ang mga EspoCRM File ngadto sa Imohang Server
-
-Inig ka-kompleto sa download, i-upload ang package ngadto sa imohang web server.
-Para ma-upload ni, pwede ka mugamit og SSH, FTP, o ang hosting administration panel.
-I-extract ang archive ngadto padulong sa imohang publikong web server directory (e.g., `public_html`, `www`, etc.).
-
-_Timan-e: Para sa FTP, gikinahanglan nimo i-extract ang archive una nimo i-upload ni sa imong web server._
-
-### 3. Paghimo og MySQL Database para gamiton sa EspoCRM
-
-Adto sa imohang hosting administration nga panel, o sa SSH, ug paghimo og bag-o nga database ug user para sa EspoCRM (e.g., `MySQL Databases` sa cPanel).
-
-### 4. Ipadagan ang EspoCRM installation nga proseso
-
-Karon, abilihi ang imohang web browser, ug adto sa URL nga naay mga EspoCRM file (e.g., `http://yourdomain.com/espo`).
-
-Kung nakita ni nimo ni nga screen, naa kay "Permission denied" nga error.
-Busa, gikinahanglan nimo i-execute ang nadisplay nga command sa terminal gamit ang SSH, o i-set ang sakto nga permission.
-Gikinihanglan nga 755 para sa mga directory, 644 para sa mga file, ug 775 para sa `data` nga directory.
-Siguradoha usab nga sakto ang imohang _owner_ ug _group_.
-
-
-
-Kung nakakita ka ani nga nga screen, ang permission kay sakto ug makasugod naka og install sa EspoCRM.
-
-
-
-Sa kani nga page, pwede nimong basahon ug dawaton ang License Agreement.
-
-
-
-Ibutang ang mga detalye para sa imohang bag-ong nahimo nga MySQL database.
-
-
-.
-Ibutang ang name sa user ug ang password sa Administrator EspoCRM.
-
-
-
-Sa kani nga page, pwede nimong i-set ang default nga mga setting sa EspoCRM, parehas sa petsa, format sa time, timezone, currency, ug uban pa.
-
-
-
-I-butang ang SMTP nga mga setting para sa mga gipadala na nga mga email, kung gusto ka mahatagan og abilidad nga mu send og mga email.
-Ang kani nga step kay pwede ra laktaran. I-click ra ang _Next_ nga pindutanan.
-Ang kaning tanang nga mga opsyon kay pwede idungag o iusab sa EspoCRM inig human og install.
-
-
-
-Congratulations! Ang pag-install kay natapos na.
-Ang pinaka-awahi nga butang nga imohang i-setup kay ang Scheduled Tasks nga ipadagan sa imohang sistema. Mahimo ni pinaagi sa pagpadagan sa `crontab -e` sa linux cli ug sa _Windows Tasks Scheduler_ sa Windows nga mga sistema.
-
-
-
-Naglaum kami nga malingaw kamo og pagtrabaho sa EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/ceb_PH/administration/layout-manager.md b/i18n/ceb_PH/administration/layout-manager.md
deleted file mode 100644
index 250eb6f95..000000000
--- a/i18n/ceb_PH/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Layout Manager
-
-Ang Layout Manager kay makita sa administration panel. Muhatag kini og abilidad nga mu-customize sa hitsura sa mga detail, edit, list view ug sa mga search filter ug field para sa mass-update nga form.
-
-## List
-
-Ang main layout para sa list view. Mudefine kini sa mga column ug ilahang mga parameter.
-
-
-
-Ang mga pwedeng gamiton nga mga parameter para sa column kay gilista sa ubos.
-
-### Width (%)
-
-Ang hilapdon sa column (porsyento), kung blangko nagpasabot ni nga auto-width.
-
-### Link
-
-Kung gicheck, ang field kay i-display isip usa ka link ngadto sa detail view sa rekord. Kasagarang gamiton para sa mga name field.
-
-### Not Sortable
-
-Mu-disable sa abilidad nga mupahan-ay sa mga column.
-
-### Align
-
-Mu-align sa column ngadto padulong sa wala o padulong sa tuo.
-
-## Detail
-
-Ang main layout para sa detail view ug sa edit view. Mu-define ug mga panel, mga row, ug mga cell. Ang mga cell kay naay sulod nga mga field.
-
-Ang row kay pwede maglangkob og duha ka mga cell o usa ka cell nga gi-expand ngadto sa pinakadako nga hilapdon sa row. Para ipuno ang row nga naay gi-expand nga cell, gikinahanglan nimo nga mupuno og bag-o nga row ug mu-click ug minus nga sign nga naa sa bisan unsang cell.
-
-
-
-## List (Small)
-
-Ang list layout para sa mga relationship panel. Pwede pud ni gamiton sa ubang mga okasyon nga resonable ra nga mupadisplay og mga list nga pig-ot ra ang view.
-
-## Detail (Small)
-
-Ang detail view para sa quick create, quick view, ug quick edit nga mga form.
-
-## Mga Search Filter
-
-Ang lista sa mga field kung asa pwede mangita nga naa sa list view.
-
-## Mass Update
-
-Ang lista sa mga field nga naa sa Mass Update nga form.
-
-## Mga Relationship Panel
-
-Ang lista sa mga relationship panel nga gidisplay sa detail view sa ubos nga bahin. Ang mga panel kay pwede usbon ang posisyon. Posible nga i-define ang mga kolor sa panel gamit ang Style nga parameter.
-
-## Mga Side Panel
-
-Mga side panel para sa Detail, Edit, Detail Small, Edit Small nga mga form. Muhatag og abilidad nga mutago o mu-reorder sa mga panels list Acitivities, History, Tasks, ug uban pa. Ang mga panel kay pwede makoloran gamit ang Style nga parameter.
-
-## Mga Additional Layout
-
-Ang ubang mga entity type kay naglangkob ug mga dugang pa nga mga layout: Convert Lead, List for Account.
diff --git a/i18n/ceb_PH/administration/ldap-authorization-for-ad.md b/i18n/ceb_PH/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index f2d8e6dc7..000000000
--- a/i18n/ceb_PH/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# LDAP authorization para sa Active Directory
-
-Example sa configuration LDAP authorization para sa Active Directory nga server. Ang tibuok guide sa configuration LDAP authorization kay makit-an [diri](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/ceb_PH/administration/ldap-authorization-for-openldap.md b/i18n/ceb_PH/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 0cc51fedf..000000000
--- a/i18n/ceb_PH/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# LDAP authorization para sa OpenLDAP
-
-Example sa configuration LDAP authorization para sa OpenLDAP nga server. Ang tibuok guide sa configuration LDAP authorization kay makit-an [diri](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/ceb_PH/administration/ldap-authorization.md b/i18n/ceb_PH/administration/ldap-authorization.md
deleted file mode 100644
index f35e88ddf..000000000
--- a/i18n/ceb_PH/administration/ldap-authorization.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# Ldap Authorization
-
-Sa kani nga guide, ipakita namo kung unsaon pag-configure sa LDAP authorization para sa EspoCRM.
-Tana.
-
-Adto sa imohang LDAP server ug paghimo og usa ka base DN para sa EspoCRM nga mga user parehas sa
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Nanginahanglan kita muhimo og system user kung asa naay access sa mga users DN (“cn=espo-users,ou=users,dc=espo,dc=local”). Busa, ang tibuok DN para sa kaning system user kay
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Karon, mupuno kita og LDAP user para mu-access sa EspoCRM. E.g. Espo Tester nga naay user name nga "tester" sa sulod sa “cn=espo-users,ou=users,dc=espo,dc=local” nga DN. Palihug timan-e: para makagamit sa kani nga login format para sa EspoCRM, gikinahanglan nimo nga i-specify ang “Username Attribute” ug “Base DN” nga mga opsyon.
-
-Dayon, adto sa EspoCRM Authentication nga mga setting sa Administrator nga panel, pilia ang `LDAP` nga method ug ibutang ang mga LDAP nga mga detalye:
-
-
-
-* Host – ang LDAP IP o host name.
-* Port – ang connection port.
-* Auth – ang access credentials para sa LDAP server:
- * Full User DN – ang full system user DN nga nitugot sa pagpangita sa ubang mga user.
- * Password – ang password para ma-access ang LDAP nga server.
-* Security – SSL o TSL nga protocol.
-* Username Attribute – ang attribute nga mu-ila sa user. Para sa Active Directory, pwede ni “userPrincipalName” o “sAMAccountName”.
-* Account Canonical Form – ang type sa imohang account canonical form. Naay 4 ka mga opsyon:
- * Dn – ang form nga naa sa format `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – ang form nga `tester`.
- * Backslash – ang form nga `COMPANY\tester`.
- * Principal – ang form nga `tester@company.com`.
-* Bind Requires Dn – kung nanginahanglan muformat sa username didto sa DN form.
-* Base Dn – ang default base DN nga gamiton para mangita og mga user.
-* User Login Filter – ang filter nga mutugot sa pag restrict sa mga user nga naay abilidad nga mu gamit sa EspoCRM. E.g. `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – Ang domain nga gamiton para sa authorization sa LDAP nga server.
-* Account Domain Name Short – Ang mubo nga domain nga gamiton para sa authorization sa LDAP nga server.
-* Try Username Split – ang opsyon nga mubuwag sa username ngadto sa domain.
-* Opt Referrals – kung ang mga referral kay gikinahanglang i-follow ngadto padulong sa LDAP client.
-* Create User in EspoCRM – ang kani nga opsyon kay mutugot sa EspoCRM nga muhimo og user gikan sa LDAP.
- * User First Name Attribute – LDAP attribute nga gamiton para mudetermina sa pangalan sa user.
- * User Last Name Attribute – LDAP attribute nga gamiton para mudetermina sa apelyedo sa user.
- * User Title Attribute – LDAP attribute nga gamiton para mudeterminal sa title sa user.
- * User Email Address Attribute – LDAP attribute nga gamiton para mudetermina sa email address sa user.
- * User Phone Number Attribute – LDAP attribute nga gamiton para mudetermina sa phone number sa user.
-
-Karon, adto sa login nga page ug i-enter ang mga user credential.
-
-
-
-Ang user kay na-authenticate na ug nahimo automatically didto sa EspoCRM.
-
-## Mga configuration instruction basi sa imohang server:
-* [Active Directory server](ldap-authorization-for-ad.md)
-* [OpenLDAP server](ldap-authorization-for-openldap.md)
-
-Para dugang impormasyon bahin sa pag-configure sa LDAP, pwede nimong basahon ang [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/) nga page, kay ang EspoCRM nigamit ani nga library.
-
-
-
-
diff --git a/i18n/ceb_PH/administration/maps.md b/i18n/ceb_PH/administration/maps.md
deleted file mode 100644
index fea9be11d..000000000
--- a/i18n/ceb_PH/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Mga Mapa
-
-## Unsaon pagpakita sa mapa basi sa address nga field
-
-Kada Address nga field kay naay kaparehas nga Map nga field. Gikinahanglan ra nga imong ibutang ni sa Detail layout. Mugamit kini og Google Maps nga service.
-
-`Administration > Layout Manager > Choose entity (Account, Contact, Lead or custom one) > Detail > Drag & Drop Map field.`
-
-Himoang lapad ang cell gamit ang minus sign.
-
-Pwede sad nimong i-configue ang hitas-on sa imohang field.
-
-`Administration > Entity Manager > Choose entity > Fields > find the map field and click on it > edit the height and save.`
-
-## Api nga Key
-
-Gikan pa sa bersyon 4.2.0 sa EspoCRM, gikinahanglan nimo nga i-specify ang Api Key para mugamit og Google Maps (Administration > Integration > Google Maps).
-
diff --git a/i18n/ceb_PH/administration/moving-to-another-server.md b/i18n/ceb_PH/administration/moving-to-another-server.md
deleted file mode 100644
index 7cf8d9736..000000000
--- a/i18n/ceb_PH/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Pagbalhin sa EspoCRM ngadto sa laing serber
-
-Sunda kini nga mga lakang aron mabalhin ang EspoCRM ngadto sa laing serber:
-
-### Una nga lakang. Mga backup file
-
-Pag-abli ug usa ka file manager o pag-login gamit ang SSH para i-archive ang tanang files nga pwede ma-archive gikan sa EspoCRM nga direktoryo: Mga dugang nga [detalye](backup-and-restore.md#step-1-pag-backup-sa-mga-file).
-
-### Ika-duha nga lakang. Back-upi ang imohang database
-
-Ang data nga nasulod sa database (MySQL, MariaDB) kay gikinahanglan naback-up. Palihug ug sunod sa mga [rekomendasyon](backup-and-restore.md#step-2-pag-backup-sa-database).
-
-### Ika-tulo nga lakang. Kopyaha ang mga file ug mga database backup ngadto sa laing serber
-
-Pagkopya og mga backup nga mga file ug ang imohang database ngadto sa bag-ong serber.
-
-### Ika-upat nga lakang. I-unarchive ang mga backup file
-
-Para i-unarchive ang mga backup, pwede kang mugamit og Archive Manager o kani nga mga [pagtudlo](backup-and-restore.md#step-1-pag-unarchive-sa-mga-backup-nga-file).
-Timan-e: Ang mga file nanginahanglan nga iplastar ngadto sa web-serber nga direktoryo.
-
-### Ika-lima nga lakang. I-konpigyur ang usa ka serber
-
-I-konpigyur ang usa ka bag-ong serber base sa mga rekomendasyon [diri](server-configuration.md).
-
-### Ika-unom nga lakang. Sakto nga mga permission
-
-I-set ang mga gikinahanglang mga [permission](server-configuration.md#mga-gikinahanlang-permiso-para-sa-mga-unix-based-nga-mga-sistema) og ang tag-iya sa mga file.
-
-### Ika-pito nga lakang. I-import ang imohang database backup
-
-Una, gikinahanglan nimong muhimo og bag-o nga database gamit ang usa ka user sa MySQL. Para ma-import ang imohang database gikan sa backup, sunda ang kaning mga [giya](backup-and-restore.md#step-3-pag-import-sa-database-dump).
-
-### Ika-walo nga lakang. Sakto nga mga EspoCRM configuration
-
-Human sa malampusong pag-import ug pag-konpigyur sa serber, palihug og usab para masakto ang EspoCRM nga mga configuration sa file nga `ESPOCRM_DIRECTORY/data/config.php`:
-
- * mga setting sa koneksyon sa database:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'PANGALAN_SA_IMONG_DATABASE',
- 'user' => 'IMOHANG_USER',
- 'password' => 'IMOHANG_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - kung ang pangalan sa imohang domain (URL) kay nausab:
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * tag-iya sa mga default file (kung lahi ra):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- kung asa ang `www-data` kay ang web-serber nga user.
-
-### Ika-siyam nga lakang. Pag-setup sa usa ka crontab
-
-Pag-setup sa usa ka [crontab](server-configuration.md#pag-setup-og-crontab).
-
-Timan-e: gikinahanglan i-konpigyur kini gamit ang imohang web-serber nga user.
-
-Mao ra tong tanan. Karon, ang imohang EspoCRM instance kay nagdagan sa bag-o nga serber.
diff --git a/i18n/ceb_PH/administration/nginx-server-configuration.md b/i18n/ceb_PH/administration/nginx-server-configuration.md
deleted file mode 100644
index 336620c55..000000000
--- a/i18n/ceb_PH/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Ang Nginx server configuration para sa EspoCRM
-
-Ang kani nga mga instruction kay pampuno lang sa [Server Configuration](server-configuration.md) nga mga guideline. Palihug timan-e nga ang tanang mga configuration setting nga gilista diri kay gihimo sa Ubuntu nga server.
-
-## Mga PHP requirement
-
-Para ma-install ang tanang gikinahanglan nga mga library, ipadagan ang kani nga mga command ngadto sa terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Pag-ayo sa issue nga “API Error: EspoCRM API is unavailable”:
-
-Himoa ra ang mga gikinahanglan nga mga lakang. Pagkahuman sa tagsa tagsa ka mga lakang, e-check kung na resolba naba ang problema.
-
-### 1. I-enable ang mga rewrite rule sa Nginx server
-
-Ipuno ni nga code sa imohang Nginx server block config nga file (/etc/nginx/sites-available/IMOHANG_SITE) sulod sa “server” nga bloke:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Kung wala ka ani nga file, gikinahanglan ka muhimo niini. Para mahimo ni, pag-abli og terminal ug ipadagan ni nga mga command.
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Ug ipuno ang mga code nga nakalista sa taas. Para sa dugang pa nga mga impormasyon kung unsaon pag-configure sa usa ka bag-o nga Virtual Host sa Nginx, palihug ug basa ani nga [ guideline](nginx-virtual-host.md).
-
-Ipadagan ni nga command sa usa ka terminal para e-check kung ang tanan kay maayo ra.
-
-```
-sudo nginx -t
-```
-
-Kon mao, ipadagan ang command para ma-restart ang nginx nga server:
-
-```
-sudo service nginx restart
-```
-
-### 2. Pagdungag og RewriteBase path
-
-Pag-abli og file sa /ESPOCRM_DIRECTORY/api/v1/.htaccess ug ilisi ang mga musnod nga linya:
-
-```
-# RewriteBase /
-```
-og
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-kung asa ang REQUEST_URI kay usa ka parte sa URL, e.g. para sa “http://example.com/espocrm/”, ug ang REQUEST_URI kay “espocrm”.
diff --git a/i18n/ceb_PH/administration/nginx-virtual-host.md b/i18n/ceb_PH/administration/nginx-virtual-host.md
deleted file mode 100644
index ee6238119..000000000
--- a/i18n/ceb_PH/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Pag-konpigyur sa usa ka Virtual Host nga naa sa Nginx para sa EspoCRM
-
-Sa kani nga giya, ipakita namo unsaon pag-konpigyur sa usa ka virtual host nga naa sa Nginx para sa EspoCRM nga naa sa Ubuntu serber.
-
-## Himo og usa ka serber block nga file
-
-Para himoon ni nga file, pag-abli ug terminal ug ipadagan ni nga mga komand:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Karon, ablihi ang kani nga file (/etc/nginx/sites-available/espocrm.conf) ug usba ang code nga gikinahanglang musunod sa format nga giprint sa ubos (ang ubang mga setting kay pwede lahi base sa inyohang konpigurasyon):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.lokal; # Ilisi ang espocrm.lokal ngadto sa inyohang domain name
- root /var/www/html/espocrm; # Ispecify inyohang EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL konpigurasyon
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # I-specify ang inyohang PHP (php-cgi or php-fpm) basi sa inyohang konpigurasyon
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Puno og rewrite nga mga rule
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## I-enable ang kaning serber block
-
-Himo og usa ka symbolic link:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Ipadagan ni nga komand para tan-awon kong ang tanan kay nigana ra:
-
-```
-sudo nginx -t
-```
-
-Ug i-restart ang Nginx nga serber:
-
-```
-sudo service nginx restart
-```
-
-## I-konpigyur ang imohang mga lokal host (opsyonal, para ra sa lokal domain)
-
-Kung nagdugang ka og lokal domain, gikinahanglan nimo i-konpigyur ni sa imohang lokal nga kompyuter (dili sa serber). Para sa Ubuntu, ablihi ang file `/etc/hosts` ug ipuno ang kani nga linya:
-
-```
-192.168.1.1 espocrm.lokal # specify the IP address of your Nginx serber
-```
-
-Para sa Windows, sunda kini nga mga [giya](http://support.microsoft.com/kb/923947).
diff --git a/i18n/ceb_PH/administration/portal.md b/i18n/ceb_PH/administration/portal.md
deleted file mode 100644
index b370844f2..000000000
--- a/i18n/ceb_PH/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Portal
-
-Ang portal kay muhatag og abilidad nga mu-access sa ispisipiko nga crm data ug mga function para sa inyohang mga kustomer og partner. Ang administrador kay makahimo og nagkalain-laing mga portal. Ang kada usa ka portal kay mamahimong manag-iya ug iyahang kaugalingong mga setting, dashboard, lista sa user, ug mga access kontrol nga setting.
-
-Para muhimo og portal sunda ang Administration > Portals, i-click ang Create Portal nga pindutanan.
-
-* `Is Active`. Kung wala na-check, ang portal kay dili magamit sa bisan kinsa.
-* `Is Default`. Nagpasabot nga ang portal kay mamahimong mas mubo pa nga url: http(s)://YOUR_ESPO_URL/portal.
-* `Roles`. I-specify ang usa o mas daghan pa nga mga portal role nga i-apply ngadto sa mga user nga naka-log sa imohang portal.
-* `Tab List`. Mga tab nga ipakita sa navigation bar.
-* `Dashboard Layout`. I-specify ang mga dashlet nga ipakita sa home page sa portal. Timan-e nga ang mga portal user kay dili ka-configure sa ilahang dashboard.
-* `URL`. Read only field nga mupakita sa link kung asa maka-access ka sa portal.
-
-## Mga Portal User
-
-Ang mga administrador kay makahimo og mga portal user.
-
-1. Administration > Users.
-2. I-click ang tuo nga dropdown sunod sa Create User.
-3. I-click ang Create Portal User.
-4. Ipili ang Contact nga maoy i-link sa portal user.
-5. Pun-a ang form og i-click ang save.
-
-Ang portal user kay gikinahanglan i-link sa Portal nga rekord para maka-access sa kadto nga portal.
-
-## Mga Portal Role
-
-Ang mga portal role kay parehas ra sa regular nga mga role sa EspoCRM pero naay mga gagmay nga kalahian.
-
-* `not-set` level nga mu-dili mutugot og access.
-* `own` level kay nagpasabot nga ang rekord kay gihimo sa user. E.g. ang portal user kay ni-case sa ubang case ug ang kani nga case kay gitag-iya sa kani nga user.
-* `account` level nga nagpasabot nga ang rekord kay naay relasyon sa account nga ang portal user kay naa puy relasyon.
-* `contact` level nga nagpasabot nga ang rekord kay naay relasyon sa contact nga ang portal user kay naa puy relasyon.
-
-Ang Assigned User ug ang Teams fields kay read-only ra para sa mga portal user.
-
-### Example
-
-`Ang mga portal user kay gikinahanglan muhimo og mga case, mutan-aw sa mga case nga naay relasyon sa ilahang account; gikinahanglan sila nga mutan-aw sa knowledge base.`
-
-1. Abili sa Create Portal Role nga form (Administration > Portal Roles > Create Role).
-2. I-enable ang access sa mga Case, i-set ang: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. I-enable ang access sa Knowledge Base, i-set ang: `create - no, read - account, edit - no, delete - no`.
-4. I-edit ang imohang portal nga rekord (Administration > Portals). Pilia imohang portal role sa Roles field ug i-save.
-
-## Access sa Portal
-
-Pwede nimong makit-an ang url para sa portal sa 'URL' field sa portal record. Posible usab mugamit ug mga serve configuration tool (parehas sa mod_rewrite) para ma access ang lahi nga url. Para sa in-ani nga kaso, gikinahanglan nimo i-fill ang 'Custom URL' nga field.
-
-### I-access ang portal gamit ang Custom URL para sa Apache server
-
-Custom nga URL: akoang-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName akoang-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Mga Mod rewrite na balaod
-
-I-specify ang portal record ID kaysa sa `{PORTAL_ID}`. Ang portal record ID kay naa makit-an sa address bar sa imohang web browser kung imohang ablihan ang detail view sa imohang portal record. Parehas sa: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. Ang 16b9hm41c069e6j24 kay usa ka portal record id.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/ceb_PH/administration/roles-management.md b/i18n/ceb_PH/administration/roles-management.md
deleted file mode 100644
index 6274f300f..000000000
--- a/i18n/ceb_PH/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Management sa mga Role
-
-## Ang Kinatibuk-an
-
-Para ma-restrict ang access sa ubang mga user, gikinahanglan nimo gamiton ang Roles. Ang administrador kay maka dumala ug mga role sa Administration panel. Ang tagsa-tagsa ka mga role kay nag-define sa access sa ubang mga area (mga iskop) nga asa i-aplay sa mga user nga nakatag-iya ana nga role.
-
-Ang usa ka user kay pwede naay daghan nga mga role. Ang kadtong mga role kay pwede ipili para sa usa ka ispisipiko nga user ('Roles' field sa User entry) ug/o i-mana gikan sa mga team nga diin nalangkob ang user.
-
-Kung ang user kay naay daghan nga mga role, i-merge sila para ang permissive rule kay ang mahatagan og mas dako pa na prayoridad. Nagtugot kini nga sayon ra ug flexibly nga madumala sa administrador ang access level control.
-
-Posible nga makita ang mga permission nga gi-aplay sa usa ka user pinaagi sa pag-click sa 'Access' nga pindutanan sa detail view sa user.
-
-
-
-## Example
-
-Pananglitan, ang user kay nalangkob sa team nga ‘Sales’. Ang kadto nga team kay naa nag-inusara nga role nga ‘Salesman’. Ang tanang user gikan nianing team kay makadawat og ‘Salesman’ nga role.
-
-Ang ‘Salesman’ nga role kay gidefine gamit ang musunod nga pamaagi:
-
-Lead:
-```
-create - yes
-read – team
-usab – own
-delete – no
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-usab – own
-delete – no
-stream - team
-```
-
-Ang mga user kay mamahimong mubasa ngadto ra sa mga lead ug oportunidad kung asa nalangkob sa ‘Sales Department’ team (‘Teams’ field).
-Ang user kay mamahimong mu-usab ngadto ra sa mga lead ug oportunidad kung asa na-assign sila o sa ilahang mga nabuhat.
-Ang mga user kay dili mamahimong mutang-tang ug bisan unsang lead o oportunidad.
-
-Gusto mi nga muhatag ug mas daghan mga nga mga right pra sa usa ka user nga nagkupot ug sales manager nga posisyon sa usa ka kompanya. Ang kani nga empleyado kay gikinahanglang naay abilidad nga mu basa/usab/delete sa tanang mga rekord gikan sa ‘Sales’ team. Ang user kay gikinahanglan nalangkob sa atoang ‘Sales’ team. Pero nanginahanglan ta nga mubuhat og bag-o nga role nga ‘Sales Manager’ ug i-select ang kani nga role para ato nga user sa ‘Roles’ field.
-
-Ang ‘Sales Manager’ nga role kay gi-define pinaagi sa musunod:
-
-Lead:
-```
-create - yes
-read – team
-usab – team
-delete – team
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-usab – team
-delete – team
-stream - team
-```
-
-Ang atoang user kay mamahimong mudumala sa tanang mga lead ug oportunidad gikan sa ‘Sales’ team.
-
-## Mga Espesiyal Permisyon
-
-### Assignment nga Permisyon
-
-I-set ni nga parameter aron ma-restrict ang abilidad nga mure-assign ug mga rekord ngadto sa uban nga user ug/o mga team. Kung imong i-set ngadto sa `team` - posible na i-assign ra ni sa mga users gikan sa kaugalingong (mga) team. Kung `no` - ang mga user kay dili mamahimong maka-re-assign.
-
-Mu-define pud kini kung ang user kay mamahimo bang makapost ngadto sa stream sa laing mga user/team.
-
-### User nga Permisyon
-
-Mutugot nga mu-restrict sa abilidad sa mga user nga mutan-aw ug mga aktibidad, kalendaryo og stream sa ubang mga user.
-
-### Portal nga Permisyon
-
-Mudefine ug access sa impormasyon sa portal, abilidad nga makapost ug mga mensahe sa mga portal user.
-
-### Group Email Account nga Permisyon
-
-Mudefine ug access ngadto sa mga group email account, usa ka abilidad nga mupadala og mga email gikan sa group SMTP.
-
-### Export nga Permisyon
-
-Mudefine kung ang user naa bay abilidad para mu-export ug mga rekord. (gikan pa sa bersyon 4.9.0)
-
-## Mga Permisyon nga Default
-
-Ang mga user kay makabasa ug maka-usab sa tanang rekord kung walay nakabutang nga permission. Pero dili sila maka-tangtang gawas sa kadto ilahang binuhat ug kadto pung mga naka-assign sa ilaha.
-
-Naay abilidad para marestrict ang access nga gi-aplay by default pinaagi sa pag-enable sa 'ACL Strict Mode' sa Administration > Settings.
-
-## Field Level nga Seguridad
-
-Mutugot sa pag-control sa access para sa usa ka ispisipiko nga field.
-
-Ang user kay makabasa sa tanan field kung kini kay makabasa sa rekord (by default). Ang user kay maka-usab ug bisan unsang field kung kini kay maka-usab sa rekord. Pwede nimong i-restrict ang access sa mga ispisipiko nga mga field gamit ang Field Level Security.
-
-Sa edit view sa usa ka role rekord sa Field Level seksiyon, i-click ang plus nga icon sunod sa ispisipiko nga iskop dayon pilia ang gikinahanglan nga field. Dayon, gikinihanglan nimo nga i-specify ang access level para sa `read` ug `usab` nga mga aksyon. Naay duha ka mga opsyon: `yes` ug `no`.
-
-
diff --git a/i18n/ceb_PH/administration/server-configuration.md b/i18n/ceb_PH/administration/server-configuration.md
deleted file mode 100644
index 9a0995e54..000000000
--- a/i18n/ceb_PH/administration/server-configuration.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Server Konpigyurasyon para sa EspoCRM
-
-Ang EspoCRM aky pwede i-instolar sa Apache ([mga giya kung unsaon](apache-server-configuration.md)), Nginx ([mga giya kung unsaon](nginx-server-configuration.md)), o IIS nga server nga naay suporta para sa bersiyon 5.6 o mas taas pa nga PHP ug bersiyon 5.1 o mas taas pa nga MYSQL.
-
-## Mga Girekomenda nga Konpigyurasyon
-
-### Mga Gikinahanglan nga PHP
-
-EspoCRM requires PHP 5.6 or greater, with the following extensions enabled:
-Ang EspoCRM kay nanginahanglan og bersyon 5.6 o mas taas pa nga PHP, nga naay mga musunod nga gi-enable nga mga ekstensiyon:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – para i-akses ang MySQL sa PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – ang mga kapanguhaan gay mugamit ani nga mga format (metadata, layout, pinulongan], ug uban pa);
-* [GD](http://php.net/manual/en/book.image.php) – to manipulate images;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – para masigurado ang pinakataas nga porma sa proteksiyon;
-* [Zip](http://php.net/manual/en/book.zip.php) – para mamahimong makaupgrade sa EspoCRM ug muinstolar og mga ekstensiyon;
-* [IMAP](http://php.net/manual/en/book.imap.php) – para mabantayan ang mga mailbox sa EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Girekomenda usab nga naay [mailparse](https://pecl.php.net/package/mailparse) pec1 nga ekstensiyon nga nakainstolar. Gikinahanglan ni para sa sayon nga mag pag-gana sa feature nga pagkuha og email.
-
-mga php.ini setting:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Mga Gikinahanglan nga MySQL
-
-Ang EspoCRm kay nagsuporta sa bersiyon 5.1 o mas taas pa nga MySQL.
-Walay espesiyal nga mga kalahian. Ang tanan default nga setting kay maayo ra para sa EspoCRM
-
-## Mga Gikinahanlang Permiso para sa mga Unix-based nga mga Sistema
-
-Ang mga file og mga direktoryo kay gikinahanglan sa mga musunod nga permiso:
-
-* `/data`, `/custom`, `/client/custom` – gikinihanglan nga ang tanan nga mga file, direktoryo, ug mga subdirectory kay masuwatan (664 para sa mga file, 775 para sa mga direktoryo, naglangkob sa tanan subdirectory og mga file);
-* `/application/Espo/Modules`, `/client/modules` – gikinahanglang ang tanang bag-o nga direktoryo kay masuwatan (775 para sa karon nga direktoryo, 644 para sa mga file, 755 para sa mga direktoryo og mga subdirectory);
-* Ang ubang lahing mga file ug direktoryo kay gikinahanglan nga mabasa (644 para sa mga file, 755 para sa mga direktoryo).
-
-Para i-set ang mga permiso, i-eksekyut ang mga musunod ng mga command sa terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Ang tanang mga file kay gikinahanglan nga gitag-iya o gi tag-iya na grupo sa webserver nga proseso. Pwede kining “www-data”, “daemon”, “apache”, “www”, etc.
-Timan-e: Sa Bitnami nga Stack, ang mga file kay gikinahanglan nga gitag-iya ug gi tag-iya na grupo sa “daemon” user.
-Timan-e: Sa mga shared nga mga host, ang file kay gikinahanglang gipanag-iya o gi panag-iya nga grupo sa imohang user account.
-
-Para i-set ang tag-iya ug grupo nga tag-iya, ipadagan ang mga musunod nga mga command sa terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## Pag-setup og crontab
-
-Para makasetup og usa ka crontab sa UNIX nga sistema, buhata ang mga musunod nga mga lakang:
-
-* 1. Pag-login isip usa ka administrador sa imohang EspoCRM nga instance.
-* 2. Adto sa Scheduled Jobs nga seksiyon sa sulod sa administrador nga panel (Menu > Administration > Scheduled Jobs) ug kopyaha ang string nga para sa crontab. Ang hitsura kay mura aning naa sa ubos.
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Pag-abli ug usa ka terminal ug ipadagan ni ang musunod nga command:
-```
-crontab -e -u WEBSERVER_USER
-```
-Ang WEBSERVER_USER kay pwede bisan asa aning mga musunod “www”, “www-data”, “apache”, etc (depende sa imohang webserver).
-
-* 4. I-paste ang nakopya nga string (gikan sa ikaduhang lakang) ug i-save ang crontab nga file (Ctrl+O, then Ctrl+X para sa nano editor).
-
-## Mga konpigurasyon ug mga instruksiyon base sa imohang server
-
-* [Konpigurasiyon sa Apache server](apache-server-configuration.md).
-* [Konpigurasiyon sa Nginx server](nginx-server-configuration.md).
diff --git a/i18n/ceb_PH/administration/troubleshooting.md b/i18n/ceb_PH/administration/troubleshooting.md
deleted file mode 100644
index 67f1ddd5d..000000000
--- a/i18n/ceb_PH/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Pag-troubleshoot
-
-## I-check ang mga log
-
-Para masakpan ang problema, gikinahanglan nimong i-check ang mga error log file.
-
-#### Mga EspoCRM error log
-
-Ang mga EspoCRM log kay makit-an sa `/logs/*.log` ug naay sulod nga mga impormasyon sa mga sayop o pagkaguba.
-
-#### Mga Apache error log
-
-Para sa Ubuntu server, ang apache error log kay makit-an sa `/var/log/apache2/error.log` ug naa kini sulod nga mga impormasyon sa mga sayop o pagkaguba. Ang lokasyon sa mga log file kay pwede maglahilahi sa ubang mga sistema.
-
-## I-enable ang debugging mode
-
-Para i-enable ang mode para maka debug, adto sa installed EspoCRM nga direktoryo, ablihi ang file `data/config.php` ug usba ang balor:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-ngadto sa
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Ang mga Scheduled Job kay wala nang-gana
-
-#### Problema #1: Ang imong crontab kay wala nakonpigyur
-
-1. Pag-login gamit ang SSH ngadto sa imohang server.
-
-2. I-konpigyur ang imohang [crontab](server-configuration.md#pag-setup-og-crontab) gamit sa mga musunod nga mga lakang.
-
-Timan-e: Ang crontab kay gikinahanglang i-konpigyura sa ubos sa web-server nga user, e.g. `crontab -e -u www-data`.
-
-3. Huwat ug pipila ka oras ug i-check ang mga Sheduled Job para matan-aw kung ang mga trabahoonon kay nabuhat na (tan-aw og usa ka Log nga panel).
-
-#### Problema #2. Ang Crontab kay nakonpigyura na, pero ang mga Scheduled Job kay wala nigana
-
-Para siguradohon nga walay error nga nahitabo samtang nagdagan si cron, suwayi og padagan ang musunod nga cron command sa usa ka terminal:
-
-1. Pag-login gamit ang SSH ngadto sa imohang server.
-
-2. Adto sa imohang direktoryo kung asa naka-instolar ang EspoCRM. E.g. para sa `/var/www/html/espocrm` nga direktoryo ang command kay:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Ipadagan ang crontab command:
-
-```bash
-php cron.php
-```
-
-Timan-e: Gikinahanglan kini nga i-eksekyut ubos sa web-server nga user. Kung wala ka naka-login isip root, ang command kay gikinahanlan ni (e.g para sa Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-kung asa ang `www-data` kay usa ka web-server nga user.
-
-4. Kung walay mga error, i-check ang mga Scheduled Job aron tan-awon kung naay mga na-eksekyut (tan-awa ang Log panel).
-
-## Ang EspoCRM wala ni-load pagkahuman ug updgare
-
-Pwede ni mahitabo sa ubang mga shared nga hosting.
-
-Tan-awa ang mga permiso sa mga kani nga file:
-/index.php
-/api/v1/index.php
-
-Gikinahanglan ni nga 644. Kung naay bisan usa ka file nga naay permiso nga 664, gikinahanglan nimo ni usbon ngadto sa 644. Gamita imohang kontrol panel sa hosting o chmod nga command.
-
-```
-chmod 644 /path/to/file
-```
-Para sa dugang nga impormasyon bahin sa mga permiso sa file: [diri](server-configuration.md#mga-gikinahanlang-permiso-para-sa-mga-unix-based-nga-mga-sistema).
diff --git a/i18n/ceb_PH/administration/upgrading.md b/i18n/ceb_PH/administration/upgrading.md
deleted file mode 100644
index 83c69742c..000000000
--- a/i18n/ceb_PH/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Unsaon pag-upgrade sa EspoCRM
-
-Ang EspoCRM kay pwede i-upgrade ngadto sa pinakabag-o nga version pinaagi sa pagsunod sa mga musunod nga mga step:
-
-### Step 1. Tanawa ang imohang current nga version
-
-Para tan-awon ang imohang version, adto sa Administration > Upgrade nga page.
-
-### Step 2. I-download ang mga gikinahanglan nga mga package
-
-Adto sa [upgrade page](https://www.espocrm.com/download/upgrades/) ug i-download ang mga gikinahanglan nga mga package basi sa sakto nga version.
-
-### Step 3. Paghimo og backup (opsyonal)
-
-Paghimo og backup sa imohang EspoCRM nga mga file ug data usa mag-upgrade. Sunda ang kani nga mga [instruction](backup-and-restore.md) aron mabuhat nimo kini.
-
-### Step 4. Proseso sa pag-upgrade
-
-Adto sa Administration > Upgrade. I-upload ug i-install ug tagsa tagsa ang mga upgrade package.
-
-Pwede nimong i-check kung naa nimo ang pinaka bago nga version sa Menu > About.
-
-## Pag-upgrade gamit ang CLI
-
-Pwede pud nimong himoon ang pag-upgrade gamit ang command line interface. Gikinahanglan nimo i-execute ni ang musunod nga command gian sa EspoCRM root nga directory:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/ceb_PH/administration/workflows.md b/i18n/ceb_PH/administration/workflows.md
deleted file mode 100644
index 95e1ef3f1..000000000
--- a/i18n/ceb_PH/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Mga Workflow
-
-Ang workflows nga feature kay naa makit-an sa [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Ang mga workflows kay mu-awtomeyt sa imohang mga proseso sa negosyo sa sayon nga pamaagi. Makit-an ni sa Administration nga panel. Para mugama ug workflow nga balaod, gikinahanglan nimong ipatin-aw ang mga musunod:
-
-* Target Entity - kong unsa nga entity type workflow ang gigamit;
-* Trigger Type - kon kanus-a sugdan ang workflow;
-* Conditions - mga kondisyon nga nanginahanglan maabtan para masugdan ang workflow;
-* Actions - unsa ang buhaton kong nasugdan na ang workflow.
-
-
-## Mga Tipo sa Magpasugod
-
-### Pagkahuman mahimo ang rekord
-
-Masugdan ra kung usa ka bag-o nga rekord ang nabuhat. Kung ang gipasabot nga mga kondisyon kay naabot, ang mga aksyon kay i-eksekyut.
-
-### Pagkahuman masave ang rekord
-
-Masugdan ra kung ang bag-o nga rekord kay nahimo na ug ang nahimo na nga rekord kay na-update. Kung ang mga gipasabot nga mga kondisyon kay naabot, ang mga aksyon kay i-eksekyut.
-
-Para sa mga balaod sa worflow nga naay in-ani nga tipo sa pagpasugod, komon nga nga buhaton nga mukuha ug kondisyon para mucheck kung ang ubang mga field kay 'nausab'. E.g. Kung ang status sa Case kay nausab, sugdi ang ubang mga aksyon.
-
-### Scheduled
-
-Sugdan sumala sa gihimo nga scheduling. Pwede kang muset-up para ipadagan ni kada adlaw, kada semana, etc. Ang mga aksyon kay i-apply sa mga rekord nga giuli sa list repot. Mao gikinahanglan pud nimong mubuhat og list report.
-
-Ang scheduling kay gi-specify ngadto sa usa ka crontab nga notasyon.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Tuig (naa sulod sa: 1900-3000)
-| | | | +---- Adlaw sa semana (naa sulod sa: 1-7, 1 kay nagpasabot nga Lunes)
-| | | +------ Buwan sa tuig (naa sulod sa: 1-12)
-| | +-------- Adlaw sa buwan (naa sulod sa: 1-31)
-| +---------- Oras (naa sulod sa: 0-23)
-+------------ Minuto (naa sulod sa: 0-59)
-```
-
-### Sekwensyal
-
-Tagsa ra kani gamiton. Ipadagan unta kini sa laing workflow. Naghatag ug abilidad nga muhimo og mga komplikado nga lohiko.
-
-Timan-e: Para sa mga sequential nga mga workflow, girekomenda nga gamiton ang [BPM tool](bpm.md) kaysa sa Workflows nga feature.
-
-## Mga Kondisyon
-
-Pwede nimong ilista ang mga kondisyon nga gikinahanglan nga maabot para masugdan ang workflow. Naay duha ka mga pamaggi kong unsan paglista sa mga kondisyon: gamit ang UI condition builder og gamit ang formula.
-
-### UI condition builder
-
-Mga pwedeng gamiton nga mga tipo sa kondisyon:
-
-* _equals_ - ang field kay pareha ra sa usa ka espisipiko nga balor o ang balor sa lahi nga field;
-* _was equal_ - ang field kay pareho ra sa usa ka espisipiko nga balor sa di pa masugdan ang workflow;
-* _not equals_ - ang field kay di parehas og balor sa usa ka espisipiko nga balor o ang balor sa lain nga field;
-* _was not equal_ - ang field kay dili pareho sa usa ka espisipiko nga balor sa di pa sugdan ang workflow;
-* _empty_ - ang balor sa field kay blangko;
-* _not empty_ - ang balor sa field kay di blangko;
-* _changed_ - ang field kay nausab;
-* _not changed_ - ang field kay wala nausab.
-
-### Mga kondisyon nga pormula
-
-Ang pormula kay muhatag og abilidad nga mudefine sa mga kondisyon sa bisan unsa nga pagkakomplikado. Para mubasa mahitungod sa pormula syntax sunda ni nga [artikulo](formula.md).
-
-Timan-e: Gikinahanglan nga walay bisan unsang `;` nga delimeter ang gamiton sa code nga pormula kung idetermina ang kondisyon.
-
-## Mga Aksyon
-
-### Pagpadala ug Email
-
-Ang sistema kay magpadala ug email gamit ang gi-specify nga email template. Ang address sa mudawat sa email kay makuha gikan sa gitarget nga rekord, bisan unsang related nga rekord, ang kasamtangang user, mga follower, mga team user o mga gispecify. Ang email kay mapadala karon dayon o ipadugay para sa espisipiko nga interbal.
-
-### Paghimo ug Rekord
-
-Ang sistema kay muhimo og bag-o nga rekord sa bisan unsang entity nga tipo. Kung naay relasyon bahin sa gitarget nga rekord og ang naghimo nga rekord, naay posibilidad nga himoan og relasyon ang duha ka rekord.
-
-Naay abilidad nga mu-define ug formula para ikalkula ang mga field.
-
-### Paghimo og mga Related nga Rekord
-
-Ang sistema kay muhimo og rekord nga naay relasyon sa gitarget nga rekord. Naay posibilidad nga mudefine ug pormula para ikalkula ang mga field.
-
-### Pag-update sa Gitarget nga Rekord
-
-Mupahimo og mga pag-usab sa mga espisipiko nga mga field sa gitarget nga rekord. Posibleng i-define ang pormula para ikalkula ang mga field.
-
-Kung gikinahanglan nimong mudugang og mga bag-o nga mga item ngadto sa Link-Multiple field nga walay mawala nga nahimo na nga datos (e.g. Teams), gikinahanglan nimong gamiton ang pormula nga punsyon nga entity\addLinkMultipleId. Pananglitan: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### I-update ang Related nga Rekord
-
-Nagtugot nga muusab sa mga espisipiko nga mga field sa mga related rekord o mga rekord. Posible kini nga mudefine ug mga pormula para mukalkula sa mga field.
-
-### Link sa Laing Rekord
-
-Mu-relate sa gitarget nga entity sa laing espisipiko nga entity. E.g. mudugang ug espisipiko nga team ngadto sa rekord.
-
-### Unlink sa Laing Rekord
-
-Mu-unrelate sa gitarget nga entity sa laing espisipiko nga entity. E.g. mutangtang ug espisipiko nga team gikan sa rekord.
-
-### I-apply ang Assignment nga Balaod
-
-I-assign ang gitarget nga rekord sa user gamit ang distribusyon nga balaod. Naay duha ka mga balaod nga pwedeng gamiton: Round-Robin ug Least-Busy.
-
-* Round-Robin - ang mga user kay pilion gikan sa taas ngadto sa ubos sa lista (team) ug balikon nasad pag-usab.
-* Least-Busy - ang user nga naay pinakagamay nga na-assng nga mga rekord maoy pilion para sa assignment.
-
-_List Report_ - Para sa Least-Busy nga distribusyon, i-determina kung unsa nga rekord ang gikonsiderar para makalkula ang ihap sa naka-assign nga mga rekord. E.g. para sa mga Case, gikinahanglan natong kwaon ra ang mga rekord nga naay aktibo nga estado.
-
-### Paghimo og Notipikasyon
-
-I-notify ang mga espisipiko nga mga user gamit ang kani nga mga mensahe. Posibleng mugamit og mga placeholder sa message template: {entity} - gitarget nga record, {user} - ang kasamtangang user.
-
-### Himuong Musunod
-
-Pugson ang mga espisipiko nga mga user nga musunod sa gitarget nga entity o ang gispecify nga related nga entity.
-
-### Pagsugod sa Lain na sad nga Workflow
-
-Mutugot nga muhimo og sekwensiyal nga mga workflow. Posible nga i-branch ang workflow gamit ang mga kondisyon: pwede nimong i-setup ang workflow para i-trigger ang duha ka workflow gamit ang managlahing mga kondisyon nga gidefine sa kato nga mga workflow.
-
-Posible sad dugayon ug eksekyut ang sekwensiyal nga workflow. Sa sekwensiyal nga workflow, pwede nimong i-define ang kondisyon nga mu-check kung ang espisipiko nga mga field kay nausab kay ang ginikanan nga workflow kay gisugdan sa gamit ang _Changed_ ug _Was Equal_ nga mga tipo sa kondisyon.
-
-Timan-e: Para sa sekwensiyal nga mga workflow, girekomenda nga mugamit og [BPM nga tool](bpm.md) kaysa sa Workflows nga feature.
-
-### Ipadagan ang Service nga Aksyon
-
-Mutugot nga ipadagan ug mga espisipiko nga mga script. Kung walay mga pag-usab, ang mga musunod nga aksyon kay pwede gamiton:
-
-* Send Invitations - para sa Meetings/Calls;
-* Add Quote Items - para sa Quotes.
-
-Ang mga developer kay pwede kasulat ug ilahang kaugalingong mga aksyon nga serbisyo. Tan-awa ang [ubang mga detalye](../development/workflow-service-actions.md).
-
-## Using Formula in Actions
-
-Posible nga mudefine ug pormula para ikalkula ang mga field para sa Create Record, Update Target Record, Create Related Record, Update Related Record. Para sa nauwahi nga duha, para magamit ang mga attribute sa gitarget nga entity, gikinahanglan nimong mugamit sa punsyon nga `targetEntity\attribute`. Para gamiton ang mga attribute sa gitarget nga entity nga na-set usa nasugdan ang workflow, gamita ang punsyon nga `targetEntity\attributeFetched`.
-
-Pananglitan:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/ceb_PH/development/api.md b/i18n/ceb_PH/development/api.md
deleted file mode 100644
index 60873252e..000000000
--- a/i18n/ceb_PH/development/api.md
+++ /dev/null
@@ -1,224 +0,0 @@
-# Ang REST API
-
-Ang EspoCRM kay usa ka single page nga aplikasyon mao ang frontend mugamit og REST API para mukonektar sa backend.
-
-Ang tanan nga mga operasyon nga imong gihimo gamit ang UI mahimo nimung ipadagan pinaagi sa mga tawag sa API gamit ang imong programming nga pinulongan.
-Mahimo nimu nga mahibal-an kon sa unsang paagi naglihok ang API kung imong subayon kung unsay nahitabo sa network tab sa console sa imung browser.
-
-Kadaghanan sa mga gimbuhaton sa API mubalik ug JSON. Ang mga tawag sa POST, PATCH kasagaran nagkinahanglan sa pipila ka datos sa JSON sa payload.
-
-Ang Base URL sa EspoCRM API mao ang: `api/v1/`. Kinahanglan ni nimu i-prepend sa mga ekspresyon niining reperensya. Pananglitan:
-
-`GET http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Pagpamatuod
-
-EspoCRM API gagamit ug [Basic Authentication](http://en.wikipedia.org/wiki/Basic_access_authentication). Ang username o password/token nagaagi sa `Authorization` header nga naka-encode sa base64.
-
-`"Authorization: Basic " + base64Encode(username + ':' + password)`
-
-
-Mas maayo nga gamiton ang auth token imbis nga password kon magtrabaho ka sa api. Sa kini nga kaso gikinahanglan nimo ang paghatag ug username ug password / token sa header sa `Espo-Authorization`.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-
-1. Pagkuha ug access token pinaagi sa `GET App/user` nga request uban ang username ug password nga gipasa sa header sa `Espo-Authorization`.
-2. Gamita kini nga token imbis ang password isa `Espo-Authorization` header alang sa dugang pa nga request.
-3. Kung ang request mubalik ug 403 nga sayop kana nagpasabot nga bisan asa sa username/password sayup o ang token kay dili na balido.
-
-#### Pamatuod sa Pag-ila / Tukma nga Datos sa User
-
-`GET App/user`
-
-Ang mga ibalik:
-
-* `token` - access token nga gamiton;
-* `acl` - impormasyon bahin sa pag-access sa user;
-* `preferences` - mga gusto sa tiggamit;
-* `user` - mga user rekord nga attribute.
-
-
-## Mga Operasyon sa CRUD
-
-#### Paglista sa mga Entity
-
-`GET {entityType}`
-
-Pagkuha ug mga parametro:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) max nga gidak-on;
-* `where` - (array) mga filter;
-* `sortBy` - (string) field nga pwede han-ayan;
-* `asc` - (bool) matang nga direksyon.
-
-_Pananglitan_
-
-`GET Account?offset=0&maxSize=20`
-
-Mobalik:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Pagbasa sa Entity
-
-`GET {entityType}/{id}`
-
-Nagbalik sa mga attribute sa JSON object.
-
-_Pananglitan_
-
-`GET Account/5564764442a6d024c`
-
-#### Paghimo sa Entity
-
-`POST {entityType}`
-
-Payload: Object sa mga entity attribute.
-
-Mubalik og mga entity attribute nga JSON object.
-
-_Pananglitan_
-
-`POST Account`
-
-Payload:
-```
-{
- "name": "Test",
- "assignedUserId": "1"
-}
-```
-
-#### Pag-Update sa Entity
-
-`PATCH {entityType}/{id}`
-
-o
-
-`PUT {entityType}/{id}`
-
-Payload: Ang object sa mga entity attribute kinahanglan nga usbon.
-
-Mobalik sa mga attribute nga JSON object.
-
-_Pananglitan_
-
-`PATCH Account/5564764442a6d024c`
-
-Payload:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Pagtangtang sa Entity
-
-`DELETE {entityType}/{id}`
-
-_Pananglitan_
-
-`DELETE Account/5564764442a6d024c`
-
-
-## Mga Entity nga may Kalabutan
-
-#### Paglista sa Entity nga may Kalabutan
-
-`GET {entityType}/{id}/{link}`
-
-* `offset` - (int) offset;
-* `maxSize` - (int) kinadak-an nga gidak-on;
-* `where` - (array) mga filter;
-* `sortBy` - (string) field nga pwede han-ayan;
-* `asc` - (bool) matang nga direksyon.
-
-_Pananglitan_
-
-`GET Account/5564764442a6d024c/opportunities`
-
-Ang ibalik:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Pag-Link sa Entity
-
-`POST {entityType}/{id}/{link}`
-
-Payload:
-
-1. `id` attribute.
-2. `ids` attribute array.
-3. `"massRelate": true` ug `"where": {...}` pag-asoy sa daghang mga rekord pinaagi sa mga search criteria.
-
-_Pananglitan_
-
-`POST Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Pag-unlink sa Entity
-
-`DELETE {entityType}/{id}/{link}`
-
-Payload:
-
-1. JSON nga naay `id` attribute.
-2. JSON nga naay `ids` array nga attribute.
-
-_Pananglitan_
-
-`DELETE Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-## Pag-stream
-
-#### Paglista sa mga entry sa stream alang sa kasamtangan nga tiggamit
-
-`GET Stream`
-
-Pagkuha ug mga parametro:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) kinadak-an nga gidak-on;
-
-#### Paglista sa mga entry sa stream nga may kalabutan sa usa ka espesipiko nga rekord
-
-`GET {entityType}/{id}/stream`
-
-Pagkuha uga mga parametro:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) kinadak-an nga gidak-on;
-
-#### Pagsunod sa Rekord
-
-`PUT {entityType}/{id}/subscription`
-
-#### Pag-unfollow sa Rekord
-
-`DELETE {entityType}/{id}/subscription`
-
-
-
diff --git a/i18n/ceb_PH/development/custom-field-type.md b/i18n/ceb_PH/development/custom-field-type.md
deleted file mode 100644
index 77bda9a9f..000000000
--- a/i18n/ceb_PH/development/custom-field-type.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Paghimo og Custom nga Field Type
-
-### Field Definition
-
-Himo og usa ka file nga `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` nga naa ang gikinahanglan nga mga parametro.
-```
-{
- "view": "custom:views/fields/{field-type}"`
-}
-```
-
-Gamit og mga out-of-the-box field nga tipo isip mga example: `/application/Espo/Resources/metadata/fields`.
-
-### Paghubad
-
-Ang label nga gigamit sa Entity Manager kay pwede maset sa `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` sa seksyon nga `fieldTypes`.
-Kung gikinahanglan nimo pun-an ang paghubad ngadto sa lain nga lengguwahe, gamit og needed language [language code](https://en.wikipedia.org/wiki/ISO_639-1)_[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) kaysa sa `en_US`. Sa sulod sa `data/config.php` sa seksyon `languageList` pwede ka makapangita sa lista sa mga giapil nga mga lengguwahe.
-
-### View
-
-Himo og view para sa field `client/custom/src/views/fields/{field-type}.js` ug i-define ang mga template niini
-```
-Espo.define('custom:views/fields/[field-type]', 'views/fields/base', function (Dep) {
-
- return Dep.extend({
-
- });
-});
-```
-
-Gamit og mga out-of-the-box field nga tipo isip mga example:
-- `/client/src/views/fields` - mga view;
-- `/client/res/templates/fields` - mga template.
-
-Dayon, gikinahanglan nimo ipadagan ang rebuild ngadto sa administration nga panel.
diff --git a/i18n/ceb_PH/development/custom-views.md b/i18n/ceb_PH/development/custom-views.md
deleted file mode 100644
index 283471f8a..000000000
--- a/i18n/ceb_PH/development/custom-views.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Mga Custom nga View
-
-## Mga Record View
-
-Ang EspoCRM framework naghatag ug mga flexible nga abilidad aron itakda ang mga custom view alang sa pipila nga matang sa entity. Kini kinahanglan nga gihubat sa `clientDefs` nga kategoriya sa metadata.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-Ang Record/Detail view naglakip sa tanan nga mga panel nga adunay mga field, mga relasyon ug ubang mga datos nga imong makita sa detail view. Wala kini'y header ug mga buton sa tuo nga bahin.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Here is your custom template. Omit if you don't need it.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Here is your custom view. Omit if you don't need it.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Here is your custom view. Omit if you don't need it.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Here is your custom view. Omit if you don't need it.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Custom initalization logic here. Like binding listening to model changes.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Custom code to be invoked right after rendering, when DOM is avaiable.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-Makahimo ka sa pagbuhat sa usa ka custom nga template uban sa mosunod nga path:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-Ang Detail view adunay Record/Detail view ug Header.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-Sama ra sa detail apan gamiton ra sa dihang ang rekord nga gimugna o gi-edit dili sa inline-edit mode.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-Ang List view adunday Record/List view, Header ug Search Form View.
-
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-Ang List/Record view naglangkob sa mga laray sa mga rekord.
-
-
-Kini angay nga isulti nga kinahanglan nimong makuha ang imong view class gikan sa espesipiko nga klase sa imung entity kung ang usa naa na.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Mga Field View
-
-Ang mga Custom views alang sa mga espesipiko nga mga field kinahanglan nga matino sa seksyon sa entityDefs sa metadata.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
-
diff --git a/i18n/ceb_PH/development/dynamic-forms.md b/i18n/ceb_PH/development/dynamic-forms.md
deleted file mode 100644
index 05a2baed9..000000000
--- a/i18n/ceb_PH/development/dynamic-forms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Mga Dynamic Form
-
-Timan-e: Gikan sa bersiyon 4.3.0, posible na nga mudefine og dynamic nga form pinaagi sa UI sa admin sa Entity Manager.
-
-Naay abilidad nga mu-define og linihokan sa form sa EspoCRM.
-
-## Pananglitan
-
-> Gikinahanglang ipakita ang _nextStep_ field ngadto sa Opportunity detail view kung ang stage kay 'Closed Won'.
->
-
-Himo og file nga `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Nagpasabot to nga ang _nextStep_ nga field kay itago (kung wala ray usbon) ug ipakita kung ang stage kay 'Closed Won'.
-
-Ang lista sa mga pwedeng buhaton nga mga aksyon: `show`, `hide`, `setRequired`, `setNotRequired`.
-
-Naay puy abilidad nga mutago/mupakita ug mga panel. Ispecify ang pangalan sa panel sa `panels`, attribute nga parehas sa `fields`.
diff --git a/i18n/ceb_PH/development/extension-packages.md b/i18n/ceb_PH/development/extension-packages.md
deleted file mode 100644
index dadac4b51..000000000
--- a/i18n/ceb_PH/development/extension-packages.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Mga Ekstensyon nga Pakete
-
-Ang mga ekstenyon motugot kanimo pagdungag ug dugang nga katuyoan ngadto sa EspoCRM. Mahimo kini i-instolar gumikan sa Administrator panel ubos sa seksyon sa `Kustomisasyon`.
-
-## Unsaon Paghimo ug Ekstensyon nga Pakete
-
-Usa ka istruktura sa pakete:
-
-* `/manifest.json` – usa ka file nga naglangkob sa mga kabtangan sa ekstensyon;
-* `/files` – usa ka direktoryo nga naglangkob sa ekstensyon nga mga file;
-* `/scripts` – naglangkob sa mga script sa ekstensyon.
-
-### Manipesto
-```json
-{
- "name": "Pangalan sa Ekstensyon",
- "version": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "author": "Imohang Pangalan",
- "description": "Deskripsyon sa Ekstensyon",
- "delete": []
-}
-```
-
-* Ang syntax sa `version` ug `acceptableVersions` gihulagway sa v2.0.0 espesipikasyon nga makita sa http://semver.org.
-* `delete` - ang listahan sa mga core nga mga file nga kinahanglan nga papason. Kini nga parametro wala girekomendar nga gamiton. Mahimo nimo kini sal-angan.
-
-### Mga File
-
-Ang tanan nga ekstensiyon nga mga file kinahanglan ibutang sa `files` nga direktory. Sila kopyahon ngadto sa EspoCRM core nga direktory.
-
-### Mga Script
-
-Alang sa lainlaing mga katuyoan ang EspoCRM nagsuporta sa mosunod nga mga matang sa mga script. Ang tanan niini kinahanglan ibutang sa direktoryo sa `scripts`.
-
-* `BeforeInstall.php` – usa ka script nga gipatuman sa dili pa ang proseso sa pag-instalar;
-* `AfterInstall.php` – buhaton sa dihang nahuman na ang proseso sa pag-instalar;
-* `BeforeUninstall.php` – buhaton sa wala pa ang proseso sa pag-uninstall;
-* `AfterUninstall.php` – buhaton sa diha nga ang proseso sa pag-instalar nahuman na.
-
-Pananglitan:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Pakete
-
-Sa katapusan, gikinahanglan nato nga ibutang ang tanan nga mga file ngadto sa .zip archive.
diff --git a/i18n/ceb_PH/development/hooks.md b/i18n/ceb_PH/development/hooks.md
deleted file mode 100644
index 292c2a5d6..000000000
--- a/i18n/ceb_PH/development/hooks.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Mga Hook
-
-## Pagbuhat ug usa ka Hook
-Aron makahimo ka usa ka hook, kinahanglan nimo:
-- maghimo ug file `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- ideklarar ang hook type action;
-- limpyohan ang Cache sa Administrasyon..
-
-## Mga Tipo sa mga Hook
-
-Ang nag-unang mga tipikal nga hook mao:
-
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove;
-- afterRelate;
-- afterUnrelate;
-- afterMassRelate.
-
-### Bag-ong Tipo sa Hook
-Mahimo nimong gamiton ang imong kaugalingong tipo nga hook ug sugdan kini uban sa
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Ang Order sa Hook
-Kon aduna kay daghang mga hook, nga may kalabutan sa usa ka Entity Type ug uban sa parehas nga hook type, ug ang running order importante, mahimo ka magtakda sa `public static $order` nga property sa usa ka integer value.
-
-Pataas nga han-ay - nga may pinakagamay nga numero sa han-ay runs modagan ug una.
-
-## Pananglitan
-Kini nga ehemplo nagtakda sa ngalan sa account alang sa mga bag-ong Lead, kon wala kini gitakda.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-use Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Mga Global Hook
-Kung kinahanglan nimo nga gamiton ang usa ka hook alang sa tanan nga mga entity, mahimo nimo gamiton ang mga common nga hook. Sa pagbuhat niini, ibutang ang imong hook class sa Common nga direktoryo, e.g. `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/ceb_PH/development/how-to-create-a-dashlet.md b/i18n/ceb_PH/development/how-to-create-a-dashlet.md
deleted file mode 100644
index c898e8bb3..000000000
--- a/i18n/ceb_PH/development/how-to-create-a-dashlet.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Kon unsaon paghimo og dashlet
-
-Paghimo og file nga `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` uban sa konpigurasyon sa imong dashlet.
-
-Dinhi kinahanglan nimo ipasabut ang `"view"`, ug mahimo nimo nga itakda ang `"aclScope"`, `"entityType"`, ug `"options"`.
-
-Kung kini tipikal nga listahan dashlet, gamita ang `"view":"views/dashlets/abstract/record-list"`, kung dili, paghimo og kaugalingon nga [view](https://github.com/espocrm/documentation/blob/master/docs/development/custom-views.md).
-
-## Mga Opsyon
-Pinaagi sa default sa mga opsyon sa dashlet mahimo nimong itakda ang _Titulo_ ug _Auto-refresh Interval_.
-
-Ang dugang nga mga option field mahimo nimung itakda sa `"options"` > `"fields"`.
-
-Aron matino ang mga posisyon sa field, itakda ang layout sa `"options"` > `"layout"` > `"rows"`
-
-Mahimo usab nimo matino ang ubang mga kapilian, kung ang imong view nagkinahanglan og dugang nga impormasyon.
-
-## Pananglitan
-
-`application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json`
-
-```
-{
- "view":"views/dashlets/abstract/record-list",
- "aclScope": "Case",
- "entityType": "Case",
- "options": {
- "fields": {
- "title": {
- "type": "varchar",
- "required": true
- },
- "autorefreshInterval": {
- "type": "enumFloat",
- "options": [0, 0.5, 1, 2, 5, 10]
- },
- "displayRecords": {
- "type": "enumInt",
- "options": [3,4,5,10,15]
- },
- "expandedLayout": {
- "type": "base",
- "view": "views/dashlets/fields/records/expanded-layout"
- }
- },
- "defaults": {
- "sortBy": "createdAt",
- "asc": false,
- "displayRecords": 5,
- "expandedLayout": {
- "rows": [
- [
- {
- "name": "number"
- },
- {
- "name": "name",
- "link": true
- },
- {
- "name": "type"
- }
- ],
- [
- {
- "name": "status"
- },
- {
- "name": "priority"
- }
- ]
- ]
- },
- "searchData": {
- "bool": {
- "onlyMy": true
- },
- "primary": "open"
- }
- },
- "layout": [
- {
- "rows": [
- [
- {"name": "title"}
- ],
- [
- {"name": "displayRecords"},
- {"name": "autorefreshInterval"}
- ],
- [
- {"name": "expandedLayout"},
- false
- ]
- ]
- }
- ]
- }
-}
-```
-Didto makita nimo ang pipila ka mga ehemplo `application/Espo/Modules/Crm/Resources/metadata/dashlets`.
-
-## Paghubad
-
-Ang paghubad sa dashlet anaa na sa `Global` nga scope, sa sekyon sa `"dashlets"`.
-
-__Human sa tanan ayaw kalimot sa Paglimpyo sa Cache sa Administrasyon.__
diff --git a/i18n/ceb_PH/development/link-multiple-with-primary.md b/i18n/ceb_PH/development/link-multiple-with-primary.md
deleted file mode 100644
index ccba3172f..000000000
--- a/i18n/ceb_PH/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# Pagdugtong sa daghang mga field kauban sa nahauna
-
-Usahay ikaw adunay `hasMany` nga relasyon ug kinahanglan nga aduna kay abilidad sa pagpili sa pangunang rekord sa mga naa nay kabalutan. Pananglitan, `Contacts` nga field sa Case entity.
-
->Kinahanglan nga buhaton ang `contacts` linkMultiple nga field uban ang panguna para sa atong custom nga entity `Stock`.
->
-
-### Unang Lakang
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-### Ikaduhang Lakang
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-### Ikatulong Lakang
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-### Ika-upat nga Lakang
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-### Ikalimang Lakang
-Padagan anag Rebuild
-
-### Ika-unom nga lakang
-Ipatuman ang SQL query
-```sql
-UPDATE stock
-JOIN contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
diff --git a/i18n/ceb_PH/development/metadata.md b/i18n/ceb_PH/development/metadata.md
deleted file mode 100644
index 0ae00a2ff..000000000
--- a/i18n/ceb_PH/development/metadata.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Metadata
-
-Ang metadata gituyo alang sa: pagtipig sa datos sa sistema sama sa mga field sa entity ug relasyon; pagtakda sa mga frontend nga controller, mga view, mga panel; pagtino sa mga field, mga dashlet; ug ubang mga datos nga gikinahanglan alang sa aplikasyon.
-
-
-## Unsaon Pag-access
-
-#### Backend
-
-Ang object sa metadata sa `Espo\Core\Utils\Metadata` nga klase mahimong makuha gikan sa Container. Ang path ngadto sa usa ka gikinahanglan nga parametro gitino gamit ang mga tulbok `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-will return `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-mobalik ug usa ka associative array sa tanan nga mga field.
-
-#### Frontend
-
-Ang object sa metadata mahimong makuha gikan sa tanan nga mga view object pinaagi sa `#getMetadata`. Kini mugana sa samang paagi sa backend.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## Giunsa kini pagtipig
-
-Ang metadata gitipigan sa mga file sa JSON nga nahimutang sa lainlaing mga dapit
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-Sa higayon nga ma-access mo ang datos pinaagi sa path `clientDefs.Account.views.edit` ang unang lexeme `clientDefs` mag-uyon sa pangan sa dir, ang ikaduha nga `Account` a pag-file sa ngalan `Account.json`. Ang tanan nga mosunod nga lexemes mag-uyon sa path sa JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-Ang tanan nga mga JSON nga mga file gikan sa mga directoryo gihiusa sa rekursibo nga pamaagi
-ngadto sa usa ka php array ug gitipigan sa cache file.
-
-## Pag-extend
-
-Sanglit ang metadata gihiusa na sa rekursibo nga pamaagi, dali ra nimu mausab ang mga json object ug mga array sa _custom_ and in your _module_. Mahimo usab nimo ang pagdugang sa mga kasamtangan nga mga arrays pinaagi sa paggamit sa `__APPEND__` (sukad sa bersyon 2.6.0) ingon nga ang una nga elemento sa han-ay.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/ceb_PH/development/new-function-in-formula.md b/i18n/ceb_PH/development/new-function-in-formula.md
deleted file mode 100644
index 3a81e12d9..000000000
--- a/i18n/ceb_PH/development/new-function-in-formula.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Pagdeklara sa ug mga bag-o nga punsyon para sa Formula
-
-Ang EspCRM kay naghatag og posibilidad nga muhimo og mga custom nga punsyon nga pwedeng gamiton sa formula.
-
-Kung ang imong punsyon kay naay kalabotan sa usa sa mga grupo parehas sa String, Logic, Date, paghimo og file sa __{GroupName}Group__ nga folder, nga naay pangalan nga __{FunctionName}Type.php__ ug naay __{FunctionName}Type__ nga class nga deklarasyon. Gikinahanglan nimong itakda ang method __'process'__.
-
-Pananglitan, muhimo ta og bag-o nga string nga punsyon para susihon kung ang usa ka string (HAYSTACK) kay naglangkob sa ubang string (NEEDLE) nga posibleng naay offset (OFFSET).
-
-Himo og file `application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` nga naay code nga:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-use \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Pagbutang sa punsyon ngadto sa lista
-
-Para mapuno ang nahimo nga punsyon ngadto sa listahan sa mga punsyon sa formula, himo og file nga `custom/Espo/Custom/Resources/metadata/app/formula.json` ug ipuno ang code nga:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Pag-clear cache__ ug gamita ni nga punsyon sa formula. Pwede ni nimong i-type `string\contains(HAYSTACK, NEEDLE, OFFSET)` o pilion gikan sa listahan sa mga punsyon, kung imoha ning ipuno.
-
diff --git a/i18n/ceb_PH/development/orm.md b/i18n/ceb_PH/development/orm.md
deleted file mode 100644
index 75c66812b..000000000
--- a/i18n/ceb_PH/development/orm.md
+++ /dev/null
@@ -1,228 +0,0 @@
-# ORM, Unsaon pagdumala sa mga entity ug pagbuhat og mga query
-
-Ang EspoCRM kay naay mga nahimo na nga ORM (Object-relational mapping). Simple ra ang paghimo, pag-update, pagbasa, pag-tangtang, ug pagpangita sa mga entity. Ang tanan nga operasyon kay pwede himoon gamit ang EntityManager nga object. Ang EntityManager kay makit-an sa rekord nga Services pinaagi sa method nga `#getEntityManager()`.
-
-
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Paghimo og bag-o nga entity
-```php
-$account = $entityManager->getEntity('Account')
-```
-o
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Pagkuha sa mga nahimo na
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-o
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Pagkuha sa balor
-```php
-$fieldValue = $account->get('fieldName');
-```
-
-#### Naay balor
-```php
-$fieldNameIsSet = $account->has('fieldName'); // true o false
-```
-
-#### Pagtakda sa balor
-```php
-$account->set('fieldName', 'Test Account');
-```
-
-```php
-$account->set(array(
- 'name' => 'Test Account',
- 'assignedUserId' => '1'
-));
-```
-
-#### Pag-Store
-```php
-$entityManager->saveEntity($account);
-```
-o
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Pag-tangtang
-```php
-$entityManager->removeEntity($account);
-```
-o
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Pagpangita
-```php
-$accountList = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer'
-])->find();
-```
-
-Paubos nga paghan-ay:
-
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', true)->find();
-```
-
-Pataas nga paghan-ay:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt')->find();
-```
-
-o:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', 'DESC')->find();
-```
-
-#### Pagpangita sa pinakauna
-```php
-$account = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer',
-])->findOne();
-```
-
-#### Pagpangita sa mga naay kalabotan
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
-```
-
-#### Relate nga mga entity
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
-```
-o
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
-```
-
-#### Mga unrelate nga entity
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
-```
-o
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
-```
-
-### Pili og mga Query nga Parametro
-
-#### Where nga clause
-
-##### Mga Comparison Operator
-
-Mga gisuportahang operator: `>`, `<`, `>=`, `<=`, `=`, `!=`.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'amount>=' => 100
-])->find();
-```
-
-##### IN ug NOT IN nga mga operator
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage' => ['Closed Lost', 'Closed Won']
- ])->find();
-```
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage!=' => ['Closed Lost', 'Closed Won']
-])->find();
-```
-
-##### Mga LIKE operator
-
-Mga gisuportahan nga mga operator:
-* `*` - LIKE,
-* `!*` -- NOT LIKE.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'name*' => '%service%'
-])->find();
-```
-
-##### Mga OR, AND operator
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- [
- 'OR' => [
- ['stage' => 'Closed Won'],
- ['stage' => 'Closed Lost']
- ],
- 'AND' => [
- 'amountConverted>' => 100,
- 'amountConverted<=' => 999
- ]
- ]
-])->findOne();
-```
-
-#### Distinct
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->distinct()->where(...)->find();
-```
-
-#### Join
-
-```
-$contactList = $entityManager->getRepository('Contact')->distinct()->join('opportunities')->where([
- 'opportunities.stage' => 'Closed Won'
-])->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()->leftJoin('opportunities')->where(...)->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()
-->join(['opportunities', 'aliasForJoinedTable'])
-->where([
- 'aliasForJoinedTable.stage' => 'Closed Won'
-])->find();
-```
-
-#### Group By
-
-```
-$selectParams = [
- 'select' => ['MONTH:closeDate', 'SUM:amountConverted']
- 'groupBy' => ['MONTH:closeDate'],
- 'whereClause' => [
- 'stage' => 'Closed Won'
- ],
- 'orderBy' => 1 // ordering by the first column
-];
-
-// pag-gamit og mga left join para sa pag-convert sa currency
-$this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams);
-
-$pdo = $this->getEntityManager()->getPDO();
-$sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams);
-$sth = $pdo->prepare($sql);
-$sth->execute();
-
-// Mga resulta
-$rowList = $sth->fetchAll(\PDO::FETCH_ASSOC);
-```
diff --git a/i18n/ceb_PH/development/scheduled-job.md b/i18n/ceb_PH/development/scheduled-job.md
deleted file mode 100644
index cf2ee6757..000000000
--- a/i18n/ceb_PH/development/scheduled-job.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Ang Paghimo og Gischedule nga Trabahoon
-
-Para muhimo og usa ka custom nga Gischedule nga Trabahoon, himo og usa ka file `custom/Espo/Custom/Jobs/{JOB_NAME}.php` nga naay sulod nga.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //ang tanang lohika kay gikinahanglan himoon diri sa method nga run
- }
-}
-```
-
-Usab, pwede sad ka mu-set ug label para sa imohang trabahoon (`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-Para i-implementar ang mga kausaban, adto sa Administration nga panel ug i-Clear ang Cache.
diff --git a/i18n/ceb_PH/development/workflow-service-actions.md b/i18n/ceb_PH/development/workflow-service-actions.md
deleted file mode 100644
index 05b2cd977..000000000
--- a/i18n/ceb_PH/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Pagpuno og custom nga service nga aksyon para sa Workflow
-
-Ang Workflows mutugot sa paghimo og mga custom service nga mga aksyon. Ang musunod nga example kay mupakita kung unsaon ni pagbuhat para sa Call nga entity.
-
-## Unang Lakang. Himo og service nga class
-
-```php
- Clear Cache. Karon, magamit na ang service action para sa Workflows nga naa sa Run Service Action nga form.
diff --git a/i18n/ceb_PH/user-guide/activities-and-calendar.md b/i18n/ceb_PH/user-guide/activities-and-calendar.md
deleted file mode 100644
index 630a94a4a..000000000
--- a/i18n/ceb_PH/user-guide/activities-and-calendar.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Mga Aktibidad ug Kalendaryo
-
-Adunay tulo ka klase nga matang sa mga aktibidad nga anaa sa EspoCRM gumikan sa default:
-
-* Mga miting;
-* Mga tawag;
-* Mga tahas.
-
-Ang administrador makahimo ug usa ka custom nga entity sa matang sa panghitabo. Unya sa Administration > Settings > Activities posible nga itakda kini nga klase sa entity isip usa ka aktibidad ug mahimo kining makita sa kalendaryo.
-
-Adunay 'My Activities' nga dashlet nga nagpakita sa aktwal ug umaabot nga mga tahas sa aktibidad nga may kalabutan sa kasamtangan nga tiggamit.
-
-Ang mga Account, Contact, Lead, Oportunidad ug Kaso adunay Activities panel nga makita sa detail view. Ang mga custom nga entity sa Base Plus nga matang adunay usab Activities panel.
-
-## Mga Miting, Mga Tawag
-
-### Mga Nanambong
-
-Adunay 3 nga matang sa mga nanambong nga gisuportahan: Mga tiggamit, Mga Contact, Mga Lead. Alang sa matag mitambong posible nga mahibal-an ang status sa pagdawat: Gidawat, Tentative, Mibalibad. Adunay usa ka abilidad sa pagpadala sa mga email sa imbitasyon ngadto sa mga nanambong pinaagi sa pag-klik sa button sa ibabaw nga bahin sa tuo. Ang mga nanambong makahimo sa pagtakda sa ilang status sa pagdawat pinaagi sa pag-klik sa katugbang nga link sa email.
-
-### Mga Pahinumdom
-
-Adunay duha ka matang sa pahinumdom: Popup (in-app nga mensahe) ug Email.
-
-### Default nga Gidugayon
-
-Ang default nga gidugayon mahimong usbon sa administrador sa Administration > Entity Manager > Meetings / Calls > Fields > Duration > Default. Kini kinahanglan nga itakda sa mga segundo.
-
-## Mga aktibidad
-
-Dili kinahanglan ang petsa sa pagsugod ug petsa nga gikinahanglan nga mga field. Ang mga petsa mahimong matino nga adunay o walay time parts.
-
-### Mga Pahinumdom
-
-Ang mga pahinumdum sa tahas sa aktibidad mahimong magamit kung ang petsa nga gikihanglan kay gitakda ug adunay time part.
-
-## Ang Kalendaryo
-
-Ang kalendaryo nagpakita sa mga Miting, Mga Tawag, mga Gimbuhaton. Posible usab nga ipakita ang mga custom entity sa klase sa Event.
-
-Gisuportahan nga mga View:
-
-* Buwan;
-* Seman;
-* Adlaw;
-* Timeline.
-
-Ang mga tiggamit mahimong makadugang sa Kalendaryo sa ilang dashboard.
-
-Posible nga makita ang kalendaryo sa laing tiggamit (kung adunay access nga gitino sa mga posisyon). Ang button sa kalendaryo anaa sa detail view sa tiggamit.
-
-### Gipakigbahin nga Kalendaryo
-
-Ang gipakigbahin nga kalendaryo anaa lamang sa Timeline view. Nagatugot kini sa pagtan-aw sa mga panghitabo sa daghang tiggamit.
diff --git a/i18n/ceb_PH/user-guide/browser-support.md b/i18n/ceb_PH/user-guide/browser-support.md
deleted file mode 100644
index 6728ff83b..000000000
--- a/i18n/ceb_PH/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Suporta sa browser
-
-Murekomenda kami sa pag-gamit sa pinakabag-o nga bersiyon sa Google Chrome o Mozilla Firefox. Ang EspoCRM kay mugana ug maayo sa kani nga mga browser. Amoang pagacheckon ang tanan mga feature sa kani nga mga browser.
-
-Ang Microsoft Edge og Safari kay gisuportahan usab, pero dili kaayo dako ang garantiya nga ang tanan mugana.
-
-Wala namo girekomenda ang paggamit sa Internet Explorer 11.
diff --git a/i18n/ceb_PH/user-guide/case-management.md b/i18n/ceb_PH/user-guide/case-management.md
deleted file mode 100644
index 0bc75dcae..000000000
--- a/i18n/ceb_PH/user-guide/case-management.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Pagdumala sa Kaso
-
-Ang mga kaso naghatag og abilidad sa pagsubay sa isyu. Kini usa ka labing mahinungdanon nga aspeto sa pagserbisyo sa customer sa EspoCRM. Ang termino sa tiket mahimo usab nga gamiton alang sa Mga Kaso.
-
-Ang entity sa mga kaso mahimong mahilambigit sa usa ka Account ug / o adunay daghang mga Contact.
-
-Ang bag-ong mga kaso kinahanglan nga lihukon sa mosunod nga mga sitwasyon:
-
-* Sa manual nga pamaagi sa mga tiggamit sa CRM;
-* Sa manual nga pamaagi sa tiggamit sa customer portal;
-* Pinaagi sa API (e.g. pinaagi sa web form);
-* Awtomatiko sa diha nga ang usa ka bag-ong email miabut sa usa ka espesipiko nga mailbox.
-* Awtomatiko gumikan sa lagda sa Workflow.
-
-Ang rekord sa kaso adunay usa ka stream nga mahimong magamit alang sa komunikasyon tali sa kustomer ug serbisyo. Ang mga tiggamit sa CRM makahimo usab ug mga internal nga post nga dili makita sa usa ka customer portal.
-
-Sa diha nga ang bag-ong kaso gimugna sa usa ka tiggamit sa portal, dili na kini igahin sa bisan kinsa nga tiggamit. Pinaagi sa paggamit sa [Workflows](../administration/workflows.md) ang administrador makahimo og lagda nga mopahibalo sa pipila ka mga tiggamit mahitungod sa bag-ong kaso sa sistema. Ang mga Workflow naghatag usab ug abilidad sa pag-apply ug assignment rule sa mga bag-ong kaso, i.e. Round-Robin ug Least-Busy nga mga lagda. Alang sa mas komplikado nga mga business flow, kini girekomendar nga gamiton [BPM tool](../administration/bpm.md).
-
-Aron mapugngan nga di masal-angan mga bag-ong kaso, ang mga tiggamit makadugang ug klase sa Case entity ngadto sa listahan sa Global Auto-follow sa Preferences. Dayon kini awtomatikong mosunod sa matag bag-ong kaso.
-
-Pahinumdum: Kon walay user sa portal nga nalingkit sa usa ka nalambigit nga kontak, ang customer dili makadawat ug pahibalo nga email kabahin sa mga update sa stream. Kinahanglan nga gamiton ang mga email para sa komunikasyon sa customer.
-
-### Email-to-Case
-
-Ang administrador maka-set up ug Group Email Account nga maghimo og bag-ong kaso sa matag bag-ong inbound email. Alang sa dugang impormasyon [tan-awa dinhi](../administration/emails.md#email-ngadto-kaso).
-
-### Base sa Kahibalo
-
-Ang mga tiggamit makasaysay sa base sa kahibalo sa mga artikulo sa rekord sa kaso.
-
-### Portal sa Customer
-
-Ang administrador makahimu ug usa ka [portal](../administration/portal.md) diin ang mga kustomer makahimo sa pagmugna og mga kaso.
-
-Tungod kay ang mga tiggamit sa portal awtomatikong mosunod sa ilang mga kaso, sila makadawat sa mga pagpahibalo sa email bahin sa mga bag-ong mensahe sa Stream.
diff --git a/i18n/ceb_PH/user-guide/emails.md b/i18n/ceb_PH/user-guide/emails.md
deleted file mode 100644
index bd92569c2..000000000
--- a/i18n/ceb_PH/user-guide/emails.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Mga Giya sa Paggamit sa mga Email
-
-Ang EspoCRM kay naghatag og abilidad nga mukuha ug email gikan sa IMAP nga box. Gihimo niining posible ang paggamit sa EspoCRM isip usa ka email client kauban sa mga feature nga para ra sa CRM.
-
-## Mga IMAP account
-
-*Timan-e: Gikinahanglan ka nga naay [cron](../administration/server-configuration.md#pag-setup-og-crontab) nga sakto pagkakonpigyura sa imohang sistema para naay mugana ang mga padulong nga mga email.*
-
-Ang user kay maka-setup ug IMAP account sa Personal Email Accounts nga page (Emails tab > top-right menu > Personal Email Accounts).
-
-I-specify kung asa nga mga folder ang ipangmonitor sa Monitored Folders nga field. Kung wala ray giusab, kini kay giset padulong sa INBOX. Kung mugamit kag eksternal nga email client para mupadala og email, pwede nimong mupuno og Sent nga folder para iarchive ang kadtong mga email.
-
-Ang *Fetch Since* kay mutugot nga makapili ka sa petsa kung kanus-a ang mga email kay gigikanan og archive. I-set sa bisan unsang mga petsa sa dili pa ang karong adlawa kung gusto ka iarchive ang mga karaan nga email.
-
-Naay abilidad nga mudirekta ug *Folder* sa Personal Email Account. Ang mga padulong nga mga email kay ibutang sa kadto nga folder.
-
-## Mga SMTP account
-
-Ang mga user kay mamahimong muset-up ug mga SMTP nga mga setting sa Preferences ug sa ilaha pong mga Personal Email Account. Ang administrado kay mamahimo pong mugamit ug system SMTP (himoon ning Shared).
-
-Ang mga user kay pwede mahatagan og daghang SMTP nga account (gikan sa bersiyon 4.2.0). Pero ang mga email address nga magamit sa user para mupadala og email kay i-define sa mga email address sa *User* nga rekord.
-
-## Paggamit sa mga Email
-
-Ang mga email kay kwaon sa cron (sa background) kada pipila ka mga minuto (ang hingdugayon kay depende sa gi-set Administrador).
-Pwede nimong tan-awon ang imohang tanang mga email sa Emails nga tab. Adunay mga standard folder nga Ibox, Sent, Draft emails sa wala nga bahin.
-
-Ang *Status* nga field. Ang `Sent` kay nagpasabot nga gikan kini sa CRM, `Archived` – gikuha gikan sa IMAP nga accoun o gimanomano nig archive, `Draft` – pasabot nga ang email kay nahimo isip usa ka draft.
-
-Kung maabot ang bag-o nga email, ang sistema kay musuway og ila kung kang kinsa nga rekord nakatag-iya niini. Pwede kini mulink sa Account, Lead, Opportunity, Case (ug Contact sa B2C nga mode) etc. Kung wala kini nailhan, ang user kay maka manomanog link pinaagi sa pagbutang sa *Parent* nga field.
-
-Kung ang email nigikan sa usa ka potensiyal nga kliyente, ang user kay mamahimong **mu-convert ngadto sa Lead**. Pag-abli og Email entry ug i-click ang Create lead nga naa sa pinakababaw sa tuo nga menu.
-
-Posible usab nga **muhimo og Task o Case** gikan sa email nga rekord.
-
-Kung ang mga email address (from, to, cc) sa usa ka email nga rekord kay mahibal-an sa sistema, ipakita niini ang mga tawo nga naay relasyon niini (Contact, Leader, User etc). Kung ang uban nga mga email address kay bag-o, pwede nimong **muhimo og contact** gikan didto.
-
-Ang tanang mga email nga naay relasyon sa usa ka espisipiko nga rekord kay ipakita sa History na panel sa kadto nga rekord. Kung ang ubang mga email kay naay relasyon, pananglitan, sa oportunidad pero ang oportunidad kay naay relasyon sa kadto nga account, ipakita kini sa duha (oportunidad og account).
-
-## Pagpadala ug mga Email
-
-Pwede kang muhimo og bag-o nga email gamit ang pila ka mga pamaagi:
-* *Compose Email* nga pindutanan sa Emails list nga view;
-* pagtubag sa lain nga email;
-* pagclick sa usa ka email address sa laing rekord;
-* *Compose Email* aksyon sa Activities nga panel.
-
-Naay abilidad nga **mupili og template** sa imohang email.
-
-Mahimo kang muset-up sa **email signature** didto sa Preferences.
-
-## Mga Email Folder
-
-Ang mga user kay mamahimong muhimo og ilahang kaugalingong mga email folder para conveninent nga mabutangan og uban nga mga email. Ang lista sa mga pwedeng folder kay naa makit-an sa Emails nga page sa walang bahin sa app. Para makahimo o mu-usab sa mga folder sunda ang Emails > dropdown sa pinakataas nga tuong bahin > Folders. Ang `Skip Notification` nagpasabot nga gusto kang manotipikasyonan sa mga padulong nga email nga padulong sa ubang mga folder. Sa paggamit sa mga Email Filter, posible nga awtomatik mubutang og email sa folder gamit ang mga giset nga kriterya.
-
-## Mga Email Filter
-
-Ang administrador kay makahimo og global nga mga filder para laktaran ang mga dili nindot nga ma email. Makita kini sa Administration > Email Filters.
-
-Ang regular nga user kay makahimo og mga email filter para sa ilahang mga Personal Email Account o para sa tibuok nga inbox. Makit-an kini sa Emails > dropdown sa pinakataas nga tuong bahin > Filters.
-
-Naay duha ka klase nga mga filder:
-* Skip - ang email kay ibutang sa *Trash* o dili ma-import kung ang filter kay walay relasyon sa Personal Email Account;
-* Put in Folder - ang mga naimport nga mga email kay awtomatik nga ibutang sa folder sa gi-specify nga user.
-
-## Mga Email Template
-
-Ang mga email template kay naa makit-an sa Emails > dropdown pinakataas nga tuong bahin > Email Templates. Pwede ning magamit para sa pag email og dinaghan og para sa mga regular nga mga email. Ang `One-off` nga checkbox nagpasabot nga ang email template kay kausa ra unta gamiton, kung unsay kasagaran gamiton sa email nga marketing.
-
-Posible usab mugamit ug mga placeholder sa sulod sa email template ug subject e.g. {Account.name}, {Person.emailAddress}. Ilisan kini sa mga balor sa ilahang related nga mga rekord.
-
-Pwede kang mugamit og adisyonal nga mga gireserba nga mga placeholder sa sulod sa template: {optOutUrl} ug {optOutLink}.
-```
-Unsubscribe
-```
-Kini kay ang ubsubscribe nga link para sa dinaghang email.
diff --git a/i18n/ceb_PH/user-guide/markdown.md b/i18n/ceb_PH/user-guide/markdown.md
deleted file mode 100644
index 4796d81dd..000000000
--- a/i18n/ceb_PH/user-guide/markdown.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Markdown syntax
-
-Ang mga text field musuporta sa markdown nga syntax.
-
-## Code
-```
-`bisan unsang teksto`
-```
-
-`bisan unsang teksto`
-
-## Multiline nga code
-
-```
-``` bisan unsang teksto ```
-```
-
-```
-bisan unsang teksto
-```
-
-## Strong nga teksto
-
-```
-**bisan unsang teksto**
-```
-
-**bisan unsang teksto**
-
-## Emphasized nga teksto
-
-```
-*bisan unsang teksto*
-```
-
-*bisan unsang teksto*
-
-## Natangtang nga teksto
-
-```
-~~bisan unsang teksto~~
-```
-
-~~bisan unsang teksto~~
-
-## Blockquote
-
-```
-> bisan unsang
-> teksto
-```
-
-> bisan unsang
-> teksto
-
-## Link
-
-```
-[link nga teksto](https://www.espocrm.com)
-```
-[link nga teksto](https://www.espocrm.com)
-
-## Denumero nga listahan
-
-```
-1. Bisan unsang item
-2. Lain na sad nga item
-```
-
-1. Bisan unsang item
-2. Lain na sad nga item
-
-## Walay numero nga listahan
-
-```
-* Bisan unsang item
-* Lain na sad nga item
-```
-
-* Bisan unsang item
-* Lain na sad nga item
-
-## Pinahigda nga linya
-
-```
-___
-```
-
diff --git a/i18n/ceb_PH/user-guide/mass-email.md b/i18n/ceb_PH/user-guide/mass-email.md
deleted file mode 100644
index e2f6a8992..000000000
--- a/i18n/ceb_PH/user-guide/mass-email.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# Dinaghan nga Email
-
-## Unsaon pagpadala ug dinaghan nga email
-
-Gikinahanglan ka nga naay bisan usa ka Target List nga naay gitarget nga mga rekord ug Email Template sa imohang crm.
-
-1. Paghimo og bago nga Campaign nga naay status nga `Email` o `Newsletter`. Pilia ang usa o daghan nga mga target list sa `Target Lists` nga field.
-2. Pagkahuman ug himo sa Campaign record, paghimo og Mass Email para ani nga campaign: i-click ang plus sa Mass Email nga panel. I-specify ang _Date Start_ - kung kanusa ipadala ang mga email, ug pilia ang _Email Template_. Siguradoha nga ang _Status_ kay giset sa `Pending`.
-
-Kung ang tanan kay nakasetup ug sakto, ang mga email kay ipadala. Binahin kining ipadala kada oras (pwede nimong usbon ang hidak-on sa pagbahin sa Administration > Outbound Emails). Ang administrador kay makausab niani pinaagi sa pag-update sa `Scheduling` nga field sa `Check Group Email Accounts` Scheduled Job.
-
-Pwede nimong matan-aw kung napadala naba ang mga email sa sulod Log panel.
-
-## Testingi kong unsay napadala ngadto sa mga mudawat
-
-I-click ang right dropdown sa mass email nga row sa _Mass Email_ nga panel ug i-click ang _Send Test_.
-
-## Log
-
-Sa log, makita nimo ang:
-* Napadala nga mga email;
-* Mga email nga naabli sa nakadawat;
-* Mga link nga giclick sa nakadawat;
-* Mga receipient nga ni opt-out;
-* Bounced emails (not delivered to recipient).
-* Mga ni untol nga mga email (wala nadeliver ngadto sa makadawat).
-
-## Opt-out nga link
-
-Kung walay giusab, ang sistema kay musumpay og opt-out sa tanang mga gipadala nga email. Pero pwede nimong magamit ang custom sa imohang Email Template.
-
-Pananglitan:
-```html
-Unsubscribe gikan sa mailing list.
-```
-
-Ang administrador kay maka-disable sa minando nga opt-out link nga gipuno sa sistema sa Administration > Outbound Emails.
-
-## Tracking URL
-
-Kung gusto nimong mahibaw-an kung niabli ang nakadawat sa email sa link nga gikan sa imohang email, gikinahanglan nimong muhimo og Tracking nga URL. I-specify ang bisan unsang _Name_
- ug _URL_ kung asa ang link padulong. Dayon, gikinahanglan nimong i-paste ang nahimo nga code ngadto sa imohang Email Template.
-
-## Mga Target nga Lista
-
-Ang mga Target List kay naglangkob sa mga lista sa Accounts, Contacts, Leads ug Users nga mga rekord.
-
-Ang mga user kay maka puno og item sa mga listahan sa mga target gamit ang _Select_ nga aksyon sa kapareho nga panel sa Target List detail nga view.
-
-## Pagpuno sa mga target list ug mga Report
-
-Ang [Reports](reports.md#pagsyn-sa-mga-target-list) nga feature kay muhatag og abilidad para makapuno og target lists nga rekord nga mutukma sa espisipiko nga kriterya.
-
-## Mga Excluding Target List
-
-I-specify ang Excluding Target Lists para malikayan ang pagpadala sa dinaghan nga email sa ubang mga mudawat. Kung naay usa ka rekord nga naay email address nga kaparehas sa mga wala gilabot nga mga rekord, ang unang rekord kay dili pud apilon.
-
-## Campaign Log
-
-Sa Campaign Log, makit-an nimo ang mga email nga napadala, naablihan nga mga email, mga niuntol nga mga email, kinsa tong ni-opt out, ug kinsa tong mga ni-click sa link nga naa sa email. Posible pud nga gamiton ang kani nga log pinaagi sa paghimo og Target List (dropdown nga naa sa pinakataas nga tuong bahin sa panel) base sa mga rekord gikan sa log. Pananglitan, mupili ka ug usa ka kontak nga niclick sa link (tracking nga url).
-
-## Pagpang-ayo sa mga Maguba
-
-_Para sa mga Administrador_
-
-#### Unsay buhaton kong wala napadala ang mga email.
-
-1. Tan-awa kung ang _Send Test_ kay mugana. Kung dili mugana, tan-awa kong ang SMTP nga mga setting kay sakto ra.
-2. Tan-awa kung naset-up ang cron sa imohang sistema.
-3. Tan-awa kong naa kay `Send Mass Emails` Scheduled Job ug kong kani kay `Active` (Administration > Scheduled Jobs > Send Mass Emails). Tan-awa kong naay nasuwat sa Log.
-
-#### Unsaon kong ang mga Tracking URL kay naay sayop nga url nga dili mupadulong ngadto sa imohang crm.
-
-Tanawa ang 'siteUrl' nga parametro sa `data/config.php` nga file. Gikinahanglan ni i-set isip nga URL sa imohang EspoCRM nga pwede i-access sa gawas nga kalibutan.
-
-#### Ang mga niuntol nga email kay wala gipang-log
-
-Ang mga niuntol nga email kay pwede ra idumala gamit ang group email nga account. Dapat siguradohon nimo nga naa kay group email account nga nagmonitor sa mailbox diin ipadala ang mga niuntol nga mga email.
-
-Naa puy ubang mga mail server provider nga dili musunod sa mga standard, busa ang mga niuntol nga mga email kay dili mailhan.
diff --git a/i18n/ceb_PH/user-guide/printing-to-pdf.md b/i18n/ceb_PH/user-guide/printing-to-pdf.md
deleted file mode 100644
index 561d00c15..000000000
--- a/i18n/ceb_PH/user-guide/printing-to-pdf.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Pagprint ngadto sa PDF
-
-Timan-e: Ang kaning feature kay maanaa na gikan sa EspoCRM version 5.0.5.
-
-Ang pagprint ngadto sa PDF muhatag og abilidad nga mugenerate og mga PDF nga dokumento nga naay rekord nga datos. Ang sulod sa dokumento kay i-define pinaagi sa Template.
-
-
-1. Gikinahanglan nimong naay labing menos usa ka Template para sa entity type sa rekord nga imohang gusto i-print.
-2. 'Print to PDF' kay naa makit-an sa detail view ubos sa dropdown sunod sa 'Edit' nga pindutanan.
-
-## Mga Template
-
-Ang Templates nga tab ka gitago kung wala ray giusab. Ang administrador kay pwede kani ipuno ngadto sa Administration > User Interface.
-
-Para sa mga mas tukma nga pag-edit, girekomenda nga mugamit og Code View nga mode.
-
-Pwede nimong iprint ang mga field sa rekord ingon man usab ang mga field sa mga naay kalabutan nga rekord pinaagi sa paggamit og mga placeholder sa imohang template.
-
-Mga Example:
-
-* `{{name}}` – Pangalan sa rekord;
-* `{{assignedUserName}}` – Assigned nga User;
-* `{{account.name}}` – Pangalan sa naay kalibutan nga rekord.
-
-Posible pud nga muprint og mga image field:
-```
-
-```
-
-kung asa `imageId` – ang pangalan sa custom image nga field, gisumpayan og suffix nga `Id`.
-
-Para ipakit ang mga float nga numero nga walay praksyonal nga parte (isip usa ka integer), gamita ang musunod nga mga ekspresyon:
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Custom nga formatting para sa mga currency value:
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-
-Ang balor nga `10000.5` kay i-imprinta isip `10 000,50`.
-
-Para i-display ang mga text field (daghan nga linya), paggamit og tulo ka brace: ```{{{description}}}```.
diff --git a/i18n/ceb_PH/user-guide/quotes.md b/i18n/ceb_PH/user-guide/quotes.md
deleted file mode 100644
index 28a0c1a0d..000000000
--- a/i18n/ceb_PH/user-guide/quotes.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# Mga Quote
-
-Ang Quotes nga feature kay makit-an sa [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Ang mga quote kay espisipiko nga grupo sa mga produkto o mga serbisyo nga naay mga gidaghanon og presyo nga imohang ikutlo sa mga kustomer.
-
-Ang mga quote kay naay relasyon sa Opportunity. Pwede nimong idungag ang Quotes nga panel ngadto sa Opportunity detal view nga naa sa Administration > Layout Manager > Opportunities > Relationships. Kung muhimo ug bag-o nga quote nga naay link ngadto sa usa ka oportunidad, ibalhin niini ang mga oportunidad nga item ngadto sa quote.
-
-Pwede kang mupuno og Quotes nga panel ngadto sa Account detail nga view para makakita sa mga naay kalabutan nga mga quote. Mahimo nimo ni sa Administration > Layout Manager > Accounts > Relationships.
-
-## Mga Quote Item
-
-Ang quote kay naay lista sa mga item. Kada item kay pwede murepresenta og mga produkto sa usa ka serbisyo nga naay deskripsyon, hindaghanon, rate sa buhis, lista sa presyo ug unit price nga field. Posible pud ning manomanohon og han-ay.
-
-Naay abilidad nga mupuno og custom nga field para sa Quote Item nga entity gamit ang Entity Manager.
-
-## Mga Template
-
-Kung walay usbon, naay duha ka pwedeng magamit nga template: Quote og Invoice. Pwede kang mubuhat og mga bag-o nga template (Quotes list view > pinakababaw nga tuong bahin > Templates) ug pag-usab pud sa mga nabuhat na.
-
-Para sa mas tukma nga pag-edit, girekomendar ang paggamit sa Code view nga mode.
-
-Pwede ka muprint og mga field sa Quote nga rekord ug mga fields pud nga naay kalabutan gamit ang mga placeholder sa imohang template.
-
-Pananglitan:
-`{{accountName}}` – Pangalan sa account,
-
-`{{{billingAddressStreet}}}` – dalan,
-
-`{{account.type}}` – tipo sa related nga Account,
-
-`{{assignedUser.lastName}}` – apelyedo sa naka-assign nga user.
-
-Kung ang imong line item kay usa ka produkto, pwede kang muprint sa field sa product.
-
-Mga eksampol:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Length and color are custom fields of Product entity in examples.
-Ang hitas-on og kolor kay mga custom nga field sa Product nga entity nga naa sa mga eksampol.
-
-Pagsubay sa mga quote item:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-Posible pud nga muprint sa mga image field:
-
-```
-
-```
-kung asa ang `imageId` – kay ang pangalan sa custom nga image field nga naa sa Quote entity nga gisumpayan og suffix nga `Id`.
-
-Para sa product line nga item:
-```
-
-```
-
-Para mudisplay og mga float nga numero (parehas sa hidaghanon, unitPrice etc.) nga walay fractional nga parte (isip integer), gamita ang mga musunod nga mga ekspresyon (gikan pa sa bersiyon 4.8.3)
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Custom nga pagformat para sa mga currency nga balor (gikan pa sa bersiyon 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Ang balor nga `10000.5` kay iprint nga `10 000,50`.
-
-Para i-display ang mga text field (daghan nga linya) gamit og tulo ka mga brace: `{{{description}}}`.
-
-## Print ngadto sa PDF
-
-Ang mga quote kay pwede iprint ngadto sa PDF. Ang kani nga aksyon kay mamahimo sa dropdown sunod sa Edit nga pindutanan sa quote's detail view. Dayon ingnon ka nga mupili og Template.
-
-## Email Quote
-
-Ang Quote PDF kay pwede ipadala sa email isip usa ka attachment. Ablihi ang quote rekord, i-click ang dropdown sunod sa Edit nga button ug i-click ang Email PDF.
-
-## Automatic nga pagnumber
-
-Pwede ka muhimo og Number field gamit ang Entity Manager para sa Quote entity nga tipo. Administration > Entity Manager > Quote > Fields > Add Filed > Number. Dayon nanginahanglan nimo ning iplastar sa detail view gamit ang Layout Manager.
-
-Ang balor kay dungagan kada naay bag-o nga quote. Naay abilidad nga mu-specify og sunod nga numero ug prefix pud.
-
-## Default nga buhis
-
-Anaa na gikan sa EspoCRM 4.8.0.
-
-1. Specify default Tax record at Administration > Entity Manager > Quotes > fields > Tax > Default.
-2. Ispecifiy ang rate sa buhis sa Administration > Entity Manager > Quotes > fields > Tax Rate > Default.
-
-## Mga Invoice
-
-Ang quote kay pwede itrato isip usa ka invoice kung ang status niini kay nahimong `Approved`. Dayon ang _Date Invoiced_, _Invoice Number_ nga mga field kay manggawas. Pwede kang mugamit og lahi nga mga template para sa mga invoice para sa pagprint.
diff --git a/i18n/ceb_PH/user-guide/reports.md b/i18n/ceb_PH/user-guide/reports.md
deleted file mode 100644
index 22e1a5f64..000000000
--- a/i18n/ceb_PH/user-guide/reports.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# Mga Report
-
-Ang Reports nga feature kay naa makit-an sa [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Naay duha ka tipo sa mga report: List ug Grid.
-
-## Mga List Report
-
-Ang list report muresulta sa lista sa mga rekord nga nasugat ang mga gitakda nga mga kriterya.
-
-Para ug muhimo og bag-o nga list report, i-click ang Reports nga tab ug i-click ang Create Report nga pindutanan. Pilia ang gikinahanglan nga Entity Type dayon i-click ang Create nga pindutanan sa List Report.
-
-Sa _Columns_ nga field, pagpili og mga field nga gusto nimong ipadisplay. Sa ubos, pwede kang mutakda ug mga display nga parametro para sa kada usa ka column e.g. hilapdon ug align.
-
-Pilia ang gikinahanglang paghan-ay sa _List Order_ nga field.
-
-Sa _Filters_ nga seksiyon pwede nimong itakda ang kriterya nga mudetermina kung unsa nga rekord ang malista sa imohang report. Pwede ka mugamit og lohikal nga mga operator parehas sa 'OR' ug 'AND' dinhi.
-
-Ang mga _Runtime Filters_ mutugot nga mutakda ka og bisan unsang filter sa dili pa ipadagan nimo ang report.
-
-Pwede kang mu - __export__ sa list report results ngadto sa excel ug csv nga mga format.
-
-## Mga Grid Report
-
-Ang grid reports result muhata ug sumaryo sa mga balor nga gigrupo pinaagi sa mga gitakda nga mga field. Ang kaning mga report kay pwede idisplay isip usa ka chart.
-
-
-
-Para muhimo og bag-o nga grid report, i-click ang Reports nga tab ug dayon i-click ang Create Report nga pindutanan. Pilia ang gikinahanglan nga Entity Type dayon i-click ang Create nga pindutanan sa Grid Report.
-
-Sa _Group By_ field, pili ug usa o duha ka mga field nga gusto nimong mag-grupo sa imohang datos. Posible pud nga mag-grupo base sa tuig, buwan, adlaw para sa mga date field.
-
-Sa _Columns_ nga field, pili og usa o mas daghan pa nga mga aggregate ng punsyon parehas sa COUNT, SUM (sumasyon), MIN, MAX, AVG (average).
-
-Ang _Order by_ field muset kung unsaon paghan-ay sa mga report nga datos.
-
-Sa _Filters_ nga seksyon, makatukma ka ug kriterya nga mudetermina kung unsa nga mga rekord ang gamiton para sa imohang report. Pwede kang mugamit sa mga lohikal nga mga operator parehas sa 'OR' ug 'AND'.
-
-Ang _Runtime Filters_ mutugot nga mutukma ka og nagkalainlaing mga filter sa dili pa nimo ipadagan ang report.
-
-It's possible to __export__ grid report results to excel and csv formats.
-Posible usab nga mu __export__ ug mga grid report nga resulta ngadto sa excel ug csv nga mga format.
-
-## Mga Filter
-
-### Field filter
-
-Sayon gamiton nga tipo sa mga filter. Pwede sad ka mupili og mga field sa gitarget nga entity ug usab mga naay kalabotan nga mga entity.
-
-
-
-### OR na grupo
-
-Ang OR nagpasabot nga dili mu menos usa ka kondisyon ubos sa grupo ang gikinahanglan nga maabot.
-
-
-
-### AND na grupo
-
-Ang AND nagpasabot nga ang tanan kondisyon ubos sa grupo gikinahanglang maabot.
-
-### NOT nga grupo
-
-Naghatag og abilidad nga mufilter sa mga rekord nga wala nakaabot sa gitakda nga mga kriterya. E.g. paglista sa mga account nga walay opportunidad nga naay Closed Won o Closed Lost nga estado.
-
-
-
-### Komplikado nga Ekspresyon
-
-Para sa mas abanse pa nga paggamit. Pwede nimong gamiton ang usa ka punsyon para sa database column og ikompara ni sa resulta sa [pormula](../administration/formula.md) nga ekspresyon.
-
-Timan-e: Kug gikinahanglan nimo mukompara og simple nga string nga balor, gikinahanglan nimo ibutang ngadto sa nag-inusara nga mga quote `'bisan unsa nga string'`.
-
-Timan-e: Ang mga punsyon nga gitakda nga makig-istorya sa mga entity rekord kay dili mugana diri kay ang pormula wala giapply sa espisipiko nga rekord.
-
-
-
-### Having na grupo
-
-Ang having nga grupo kay muhatag og abilidad nga mufilter gamit ang mga aggregate nga punsyon sama sa COUNT, SUM, MAX, MIN, og AVG.
-
-Mga lain nga kaso:
-
-* Mga list account nga naay labaw pa sa usa ka oportunidad. `COUNT / opportunities.id / Grater Than / 1`.
-* Ang grid report nga mupakita sa mga account nga gigrupo ngadto sa industry kung asa ang halin kay mas dako pa sa 1,000. `SUM / opportunities.amount / Greater Than / 1000`.
-
-Timan-e: Kompatibol sa EspoCRM bersiyon 5.1.0 ug mas labaw pa.
-
-## Pagpadisplay sa dashboard
-
-Pwede ka mudisplay sa bisan unsang report sa dashboard. Para ani, gikinahanglan ka mupuno og Report dashlet ug pili sa gikinahanglan nga report sa dashlet nga opsyon.
-
-## Pagpadala og email
-
-Posible nga himoon ang sistema nga mupadala og report nga resulta ngadto sa mga user sa regular nga panahon basi sa gitakda nga oras. Gikinahanglan ni makonpigyur para sa tagsa tagsang mga report.
-
-## Pagsyn sa mga Target List
-
-Posible nga ang mga target list kay masync sa mga list report result. Hayahay kini para sa dinaghang email kung gusto nimo mupadala ug mga email ngadto ra sa mga kontak nga nakaabot sa kriterya nianang orasa sa pagpadala. Ang kani nga feature kay makit-an sa detail view sa bisan unsa nga target list sa 'Sync with Reports' nga panel.
-
diff --git a/i18n/ceb_PH/user-guide/sales-management.md b/i18n/ceb_PH/user-guide/sales-management.md
deleted file mode 100644
index 6992dc4df..000000000
--- a/i18n/ceb_PH/user-guide/sales-management.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Pagdumala sa Pagpamaligya
-
-## Mga Lead
-
-Ang lead nagrepresentar sa usa ka tawo o usa ka organisasyon nga dili pa usa ka kostumer sa pagkakaron, apan adunay potensyal nga mahimong usa. Ang pagmugna og usa ka lead record kasagaran mao ang unang lakang sa proseso sa pagbaligya. Samtang ang dugang nga kasayuran mahitungod sa lead kay gitigum, gituuhan nga ang lead makabig isip usa ka account, contact ug oportunidad.
-
-Ang mga bag-ong lead kinahanglan nga lihukon sa mosunod nga mga sitwasyon:
-
-* Sa manual nga pamaagi sa mga tiggamit sa CRM;
-* Pinaagi sa API (e.g. pinaagi sa web form);
-* Awtomatiko gumikan sa lagda sa Workflow.
-
-Pinaagi sa paggamit sa [Workflows](../administration/workflows.md) ang administrador mamahimong maka-set up sa sistema para maka-apply ug espesipikong assignment rule sa mga bag.o nga lead, i.e. Round-Robin ug Least-Busy nga mga lagda. Alang sa mas komplikadong mga business flow, girekomendar kini nga gamiton [BPM tool](../administration/bpm.md).
-
-Aron mapugngan nga di masal-angan mga bag-ong lead, ang mga tiggamit makadugang ug klase sa Lead entity ngadto sa listahan sa Global Auto-follow sa Preferences. Dayon kini awtomatikong mosunod sa matag bag-ong kaso.
-
-## Mga Oportunidad
-
-Ang oportunidad nagrepresentar sa usa ka potensyal o sirado nga deal. Ang oportunidad nga adunay 'Closed Won' nga yugto giisip nga alang sa pagkalkula sa kita sa pagbaligya.
-
-Ang mga mosunod nga mga hugna mabatunan pinaagi sa default:
-
-* Pagpangita;
-* Kwalipikasyon;
-* Proposal;
-* Negosasyon;
-* Closed Won;
-* Closed Lost.
-
-Ang administrador makatakda ug mga kostumbre nga mga yugto depende sa business flow sa kompanya. Apan wala kini girekomendar nga kuhaon ang 'Closed Won' nga yugto tungod kay kini gigamit sa pagkalkulo sa usa ka kita.
-
-## Sales analytics
-
-Ang mosunod nga mga tsart anaa sa dashboard pinaagi sa default:
-
-* Sales sa Bulan;
-* Mga Oportunidad gumikan sa Lead Source;
-* Mga Oportunidad gumikan sa yugto;
-* Sales Pipeline.
-
-Pinaagi sa paggamit sa [Reports tool](reports.md) posible nga makita ang mga istatistika sa pagpamaligya nga gibase sa espesipiko nga criteria. Ang tsart sa mga report mahimong ipakita sa dashboard.
-
-### Forecast sa Kita
-
-1. Paghimo og bag-ong grid report alang sa Opportunity entity type.
-2. Idugang ang 'MONTH: Close Date' sa Group By field.
-3. Idugang ang 'SUM: Amount Weighted' sa Columns field.
-4. Idguang ang 'Close Date' sa Runtime Filters field.
-5. Pilia ang 'Bar (vertical)' nga matang sa tsart.
-
-Kini nga report magpakita sa mga forecast sa kita nga gibase sa mga kalagimitan sa mga oportunidad.
-
-Ang mga tiggamit nga adunay access niini nga report makahimo sa pagdugang niini sa ilang mga dashboard.
diff --git a/i18n/ceb_PH/user-guide/stream.md b/i18n/ceb_PH/user-guide/stream.md
deleted file mode 100644
index 8de58c799..000000000
--- a/i18n/ceb_PH/user-guide/stream.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Stream
-
-Ang Stream sa EspoCRm kay usa ka feed kung asa ka makakita ug mga update ug mga bag-ong adisyon para sa mga rekord nga nagsunod ka. Pwede pug ka makapost sa imohang stream ug sa stream sa uban nga mga user (gikan sa bersiyon 3.8.0). Naay duha ka klase nga mga stream sa EspoCRM: record stream ug user stream.
-
-Kung wala ray nausab, ang musunod nga mga entity kay naay mga stream: Accounts, Contacts, Leads, Opportunities, Cases. Ang mga administrador kay mu-enable o disable sa stream para sa usa ka entity gamit ang [Entity Manager](../administration/entity-manager.md).
-
-## Record Stream
-
-Ang Record Stream kay ipakita sa sulod sa Stream nga panel sa usa ka espisipiko nga rekord sa detail view. Ang mga post, update, ug mga bag-ong adisyon nga naay relasyon sa kasamtangang rekord kay ipakita dinhi.
-
-## User Stream
-
-Ang mga user ka mamahimong mutan-aw sa ilahang stream sa Stream dashlet ug sa Stream tab sad. Ang mga user kay pwede sam makakita sa stream sa laing mga user sa detail view sa user, kung naa silay access nga gikontrolar sa `User Pemission` nga field sa mga Role.
-
-Ang user stream kay makakita og post, mga update, ug mga bag-ong adisyon sa mga naay relasyon na rekord nga gisunod sa user. Pwede usab ka makakita og mga post nga giaddress ngadto sa user. Kadtong mga post kay walay relasyon sa bisan unsang rekord.
-
-## Mga Notipikasyon
-
-Makadawat ka og mga notipikasyon kabahin sa mga bag-o nga adisyon sa imohang stream nga gihimo sa ubang mga user.
-
-## Mga Post
-
-Pwede kang muhimo og post nga naay relasyon sa usa ka rekord. Pwede usab ka maka-attach ug daghan nga mga file ug imahe didto sa imohang post. Kung gusto kang muhisgot ug uban tawo sa imohang post, pwede kang mu-type og `@` nga simbolo ug sugdan ug type ang pangalan sa user. Ang user nga imohang nahisgot sa imohang post kay mahatagan og notipikasyon kabahin niini.
-
-## Mga post ngadto sa mga user
-
-_This feature is available since version 3.8.0._
-_Ang kani nga feature kay naa na gikan sa bersiyon 3.8.0._
-
-Ang mga user kay mamahimong muhimo og post ngadto sa mga user, sa mga team, o sa tanang mga user ug sa kaugalingon. Ang access para sa kani nga abilidad kay gikontrolar sa `Assignment Permission` nga field sa mga Role.
-
-## Pag-filter
-
-Pwede nimong i-filter ang mga butang nga gusto nimong ipakita sa stream: `All`, `Posts` o `Updates`.
-
diff --git a/i18n/es_ES/README.md b/i18n/es_ES/README.md
deleted file mode 100644
index 7835cf492..000000000
--- a/i18n/es_ES/README.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Documentacion EspoCRM
-
-### Administracion
-* [Configuracion de Servidor](administration/server-configuration.md)
- * [Apache](administration/apache-server-configuration.md)
- * [Nginx](administration/nginx-server-configuration.md)
-* [Instalacion](administration/installation.md)
-* [Actualizacion](administration/upgrading.md)
-* [Control de Roles (Control de Acceso)](administration/roles-management.md)
-* [Emails](administration/emails.md)
-* Personalizacion
- * [Entity Manager: entidades, campos, relaciones](administration/entity-manager.md)
- * [Administrador de diseño](administration/layout-manager.md)
- * [Extensiones](administration/extensions.md)
-* Automatizacion
- * [Business Process Management (BPM)](administration/bpm.md)
- * [Diagramas de Flujo](administration/workflows.md)
- * [Campos calculados (fórmula)](administration/formula.md)
-* [Importación de datos](administration/import.md)
-* [Portal](administration/portal.md)
-* [Autorización LDAP](administration/ldap-authorization.md)
- * [Directorio Activo](administration/ldap-authorization-for-ad.md)
- * [OpenLDAP](administration/ldap-authorization-for-openldap.md)
-* [Solucionador de problemas](administration/troubleshooting.md)
-* misceláneo
- * [Mapas](administration/maps.md)
- * [Modo B2C](administration/b2c.md)
- * [Copia de seguridad y restaurar](administration/backup-and-restore.md)
- * [Mudarse a otro servidor](administration/moving-to-another-server.md)
-
-
-### Guía del usuario
-* [Emails](user-guide/emails.md)
-* [Stream](user-guide/stream.md)
-* [Correo electrónico masivo](user-guide/mass-email.md)
-* [Reportes](user-guide/reports.md)
-* [Citas](user-guide/quotes.md)
-* [Sintaxis de Markdown](user-guide/markdown.md)
-* misceláneo
- * [Soporte del navegador](user-guide/browser-support.md)
-
-### Desarrollo
-* [API](development/api.md)
-* [ORM: Cómo administrar entidades](development/orm.md)
-* [Metadata](development/metadata.md)
-* [Vistas personalizadas](development/custom-views.md)
-* [Formularios dinámicos](development/dynamic-forms.md)
-* [Vincular campo múltiple con un registro primario](development/link-multiple-with-primary.md)
-* [Paquetes de extensión](development/extension-packages.md)
-* [Hooks](development/hooks.md)
-* [Creando trabajos programados personalizados](development/scheduled-job.md)
-* [Definición de nuevas funciones para la Fórmula](development/new-function-in-formula.md)
-
-
-[Documentación en el sitio web](https://www.espocrm.com/documentation/)
diff --git a/i18n/es_ES/_static/scripts/backup.sh b/i18n/es_ES/_static/scripts/backup.sh
deleted file mode 100644
index 88a32ee83..000000000
--- a/i18n/es_ES/_static/scripts/backup.sh
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/bin/bash
-
-DEFAULT_PATH_TO_ESPO="/var/www/html"
-DEFAULT_BACKUP_PATH=$(pwd)
-
-if [ -z "$1" ]; then
- echo "Enter a full path to EspoCRM directory ($DEFAULT_PATH_TO_ESPO):"
- read PATH_TO_ESPO
- if [ -z "$PATH_TO_ESPO" ]; then
- PATH_TO_ESPO=$DEFAULT_PATH_TO_ESPO
- fi
-else
- PATH_TO_ESPO=$1
-fi
-
-if [ ! -d "$PATH_TO_ESPO" ]; then
- echo "Error: The directory '$PATH_TO_ESPO' does not exist."
- exit 1
-fi
-
-if [ ! -r "$PATH_TO_ESPO" ]; then
- echo "Error: The directory '$PATH_TO_ESPO' is not readable."
- exit 1
-fi
-
-if [ -z "$2" ]; then
- echo "Enter a full path to backup directory ($DEFAULT_BACKUP_PATH):"
- read BACKUP_PATH
- if [ -z "$BACKUP_PATH" ]; then
- BACKUP_PATH=$DEFAULT_BACKUP_PATH
- fi
-else
- BACKUP_PATH=$2
-fi
-
-if [ ! -d "$BACKUP_PATH" ]; then
- echo "Error: The directory '$BACKUP_PATH' does not exist."
- exit 1
-fi
-
-if [ ! -w "$BACKUP_PATH" ]; then
- echo "Error: Backup directory '$BACKUP_PATH' is not writable."
- exit 1
-fi
-
-cd $PATH_TO_ESPO
-
-if [ ! -f "data/config.php" ]; then
- echo "Error: The '$PATH_TO_ESPO' is not EspoCRM directory."
- exit 1
-fi
-
-DB_USER=$(php -r "\$config=include('data/config.php'); echo \$config['database']['user'];")
-DB_PASS=$(php -r "\$config=include('data/config.php'); echo \$config['database']['password'];")
-DB_NAME=$(php -r "\$config=include('data/config.php'); echo \$config['database']['dbname'];")
-
-BACKUP_NAME=$(basename $PATH_TO_ESPO)
-BACKUP_ARCHIVE_NAME="$(date +'%Y-%m-%d_%H%M%S').tar.gz"
-
-cd $BACKUP_PATH
-mkdir $BACKUP_NAME
-cd $BACKUP_NAME
-
-# Create database dump
-mysqldump --user=$DB_USER --password=$DB_PASS $DB_NAME > "db.sql" || {
- echo "Enter MySQL user:"
- read DB_USER
-
- echo "Enter MySQL password:"
- read DB_PASS
-
- mysqldump --user=$DB_USER --password=$DB_PASS $DB_NAME > "db.sql" || {
- echo "Error: Cannot dump the database '$DB_NAME'. "
- exit 1
- }
-}
-
-tar -czf "db.tar.gz" "db.sql"
-rm "db.sql"
-
-# Archive files
-tar -czf "files.tar.gz" -C $PATH_TO_ESPO .
-
-# Create a full backup archive
-cd ..
-tar czf "$BACKUP_ARCHIVE_NAME" $BACKUP_NAME/
-
-# Remove temporary files
-rm -rf $BACKUP_NAME
-
-echo "Backup is created, '$BACKUP_PATH/$BACKUP_ARCHIVE_NAME'."
diff --git a/i18n/es_ES/administration/apache-server-configuration.md b/i18n/es_ES/administration/apache-server-configuration.md
deleted file mode 100644
index 9f98b480a..000000000
--- a/i18n/es_ES/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Configuracion del servidor Apache para EspoCRM
-
-Estas instrucciones son complementarias a la guia de [Configuration de servidor](server-configuration.md). Por favor tome en cuenta que toda configuracion listada aqui esta hecha en un servidor Ubuntu.
-
-## Requerimientos PHP
-
-Para instalar todas las librerias necesarias, ejecute estos comandos en el terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Arreglando el problema “API Error: EspoCRM API is unavailable”:
-
-Tome solo los pasos necesarios. Despues de cada paso, verifique si el error ha sido resuelto.
-
-### 1. Habilitar el soporte "mod_rewrite" en Apache
-
-Para habilitar "mod_rewrite", ejecute estos comandos en el terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Habilitar el soporte .htaccess
-
-Para habilitar el soporte .htaccess, agregue/edite la configuracion de Servidor /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf o /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Después, ejecute este comando en el terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Agregue la ruta RewriteBase
-
-Abra el archivo /ESPOCRM_DIRECTORY/api/v1/.htaccess y reemplace la siguiente linea:
-
-```
-# RewriteBase /
-```
-
-con
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-Donde REQUEST_URI es la parte del URL, Es decir, para “http://example.com/espocrm/”, REQUEST_URI es “espocrm”.
-
-
-## Habilitar el soporte de Autorizacion HTTP (solo para FastCGI).
-
-FastCGI no suporta la autorizacion HTTP por defecto. Si tu usas FastCGI, tu tienes que habilitarlo en tu VirtualHost o /etc/apache2/apache2.conf (httpd.conf) agregando el siguiente codigo:
-
-Para el módulo Fcgid:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Para el módulo FastCgi:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Para verificar que modulo esta siendo usado actualmente, ejecute este comando y encuentre el modulo:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/es_ES/administration/b2c.md b/i18n/es_ES/administration/b2c.md
deleted file mode 100644
index a7e0656c5..000000000
--- a/i18n/es_ES/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Configurando EspoCRM para B2C (Business-to-Client)
-
-Por defecto EspoCRM esta configurado para usarlo como B2B (Business-to-Bussiness). Pero tu puedes facilmente configurarlo para B2C.
-
-* Cambie `b2cMode` a 'true' en tu archivo de configuración `data/config.php`. Desde la version 4.3.0 puede ser configurado desde Administration > Seetings.
-* Elimine la pestaña *Account* desde el menú ne navegación. (Administration > User Interface).
-* Elimine los campos *Account* de tus diseños (Administation > Layout Manager).
-* Deshabilite el acceso a *Account* para todos tus Roles (Administration > Roles).
-* Elimine la cuenta desde las listas de selección de todos los campos principales (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
diff --git a/i18n/es_ES/administration/backup-and-restore.md b/i18n/es_ES/administration/backup-and-restore.md
deleted file mode 100644
index ffcec2fef..000000000
--- a/i18n/es_ES/administration/backup-and-restore.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# Respaldar y Restaurar
-
-## Como respaldar EspoCRM manualmente
-
-EspoCRM consiste en archivos y datos de bases de datos. Todos estos datos son necesarios para crear una copia de seguridad completa de EspoCRM. Aquí hay instrucciones sobre cómo hacerlo en el servidor Ubuntu con MySQL.
-
-### Paso 1. Respaldar archivos
-
-Cree un archivo del contenido del directorio de EspoCRM instalado. Para Ubuntu, la ruta predeterminada es `/var/www/html`. Puedes usar este comando:
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Paso 2. respaldar base de datos
-
-Para hacer una copia de seguridad de todos sus datos, debe conocer el nombre de la base de datos y las credenciales de acceso. Puede encontrar el nombre de la base de datos en el archivo de configuración `/ESPOCRM_DIRECTORY/data/config.php` en la sección `base de datos`. Puede usar este comando para hacer una copia de seguridad de su base de datos:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Paso 3. Copiar el Respaldo
-
-Esto es todo. Ahora, tu tienes que copiar el respaldo creado en un sitio seguro.
-
-
-## Como respaldar EspoCRM con un script
-
-Puedes usar un script para respaldar todos los datos necesarios. Inicia sesión via SSH y ejecute los comandos (probados en un servidor Ubuntu).
-
-### Descargar el script
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Ejecutar el script
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-donde
- * `PATH_TO_ESPOCRM` es la direccion del directorio de instalacion de EspoCRM.
- * `BACKUP_PATH` es la direccion al directorio del respaldo.
-
-Para el servidor Ubuntu es:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Nota: Si su usuario de MySQL no tiene los derechos necesarios para volcar su base de datos, se le pedirá que ingrese las credenciales de otro usuario de MySQL.
-
-Despues de una creacion exisota, obtendrá una ruta a la copia de seguridad creada.
-
-## Restaurar EspoCRM desde un respaldo
-
-Puede restaurar EspoCRM desde la copia de seguridad creada como se describe arriba.
-
-### Paso 1. Desarchivar archivos de copia de seguridad
-
-Para desarchivar archivos, puede usar Archive Manager o ejecutar el siguiente comando. Los archivos deben colocarse en el directorio del servidor web.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-donde:
- * `/var/www/html` es el directorio del servidor web.
-
-### Paso 2. Establecer los permisos requeridos
-
-Los archivos deben ser propiedad de un usuario del servidor web y tener los permisos correctos. Por favor, configure los permisos requeridos siguiendo estas [instrucciones](server-configuration.md/#permisos-requeridos-para-sistemas-basados-en-unix).
-
-### Paso 3. Importar el volcado de la base de datos
-
-El volcado de la base de datos se debe importar a la misma base de datos con las mismas credenciales de usuario; de lo contrario, la corrección se debe realizar en el archivo de configuración `ESPOCRM_DIRECTORY/data/config.php`. Para importar su base de datos desde el volcado, ejecute el siguiente comando en una terminal:
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Paso 4. Verificar/configurar crontab
-
-Compruebe si su crontab está configurado correctamente. Ejecute el siguiente comando y compruebe si una ruta a EspoCRM es correcta:
-
-```bash
-sudo crontab -l -u www-data
-```
-Donde:
- * `www-data` es tu usuario del servidor web.
-
-Si tiene que hacer algún cambio, use este comando:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Aquí se describen más detalles sobre la configuración de [crontab](server-configuration.md/#configurar-un-crontab) para EspoCRM.
diff --git a/i18n/es_ES/administration/bpm.md b/i18n/es_ES/administration/bpm.md
deleted file mode 100644
index 3d33a9d0a..000000000
--- a/i18n/es_ES/administration/bpm.md
+++ /dev/null
@@ -1,207 +0,0 @@
-# Business Process Management
-
-La herramienta Business Process Management (BPM) brinda la capacidad de modelar y automatizar procesos comerciales en EspoCRM. Es un motor que ejecuta procesos comerciales descritos en el estándar BPMN 2.0. La herramienta BPM está disponible en la extensión
-
-
-### Diferencia de la herramienta de flujos de trabajo
-
-La herramienta Flujos de trabajo está diseñada para la automatización de reglas comerciales simples, sin elementos de flujo secuencial, cuando no es necesario mostrar el flujo de forma gráfica.
-
-La herramienta BPM está diseñada para flujos de negocios más complejos, donde puede haber flujos divergentes y convergentes, retrasos en la ejecución e interacciones del usuario. Una vista del diagrama de flujo hace que el proceso comercial sea más comprensible para un ser humano, un registro permite ver cómo se llevó a cabo el proceso.
-
-## Diagramas de flujo de proceso
-
-El enlace para procesar diagramas de flujo está disponible desde el panel de administración. También se puede agregar como una pestaña en el panel de navegación.
-
-Los diagramas de flujo están destinados al modelado de procesos de negocio. El administrador puede crear y editar diagramas de flujo. Los usuarios normales solo pueden ver diagramas de flujo.
-
-Cada diagrama de flujo tiene su tipo de entidad específica (campo Tipo de objetivo). El diagrama de flujo determina la ejecución de instancias de proceso futuras. Comprende elementos de diagrama de flujo y conexiones entre elementos.
-
-Si el diagrama de flujo del proceso tiene desactivado el campo "Está activo", no iniciará las instancias del proceso.
-
-Para mostrar detalles y parámetros de un cierto elemento del diagrama de flujo, debe hacer clic en él. En el modo de edición, podrá editar los parámetros.
-
-## Procesos
-
-Los procesos están disponibles desde el panel de administración. El enlace también se puede agregar como una pestaña en el panel de navegación.
-
-El proceso representa la instancia del proceso empresarial. Cuando se inicia, obtiene el estado 'Iniciado'. Cuando el proceso finaliza, obtiene el estado 'Terminado'. El proceso también puede ser detenido manualmente por un usuario que tiene acceso para editar el proceso. Si se detiene manualmente, obtiene el estado 'Detenido'.
-
-El proceso se ejecuta de acuerdo con el diagrama de flujo. El diagrama de flujo del proceso no se puede cambiar después de iniciar el proceso.
-
-El proceso está relacionado obligatoriamente con un solo registro objetivo.
-
-Los procesos se pueden iniciar automáticamente (en condiciones específicas o por programación) o manualmente (cuando hay al menos un evento de inicio en el diagrama de flujo). Para iniciar el proceso manualmente, el usuario debe hacer clic en el botón "Iniciar proceso" en la vista de lista de procesos.
-
-## Elementos del diagrama de flujo
-
-### Eventos
-
-Los eventos se muestran en un diagrama de flujo como círculos.
-
-#### Evento de inicio
-
-No tiene parámetros Es un punto de partida del proceso. El evento de inicio puede iniciarse manualmente por un usuario que tenga acceso para crear procesos. El usuario debe hacer clic en el botón 'Iniciar proceso' en la vista de lista de procesos.
-
-#### Evento de inicio condicional
-
-Un punto de partida del proceso. Se supone que debe activarse automáticamente cuando se cumplen las condiciones especificadas. Hay dos tipos de activador: 'Después de crear el registro', 'Después de guardar el registro'.
-
-#### Evento de inicio del temporizador
-
-Un punto de partida del proceso. Inicia procesos por programación. Debe especificar el informe de lista que devuelve registros para iniciar procesos y programar en notación crontab.
-
-#### Evento intermedio condicional
-
-Este evento detiene el flujo hasta que se cumplan los criterios especificados.
-
-#### Evento intermedio del temporizador
-
-Este evento detiene el flujo y espera mientras esté especificado por los parámetros del evento.
-
-Para configuraciones de temporizador más complejas, puede utilizar [fórmula](formula.md). Los scripts de fórmulas deben devolver el valor de Fecha y hora (en la zona horaria UTC). Una vez que llegue este momento, el flujo pasará al siguiente elemento.
-
-Al utilizar la función de fórmulas datetime \ más cercana, es posible establecer el temporizador en un momento específico en el futuro, p. el comienzo del siguiente día hábil.
-
-#### Fin del evento
-
-Termina el flujo actual. No finaliza los flujos que se ejecutan en paralelo. Cuando el flujo llega al evento final y no hay nada en ejecución en paralelo, el proceso finaliza.
-
-#### Terminar evento final
-
-Finaliza todos los flujos. El proceso se terminó posteriormente.
-
-### Puertas de enlace
-
-Las puertas de enlace se muestran como diamantes.
-
-#### Puerta de enlace exclusiva
-
-Puede divergir o converger flujos.
-
-En caso de divergencia, define un único flujo (camino) que se elegirá según los criterios especificados. La primera condición cumplida determina el flujo, las siguientes condiciones se omiten. Existe la posibilidad de especificar el flujo predeterminado. El flujo predeterminado se elige si no hay ninguna condición cumplida. El flujo predeterminado está marcado con un signo de barra inclinada.
-
-En caso de convergencia, solo dirige el flujo hacia el elemento saliente. No se bloquea después del flujo, por lo que los flujos paralelos no se fusionarán en un solo flujo.
-
-
-
-
-
-#### Puertas de enlace inclusivos
-
-Puede divergir o converger flujos.
-
-En caso de divergencia, puede dirigir a uno o múltiples flujos paralelos (rutas), dependiendo del cumplimiento de los criterios de cada flujo. El flujo predeterminado se elige si no hay ninguna condición cumplida. El flujo predeterminado está marcado con un signo de barra inclinada.
-
-Si es necesario fusionar los flujos paralelos producidos por una puerta de enlace inclusiva divergente, debe utilizar una puerta de enlace inclusiva convergente. Esperará todos los flujos entrantes y luego continuará hacia el elemento saliente.
-
-
-
-Nota: Las pasarelas divergentes y convergentes deben estar equilibradas.
-
-Nota: Si uno de los flujos paralelos se ha terminado por algún motivo, la puerta de enlace divergente nunca se procesará. El proceso será bloqueado. Evite un diseño de diagrama de flujo que pueda provocar tal situación.
-
-#### Puertas de Enlace Paralelas
-
-Puede divergir o converger flujos.
-
-En caso de divergencia, el flujo se divide en múltiples flujos paralelos. No hay parámetros para este tipo de puerta de enlace.
-
-En caso de convergencia, espera hasta que lleguen todos los flujos entrantes y luego continúa hasta el siguiente elemento saliente.
-
-
-
-Nota: Las pasarelas divergentes y convergentes deben estar equilibradas.
-
-Nota: Si uno de los flujos paralelos se ha terminado por algún motivo, la puerta de enlace divergente nunca se procesará. El proceso será bloqueado. Evite un diseño de diagrama de flujo que pueda provocar tal situación.
-
-#### Puertas de Enlace basadas en eventos
-
-Solo puede divergir flujos.
-
-Detiene el flujo hasta que cualquiera de los eventos salientes se active. El evento desencadenado determina el flujo único. Otros eventos salientes son rechazados.
-
-Solo los eventos intermedios pueden estar en el otro extremo de los flujos de secuencia de salida.
-
-
-
-### Actividades
-
-Las actividades se muestran como rectángulos redondeados.
-
-#### Tareas
-
-La tarea se puede ejecutar siguiendo las acciones:
-
-* Crear registro: crea un nuevo registro de cualquier tipo de entidad;
-* Crear registro relacionado: crea un nuevo registro relacionado con el registro objetivo;
-* Actualizar registro objetivo;
-* Actualizar registro relacionado: actualiza el registro o los registros relacionados con el registro objetivo;
-* Actualizar registro creado: actualiza el campo específico de cualquier registro creado en el proceso actual;
-* Registro de proceso de actualización: se puede usar para asignar el proceso a un usuario o equipo específico;
-* Enlace a otro registro: vincula el registro objetivo con un registro especificado;
-* Desvincular de otro registro: desvincula el registro objetivo del registro especificado;
-* Aplicar regla de asignación: asigna el registro objetivo, el registro del proceso o cualquier registro creado por el proceso de acuerdo con la regla específica;
-* Crear notificación: crea notificaciones en la aplicación para usuarios específicos;
-* Hacer seguimiento: hace que los usuarios específicos sigan el registro objetivo, el registro del proceso o cualquier registro creado por el proceso;
-* Ejecutar acción de servicio: ejecuta acciones de servicio personalizadas implementadas por los desarrolladores.
-
-Las acciones disponibles para la tarea son casi las mismas que en la función de flujo de trabajo. Ver más detalles sobre [acciones del flujo de trabajo](workflows.md#acciones).
-
-#### Enviar mensaje de Tarea
-
-Envía un mensaje de correo electrónico a un destinatario específico.
-
-#### Tarea de usuario
-
-Proporciona una capacidad flexible de interacción del usuario. Detiene la ejecución hasta que el usuario (especificado explícitamente o por regla de asignación) resuelve la tarea. El registro de Tarea de usuario de proceso se creará en el sistema. Por defecto hay tres tipos de acciones: Aprobar, Revisar, Lograr.
-
-* El tipo de aprobación requiere que el usuario elija entre 'Aprobado' y 'Rechazado'.
-* El tipo de revisión brinda solo una opción: 'Revisado'.
-* El tipo de realización tiene dos opciones: 'Completado' y 'Fallido'.
-
-
-El usuario asignado al registro de Tarea de usuario de proceso creado recibirá una notificación en la aplicación. El administrador también puede habilitar las notificaciones por correo electrónico.
-
-Los usuarios también pueden agregar el dashlet Tareas de usuario de proceso en su tablero para ver sus tareas de usuario de proceso reales.
-
-Es posible leer la resolución de la tarea del usuario pasado dentro de puertas de enlace divergentes o eventos condicionales, haciendo una ramificación en el flujo del proceso.
-
-#### Tarea de script
-
-Ejecuta el script en lenguaje [espo-formula](formula.md). Todas las variables establecidas (`$variableName`) se almacenarán y estarán disponibles dentro del proceso.
-
-### Flujos
-
-#### Flujo de secuencia
-
-Representado como una flecha sólida. Indica el orden en que se ejecutarán los elementos del proceso.
-
-## Condiciones
-
-Los eventos condicionales, las puertas de enlace divergentes exclusivas e inclusivas tienen condiciones que determinan el flujo del proceso.
-
-A través de la interfaz de usuario existe la posibilidad de verificar las condiciones para los siguientes registros:
-
-* Registro objetivo;
-* Registros relacionados con el objetivo a través de relaciones de muchos a uno e hijos a padres;
-* Registros creados por el proceso a través de tareas;
-* Registros de tareas del usuario, lo que permite verificar la resolución.
-
-También es posible definir condiciones en el lenguaje [Espo-formula](formula.md).
-
-Las condiciones en la herramienta BPM son las mismas que en la función de flujo de trabajo. Ver más detalles sobre [las condiciones del flujo de trabajo](workflows.md#condiciones).
-
-## Ejemplos
-
-### Ejemplo 1
-
-
-
-### Ejemplo 2
-
-
-
-### Ejemplo 3
-
-
diff --git a/i18n/es_ES/administration/email-fetching.md b/i18n/es_ES/administration/email-fetching.md
deleted file mode 100644
index cfb7c6fd9..000000000
--- a/i18n/es_ES/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Emails
-
-El documento es movido [aquí](emails.md).
diff --git a/i18n/es_ES/administration/emails.md b/i18n/es_ES/administration/emails.md
deleted file mode 100644
index a95e024eb..000000000
--- a/i18n/es_ES/administration/emails.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Emails
-
-> Importante. [Cron](server-configuration.md#configurar-un-crontab) debe configurarse en su sistema para que funcione el correo electrónico. Puede encontrar la información en su EspoCRM en Administration > Scheduled Jobs.
-
-## Vista General
-
-EspoCRM tiene la capacidad de monitorear los buzones IMAP. El correo electrónico se puede archivar de dos maneras: Cuentas de correo electrónico grupales y Cuentas de correo electrónico personales. Las cuentas entrantes grupales están destinadas a buzones grupales: el caso más común es un buzón de soporte. Las cuentas de correo electrónico personales están destinadas a los buzones de correo personales de los usuarios.
-
-A medida que se recibe un correo electrónico, el sistema intenta vincularlo con el registro apropiado (Cuentas, Plomo, Oportunidad, Caso). Los usuarios que sigan ese registro recibirán una notificación sobre un nuevo correo electrónico en el sistema, incluso si no están en A o CC.
-
-## Cuentas de correo grupal
-
-Solo el administrador puede configurar cuentas de correo electrónico grupales. Las cuentas de correo grupal se pueden usar para recibir y enviar correos electrónicos. El envío de correos electrónicos desde cuentas de grupo ha estado disponible desde la versión 4.9.0.
-
-El campo Equipos determina a qué equipos se asignarán los correos electrónicos entrantes.
-
-Si la cuenta de correo electrónico grupal tiene SMTP y se marca como compartida, un acceso será controlado por Roles a través del permiso de Cuenta de correo electrónico grupal. El campo Equipos se usará si el nivel de permiso se establece en 'equipo'.
-
-Existe la posibilidad de que el sistema envíe una respuesta automática para los correos electrónicos entrantes.
-
-## Email-A-Case
-
-Existe una opción para que el sistema cree casos a partir de correos electrónicos de grupos entrantes.
-Esta función está destinada a los equipos de soporte.
-Los casos se pueden distribuir a los usuarios de un equipo específico de acuerdo con estas formas:
-`direct assignment`, `round-robin` y `less-busy`.
-Solo el primer correo electrónico en el hilo crea un nuevo caso.
-Cada uno posterior se vinculará con el registro de caso existente y se mostrará en su panel de Stream.
-
-Cuando los usuarios desean enviar una respuesta al cliente, deben asegurarse de que el caso esté seleccionado como padre del correo electrónico que se está enviando. Hará que el cliente responda a la dirección de correo electrónico del grupo en lugar de a la del usuario.
-
-## Cuentas personales de correo electrónico
-
-Los usuarios pueden configurar sus propias cuentas de correo electrónico que necesitan ser monitoreadas. Emails > Top Right Dropdown Menu > Personal Email Accounts. El administrador también puede administrar las cuentas de correo electrónico de los usuarios.
-
-## Filtros de correo electrónico
-
-Estos permiten el filtrado de correos electrónicos entrantes según criterios específicos. por ejemplo. Si no desea que se importen mensajes de notificación enviados por alguna aplicación a EspoCRM, puede crear un filtro para hacer que EspoCRM los omita.
-
-El administrador puede crear filtros globales, aplicados a todas las cuentas de correo electrónico. Los usuarios pueden crear filtros para su propia cuenta de correo electrónico personal y para la bandeja de entrada completa.
diff --git a/i18n/es_ES/administration/entity-manager.md b/i18n/es_ES/administration/entity-manager.md
deleted file mode 100644
index 7a704ff4c..000000000
--- a/i18n/es_ES/administration/entity-manager.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# Entity Manager
-
-Entity Manager está disponible en el panel de administración. Proporciona la capacidad de personalizar al máximo tu instancia de EspoCRM. Usted puede hacer lo siguiente:
-
-* Agregue nuevos tipos de entidades.
-* Personalice los tipos existentes de entidades: cambie las etiquetas, el orden predeterminado en la vista de lista, active o desactive la transmisión.
-* Configurar campos: agregar nuevo, personalizar los existentes.
-* Configure las relaciones: agregue nuevas, cambie las etiquetas de las existentes.
-
-## Creando nueva entidad
-
-Haga clic en el botón `Crear entidad` en la página Administrador de la entidad. Especifique el nombre, las etiquetas y el tipo. Si selecciona `Persona`, su entidad tendrá los campos Correo electrónico, Teléfono, Nombre, Apellido y Saludo. Marque `Stream` si desea que su entidad tenga un panel de flujo y que los usuarios puedan Seguir entidades de este tipo.
-Types:
-
-* Base: entidad vacía solo con campos básicos como Nombre, Usuario asignado, Equipos, Descripción.
-* Base Plus - como Base pero con paneles de Actividades, Historial, Tareas (disponible desde 4.3.0).
-* Evento: fecha de inicio, fecha de finalización, duración, padre, campos de estado. Disponible en el panel Calendario y Actividades (desde 4.3.0, debe estar habilitado en Administration > Settings).
-* Persona: correo electrónico, teléfono, nombre, apellido, saludo, campos de dirección. Actividades, historia, paneles de tareas.
-* Empresa: correo electrónico, teléfono, dirección de facturación, campos de dirección de envío. Actividades, historia, paneles de tareas.
-
-## Actualizar la entidad existente
-
-Si hace clic en el enlace `Editar` en una entidad determinada, podrá cambiar algunos parámetros de esa entidad.
-
-* Etiquetas - nombre singular y plural de la entidad.
-* Los registros de pedidos predeterminados están ordenados por vistas de lista.
-* Stream - si la función Stream está habilitada para esta entidad.
-* Deshabilitado - compruebe si no necesita esta entidad en su sistema.
-* Campos de filtro de texto - en qué campos buscar el filtro de texto principal y la búsqueda global.
-
-
-## Campos
-
-Al hacer clic en el enlace `Campos` , se moverá a una página separada. Allí podrá crear nuevos campos o actualizar los existentes. Los siguientes tipos de campos están disponibles en Entity Manager:
-
-* Dirección - dirección con calle, ciudad, estado, código postal y país;
-* Matriz - lista de valores, con la capacidad de seleccionar valores múltiples (no es una buena opción si necesita buscar por este campo); los usuarios pueden agregar sus propios valores si las opciones no están especificadas.
-* Archivo Adjunto Múltiple - archivos adjuntos múltiples;
-* Aumento automático - solo lectura generada;
-* Booleano - casilla de verificación, verdadero o falso;
-* Moneda - para valores de moneda;
-* Fecha;
-* Fecha y hora;
-* Enum - seleccione el cuadro, con la capacidad de seleccionar solo un valor;
-* Archivo - cargando un archivo;
-* Flotante - número con una parte decimal;
-* Extranjero - un campo de entidad relacionada;
-* Imagen - carga del archivo de imagen con una vista previa;
-* Entero - número entero;
-* Número - número de autoincremento del tipo de cadena con un posible prefijo y una longitud específica;
-* Multi-enumeración - lista de valores, con la capacidad de seleccionar valores múltiples (no es una buena opción si necesita buscar en este campo), similar a Matriz pero más agradable.
-* Texto - área de texto, para textos largos de líneas múltiples;
-* Url - para enlaces;
-* Varchar - texto corto;
-* Wysiwyg - similar al campo de texto, con la capacidad de formatear texto.
-
-Parámetros:
-* Obligatorio - si el llenado del campo es obligatorio.
-* Valor predeterminado - valor del campo establecido al crear un nuevo registro.
-* Auditado - las actualizaciones del campo se registrarán en Stream.
-
-**Nota**: Después de haber agregado el nuevo campo, debe poner este campo en [diseños](layout-manager.md) (Administration > Layout Manager).
-
-### Lógica Dinámica
-
-Brinda la capacidad de hacer formas dinámicas. Es posible definir las condiciones que hacen que ciertos campos sean visibles, obligatorios o de solo lectura. Las condiciones se verificarán automáticamente cuando se cambien los datos en el formulario.
-
-Para los campos Enum, Array y Multi Enum, es posible definir diferentes conjuntos de opciones que estarán disponibles para el campo dependiendo de qué condición se cumpla.
-
-## Relaciones
-
-Puede crear nuevas relaciones entre entidades personalizadas y listas para usar. Hay 3 tipos de relaciones disponibles:
-
-* Uno a muchos: después de haber creado esta relación, puede colocar un campo de enlace en el diseño detallado de la entidad correcta y agregar el panel de relaciones a la entidad izquierda;
-* Muchos-a-Uno: lo mismo que Uno-a-Muchos, pero viceversa;
-* Muchos a muchos: paneles de relaciones en ambos lados.
-
-El parámetro `Link Multiple Field` implica que el campo del tipo `linkMultiple` se creará junto con la relación. Puedes poner un campo así en el diseño. Es conveniente para la recolección rápida de registros relacionados. No es una buena opción si su relación está destinada a tener muchos registros vinculados que pueden ralentizar la carga de la pantalla de vista detallada.
-
-Si el parámetro 'Auditado' está marcado, las actualizaciones de la relación se registrarán en Stream.
diff --git a/i18n/es_ES/administration/extensions.md b/i18n/es_ES/administration/extensions.md
deleted file mode 100644
index 22dfca611..000000000
--- a/i18n/es_ES/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Administrar extensiones
-
-## Cómo instalar una extensión
-
-Para instalar la extensión de EspoCRM (por ejemplo, Paquete avanzado, Integración de VoIP):
-
-1. Inicia sesión como administrador.
-2. Vaya a Administration > Extensions.
-3. Cargue su paquete de extensión (archivo zip).
-4. Haga clic en el botón Instalar.
-
-
-## Cómo actualizar una extensión
-
-Para actualizar una extensión ya instalada (por ejemplo, paquete avanzado, integración de VoIP) a una versión más nueva:
-
-1. Descargue la nueva versión de la extensión necesaria.
-2. Inicia sesión como administrador.
-3. Vaya a Administration > Extensions.
-4. Suba su nuevo paquete de extensión (archivo zip) sin desinstalar la versión ya instalada.
-5. Haga clic en el botón Instalar.
-
-
-## Cómo desinstalar una extensión
-
-Pasos para desinstalar una extensión instalada:
-
-1. Inicia sesión como administrador.
-2. Vaya a Administration > Extensions.
-3. Encuentra la extensión necesaria en la lista de extensiones disponibles.
-4. Haga clic en el botón Desinstalar.
-
-
-## Cómo eliminar una extensión
-
-Cuando se desinstala una extensión, todavía está disponible en el sistema. Puede ser completamente eliminado. Pasos para eliminar una extensión:
-
-1. Inicia sesión como administrador.
-2. Vaya a Administration > Extensions.
-3. Encuentra la extensión necesaria en la lista de extensiones disponibles.
-4. Haga clic en el botón Eliminar.
diff --git a/i18n/es_ES/administration/formula.md b/i18n/es_ES/administration/formula.md
deleted file mode 100644
index 272d35d4c..000000000
--- a/i18n/es_ES/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Campos calculados (fórmula)
-
-En el administrador de entidades, es posible definir el script (fórmula) para un tipo de entidad específico. Este script se ejecutará cada vez que se guarde el registro.
-Proporciona la capacidad de establecer automáticamente campos específicos (atributos) con valores derivados del cálculo.
-
-Para editar la fórmula, siga el menú desplegable Administration > Entity Manager > dropdown menu a la derecha en la fila de entidad necesaria> Fórmula.
-
-También es posible que necesite establecer campos, que se supone que deben calcularse, de solo lectura a través de Entity Manager.
-
-
-## Sintaxis
-
-La fórmula de EspoCRM está escrita en el lenguaje simple diseñado específicamente para esta función.
-
-Hay operadores, atributos de funciones y valores que se pueden usar en la fórmula. Las expresiones separadas deben estar delimitadas por caracteres `;`.
-
-### Operadores
-
-* `=` - asignación.
-* `||` - O logico,
-* `&&` - Y logico,
-* `!` - NO logico,
-* `+`- suma numerica,
-* `-` - resta numerica,
-* `*` - multiplicacion numerica,
-* `/` - Division numerica,
-* `%` - Modulo numerico,
-* `==` - comparación igual que,
-* `!=` - comparación distinto que,
-* `>` - comparación mayor que,
-* `<` - Comparación menor que,
-* `>=` - comparación mayor que o igual a,
-* `<=` - comparación menor que o igual.
-
-Prioridad de los operadores:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Atributos
-
-Los atributos representan valores de campo de la entidad objetivo. Puede insertar atributos disponibles haciendo clic en el botón más.
-
-Es posible acceder a atributos de entidades relacionadas con el siguiente formato `linkName.attributeName`.
-
-
-### Funciones
-
-Formato de uso de la función: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Las funciones listas para usar se enumeran a continuación.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` Si se cumple CONDICIÓN, entonces hace CONSECUENT. Si no -- hace ALTERNATIVE.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` Si se cumple CONDICIÓN, entonces hace CONSECUENT. Si no -- no hace nada.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Concatena dos o más cadenas.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Extrae los caracteres de un STRING por la posición START y LENGTH.
-
-Si se omite LONGITUD, se devolverá la subcadena que comienza desde START hasta el final de STRING.
-
-Si LENGTH es negativo, se omitirán muchos caracteres al final de STRING.
-
-#### string\\trim
-`string\trim(STRING)` Quita espacios en blanco desde el principio y el final de STRING.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Convierte letras a minúsculas. (desde la versión 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Convierte letras a mayúsculas. (desde la versión 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Devuelve la fecha de hoy.
-
-#### datetime\now
-`datetime\now()` Devuelve la fecha actual.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Convierte VALOR de fecha o de fecha y hora en una cadena formateada según la configuración de la aplicación. TIMEZONE y FORMAT se pueden omitir. Si se omite TIMEZONE, se usará la zona horaria predeterminada. Si se omite FORMAT, se usará el formato predeterminado.
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Devuelve la fecha del mes (1-31). `0` si VALUE está vacío. Si se omite TIMEZONE, se utiliza la zona horaria del sistema. (desde la versión 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Devuelve el mes (1-12). `0` si VALUE está vacío. Si se omite TIMEZONE, se utiliza la zona horaria del sistema. (desde la versión 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Año de devoluciones `0` si VALUE está vacío. Si se omite TIMEZONE, se utiliza la zona horaria del sistema. (desde la versión 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Hora de devolución (0-23). `-1` si VALUE está vacío. Si se omite TIMEZONE, se utiliza la zona horaria del sistema. (desde la versión 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Devuelve el minuto (0-59). `-1` si VALUE está vacío. Si se omite TIMEZONE, se utiliza la zona horaria del sistema. (desde la versión 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Devuelve el día de la semana (0-6). `-1` si VALUE está vacío. `0` - para el domingo. Si se omite TIMEZONE, se utiliza la zona horaria del sistema. (desde la versión 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Devuelve la diferencia entre dos fechas o fechas. INTERVAL_TYPE puede ser 'años', 'meses', 'días', 'horas', 'minutos'. Devuelve `null` si falla. El resultado será negativo si VALUE_1 < VALOR_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Haga clic en el botón Eliminar. Agrega MINUTOS a datetime VALUE. MINUTOS puede ser negativo.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Agrega HOURS a fecha y hora VALUE. HOURS puede ser negativo.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Agrega DAYS a fecha y hora VALUE. DAYS puede ser negativo.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Agrega WEEKS a fecha y hora VALUE. WEEKS puede ser negativo.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Agrega MONTHS a fecha y hora VALUE. MONTHS puede ser negativo.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Agrega YEARS a fecha y hora VALUE. YEARS puede ser negativo.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` Devuelve la fecha más cercana o la fecha y hora a VALUE según los argumentos pasados. (desde la versión 5.0.0)
-
-TYPE puede ser uno de los siguientes valores: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. TARGET es un valor entero o un valor de cadena. IS_PAST significa encontrar lo más cercano en el pasado. Si se omite TIMEZONE, se usa la zona horaria predeterminada.
-
-Ejemplos:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Devolverá el valor de fecha y hora más cercano en el futuro con 20:00 horas.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` devolverá `2017-11-01`, el primer día del mes.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Regresará el próximo lunes (el comienzo del día).
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Convierte VALOR numérico en una cadena formateada según un formato específico o la configuración de la aplicación predeterminada. Si se utilizan DECIMALS, DECIMAL_MARK o THOUSAND_SEPARATOR, se utilizan los valores predeterminados del sistema.
-
-Ejemplos:
-
-`number\format(2.666667, 2)` - resulta 2.67;
-
-`number\format(1000, 2)` - resulta 1,000.00;
-
-`number\format(10.1, 0)` - resulta 10.
-
-
-#### number\abs
-`number\abs(VALUE)` Valor absoluto. Devuelve nulo si VALUE no es numérico.
-
-#### number\round
-`number\round(VALUE, PRECISION)` Devuelve el valor redondeado de VALOR a la PRECISIÓN especificada (número de dígitos después del punto decimal). PRECISION también puede ser negativo o cero (predeterminado).
-
-#### number\floor
-`number\floor(VALUE)`Devuelve el siguiente valor entero más bajo al redondear el valor si es necesario. (desde la versión 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` Devuelve el siguiente valor entero más alto redondeando el valor si es necesario. (desde la versión 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Devuelve TRUE si la entidad es nueva (se está creando) y FALSE si no (se está actualizando).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Devuelve TRUE si se modificó ATTRIBUTE de la entidad.
-
-Ejemplo:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Devuelve TRUE si ATTRIBUTE de la entidad no fue cambiado.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Atributo que se estableció cuando la entidad objetivo se extrajo de la base de datos. Antes de que fuera modificado.
-
-Ejemplo:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Agrega ID para vincular múltiples campos. Por ejemplo, agregue 'someTeamId' al campo 'equipos'.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Agrega la lista de identificadores. (desde la versión 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Comprueba si el campo Enlace múltiple tiene una ID específica.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Elimina una ID específica del campo link multiple.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Comprueba si la entidad objetivo está relacionada con otra entidad representada por LINK e ID.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Devuelve ATTRIBUTE del usuario actual.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Devuelve una matriz. (desde la versión 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Devuelve verdadero si LIST contiene VALOR. Se puede usar para campos de Array y Multi-Enum. (desde la versión 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Agrega uno o más elementos al final de una matriz y devuelve la nueva matriz. (desde la versión 5.0.0)
-
-#### array\length
-`array\length(LIST)` Devuelve el recuento de elementos en LIST. (desde la versión 4.8.1)
-
-
-### Values
-
-* Strings. Por ejemplo. 'alguna cadena de texto';
-* Numeros enteros. Por ejemplo. 1, 100, 40300.
-* Numeros decimales. Por ejemplo. 5,2.
-
-### Variables
-
-Es posible definir variables personalizadas en fórmula.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Examples
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Using formula in Workflows
-
-Puede utilizar la fórmula en condiciones y acciones de flujo de trabajo. Consulte [documentación de flujos de trabajo](workflows.md#usar-fórmula-en-acciones-1) para obtener más información.
diff --git a/i18n/es_ES/administration/import.md b/i18n/es_ES/administration/import.md
deleted file mode 100644
index ddcd397bf..000000000
--- a/i18n/es_ES/administration/import.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Importar
-
-Importar solo es accesible para usuarios administrativos. Administration> Import Puede importar solo desde archivos CSV.
-
-## Paso 1
-
-Seleccione qué tipo de registros necesita importar (campo Tipo de entidad).
-Seleccione un archivo CSV. Un archivo debe formatearse con `UTF-8`.
-Seleccione `¿Qué hacer?`. Opciones disponibles: 'Crear solo', 'Crear y actualizar', 'Solo actualizar'.
-
-* `Create Only` - selecciónelo si quiere que el registro se cree solo.
-* `Crear y actualizar`: se crearán registros, pero si se encuentran registros con valores de campo coincidentes, se actualizarán. Podrás comprobar con qué campos coincidir en el _Step 2_.
-* `Solo actualización`: solo se encontrarán registros con valores de campo coincidentes, se actualizarán.
-Once you select a csv file you will be able to see how it should be parsed in Preview panel. When you change properties the preview will be updated.
-
-* `Header Row` - si el archivo CSV tiene la primera fila con los nombres de los campos.
-* `Execute in ocioso`: recomendado si tiene un gran grupo de registros para importar. La importación se procesará a través de cron. El estado se establecerá en 'Completado' cuando finalice el proceso de importación.
-* `Omitir búsqueda de duplicados` - disminuirá el tiempo de ejecución de importación.
-
-Haga clic en el botón _Next_ para pasar al _Paso 2_ ..
-
-
-
-## Paso 2
-
-Configure la asignación de campo: cómo los campos corresponden a las columnas del archivo csv. Puede omitir las columnas que no sean necesarias aquí.
-En los casos de 'Crear y actualizar' y 'Actualizar solamente', debe verificar los campos por los cuales se encontrarán los registros que se deben actualizar.
-Agregue los valores predeterminados con los que desea que se establezcan los registros nuevos y actualizados. P.ej. puede especificar campos de Usuario asignado o Equipos.
-
-Una vez realizada la importación, podrá revertir los registros creados, ver duplicados y registros actualizados. Duplicar significa que hubo un registro similar en el sistema. Puede eliminar todos los duplicados importados a la vez. Nota: Revertir no funciona con registros actualizados.
-
-Click en el boton _Run Import_ para continuar. Puede tomar algún tiempo antes de que finalice un proceso de importación. Si desea importar un gran grupo de registros (depende de la configuración de su servidor, generalmente si hay más de 200 registros), debe asegurarse de que el parámetro php `set_time_limit` sea lo suficientemente grande.
-
-
-
-## Cómo importar a la lista de objetivos
-
-Cuando importa Contactos, Clientes potenciales o Cuentas, puede agregarlos a una lista de objetivos. En el Paso 2, debe agregar el campo Lista de objetivos en el panel `Valores predeterminados` y seleccionar un registro de lista de objetivos necesario. También puede usar la importación `Actualizar solo` o` Crear y actualizar` para agregar objetivos existentes a una lista de objetivos.
diff --git a/i18n/es_ES/administration/installation.md b/i18n/es_ES/administration/installation.md
deleted file mode 100644
index a807abccf..000000000
--- a/i18n/es_ES/administration/installation.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Instalación
-
-### Requisitos
-EspoCRM se ejecuta en la mayoría de los proveedores de alojamiento. Los requisitos incluyen lo siguiente:
-
-* PHP 5.5 o la última versión de PHP con habilitado pdo, json, biblioteca GD, extensiones mcrypt (generalmente habilitadas por defecto);
-* MySQL 5.1 o superior.
-
-Consulte el artículo [Configuracion del servidor](server-configuration.md) para más información.
-
-### 1. Descargue el paquete de instalación de EspoCRM
-Para obtener la última versión de EspoCRM, siga el enlace [descargar página](http://www.espocrm.com/download/).
-
-### 2. Cargue los archivos de EspoCRM a su servidor
-
-Una vez que se completa la descarga, suba el paquete a su servidor web.
-Para subirlo, puede usar SSH, FTP o el panel de administración de hosting.
-Extraiga el archivo a su directorio público del servidor web (por ejemplo, `public_html`,` www`, etc.).
-
-_Nota: para FTP, necesita extraer el archivo antes de cargarlo en su servidor web._
-
-### 3. Crear una base de datos MySQL para que EspoCRM use
-
-Vaya a su panel de administración de hosting, o a SSH, y cree una nueva base de datos y usuario para EspoCRM (por ejemplo, `Bases de datos MySQL` en cPanel).
-
-### 4. Ejecute el proceso de instalación de EspoCRM
-
-Ahora, abra su navegador web y vaya a la URL con los archivos de EspoCRM (Por ejemplo, `http://yourdomain.com/espo`).
-
-Si ve esta pantalla, tiene un error "Permiso denegado".
-Por lo tanto, debe ejecutar el comando que se muestra en el terminal a través de SSH o establecer el permiso correcto.
-Debe ser 755 para directorios, 644 para archivos y 775 para directorio `datos`.
-También asegúrese de tener el _owner_ y _group_ correcto.
-
-
-
-Si ve la siguiente pantalla, el permiso es correcto y puede comenzar a instalar EspoCRM.
-
-
-
-En esta página, puede leer y aceptar el Acuerdo de licencia.
-
-
-
-Ingrese los detalles de su base de datos MySQL recién creada.
-
-
-
-Ingrese el nombre de usuario y la contraseña del administrador EspoCRM.
-
-
-
-En esta página puede establecer la configuración predeterminada de EspoCRM, como el formato de fecha y hora, la zona horaria, la moneda y otros.
-
-
-
-Ingrese la configuración de SMTP para los correos electrónicos salientes, si desea tener la capacidad de enviar correos electrónicos.
-Este paso se puede omitir haciendo clic en el botón _Next_.
-Todas estas opciones se pueden agregar / cambiar en EspoCRM después de la instalación.
-
-
-
-¡Felicidades! La instalación esta completa.
-Lo último para configurar las tareas programadas para que las ejecute su sistema. Se puede hacer ejecutando `crontab -e` en linux cli y en _Windows Tasks Scheduler_ en sistemas Windows.
-
-
-
-Esperamos que disfrute trabajando en EspoCRM.
diff --git a/i18n/es_ES/administration/layout-manager.md b/i18n/es_ES/administration/layout-manager.md
deleted file mode 100644
index eb2f85c05..000000000
--- a/i18n/es_ES/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Layout Manager
-
-Layout Manager está disponible en el panel de administración. Ofrece la posibilidad de personalizar la apariencia de detalles, editar, mostrar vistas, así como también buscar filtros y campos para formularios de actualización masiva.
-
-## Listas
-
-El diseño principal de la vista de lista. Define columnas y sus parámetros.
-
-
-
-Los parámetros disponibles para las columnas se enumeran a continuación.
-
-### Ancho (%)
-
-Ancho de columna en porcentaje, vacío significa ancho automático.
-
-### Link
-
-Si se selecciona, el campo se mostrará como un enlace a la vista de detalle del registro. Usualmente se usa para campos de nombre.
-
-### No ordenable
-
-Desactiva la capacidad de ordenar la columna.
-
-### Align
-
-Align the column to the left or to the right.
-
-## Detalles
-
-El diseño principal de la vista de detalles y la vista de edición. Define paneles, filas y celdas. Las celdas contienen campos.
-
-La fila puede contener dos celdas o una celda que se expande al ancho completo de la fila. Para agregar la fila con una celda expandida, debe agregar la nueva fila y hacer clic en un signo menos en cualquier celda.
-
-
-
-## Lista (pequeña)
-
-El diseño de la lista para paneles de relaciones. También se puede usar en otros lugares donde es razonable mostrar listas en la vista estrecha.
-
-## Detalle (Pequeño)
-
-La vista de detalle para crear rápidamente, vista rápida y formularios de edición rápida.
-
-## Filtros de búsqueda
-
-La lista de campos disponibles en la vista de lista para buscar por.
-
-## Actualización masiva
-
-La lista de campos disponibles en el formulario de Actualización masiva.
-
-## Paneles de relación
-
-La lista de paneles de relaciones que se muestran en la vista de detalles en la parte inferior. Los paneles pueden ser reordenados. Es posible definir el color del panel con el parámetro Estilo.
-
-## Paneles laterales
-
-Paneles laterales para Detalle, Editar, Detalle Pequeño, Editar formularios pequeños. Proporciona la capacidad de ocultar o reordenar los paneles de actividades, historial, tareas y otros. Los paneles pueden ser coloreados por el parámetro Estilo.
-
-## Diseños adicionales
-
-Algunos tipos de entidades contienen diseños adicionales: Convertir plomo, Lista para cuenta.
diff --git a/i18n/es_ES/administration/ldap-authorization-for-ad.md b/i18n/es_ES/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index ee74af98b..000000000
--- a/i18n/es_ES/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Autorización de LDAP para Active Directory
-
-Ejemplo de autorización LDAP de configuración para el servidor de Active Directory. La guía completa de la autorización LDAP de configuración se describe [aquí](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/es_ES/administration/ldap-authorization-for-openldap.md b/i18n/es_ES/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index d73ba2da8..000000000
--- a/i18n/es_ES/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Autorización de LDAP para OpenLDAP
-
-Ejemplo de autorización LDAP de configuración para el servidor OpenLDAP. La guía completa de la autorización LDAP de configuración se describe [aquí](ldap-authorization.md).
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/es_ES/administration/ldap-authorization.md b/i18n/es_ES/administration/ldap-authorization.md
deleted file mode 100644
index f52e7caf7..000000000
--- a/i18n/es_ES/administration/ldap-authorization.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Autorización Ldap
-
-En esta guía, le mostraremos cómo configurar la autorización de LDAP para EspoCRM. Vamonos.
-
-Vaya a su servidor LDAP y cree un DN base para los usuarios de EspoCRM
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Tenemos que crear un usuario del sistema que tendrá acceso a los usuarios DN (“cn=espo-users,ou=users,dc=espo,dc=local”). Entonces, el DN completo para este usuario del sistema será
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Ahora, podemos agregar usuarios de LDAP para acceder a EspoCRM. por ejemplo. Espo Tester con el nombre de usuario "tester" dentro de “cn=espo-users,ou=users,dc=espo,dc=local” DN. Tenga en cuenta: para poder utilizar este formato de inicio de sesión para EspoCRM, debe especificar las opciones "Nombre de usuario" y "DN base".
-
-A continuación, vaya a la configuración de Autenticación de EspoCRM en el panel Administrador, seleccione el método `LDAP` y complete los detalles de LDAP:
-
-
-
-* Host: IP de LDAP o nombre de host.
-* Puerto - puerto de conexión.
-* Auth: credenciales de acceso para el servidor LDAP:
- * DN de usuario completo: el DN de usuario del sistema completo que permite buscar a otros usuarios.
- * Contraseña: la contraseña para acceder al servidor LDAP.
-* Seguridad: protocolo SSL o TSL.
-* Atributo de nombre de usuario: el atributo para identificar al usuario. Para Active Directory puede ser "userPrincipalName" o "sAMAccountName".
-* Formulario canónico de la cuenta: tipo de formulario canónico de su cuenta. Hay 4 opciones:
- * Dn - la forma en el formato `CN = probador, CN = Espocrm, DC = compañía, DC = com`.
- * Nombre de usuario - el formulario `probador`.
- * Barra diagonal: el formulario `COMPAÑÍA \ probador`.
- * Principal - el formulario `tester @ company.com`.
-* Enlace Requiere Dn - si es necesario formatear el nombre de usuario en el formulario DN.
-* Base Dn: el DN base predeterminado que se utiliza para buscar usuarios.
-* Filtro de inicio de sesión de usuario: el filtro que permite restringir a los usuarios que pueden usar EspoCRM. Por ejemplo. `memberOf = cn = espoGroup, cn = espo-users, ou = usuarios, dc = espo, dc = local`.
-* Nombre de dominio de la cuenta: el dominio que se utiliza para autorizar el servidor LDAP.
-* Nombre de dominio de cuenta corto: el dominio corto que se utiliza para autorizar el servidor LDAP.
-* Pruebe el nombre de usuario dividido: la opción de dividir un nombre de usuario con el dominio.
-* Opt Referencias - si las referencias deben seguirse al cliente LDAP.
-* Crear usuario en EspoCRM: esta opción permite a EspoCRM crear un usuario desde LDAP.
- * Atributo del nombre del usuario: atributo LDAP que se utiliza para determinar el nombre del usuario.
- * Atributo del apellido del usuario: atributo LDAP que se utiliza para determinar el apellido del usuario.
- * Atributo de título de usuario: atributo LDAP que se utiliza para determinar el título del usuario.
- * Atributo de dirección de correo electrónico de usuario: atributo LDAP que se utiliza para determinar la dirección de correo electrónico del usuario.
- * Atributo del número de teléfono del usuario: atributo LDAP que se utiliza para determinar el número de teléfono del usuario.
-
-Ahora, vaya a la página de inicio de sesión e ingrese las credenciales de usuario.
-
-
-
-El usuario ha sido autenticado y creado automáticamente en el EspoCRM.
-
-## Instrucciones de configuración basadas en su servidor:
-* [Servidor de Active Directory](ldap-authorization-for-ad.md)
-* [Servidor OpenLDAP](ldap-authorization-for-openldap.md)
-
-Puede obtener más información sobre la configuración de LDAP en la página [Biblioteca Zend \ Ldap](https://zendframework.github.io/zend-ldap/intro/), ya que EspoCRM utiliza esta biblioteca.
diff --git a/i18n/es_ES/administration/maps.md b/i18n/es_ES/administration/maps.md
deleted file mode 100644
index 83709f113..000000000
--- a/i18n/es_ES/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Mapas
-
-## Cómo mostrar el mapa basado en un campo de dirección
-
-Cada campo de Dirección tiene su campo de Mapa correspondiente. Todo lo que necesita es ponerlo en el diseño detallado. Utiliza el servicio Google Maps.
-
-`Administration > Layout Manager > Choose entity (Account, Contact, Lead or custom one) > Detail > Drag & Drop Map field.`
-
-Haz la celda ancha usando el signo menos.
-
-También puede configurar la altura de su campo.
-
-`Administration > Entity Manager > Choose entity > Fields > find the map field and click on it > edit the height and save.`
-
-## Clave API
-
-Desde EspoCRM versión 4.2.0 necesita especificar Api Key para usar Google Maps (Administration > Integration > Google Maps).
-
diff --git a/i18n/es_ES/administration/moving-to-another-server.md b/i18n/es_ES/administration/moving-to-another-server.md
deleted file mode 100644
index eebd75c88..000000000
--- a/i18n/es_ES/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Mover EspoCRM a otro servidor
-
-Siga estos pasos para mover EspoCRM a otro servidor:
-
-### Paso 1. Copia de seguridad de archivos
-
-Abra un administrador de archivos o inicie sesión a través de SSH para archivar todos los archivos disponibles desde el directorio de EspoCRM. [Más detalles](backup-and-restore.md#paso-1-respaldar-archivos).
-
-### Paso 2. Haz una copia de seguridad de tu base
-
-Los datos almacenados en la base de datos (MySQL, MariaDB) se deben respaldar. Por favor, siga esta [recomendación](backup-and-restore.md#paso-2-respaldar-base-de-datos).
-
-### Paso 3. Copie los archivos y las copias de seguridad de la base de datos a otro servidor
-
-Copia copias de seguridad de archivos y de tu base de datos a un nuevo servidor.
-
-### Paso 4. Desarchivar archivos de copia de seguridad
-
-Para desarchivar los archivos de copia de seguridad, puede usar Archive Manager o esta [instrucción](backup-and-restore.md#paso-1-desarchivar-archivos-de-copia-de-seguridad).
-
-Nota: Los archivos deben colocarse en el directorio del servidor web.
-
-### Paso 5. Configurar un servidor
-
-Configure un nuevo servidor según las [recomendaciones aquí](server-configuration.md)
-
-### Paso 6. Corregir permisos
-
-Establecer los [permisos](server-configuration.md#permisos-requeridos-para-sistemas-basados-en-unix) requeridos y el propietario de los archivos.
-
-### Paso 7. Importa tu copia de seguridad de la base de datos
-
-Primero, debe crear una nueva base de datos con un usuario en MySQL. Para importar su base de datos desde la copia de seguridad, siga la [instucción](backup-and-restore.md#paso-3-importar-el-volcado-de-la-base-de-datos).
-
-### Paso 8. Corregir las configuraciones de EspoCRM
-
-Después de importar y configurar con éxito el servidor, corrija las configuraciones de EspoCRM en el archivo `ESPOCRM_DIRECTORY/data/config.php`:
-
- * configuración de conexión de base de datos:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - si se cambia su nombre de dominio (URL):
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * propietario de archivos predeterminado (solo si es diferente):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- donde `www-data` es su usuario del servidor web.
-
-### Paso 9. Configura un crontab
-
-Configura un [crontab](server-configuration.md#configurar-un-crontab).
-
-Nota: debe ser configurado bajo su usuario del servidor web.
-
-Eso es todo. Ahora, su instancia de EspoCRM se está ejecutando en un nuevo servidor.
diff --git a/i18n/es_ES/administration/nginx-server-configuration.md b/i18n/es_ES/administration/nginx-server-configuration.md
deleted file mode 100644
index f5ee75bbb..000000000
--- a/i18n/es_ES/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Configuración del servidor Nginx para EspoCRM
-
-Estas instrucciones son suplementarias a la guía [Server Configuration] (server-configuration.md). Tenga en cuenta que todos los ajustes de configuración enumerados aquí se realizan en el servidor de Ubuntu.
-
-## Requisitos de PHP
-
-Para instalar todas las librerias necesarias, ejecute estos comandos en una terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Solucionando el problema "Error de la API: la API de EspoCRM no está disponible":
-
-Tome solo los pasos necesarios. Después de cada paso, compruebe si el problema está resuelto.
-
-### 1. Habilitar reglas de reescritura en el servidor Nginx
-
-Agregue este código a su archivo de configuración de bloque de servidor Nginx (/etc/nginx/sites-available/TU_SITIO) dentro del bloque "servidor":
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Si no tiene este archivo, debe crearlo. Para esto abra una terminal y ejecute el comando:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Y agregue el código enumerado arriba. Para obtener más información sobre cómo configurar un nuevo host virtual en Nginx, lea esta [guía](nginx-virtual-host.md).
-
-Ejecute este comando en una terminal para verificar si todo está bien:
-
-```
-sudo nginx -t
-```
-
-Si es así, ejecute el comando para reiniciar el servidor nginx:
-
-```
-sudo service nginx restart
-```
-
-### 2. Agregue la ruta RewriteBase
-
-Abra un archivo /ESPOCRM_DIRECTORY/api/v1/.htaccess y reemplace la siguiente línea:
-
-```
-# RewriteBase /
-```
-con
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-donde REQUEST_URI es parte de la URL, p. para "http://example.com/espocrm/", REQUEST_URI es "espocrm".
diff --git a/i18n/es_ES/administration/nginx-virtual-host.md b/i18n/es_ES/administration/nginx-virtual-host.md
deleted file mode 100644
index 7fa725651..000000000
--- a/i18n/es_ES/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Configurar un host virtual en Nginx para EspoCRM
-
-En esta guía mostraremos cómo configurar un host virtual en Nginx para EspoCRM en el servidor de Ubuntu.
-
-## Crear un archivo de bloque de servidor
-
-Para crear este archivo, abra un terminal y ejecute el comando:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Ahora, abra este archivo (/etc/nginx/sites-available/espocrm.conf) y modifique el código siguiendo el formato impreso a continuación (algunas configuraciones pueden ser diferentes en función de su configuración):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Reemplaza espocrm.local a tu nombre de dominio
- root /var/www/html/espocrm; # Especifique su documento raíz de EspoCRM
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Especifique su PHP (php-cgi o php-fpm) en función de su configuración
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Añadir reglas de reescritura
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Habilita este bloque de servidor
-
-Crea un enlace simbólico:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Ejecute este comando para verificar si todo está bien:
-
-```
-sudo nginx -t
-```
-
-Y reinicie el servidor Nginx:
-
-```
-sudo service nginx restart
-```
-
-## Configure sus hosts locales (opcional, solo para un dominio local)
-
-Si agregó un dominio local, debe configurarlo en su computadora local (no en el servidor). Para Ubuntu, abra el archivo `/etc/hosts` y agregue la línea:
-```
-192.168.1.1 espocrm.local # especifica la dirección IP de tu servidor Nginx
-```
-
-Para Windows, siga estas [instrucciones](http://support.microsoft.com/kb/923947).
diff --git a/i18n/es_ES/administration/portal.md b/i18n/es_ES/administration/portal.md
deleted file mode 100644
index 03478b550..000000000
--- a/i18n/es_ES/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Portal
-
-Portal proporciona la capacidad de acceder a datos y funciones de crm específicos para sus clientes y socios. El administrador puede crear múltiples portales. Cada portal puede tener su propia configuración, dashlboard, lista de usuarios, configuración de control de acceso.
-
-Para crear un portal, siga Administración> Portales, haga clic en el botón Crear portal.
-
-* `is active`. Si no, el portal de verificación no estará disponible para nadie.
-* `is default`. Significa que el portal estará disponible por URL más corta: http (s): // YOUR_ESPO_URL / portal.
-* `Roles`. Especifique uno o varios roles del portal que se aplicarán a los usuarios que hayan iniciado sesión en el portal. Más información sobre los roles del portal a continuación.
-* `Tab List`. Pestañas que se mostrarán en la barra de navegación.
-* `Dashboard Layout` . Especifique los dashlets que se mostrarán en la página de inicio del portal. Tenga en cuenta que los usuarios del portal no pueden configurar su tablero.
-* `URL`. Campo de solo lectura que muestra el enlace al que puede acceder el portal.
-
-## Usuarios del portal
-
-Los administradores pueden crear usuarios del portal.
-
-1. Administración> Usuarios.
-2. Haz clic en el menú desplegable a la derecha junto a Crear usuario.
-3. Haga clic en Crear usuario del portal.
-4. Seleccione Contactar con el que se vinculará el usuario del portal.
-5. Rellene el formulario y haga clic en guardar.
-
-El usuario del portal debe estar vinculado al registro del Portal para poder acceder a ese portal.
-
-## Roles del portal
-
-Los roles del portal son similares a los roles regulares en EspoCRM pero con algunas distinciones.
-
-* el nivel `not-set` niega un acceso.
-* el nivel `own` significa que el registro es creado por el usuario. P.ej. el usuario del portal presentó un caso y este caso pertenece a este usuario.
-* nivel de `account` significa que el registro está relacionado con la cuenta con la que el usuario del portal está relacionado.
-* nivel de `contact` significa que el registro está relacionado con el contacto con el que está relacionado el usuario del portal.
-
-Los campos de Usuario asignado y Equipos son de solo lectura para usuarios del portal.
-
-### Example
-
-`Portal users should be able to create cases, view cases related to their account; they should be able to view knowledge base.`
-
-1. Open Create Portal Role form (Administration > Portal Roles > Create Role).
-2. Enable access to Cases, set: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. Enable access to Knowledge Base, set `create - no, read - account, edit - no, delete - no`.
-4. Edit your portal record (Administration > Portals). Select your portal role in Roles field and then save.
-
-## Access to Portal
-
-You can find the url for your portal in 'URL' field of the portal record. Also it's possible to use server configuration tools (such mod_rewrite) to be able to access by different url. For this case you need to fill in 'Custom URL' field.
-
-### Access portal by Custom URL for Apache server
-
-Custom URL: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Mod rewrite rules
-
-Specify portal record ID instead of `{PORTAL_ID}`. Portal record ID can is avaialble in address bar of your web browser when you open detail view of the portal record. Like: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 is a portal record id.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/es_ES/administration/roles-management.md b/i18n/es_ES/administration/roles-management.md
deleted file mode 100644
index 22e465170..000000000
--- a/i18n/es_ES/administration/roles-management.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# Gestión de Roles
-
-## Visión de Conjunto
-
-Para restringir el acceso de algunos usuarios, debes usar Roles. El administrador puede administrar roles en el panel de administración. Cada rol define un acceso a ciertas áreas (ámbitos) que se aplica a los usuarios que poseen ese rol.
-
-Un usuario puede tener múltiples roles. Esos roles se pueden seleccionar para un usuario específico (campo 'Roles' en la entrada de Usuario) y/o heredarse de los equipos a los que pertenece el usuario.
-
-Si un usuario tiene múltiples roles, se fusionarán para que la regla permisiva tenga una mayor prioridad. Eso le permite al administrador administrar el control de nivel de acceso de manera fácil y flexible.
-
-Es posible ver qué permisos se aplican a un determinado usuario haciendo clic en el botón "Acceso" en la vista de detalles del usuario.
-
-
-
-
-## Ejemplo
-
-Por ejemplo, el usuario pertenece al equipo 'Ventas'. Ese equipo tiene el rol único 'Vendedor'. Entonces, todos los usuarios de este equipo obtendrán el rol de 'vendedor'.
-
-La función 'Vendedor' se define de la siguiente manera:
-
-Liderar:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Oportunidad:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Los usuarios solo podrán leer los clientes potenciales y las oportunidades que pertenecen al equipo del "Departamento de ventas" (campo "Equipos").
-El usuario solo podrá editar aquellos clientes potenciales y oportunidades a los que están asignados o aquellos que han creado.
-Los usuarios no podrán eliminar ninguna ventaja u oportunidad.
-
-Queremos otorgar más derechos a un determinado usuario que tenga un puesto de gerente de ventas en la empresa. Este empleado debe tener la capacidad de leer/editar/ eliminar todos los registros del equipo de "Ventas". El usuario debe pertenecer a nuestro equipo de 'Ventas'. Pero necesitamos crear la nueva función 'Gerente de ventas' y seleccionar esta función para ese usuario en el campo 'Roles'.
-
-La función 'Gerente de ventas' se define de la siguiente manera:
-
-Liderar:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Opportunidad:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Nuestro usuario podrá gestionar todas las oportunidades y oportunidades del equipo de "Ventas".
-
-## Permisos Especiales
-
-### Permiso de Asignación
-
-Establezca este parámetro para restringir la capacidad de reasignar registros a otro usuario y/o equipos. Si configura `team`- entonces será posible asignar solo a usuarios de su (s) propio (s) equipo (s). Si `no` - los usuarios no podrán reasignar en absoluto.
-
-También define si el usuario puede publicar en la transmisión de otros usuarios/equipos.
-
-### Permiso del Usuario
-
-Permite restringir la capacidad de los usuarios para ver actividades, calendario y transmisión de otros usuarios.
-
-### Permiso del Portal
-
-Define un acceso a la información del portal, la capacidad de publicar mensajes a los usuarios del portal.
-
-### Permiso de Cuenta de Correo Electrónico Grupal
-
-Define un acceso a cuentas de correo electrónico grupales, la capacidad de enviar correos electrónicos del grupo SMTP.
-
-### Permiso de Exportación
-
-Defiende si el usuario tiene la capacidad de exportar registros. (desde la versión 4.9.0)
-
-## Permisos por Defecto
-
-Por defecto (si no hay ninguno aplicado) los usuarios pueden leer y editar todos los registros. Pero no puede eliminar ninguno excepto aquellos que han creado y que están asignados al mismo tiempo.
-
-Existe la posibilidad de restringir un acceso aplicado por defecto al habilitar 'ACL Strict Mode' en Administración> Configuración.
-
-## Seguridad de Nivel de Campo
-
-Permite controlar un acceso para un campo específico.
-
-De manera predeterminada, el usuario puede leer todos los campos si puede leer el registro. El usuario puede editar cualquier campo si se puede editar el registro. Puede restringir el acceso a campos específicos usando Seguridad de Nivel de Campo.
-
-En la vista de edición de un registro de roles en la sección Nivel de campo, haga clic en el icono más junto al alcance específico, luego seleccione el campo necesario. Luego podrá especificar el nivel de acceso para las acciones `read` y `edit`. Hay para las opciones: `yes` y `no`.
-
-
diff --git a/i18n/es_ES/administration/server-configuration.md b/i18n/es_ES/administration/server-configuration.md
deleted file mode 100644
index cf8ebdf00..000000000
--- a/i18n/es_ES/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Configuración del Servidor para EspoCRM
-
-EspoCRM se puede instalar en Apache ([instrucciones](apache-server-configuration.md)), Nginx ([instrucciones](nginx-server-configuration.md)), o servidor IIS con compatibilidad con PHP versión 5.6 o posterior y MySQL versión 5.1 o superior.
-
-## Recomendaciones de Configuración
-
-### Requisitos de PHP
-
-EspoCRM requiere PHP 5.6 o superior, con las siguientes extensiones habilitadas:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – para acceder a MySQL en PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – los recursos usan este formato (metadatos, diseño, idiomas y otros);
-* [GD](http://php.net/manual/en/book.image.php) – para manipular imágenes;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – para garantizar la mayor protección;
-* [Zip](http://php.net/manual/en/book.zip.php) – para poder actualizar EspoCRM e instalar extensiones;
-* [IMAP](http://php.net/manual/en/book.imap.php) – para monitorear buzones de correo en EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-También se recomienda tener instalada la extensión pecl [mailparse](https://pecl.php.net/package/mailparse). Es necesario para el funcionamiento sin problemas de la función de búsqueda de correo electrónico.
-
-configuración de php.ini:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Requerimientos de MySQL
-
-EspoCRM es compatible con MySQL versión 5.1 o superior.
-Estas no son peculiaridades especiales. Todas las configuraciones predeterminadas son buenas para EspoCRM.
-
-## Permisos Requeridos para Sistemas basados en Unix
-
-Los archivos y directorios deben tener los siguientes permisos:
-
-* `/data`, `/custom`, `/client/custom` - deben poderse escribir todos los archivos, directorios y subdirectorios (664 para archivos, 775 para directorios, incluidos todos los subdirectorios y archivos);
-* `/application/Espo/Modules`, `/client/modules` - debería poder escribirse el directorio actual (775 para el directorio actual, 644 para archivos, 755 para directorios y subdirectorios);
-* Todos los demás archivos y directorios deben ser legibles (644 para archivos, 755 para directorios).
-
-Para establecer los permisos, ejecuta estos comandos en la terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Todos los archivos deben ser de propiedad y propiedad del grupo por el proceso del servidor web. Puede ser "www-data", "daemon", "apache", "www", etc.
-Nota: En Bitnami Stack, los archivos deben ser de propiedad y propiedad del grupo por el usuario "daemon".
-Nota: en los hosts compartidos, los archivos deben ser de propiedad y propiedad del grupo de suu cuenta de usuario.
-
-Para configurar el propietario y el propietario del grupo, ejecuta estos comandos en la terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## Configurar un crontab
-
-Para configurar un crontab en un sistema UNIX, siga estos pasos:
-
-* 1. Inicie sesión como administrador en su instancia de EspoCRM.
-* 2. Vaya a la sección de Trabajos Programados en el panel del administrador (Menú > Administración > Trabajos Programados) y copie la cadena para el crontab. Se ve como esta:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Abra una terminal y ejecute este comando:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER puede ser uno de los siguientes "www", "www-data", "apache", etc. (depende de su servidor web).
-* 4. Pegue la cadena copiada (desde el paso 2) y guarde el archivo crontab (Ctrl + O, luego Ctrl + X para el editor nano).
-
-## Instrucciones de configuración basadas en su servidor:
-
-* [Configuración del servidor Apache](apache-server-configuration.md).
-* [Configuración del servidor Nginx](nginx-server-configuration.md).
diff --git a/i18n/es_ES/administration/troubleshooting.md b/i18n/es_ES/administration/troubleshooting.md
deleted file mode 100644
index 6210d59c9..000000000
--- a/i18n/es_ES/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Solución de problemas
-
-## Verificar registros
-
-Para averiguar el problema, debe verificar los archivos de registro de errores.
-
-#### Registros de errores de EspoCRM
-
-Los registros de EspoCRM se encuentran en `/logs/*.Log` y contienen alguna información de error.
-
-#### Registros de error de Apache
-
-Para el servidor de Ubuntu, un registro de error de apache se encuentra en `/var/log/apache2/error.log` y contiene toda la información de error. La ubicación de los archivos de registro puede ser diferente en otros sistemas.
-
-## Habilitar el modo de depuración
-
-Para habilitar el modo de depuración, vaya al directorio EspoCRM instalado, abra el archivo `data/config.php` y cambie el valor:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-a
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Los Trabajos Programados no funcionan
-
-#### Problema #1: Su crontab no está configurado
-
-1. Ingresa a través de SSH a tu servidor.
-
-2. Configure su crontab siguiendo estos [pasos](server-configuration.md#configurar-un-crontab).
-
-Nota: Crontab debería configurarse bajo usuario del servidor web, P.ej. `crontab-e-uwww-data`.
-
-3. Espere un momento y compruebe los Trabajos Programados para ver si se ejecutó alguna tarea (consulte un Panel de registro).
-
-#### Problema #2. Crontab está configurado, pero los Trabajos Programados no funcionan
-
-Para asegurarse de que no haya errores cuando se está ejecutando cron, intente ejecutar el comando cron en una terminal:
-
-1. Ingresa a través de SSH a tu servidor.
-
-2. Vaya al directorio donde está instalado EspoCRM. P.ej. para el directorio `/var/www/html/espocrm` el comando es:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Ejecute el comando crontab:
-
-```bash
-php cron.php
-```
-
-Nota: debe ejecutarse bajo usuario del servidor web. Si ha iniciado sesión como root, el comando debería ser (P.ej. para Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-donde `www-data` es un usuario del servidor web.
-
-4. Si no hay errores, revise los Trabajos Programados para ver si se ejecutó algún trabajo (consulte un Panel de registro).
-
-## EspoCRM no se carga después de la actualización
-
-Esto puede suceder a veces en algunos hostings compartidos.
-
-Verificar permisos de los archivos:
-/index.php
-/api/v1/index.php
-
-Deben ser 644. Si alguno de esos archivos tiene permiso 664, debe cambiarlo a 644. Use el panel de control de su hosting o el comando chmod.
-
-```
-chmod 644 /path/to/file
-```
-Más información sobre permisos de archivos: [aquí](server-configuration.md#permisos-requeridos-para-sistemas-basados-en-unix).
diff --git a/i18n/es_ES/administration/upgrading.md b/i18n/es_ES/administration/upgrading.md
deleted file mode 100644
index ce7accd26..000000000
--- a/i18n/es_ES/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Cómo actualizar EspoCRM
-
-EspoCRM se puede actualizar a la última versión mediante los siguientes pasos:
-
-### Paso 1. Verifica tu versión actual
-
-Para verificar su versión actual, vaya a Administración > Página Actualizar.
-
-### Paso 2. Descargue los paquetes de actualización necesarios
-
-Vaya a [la página de actualización](https://www.espocrm.com/download/upgrades/) y según su versión actual, descargue los paquetes necesarios.
-
-### Paso 3. Crear una copia de seguridad (opcional)
-
-Cree una copia de seguridad de sus archivos y datos de EspoCRM antes de actualizar. Siga [estas instrucciones](backup-and-restore.md) para completarla.
-
-### Paso 4. Proceso de actualización
-
-Vaya a Administración > Actualizar. Cargue e instale paquetes de actualización uno por uno.
-
-Puede verificar si tiene la última versión en Menú > Acerca de.
-
-## Actualizar a través de CLI
-
-También puede ejecutar la actualización a través de la interfaz de línea de comando. Necesita ejecutar el siguiente comando desde el directorio raíz de EspoCRM:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/es_ES/administration/workflows.md b/i18n/es_ES/administration/workflows.md
deleted file mode 100644
index a9e59909e..000000000
--- a/i18n/es_ES/administration/workflows.md
+++ /dev/null
@@ -1,161 +0,0 @@
-# Flujos de Trabajo
-
-La función de flujos de trabajo está disponible en [Paquete avanzado](https://www.espocrm.com/extensions/advanced-pack/).
-
-Los flujos de trabajo automatizan su proceso comercial de una manera fácil. Puede encontrarlo en el panel de Administración. Para crear una regla de flujo de trabajo, debe definir:
-
-* Entidad Objetivo: a qué tipo de flujo de trabajo de la entidad se aplica;
-* Tipo Disparador: cuando se activará el flujo de trabajo;
-* Condiciones: se deben cumplir las condiciones para activar el flujo de trabajo;
-* Acciones: qué hacer si se activa el flujo de trabajo.
-
-
-## Tipos de Disparadores
-
-### Después de crear el registro
-
-Disparado solo cuando se crea un nuevo registro. Si se cumplen las condiciones especificadas, se ejecutarán las acciones.
-
-### Después de guardar el registro
-
-Se activa cuando se crea un nuevo registro o se actualiza un registro existente. Si se cumplen las condiciones especificadas, se ejecutarán las acciones.
-
-Para las reglas de flujo de trabajo con este tipo de desencadenador, es una práctica común tener una condición que verifique si algún campo se 'cambió'. P.ej. Si el estado de Case cambia, entonces ejecuta algunas acciones.
-
-### Programado
-
-Activado según la programación definida. Puede configurarlo para que se ejecute todos los días, todas las semanas, etc. Las acciones se aplicarán a los registros devueltos por un informe de lista especificado. Entonces también necesita crear un informe de lista.
-
-La programación se especifica en una notación crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Año (rango: 1900-3000)
-| | | | +---- Día de la Semana (rango: 1-7, siendo 1 para Lunes)
-| | | +------ Mes del Año (rango: 1-12)
-| | +-------- Día del Mes (rango: 1-31)
-| +---------- Hora (rango: 0-23)
-+------------ Minuto (rango: 0-59)
-```
-
-### Secuencial
-
-Usado raramente. Se supone que debe ser ejecutado por otro flujo de trabajo. Brinda la capacidad de hacer una lógica compleja.
-
-Nota: Para flujos de trabajo secuenciales, se recomienda utilizar [herramienta BPM] (bpm.md) en lugar de una función de Flujos de trabajo.
-
-## Condiciones
-
-Puede especificar las condiciones que se deben cumplir para activar el flujo de trabajo. Hay dos formas de especificar condiciones: con el constructor de condiciones de UI y con la fórmula.
-
-### Constructor de condiciones de IU
-
-Algunos tipos de condiciones disponibles:
-
-* _equals_ - el campo es igual a un valor específico o un valor de otro campo;
-* _was equal_ - el campo era igual a un valor específico antes de que se activara el flujo de trabajo;
-* _not equals_ - el campo no es igual a un valor específico o un valor de otro campo;
-* _was not equal_ - el campo no era igual al valor específico antes de que se activara el flujo de trabajo;
-* _empty_ - el valor del campo está vacío;
-* _not empty_ - el valor del campo no está vacío;
-* _changed_ - el campo fue cambiado;
-* _not changed_ - el campo no fue cambiado.
-
-### Condiciones de la fórmula
-
-La fórmula proporciona la capacidad de definir condiciones de cualquier complejidad. Para leer acerca de la sintaxis de fórmulas siga [este artículo] (formula.md).
-
-Nota: No debe haber ningún delimitador `;` utilizado en el código de fórmula cuando determina una condición.
-
-## Acciones
-
-### Enviar correo electrónico
-
-El sistema enviará un correo electrónico usando una plantilla de correo electrónico especificada. La dirección de correo electrónico de un destinatario puede tomarse del registro objetivo, cualquier registro relacionado, el usuario actual, los seguidores, los usuarios del equipo o especificados. El correo electrónico puede enviarse de inmediato o retrasarse por un intervalo específico.
-
-### Crear registro
-
-El sistema creará el nuevo registro de cualquier tipo de entidad. Si existe una relación entre el registro objetivo y la creación de registros, es posible relacionar los registros.
-
-Existe la capacidad de definir fórmulas para calcular campos.
-
-### Crear registro relacionado
-
-El sistema creará el registro relacionado con el registro objetivo. Es posible definir una fórmula para calcular campos.
-
-### Actualizar registro de destino
-
-Permite el cambio de campos específicos del registro objetivo. Es posible definir una fórmula para calcular campos.
-
-Si necesita agregar nuevos elementos al campo Múltiple de enlace sin perder los datos existentes (por ejemplo, Equipos), necesita utilizar la función de fórmula entity\addLinkMultipleId. Ejemplo: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### Actualizar registro relacionados
-
-Permite el cambio de campos específicos del registro o registros relacionados. Es posible definir una fórmula para calcular campos.
-
-### Enlace con otro registro
-
-Relaciona la entidad objetivo con otra entidad específica. P.ej. agrega equipo específico al registro.
-
-### Desvincular con otro registro
-
-Desrelaciona la entidad objetivo de otra entidad específica. P.ej. elimina un equipo específico del registro.
-
-### Aplicar Regla de Asignación
-
-Asigne el registro objetivo al usuario por regla de distribución. Hay dos reglas disponibles: Round-Robin y Least-Busy.
-
-* Round-Robin: los usuarios son elegidos desde la parte superior a la parte inferior de una lista (equipo) y luego comienzan de nuevo.
-* Menos ocupado: el usuario que tenga menos registros asignados será elegido para la asignación.
-
-_List Report_ - Para la distribución Least-Busy determina qué registros se tendrán en cuenta para calcular el número de registros asignados. P.ej. para Cases, necesitamos tomar solo registros con estado activo.
-
-### Crear Notificación
-
-Notificar a usuarios específicos con el mensaje. Es posible utilizar marcadores de posición en la plantilla de mensaje: {entidad} - registro de destino, {usuario} - usuario actual.
-
-### Hacer Seguidores
-
-Obliga a usuarios específicos a seguir a la entidad objetivo o a una entidad relacionada específica.
-
-### Activa Otro Flujo de Trabajo
-
-Permite hacer flujos de trabajo secuenciales. Es posible derivar el flujo de trabajo por condición: puede configurar el flujo de trabajo para desencadenar dos flujos de trabajo con diferentes condiciones definidas en esos flujos de trabajo.
-
-Es posible retrasar la ejecución del flujo de trabajo secuencial. En el flujo e trabajo secuencial, puede definir la condición que verifica si los campos específicos se cambiaron desde que se desencadenó el flujo de trabajo primario mediante los tipos de condición _Changed_ y _Was Equal_.
-
-Nota: Para flujos de trabajo secuenciales, se recomienda utilizar [herramienta BPM] (bpm.md) en lugar de una función de Flujos de trabajo.
-
-### Ejecutar Acción de Servicio
-
-Permite ejecutar scripts de servicio específicos. Por defecto hay las siguientes acciones disponibles:
-
-* Enviar Invitaciones: para Reuniones/Llamadas;
-* Agregar Elementos de Ccotización - para Cotizaciones.
-
-Los desarrolladores pueden escribir sus propias acciones de servicio. Ver [más detalles](../development/workflow-service-actions.md).
-
-## Usar Fórmula en Acciones
-
-Es posible definir la fórmula para calcular campos para Crear registro, Actualizar registro objetivo, Crear registro relacionado, Actualizar registro relacionado. Para los dos últimos, para acceder a los atributos de la entidad objetivo, debe usar la función `targetEntity\attribute`. Para acceder a los atributos de la entidad objetivo que se estableció antes de que se activara el flujo de trabajo, use la función `targetEntity\attributeFetched`.
-
-Nota: Para flujos de trabajo secuenciales, se recomienda utilizar [herramienta BPM] (bpm.md) en lugar de una función de Flujos de trabajo.
-
-### Ejecutar Acción de Servicio
-
-Permite ejecutar scripts de servicio específicos. Por defecto hay las siguientes acciones disponibles:
-
-* Enviar invitaciones: para Reuniones/Llamadas;
-* Agregar Elementos de Cotización - para Cotizaciones.
-
-Los desarrolladores pueden escribir sus propias acciones de servicio. Ver [más detalles] (../development/workflow-service-actions.md).
-
-## Usar Fórmula en Acciones
-
-Es posible definir la fórmula para calcular campos para Crear registro, Actualizar registro objetivo, Crear registro relacionado, Actualizar registro relacionado. Para los dos últimos, para acceder a los atributos de la entidad objetivo, debe usar la función `targetEntity\attribute`. Para acceder a los atributos de la entidad objetivo que se estableció antes de que se activara el flujo de trabajo, use la función `targetEntity\attributeFetched`.
-
-Ejemplo:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/es_ES/development/api.md b/i18n/es_ES/development/api.md
deleted file mode 100644
index 79d243f34..000000000
--- a/i18n/es_ES/development/api.md
+++ /dev/null
@@ -1,225 +0,0 @@
-# REST API
-
-EspoCRM es una aplicación de una sóla página para que una interfaz utilice REST API para conectarse con un motor.
-Todas las operaciones que realice utilizando UI, las puede implementar a través de llamadas a API utilizando su lenguaje de programación.
-Puede aprender sobre cómo funciona el API si rastrea lo que ocurre en la pestaña de red en la cónsola de su buscador.
-
-La mayoría de las funciones api arrojan JSON. Las llamadas POST, PATCH suelen necesitar algunos datos JSON en carga útil.
-
-El URL base de EspoCRM es: `api/v1/`. Necesita insertarlo al principio de las expresiones en esta referencia. Ejemplo;
-
-`GET http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Autenticación
-
-El API de EspoCRM utiliza [Autenticación Básica](https://es.wikipedia.org/wiki/Autenticación_de_acceso_básica). El nombre de usuario y la contraseña/token son pasados por el encabezado `Authorization` codificado en base64.
-
-`"Authorization: Basic " + base64Encode(username + ':' + password)`
-
-
-Es mucho mejor utilizar el token de autenticación en lugar de la contraseña cuando se trabaja con api. En este caso usted necesitará proporcionar el nombre de usuario y la contraseña/token en el encabezado `Espo-Authorization`.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-
-1. Obtenga el token de acceso pidiendo `GET App/user` con el nombre de usuario y la contraseña pasada en el encabezado `Espo-Authorization`.
-2. Utilice este token en lugar de la contraseña en el encabezado `Espo-Authorization` para todos los siguientes pedidos.
-3. Si el pedido arroja un error 403, eso significa que el nombre de usuario/contraseña es incorrecto o que el token ya no es valido.
-
-#### Token de Autenticación / Datos Específicos de Usuario
-
-`GET App/user`
-
-Arroja:
-
-* `token` - el token de acceso a utilizar;
-* `acl` - información sobre el acceso del usuario;
-* `preferences` - preferencias del usuario;
-* `user` - historial de atributos del usuario.
-
-
-## Operaciones CRUD
-
-#### Listar Entidades
-
-`GET {entityType}`
-
-Obtenga parametros:
-
-* `offset` - (int) compensar;
-* `maxSize` - (int) tamaño máximo;
-* `where` - (array) filtros;
-* `sortBy` - (string) campo a clasificar por;
-* `asc` - (bool) dirección de clasificación.
-
-_Ejemplo_
-
-`GET Account?offset=0&maxSize=20`
-
-Arroja:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Leer Entidad
-
-`GET {entityType}/{id}`
-
-Arroja atributos en un objeto JSON.
-
-_Ejemplo_
-
-`GET Account/5564764442a6d024c`
-
-#### Crear Entidad
-
-`POST {entityType}`
-
-Carga útil: Objeto de los atributos de entidad
-
-Arroja atributos de entidad en un objeto JSON.
-
-_Ejemplo_
-
-`POST Account`
-
-Carga útil:
-```
-{
- "name": "Test",
- "assignedUserId": "1"
-}
-```
-
-#### Actualizar Entidad
-
-`PATCH {entityType}/{id}`
-
-o
-
-`PUT {entityType}/{id}`
-
-Carga útil: Objeto de los atributos de entidad que se necesitan para ser cambiados.
-
-Arroja atributos en objeto JSON.
-
-_Ejemplo_
-
-`PATCH Account/5564764442a6d024c`
-
-Carga útil:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Eliminar Entidad
-
-`DELETE {entityType}/{id}`
-
-_Ejemplo_
-
-`DELETE Account/5564764442a6d024c`
-
-
-## Entidades Relacionadas
-
-#### Listar Entidades Relacionadas
-
-`GET {entityType}/{id}/{link}`
-
-* `offset` - (int) compensar;
-* `maxSize` - (int) tamaño máximo;
-* `where` - (array) filtros;
-* `sortBy` - (string) campo a clasificar;
-* `asc` - (bool) dirección de clasificación.
-
-_Ejemplo_
-
-`GET Account/5564764442a6d024c/opportunities`
-
-Arroja:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Vincular Entidad
-
-`POST {entityType}/{id}/{link}`
-
-Carga útil:
-
-1. `id` atributo.
-2. `ids` formar atributo.
-3. `"massRelate": true` y `"where": {...}` para relacionar varios historiales por criterios de búsqueda.
-
-_Ejemplo_
-
-`POST Account/5564764442a6d024c/opportunities`
-
-Carga útil:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Desvincular Entidad
-
-`DELETE {entityType}/{id}/{link}`
-
-Carga útil
-
-1. JSON con `id` atributo.
-2. JSON con `ids` formar atributo.
-
-_Ejemplo_
-
-`DELETE Account/5564764442a6d024c/opportunities`
-
-Carga útil:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-
-## Transmisión
-
-#### List stream entries for the current user
-
-#### Listar entradas de transmisión para el usuario actual
-
-`GET Stream`
-
-Obtener parametros:
-
-* `offset` - (int) compensar;
-* `maxSize` - (int) tamaño máximo;
-
-#### Listar entradas de transmisión relaciondas a un historial específico
-
-`GET {entityType}/{id}/stream`
-
-Obtener parametros:
-
-* `offset` - (int) compensar;
-* `maxSize` - (int) tamaño máximo;
-
-#### Seguir al historial
-
-`PUT {entityType}/{id}/subscription`
-
-#### Dejar de al seguir hitorial
-
-`DELETE {entityType}/{id}/subscription`
-
-
diff --git a/i18n/es_ES/development/custom-field-type.md b/i18n/es_ES/development/custom-field-type.md
deleted file mode 100644
index 2fd32aa36..000000000
--- a/i18n/es_ES/development/custom-field-type.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# Creando un Campo Personalizado de Tipo
-
-## Definición de Campo
-
-Cree un archivo `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` con parametros necesitados.
-```
-{
- "view": "custom:views/fields/{field-type}"`
-}
-```
-
-Utilice tipos de campo particulares como ejemplo: `/application/Espo/Resources/metadata/fields`.
-
-`/application/Espo/Resources/metadata/fields`.
-
-### Traducción
-
-La etiqueta se utiliza en el Administrador de Entidad. Puede ser configurada en `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` en la sección `fieldTypes`. Si necesita añadir traducciones a otro idioma, utilice [código de lenguaje](https://en.wikipedia.org/wiki/ISO_639-1)_[código de país](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) en lugar de `en_US`. En `data/config.php` en la sección `languageList` puede encontrar la lista de los lenguajes incluídos.
-
-### Visualización
-
-Cree la visualización para el campo `client/custom/src/views/fields/{field-type}.js` y defina sus plantillas
-```
-Espo.define('custom:views/fields/[field-type]', 'views/fields/base', function (Dep) {
-
- return Dep.extend({
-
- });
-});
-```
-
-Utilice tipos de campo particulares como ejemplo
-- `/client/src/views/fields` - visualizaciones;
-- `/client/res/templates/fields` - plantillass.
-
-Luego necesita ejecutar reconstrucción en el panel de administración.
diff --git a/i18n/es_ES/development/custom-views.md b/i18n/es_ES/development/custom-views.md
deleted file mode 100644
index 85f66d210..000000000
--- a/i18n/es_ES/development/custom-views.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# Vistas Personalizadas
-
-## Historial de Vistas
-
-El marco metodológico de EspoCRM facilita habilidades flexibles para definir vistas personalizadas para ciertos tipos de entidad. Estos deben definirlo en la categoría `clientDefs` de metadata.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-La vista Historial/Detalle contiene todos los paneles con campos, relaciones y otros datos que podrá ver en vista detallada. No contiene encabezado y los botones están en la esquina superior derecha.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Here is your custom template. Omit if you don't need it.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Here is your custom view. Omit if you don't need it.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Here is your custom view. Omit if you don't need it.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Here is your custom view. Omit if you don't need it.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Custom initalization logic here. Like binding listening to model changes.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Custom code to be invoked right after rendering, when DOM is avaiable.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-Se le permite crear una plantilla personalizada con la ruta siguiente:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-La vista detallada contiene vista de Historial/Detalle y Encabezado.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-Lo mismo que detallada pero es utilizada cuando se está creando o editando un historial, no en el modo de edición en línea.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-La vista de Lista contiene vista de Historial/Lista, Encabezado y Vista en Forma de Búsqueda.
-
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-La vista de Lista/Historial contiene filas de historial.
-
-
-Vale la pena mencionar que usted necesita heredar su clase de vista de una clase específica para su entidad si ya existe alguna.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Vistas de Campo
-
-Las vistas personalizadas para campos específicos deberían ser especificadas en la sección entityDefs de metadata.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
diff --git a/i18n/es_ES/development/dynamic-forms.md b/i18n/es_ES/development/dynamic-forms.md
deleted file mode 100644
index fffe25212..000000000
--- a/i18n/es_ES/development/dynamic-forms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Formas Dinámicas
-
-Nota: Desde la versión 4.3.0 es posible definir formas dinámicas a través del UI del admin en el Administrador de Entidades.
-
-Existe una habilidad para definir un comportamiento de forma en EspoCRM.
-
-## Ejemplo
-
-> Necesita mostrar el campo _nextStep_ en una vista de detalle de Oportunidad sólo si la etapa es 'Closed Won'.
->
-
-Cree el archivo `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Eso significa que el campo _nextStep_ estará escondido por defecto y se mostrará si la estapa es igual a 'Closed Won'.
-
-La lista de acciones disponibles: `show`, `hide`, `setRequired`, `setNotRequired`.
-
-También existe la habilidad de esconder/mostrar paneles. Especifique los nombres de panel en `panels`, atribuya de la misma manera que `fields`.
diff --git a/i18n/es_ES/development/extension-packages.md b/i18n/es_ES/development/extension-packages.md
deleted file mode 100644
index e038308dd..000000000
--- a/i18n/es_ES/development/extension-packages.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Paquetes de Extensión
-
-Las extensiones le permiten añadir más funcionalidad a EspoCRM. Estas pueden ser instaladas por el panel del Administrador bajo la sección `Customization`.
-
-## Cómo crear un paquete de extensión
-
-Una estructura de archivo de paquete:
-
-* `/manifest.json` – un archivo que contiene propiedades de extensión;
-* `/files` – un directorio que contiene propiedades de extensión;
-* `/scripts` – contiene los scripts de extensión.
-
-### Manifiesto
-```json
-{
- "name": "Extension Name",
- "version": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "author": "Your Name",
- "description": "Description of your extension",
- "delete": []
-}
-```
-
-* La sintaxis de la `version` y `acceptableVersions` es descrita por la especificación de v2.0.0 que se puede encontrar en http://semver.org.
-* `delete` - es la lista de archivos centrales que necesitan ser borrados. No se recomienda el uso de este parámetro. Los puede omitir.
-
-### Archivos
-
-Todos los archivos de extensión deberían ser colocados en el directorio de `files`. Serán copiados al directorio central de EspoCRM.
-
-### Scripts
-
-Para diferentes propositos EspoCRM respalda los siguientes tipos de script. Todos estos deberían ser colocados en el directorio de `scripts`.
-
-* `BeforeInstall.php` – un script ejecutado antes de un proceso de instalación;
-* `AfterInstall.php` – ejecutado una vez que el proceso de instalación finalice;
-* `BeforeUninstall.php` – ejecutado antes del proceso de desinstalación;
-* `AfterUninstall.php` – ejecutado una vez que el proceso de desinslación finalice.
-
-Ejemplo:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Paquete
-
-Al final, necesitamos colocar todos estos archivos en un archivo .zip.
diff --git a/i18n/es_ES/development/hooks.md b/i18n/es_ES/development/hooks.md
deleted file mode 100644
index a42a809c2..000000000
--- a/i18n/es_ES/development/hooks.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Ganchos
-
-## Crear Gancho
-
-Para crear un gancho, necesita:
-- crear un archivo `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- declarar acción de tipo gancho;
-- limpiar el Caché en Administración.
-
-## Tipos de Gancho
-
-Los principales tipos de gancho son:
-
-- beforeSave; - antes de guardar
-- afterSave; - después de guardar
-- beforeRemove; - antes de remover
-- afterRemove; - después de remover
-- afterRelate; - después de relacionar
-- afterUnrelate; - después de quitar relación
-- afterMassRelate. - después de relación masiva
-
-### Nuevo Tipo de Gancho
-Puede usar su propio tipo de gancho y activarlo con
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Orden de Gancho
-Si tiene varios ganchos relacionados con un tipo de entidad y con el mismo tipo de gancho, y el orden de ejecución es importante, puede establecer una propiedad `public static $ order` en un valor entero.
-
-Orden ascendente - el gancho con el menor número de orden se ejecuta primero.
-
-## Ejemplo
-Este ejemplo establece el Nombre de la Cuenta para nuevos Clientes Potenciales, si no está establecido.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-use Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Ganchos Globales
-Si necesita aplicar un gancho para todas las entidades, puede usar ganchos comunes. Para hacer esto, ponga la clase de su gancho en el Directorio Común, P.ej. `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/es_ES/development/how-to-create-a-dashlet.md b/i18n/es_ES/development/how-to-create-a-dashlet.md
deleted file mode 100644
index ba2ec7213..000000000
--- a/i18n/es_ES/development/how-to-create-a-dashlet.md
+++ /dev/null
@@ -1,108 +0,0 @@
-# Cómo crear un dashlet
-
-Cree un archivo `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` con su configuración de dashlet.
-
-Aquí necesita definir `"view"`, y podría configurar `"aclScope"`, `"entityType"`, y `"options"`.
-
-Si es una lista de dashlet típica, utilice `"view":"views/dashlets/abstract/record-list"`, si no, cree su propia [vista](custom-views.md).
-
-## Opciones
-Por defecto, en las opciones de dashlet puede configurar _Title_ y _Auto-refresh Interval_.
-
-Puede configurar los campos de opciones adiconales en `"options"` > `"fields"`.
-
-Para definir la posición de los campos, configure la disposición en `"options"` > `"layout"` > `"rows"`.
-
-También puede definir otras opciones, si su vista necesita más datos.
-
-## Ejemplo
-
-`application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json`
-
-```
-{
- "view":"views/dashlets/abstract/record-list",
- "aclScope": "Case",
- "entityType": "Case",
- "options": {
- "fields": {
- "title": {
- "type": "varchar",
- "required": true
- },
- "autorefreshInterval": {
- "type": "enumFloat",
- "options": [0, 0.5, 1, 2, 5, 10]
- },
- "displayRecords": {
- "type": "enumInt",
- "options": [3,4,5,10,15]
- },
- "expandedLayout": {
- "type": "base",
- "view": "views/dashlets/fields/records/expanded-layout"
- }
- },
- "defaults": {
- "sortBy": "createdAt",
- "asc": false,
- "displayRecords": 5,
- "expandedLayout": {
- "rows": [
- [
- {
- "name": "number"
- },
- {
- "name": "name",
- "link": true
- },
- {
- "name": "type"
- }
- ],
- [
- {
- "name": "status"
- },
- {
- "name": "priority"
- }
- ]
- ]
- },
- "searchData": {
- "bool": {
- "onlyMy": true
- },
- "primary": "open"
- }
- },
- "layout": [
- {
- "rows": [
- [
- {"name": "title"}
- ],
- [
- {"name": "displayRecords"},
- {"name": "autorefreshInterval"}
- ],
- [
- {"name": "expandedLayout"},
- false
- ]
- ]
- }
- ]
- }
-}
-```
-
-Ahí puede ver algunos ejemplos `application/Espo/Modules/Crm/Resources/metadata/dashlets`.
-
-## Traducción
-
-La traducción a dashlet está en el rango `Global`, en la sección `"dashlets"`.
-
-__Después de todo no olvide limpiar el Caché en Administración.__
diff --git a/i18n/es_ES/development/link-multiple-with-primary.md b/i18n/es_ES/development/link-multiple-with-primary.md
deleted file mode 100644
index 34b0f9a93..000000000
--- a/i18n/es_ES/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,129 +0,0 @@
-# Vincule Varios Campos con Primario
-
-~Para EspoCRM 3.6.0 y superiores~
-
-A veces tiene relaciones `hasMany` y necesitas tener la capacidad de seleccionar un historial primario entre los relaciones. Como ejemplo, el campo `Contacts` de entidad Caso.
-
->Necesita crear `contacts`, vincule Varios campos con un primario para nuestra entidad personalizada `Stock`.
->
-
-### Paso 1
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-### Paso 2
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-### Paso 3
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-### Paso 4
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-### Paso 5
-Ejecutar Reconstrucción
-
-### Paso 6
-Ejecute consulta SQR
-```sql
-UPDATE stock
-JOIN contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
diff --git a/i18n/es_ES/development/metadata.md b/i18n/es_ES/development/metadata.md
deleted file mode 100644
index c4b53d802..000000000
--- a/i18n/es_ES/development/metadata.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Metadatos
-
-Los metadatos están destinados a: almacenar datos del sistema como los campos y relaciones de la entidad; especificando controladores de frontend, vistas, paneles; definir campos, dashlets; y otros datos necesarios para la aplicación.
-
-
-## Cómo accesar
-
-#### Backend
-
-Los metadatos objeto de la clase `Espo \ Core \ Utils \ Metadata` se pueden acceder desde Contenedor. La ruta a un parámetro necesario se especifica usando los puntos `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-retornará `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-retornará una matriz asociativa de todos los campos.
-
-#### Frontend
-
-El objeto metadatos es accesible desde todos los objetos de vista por el método `#getMetadata`. Funciona de la misma manera que uno de backend.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## Cómo es almacenado
-
-Los metadatos se almacenan en archivos JSON que pueden ubicarse en diferentes lugares:
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-Cuando accede a los datos por la ruta `clientDefs.Account.views.edit`, el primer lexema `clientDefs` corresponde al nombre de la carpeta, la segunda `Cuenta` al nombre de archivo `Account.json`. Todos los siguientes lexemas corresponden a la ruta en el JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-Todos los archivos JSON de estos directorios se fusionan recursivamente en una única matriz php y se almacenan en un archivo de caché.
-
-
-## Extendiendo
-
-Dado que los metadatos se fusionan recursivamente, puede redefinir fácilmente los objetos json y las matrices en _perzonalizar_ y en su _módulo_. También puede agregar a las matrices existentes utilizando `__ADJUNTAR__` (desde la versión 2.6.0) como primer elemento de la matriz.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/es_ES/development/new-function-in-formula.md b/i18n/es_ES/development/new-function-in-formula.md
deleted file mode 100644
index 0bebdf8cd..000000000
--- a/i18n/es_ES/development/new-function-in-formula.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Definiendo de nuevas funciones para Fórmula
-
-EspoCRM ofrece la posibilidad de crear funciones personalizadas que se pueden usar en fórmula.
-
-Si su función está relacionada con la de grupos como Cadena, Lógico, Fecha, cree un archivo en la carpeta __{NombreGrupo}Grupo__, llamado __{NombreFunción}Tipo.php__ con __{NombreFunción}Tipo__ declaración de clase. Necesita definir el método __'proceso'__.
-
-Por ejemplo, creemos una nueva función de cadena para verificar si una cadena (HAYSTACK) contiene otra cadena (NEEDLE) con un posible desplazamiento (OFFSET).
-
-Crea un archivo
-`application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` con el código:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-use \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Añadiendo una función a la lista
-
-Para agregar la función creada a la lista de funciones de fórmula, cree un archivo `custom/Espo/Custom/Resources/metadata/app/formula.json` y agregue el código:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Limpie Caché__ y use esta función en la fórmula. Puede escribirlo `string\contains(HAYSTACK, NEEDLE, OFFSET)` o seleccionarlo de la lista de función, si lo añadió.
diff --git a/i18n/es_ES/development/orm.md b/i18n/es_ES/development/orm.md
deleted file mode 100644
index 10012c81f..000000000
--- a/i18n/es_ES/development/orm.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# ORM (Cómo Administrar Entidades)
-
-EspoCRM tiene su propio ORM incorporado (mapeo relacional de objetos). Es muy simple crear, actualizar, leer, eliminar y buscar entidades. Todas estas operaciones están disponibles a través del objeto Administrador de Entidades. Administrador de Entidades está disponible en Servicios de registro por el método `#getEntityManager()`.
-
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Crear nueva entidad
-```php
-$account = $entityManager->getEntity('Cuenta')
-```
-o
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Obtener existente
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-o
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Obtener valor
-```php
-$fieldValue = $account->get('nombreCampo');
-```
-
-#### Tiene valor
-```php
-$fieldNameIsSet = $account->has('nombreCampo'); // verdadero o falso
-```
-
-#### Ajustar valor
-```php
-$account->set('nombreCampo', 'Probar Cuenta');
-```
-
-```php
-$account->set(array(
- 'nmbre' => 'Probar Cuenta',
- 'idAsignadoUsuario' => '1'
-));
-```
-
-#### Almacenar
-```php
-$entityManager->saveEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Remover
-```php
-$entityManager->removeEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Encontrar
-```php
-$accountList = $entityManager->getRepository('Account')->where(array(
- 'tipo' => 'Cliente',
-))->find();
-```
-
-Orden descendiente:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('creadoEn', true)->find();
-```
-
-Orden ascendente:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('creadoEn')->find();
-```
-
-o:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('creadoEn', 'DESC')->find();
-```
-
-#### Encontrar el primero
-```php
-$account = $entityManager->getRepository('Cuenta')->where(array(
- 'tipo' => 'Cliente',
-))->findOne();
-```
-
-#### Encontrar relacionado
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'oportunidades');
-```
-
-#### Entidades relacionadas
-```php
-$entityManager->getRepository('Account')->relate($account, 'oportunidades', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->relate($account, 'oportunidades', $opportunityId);
-```
-
-#### Entidades no relacionadas
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'oportunidades', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'oportunidades', $opportunityId);
-```
diff --git a/i18n/es_ES/development/scheduled-job.md b/i18n/es_ES/development/scheduled-job.md
deleted file mode 100644
index 286d1e9e7..000000000
--- a/i18n/es_ES/development/scheduled-job.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Creando un Trabajo Agendado
-
-Para definir un trabajo Agendado personalizado, cree un archivo `custom/Espo/Custom/Jobs/{JOB_NAME}.php` con el contenido.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //all the logic needs to be defined in the method run
- }
-}
-```
-
-También puede establecer una etiqueta para su trabajo (`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-Para implementar los cambios, diríjase al panel de Administración para Vacia Caché.
diff --git a/i18n/es_ES/development/workflow-service-actions.md b/i18n/es_ES/development/workflow-service-actions.md
deleted file mode 100644
index 71e5515b2..000000000
--- a/i18n/es_ES/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Agregar acción de servicio personalizada para Flujo de trabajo
-
-Los flujos de trabajo permiten crear acciones de servicio personalizadas. Este ejemplo mostrará cómo se puede hacer esto para una entidad de Llamada.
-
-## Paso 1. Crear clase de servicio
-
-```php
- Borrar Caché. Ahora la acción de servicio está disponible para Flujos de Trabajo en el formulario Ejecutar Acción de Servicio.
diff --git a/i18n/es_ES/user-guide/browser-support.md b/i18n/es_ES/user-guide/browser-support.md
deleted file mode 100644
index 21c12b226..000000000
--- a/i18n/es_ES/user-guide/browser-support.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Soporte del Navegador
-
-We recommend using the latest versions of Google Chrome or Mozilla Firefox. EspoCRM works the best in these browsers. We regularly test all features in these browsers.
-
-Microsoft Edge y Safari también son compatibles, pero hay menos garantías de que todo estará funcionando sin problemas.
-
-No recomendamos utilizar Internet Explorer 11.
-
diff --git a/i18n/es_ES/user-guide/emails.md b/i18n/es_ES/user-guide/emails.md
deleted file mode 100644
index 2ef9bb777..000000000
--- a/i18n/es_ES/user-guide/emails.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Lineamientos sobre el Uso de Correos Electrónicos
-
-EspoCRM proporciona la capacidad de buscar correos electrónicos desde el cuadro IMAP. Esto hace posible usar EspoCRM como un cliente de correo electrónico junto con características específicas de CRM.
-
-## Cuentas IMAP
-
-*Nota: Debe tener [cron](../administration/server-configuration.md#configurar-un-crontab) configurado correctamente en su sistema para tener correos electrónicos entrantes trabajando.*
-
-El usuario puede configurar la cuenta IMAP en la página Cuentas de Correo Electrónico personales (pestaña de Correo Electrónico > menú superior derecho > Cuentas de Correo Electrónico Personales).
-
-Especifique qué carpetas supervisar en el campo Carpetas Supervisadas. Por defecto está configurado en INBOX. Si utiliza un cliente de correo electrónico externo para enviar correos electrónicos, puede agregar la carpeta Enviados para archivar esos correos electrónicos.
-
-*Buscar desde* le permite elegir la fecha desde la cual se deben archivar los correos electrónicos. Configúrelo para una fecha anterior a hoy si necesita archivar correos electrónicos antiguos.
-
-Existe la posibilidad de especificar * Carpeta * en la Cuenta de Correo Electrónico Personal. Los correos entrantes se colocarán en esa carpeta.
-
-## Cuentas SMTP
-
-Los usuarios pueden configurar los ajustes de SMTP en Preferencias así como también en sus Cuentas de Correo Electrónico Personales. El administrador también puede permitir el uso del sistema SMTP (hazlo Compartido).
-
-Los usuarios pueden tener múltiples cuentas SMTP (desde la versión 4.2.0). Pero las direcciones de correo electrónico que el usuario puede usar para enviar correos electrónicos están definidas por las direcciones de correo electrónico del registro *Usuario*.
-
-## Trabajando con Correos Electrónicos
-
-Los correos electrónicos son captados por cron (en segundo plano) cada pocos minutos (el período puede ser especificado por el Administrador).
-Puede ver todos sus correos electrónicos en la pestaña Correos Electrónicos. Hay carpetas estándar de Bandeja de entrada, Enviados, Borradores de correos electrónicos en el lado izquierdo.
-
-Campo de *Estado*. `Enviado` significa que fue enviado desde CRM, `Archivado` - extraído de la cuenta IMAP o archivado manualmente, `Borrador` - significa que el correo electrónico se creó como un borrador.
-
-Cuando llega el nuevo correo electrónico, el sistema intenta reconocer a qué registro pertenece este correo electrónico. Puede vincularlo con Cuenta, Cliente Potencial, Oportunidad, Caso (y Contacto en modo B2C) etc. Si no fue reconocido, el usuario puede vincularlo manualmente al completar el campo *Padre*.
-
-Si un correo electrónico proviene de un nuevo cliente potencial, el usuario puede **convertirlo a Cliente Potencial**. Abra la entrada de Correo electrónico y haga clic en Crear Cliente Potencial en el menú superior derecho.
-
-También es posible **crear Tarea o Caso** a partir de un registro de correo electrónico.
-
-Si las direcciones de correo electrónico (de, a, cc) en un registro de correo electrónico son conocidas por el sistema se mostrará a la persona con la que están relacionadas (Contacto, Cliente Potencial, Usuario etc.). Si alguna dirección de correo electrónico es nueva, puede **crear contacto** justo desde allí.
-
-Todos los correos electrónicos relacionados con un registro específico se muestran en el panel Historial de ese registro. Si algún correo electrónico está relacionado, por ejemplo, con oportunidad, pero oportunidad está relacionada con la cuenta, se mostrará tanto en oportunidad como en cuenta.
-
-## Mandando Correos Electrónicos
-
-Puede redactar un nuevo correo electrónico de varias maneras:
-* Botón de *Escribir Correo Electrónico* en la vista de lista de Correos Electrónicos;
-* respondiendo en otro correo electrónico;
-* haciendo clic en una dirección de correo electrónico de algún registro;
-* acción *Escribir Correo Electrónico* del panel de Actividades.
-
-Existe la posibilidad de **seleccionar la plantilla** de su correo electrónico.
-
-Puede configurar la **firma del correo electrónico** en Preferencias.
-
-## Carpetas de Correo Electrónico
-
-Los usuarios pueden crear sus propias carpetas de correo electrónico para colocar algunos de los correos electrónicos para su conveniencia. La lista de carpetas disponibles está disponible en la página de Correos Electrónicos en el lado izquierdo. Para crear o editar carpetas, siga Correos Electrónicos > menú desplegable en la esquina superior derecha > Carpetas. `Omitir Notificación` significa que no se le notificará acerca de los correos electrónicos entrantes que pertenecen a la carpeta determinada. Al utilizar los Filtros de Correo Electrónico es posible colocar los correos electrónicos en carpetas automáticamente según criterios específicos.
-
-## Filtros de Correo Electrónico
-
-El administrador puede crear filtros de correo electrónico globales para omitir correos electrónicos no deseados. Están disponibles en Administración > Filtros de correo electrónico.
-
-El usuario habitual puede crear filtros de correo electrónico para sus Cuentas de Correo Electrónico Personales o para su bandeja de entrada completa. Están disponibles en Correos Electrónicos > menú desplegable en la esquina superior derecha > Filtros.
-
-Hay dos tipos de filtros:
-* Omitir - el correo electrónico se colocará en *Papelera* o no se importará si el filtro está relacionado con la Cuenta de Correo Electrónico Personal;
-* Poner en carpeta - los correos electrónicos importados se colocarán automáticamente en la carpeta de usuario especificada.
-
-## Plantillas de Correo Electrónico
-
-Las plantillas de Correo Electrónico están disponibles en Correo Electrónico > menú desplegable en la esquina superior derecha > Plantillas de Correo Electrónico. Se pueden usar tanto para envíos masivos de correos electrónicos como para correos electrónicos regulares. La casilla de verificación `One-off` significa que la plantilla de correo electrónico se utilizará solo una vez, lo que es habitual para el marketing por correo electrónico.
-
-Es posible usar colocadores de carpeta en el cuerpo de la plantilla del correo electrónico y el sujeto por ejemplo. {Account.name}, {Person.emailAddress}. Serán reemplazados por valores de registros relacionados.
-
-Puede utilizar colocadores de carpetas reservados adicionales en el cuerpo de la plantilla: {optOutUrl} y {optOutLink}.
-```
-Cancelar subscripción
-```
-
-Este es un enlace para cancelar la suscripción al correo electrónico masivo.
diff --git a/i18n/es_ES/user-guide/markdown.md b/i18n/es_ES/user-guide/markdown.md
deleted file mode 100644
index 56af05c31..000000000
--- a/i18n/es_ES/user-guide/markdown.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# Sintaxis de Markdown
-
-Los campos de texto admiten la sintaxis de markdown.
-
-## Código
-```
-`algún texto`
-```
-
-`algún texto`
-
-## Código Multilineal
-
-```
-``` algún texto ```
-```
-
-```
-algún texto
-```
-
-## Texto Remarcado
-
-```
-**algún texto**
-```
-
-**algún texto**
-
-## Texto Enfatizado
-
-```
-*algún texto*
-```
-
-*algún texto*
-
-## Texto Borrado
-
-```
-~~algún texto~~
-```
-
-~~algún texto~~
-
-## Bloque de Citas
-
-```
-> algún
-> texto
-```
-
-> algún
-> texto
-
-## Enlace
-
-```
-[texto de enlance](https://www.espocrm.com)
-```
-[texto de enlace](https://www.espocrm.com)
-
-## Lista Ordenada
-
-```
-1. Algún item
-2. Otro item
-```
-
-1. Algún item
-2. Otro item
-
-## Lista Sin Orden
-
-```
-* Algún item
-* Otro item
-```
-
-* Algún item
-* Otro item
-
-## Linea Horizontal
-
-```
-___
-```
diff --git a/i18n/es_ES/user-guide/mass-email.md b/i18n/es_ES/user-guide/mass-email.md
deleted file mode 100644
index 7f53eb70a..000000000
--- a/i18n/es_ES/user-guide/mass-email.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Correo Electrónico Masivo
-
-## Cómo enviar correos masivos
-
-Necesita tener al menos una Lista de Objetivos con registros de objetivos y una Plantilla de Correo Electrónico en su crm.
-
-1. Crea una nueva campaña con un estado `Correo electrónico` u `Hoja Informativa`. Seleccione una o algunas listas de objetivos en el campo `Listas de Objetivos`.
-2. Después de que el registro de campaña es creado, cree un Correo Electrónico Masivo para esta campaña: haga clic en más en el panel de Correo Electrónico Masivo. Especifique _Fecha Inicio_ - cuando se deben enviar correos electrónicos, y seleccione _Plantilla de Correo Electrónico_. Asegúrate de que _Estado_ esté configurado como `Pendiente`.
-
-Si todo está configurado correctamente, los correos electrónicos deberían apagarse. Deberían enviarse cada hora con porciones (puede cambiar el tamaño de la porción en Administración > Correos Electrónicos Salientes). El administrador puede cambiarlo actualizando el campo `Programación` de la tarea programada `Verificar Cuentas de Correo Electrónico Grupales`.
-
-Puede verificar si los correos electrónicos se envían en el panel de registro.
-
-## Prueba lo que se enviará a los destinatarios
-
-Haga clic en el menú desplegable de la derecha en la fila de correo electrónico masivo en el panel _Correo Electrónico Masivo_ y luego haga clic en _Enviar prueba_.
-
-## Iniciar Sesión
-
-En el registro puedes ver:
-* Email enviado;
-* Correos electrónicos abiertos por el destinatario;
-* Enlaces clickeados por el destinatario;
-* Destinatarios que optaron por salir;
-* Mensajes de correo electrónico devueltos (no entregados al destinatario).
-
-## Enlace de exclusión
-
-De manera predeterminada, el sistema agregará la opción de exclusión voluntaria a todos los correos electrónicos enviados. Pero puede usar uno personalizado en su Plantilla de Correo Electrónico.
-
-Ejemplo:
-```html
-Cancelar la suscripción a la lista de correo.
-```
-
-El administrador puede inhabilitar el enlace de exclusión voluntaria que el sistema agrega en Administración > Correos Electrónicos Salientes.
-
-## URL de Rastreo
-
-Si desea saber que su destinatario abrió el enlace desde su correo electrónico, debe crear la URL de seguimiento. Especifique cualquier _Nombre_ y _URL_ a dónde debería conducir su enlace. Luego, deberá pegar el código generado en su Plantilla de Correo Electrónico.
-
-Ejemplo:
- ```html
-Pruebe nuestra demostración
- ```
-
-## Listas de Objetivos
-
-Las Listas de Objetivos contienen las listas de Cuentas, Contactos, Clientes Potenciales y Registros de Usuarios.
-
-Los usuarios pueden completar manualmente las listas de objetivos usando la acción _Seleccionar_ en el panel correspondiente en la vista detallada de la Lista de Objetivos. Existe la habilidad de filtrar y luego seleccionar todos los resultados de la búsqueda.
-
-## Poblar Listas de objetivos con Informes
-
-La función [Reportes](reports.md#sincronización-con-listas-de-objetivos) proporciona la capacidad de rellenar listas de objetivos con registros que coincidan con criterios específicos.
-
-## Excluir Listas de Objetivos
-
-Especifique la Exclusión de Listas de Objetivos para evitar el envío masivo de correos electrónicos a ciertos destinatarios. Si hay un registro con la dirección de correo electrónico que coincida con la dirección de correo electrónico de cualquier registro excluido, también se excluirá el primer registro.
-
-## Registro de Campaña
-
-En el Registro de Campaña puede ver los correos electrónicos que se han enviado, los correos electrónicos abiertos, los correos electrónicos devueltos, los que se han excluido y quienes han hecho clic en el enlace del correo electrónico. Es posible utilizar este registro creando Lista de Objetivos (menú desplegable en la esquina superior derecha del panel) según los archivos del registro. Por ejemplo, selecciona solo los contactos que hicieron clic en el enlace (URL de rastreo).
-
-## Solución de Problemas
-
-_Para los Administradores_
-
-#### ¿Qué hacer si no se envían correos electrónicos?
-
-1. Compruebe si funciona _Envío de Pruebba_. Si no funciona, verifique si la configuración SMTP del sistema es correcta.
-2. Compruebe si tiene configurado cron para su sistema.
-3. Verifique si tiene el Trabajo Programado `Enviar correos electrónicos masivos` y está `Activo` (Administración > Trabajos Programados > Enviar Correos Electrónicos Masivos). Verifica si hay algo en el Registro.
-
-#### ¿Qué pasa si la URL de Rastreo tiene una URL incorrecta que no conduce a su crm?
-
-Compruebe el parámetro 'siteUrl' en el archivo `data/config.php`. Debe establecerse como URL de su EspoCRM accesible desde el mundo externo.
-
-#### Los correos electrónicos devueltos no se registran
-
-Los correos electrónicos devueltos solo pueden ser manejados por una cuenta de correo electrónico grupal. Asegúrese de tener una cuenta de correo electrónico grupal que supervise los correos electrónicos devueltos del buzón a los que se envía.
-
-Además algunos proveedores de servidores de correo pueden desviarse de los estándares, por lo que no se pueden distinguir los correos electrónicos devueltos.
diff --git a/i18n/es_ES/user-guide/quotes.md b/i18n/es_ES/user-guide/quotes.md
deleted file mode 100644
index 596b368da..000000000
--- a/i18n/es_ES/user-guide/quotes.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Cotizaciones
-
-La función de Cotizaciones está disponible en [Paquete avanzado](https://www.espocrm.com/extensions/advanced-pack/).
-
-Las cotizaciones son un grupo específico de productos o servicios con sus cantidades y precios que usted cotiza a los clientes.
-
-La cotización tienen una relación con Oportunidad. Puede agregar el panel Cotizaciones a la vista detallada de Oportunidad en Administración > Administrador de Diseño > Oportunidades > Relaciones. Al crear una nueva cotización vinculada a una oportunidad, transfiere artículos de oportunidad a la cotización.
-
-Puede agregar el panel Cotizaciones a la vista detallada de la cuenta para poder ver las cotizaciones relacionadas. Puede hacerlo en Administración > Administrador de Diseño > Cuentas > Relaciones.
-
-## Cotización de Artículos
-
-La cotización tiene una lista de artículos. Cada artículo puede representar un determinado producto o servicio con campos de descripción, cantidad, tasa de impuesto, precio de lista y precio unitario. Es posible ordenar los artículos manualmente.
-
-Existe la posibilidad de agregar campos personalizados para la entidad Cotizar Artículo usando Gerente de la Entidad.
-
-## Plantillas
-
-Por defecto hay dos plantillas disponibles: Cotización y Factura. Puede crear nuevas plantillas (vista por lista de Cotizaciones > menú desplegable en la parte superior derecha > Plantillas) así como también editar las existentes.
-
-Para una edición más precisa, se recomienda usar el modo de Visualización de Código.
-
-Puede imprimir los campos del registro de Cotizaciones, así como los campos de los registros relacionados mediante el uso de contenedores de posición en su plantilla.
-
-Ejemplos:
-
-`{{accountName}}` – Nombre de la cuenta,
-
-`{{{billingAddressStreet}}}` – calle,
-
-`{{account.type}}` – tipo de Cuenta relacionada,
-
-`{{assignedUser.lastName}}` – apellido del usuario asignado.
-
-Si su elemento en línea es un producto, puede imprimir los campos del producto.
-
-
-Ejemplos:
-
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-La longitud y el color son campos personalizados de la entidad Producto en ejemplos.
-
-Haciendo loop a través de artículos de cotización:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-Es posible imprimir campos de imagen:
-
-```
-
-```
-donde `imageId` - el nombre del campo de imagen personalizado en la entidad de Cotización concatenada con el sufijo `Id`.
-
-Para la línea de productos:
-```
-
-```
-
-Para mostrar números flotantes (como cantidad, precio unitario, etc.) sin partes fraccionarias (como número entero), use las siguientes expresiones (desde la versión 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Formateo personalizado para valores de moneda (desde la versión 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-El valor `10000.5` se imprimirá como `10 000,50`.
-
-Para mostrar campos de texto (líneas múltiples) use llaves triples: `{{{description}}}`.
-
-## Imprimir en PDF
-
-Las cotizaciones se pueden imprimir en PDF. Esta acción está disponible en el menú desplegable al lado del botón Editar en la vista detallada de la cotización. Luego se le pedirá que seleccione Plantilla.
-
-## Cotización de Correo Electrónico
-
-El PDF de la cotización se puede enviar por correo electrónico como archivo adjunto. Abra el registro de cotización, haga clic en el menú desplegable al lado del botón Editar y luego haga clic en Correo Electrónico PDF.
-
-## Numeración Automática
-
-Puede crear un campo Número a través del Administrador de Entidades para el tipo de entidad Cotización. Administración > Administrador de Entidades > Cotizar > Campos > Agregar Campo > Número. Luego debe colocarlo en la vista de detalles usando el Administrador de Diseños.
-
-El valor se incrementará con cada nueva cotización. Existe la posibilidad de especificar el siguiente número y el prefijo.
-
-## Impuesto Predeterminado
-
-Disponible desde EspoCRM 4.8.0.
-
-1. Especifique el registro de Impuestos predeterminado en Administración > Administrador de Entidades > Cotizaciones > Campos > Impuestos > Predeterminado.
- 2. Especifique la tasa de impuesto predeterminada en Administración > Administrador Entidades > Cotizaciones > Campos > Tasa de Impuestos > Predeterminado.
-
-## Facturas
-
-La cotización puede tratarse como una factura si su estado se convierte en `Aprobado`. Luego aparecen los campos _Fecha Facturada_, _Número de Factura_. Puede usar diferentes plantillas para facturas para impresión.
diff --git a/i18n/es_ES/user-guide/reports.md b/i18n/es_ES/user-guide/reports.md
deleted file mode 100644
index dbe85aa81..000000000
--- a/i18n/es_ES/user-guide/reports.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Informes
-
-La función Informes está disponible en [Paquete avanzado](https://www.espocrm.com/extensions/advanced-pack/).
-
-Hay dos tipos de informes: Lista y Cuadrícula.
-
-## Informes de Lista
-
-Enumere los resultados del informe en la lista de registros que cumplen los criterios especificados.
-
-Para crear un nuevo informe de lista, haga clic en la pestaña Informes y luego haga clic en el botón Crear Informe. Elija el tipo de Entidad necesaria y luego haga clic en el botón Crear en la sección Informe de Lista.
-
-En el campo _Columnas_, seleccione los campos que le gustaría que se muestren. A continuación puede especificar los parámetros de visualización para cada columna, p.e. ancho y alinear.
-
-Elija la clasificación necesaria en el campo de _Orden de Lista_.
-
-En la sección _Filtros_, puede especificar criterios que determinen qué registros se enumerarán en su informe. Puede usar los operadores lógicos 'OR' y 'AND' aquí.
-
-Los _Filtros de Tiempo de Ejecución_ le permiten especificar diferentes filtros antes de ejecutar el informe.
-
-Puede __exportar__ los resultados del informe de lista a los formatos excel y csv.
-
-## Informes de Cuadrícula
-
-La cuadrícula informa los valores resumidos agrupados por campos especificados. Estos informes se pueden mostrar como un gráfico.
-
-
-
-Para crear un nuevo informe de cuadrícula, haga clic en la pestaña Informes y luego haga clic en el botón Crear Informe. Elija el Tipo de Entidad necesario y luego haga clic en el botón Crear en la sección Informe de Cuadrícula.
-
-En el campo _Grupo Por_ elija uno o dos campos para los que desea agrupar los datos de su informe. Es posible agrupar por año, mes, día para los campos de fecha. Si agrupa por dos campos, su informe se considerará tridimensional.
-
-En el campo _Columnas_, seleccione una o más funciones agregadas, como COUNT, SUM (suma), MIN, MAX, AVG (promedio).
-
-El campo _Ordenar Por_ define cómo se ordenarán los datos del informe.
-
-En la sección _Filtros_, puede especificar los criterios que determinan qué registros se usarán en su informe. Puede usar los operadores lógicos 'OR' y 'AND' aquí.
-
-Los _Filtros de Tiempo de Ejecución_ le permiten especificar diferentes filtros antes de ejecutar el informe.
-
-El informe de cuadrícula permite mostrar resultados en forma de gráfico. Existen los siguientes _tipos de cuadros_: Barra (Horizontal), Barra (Vertical), Pie, Línea.
-
-Es posible __exportar__ los resultados del informe de cuadrícula a los formatos excel y csv.
-
-## Filtros
-
-### Filtro de Campo
-
-Es simple usar tipos de filtros. También puede elegir los campos de la entidad objetivo, así como las entidades relacionadas.
-
-
-
-
-### Grupo OR
-
-OR significa que se debe cumplir al menos una condición del grupo.
-
-
-
-### Grupo AND
-
-AND significa que se deben cumplir todas las condiciones del grupo.
-
-### Grupo NOT
-
-Ofrece la capacidad de filtrar registros que no cumplen los criterios especificados. P.ej. listar cuentas que no tienen ninguna oportunidad con los estados Cerrado Ganado o Cerrado Perdido.
-
-
-
-### Expresión Compleja
-
-Para un uso más avanzado. Puede aplicar la función para cierta columna de base de datos y compararla con el resultado de la expresión [fórmula](../administration/formula.md).
-
-Nota: si necesita comparar solo con un valor de cadena simple, debe ponerlo entre comillas simples `'alguna cadena'`.
-
-Nota: Las funciones destinadas a interactuar con el registro de entidad no funcionarán aquí porque la fórmula no se aplica al registro específico.
-
-
-
-## Mostrando en el Tablero
-
-Puede mostrar cualquier informe en el tablero. Para esto, necesita añadir un Informe de dashlet y luego elegir el informe necesario en las opciones del dashlet.
-
-## Envío de Correo Electrónico
-
-Es posible hacer que el sistema envíe los resultados de los informes a ciertos usuarios de manera regular en el tiempo especificado. Esto debe configurarse para ciertos informes individualmente.
-
-## Sincronización con Listas de Objetivos
-
-Es posible tener listas de objetivos sincronizadas con resultados de informes de listas. Es conveniente para el correo electrónico masivo cuando desea enviar correos electrónicos solo a contactos que cumplen con algunos criterios al momento del envío. Esta función está disponible en la vista de detalles de cualquier lista de objetivos en el panel 'Sincronización con Informes'.
diff --git a/i18n/es_ES/user-guide/stream.md b/i18n/es_ES/user-guide/stream.md
deleted file mode 100644
index 933bbac26..000000000
--- a/i18n/es_ES/user-guide/stream.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Transmisión
-
-La Transmisión en EspoCRM es un feed donde puedes ver actualizaciones y nuevas adiciones para los registros que sigues. También puede publicar en una transmisión propia y transmitir otros usuarios (desde la versión 3.8.0). Hay dos tipos de transmisión en EspoCRM: secuencia de grabación y secuencia de usuario.
-
-Por defecto las siguientes entidades tienen una transmisión: Cuentas, Contactos, Clientes potenciales, Oportunidades, Casos. Los administradores pueden habilitar o deshabilitar la transmisión de una entidad determinada en [Gerente de la Entidad](../administration/entity-manager.md).
-
-## Registrar la Transmisión
-
-Registrar la Transmisión se muestra en un panel de Transmisión de un cierto registro en la vista de detalles. Las publicaciones, actualizaciones y nuevas adiciones relacionadas con el registro actual se muestran aquí.
-
-## Transmisión de Usuario
-
-Los usuarios pueden ver su transmisión en el dashlet de Transmisión y en la pestaña de Transmisión. Los usuarios también pueden ver el flujo de otros usuarios en la vista de detalles del usuario, si tienen un acceso que está controlado por el campo de roles `Permiso del Usuario`.
-
-En la transmisión de usuario puede ver publicaciones, actualizaciones y nuevas adiciones relacionadas con los registros que sigue el usuario. También puede ver las publicaciones dirigidas al usuario. Esas publicaciones no están relacionadas con ningún registro.
-
-## Notificaciones
-
-Recibirá notificaciones sobre nuevas adiciones a su transmisión que fueron causadas por otros usuarios.
-
-## Publicaciones
-
-Puede crear publicaciones relacionadas con un determinado registro. También puede adjuntar múltiples archivos e imágenes a su publicación. Si quiere mencionar a alguien en su publicación, solo tiene que escribir el símbolo `@` y comenzar a escribir el nombre del usuario. El usuario que ha mencionado en su publicación recibirá una notificación al respecto.
-
-## Publicaciones a los usuarios
-
-_Esta función está disponible desde la versión 3.8.0._
-
-Los usuarios pueden crear publicaciones para ciertos usuarios, para ciertos equipos, para todos los usuarios y para sí mismos. Un acceso para esta habilidad está controlado por el campo `Permiso de Asignación` de Roles.
-
-## Filtrado
-
-Puede filtrar qué mostrar en una transmisión: `Todo`, `Publicaciones` o `Actualizaciones`.
diff --git a/i18n/fr_FR/administration/b2c.md b/i18n/fr_FR/administration/b2c.md
deleted file mode 100644
index 287921b84..000000000
--- a/i18n/fr_FR/administration/b2c.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# La Configuration d'EspoCRM pour B2C (Business-to-Client)
-
-Par défaut, EspoCRM est conçu pour utiliser pour B2B business. Mais vous pouvez facilement l’installer pour B2C.
-
-Veuillez Changer b2cMode en vrai dans votre fichier de configuration data / config.php. Depuis la version 4.3.0, il se peut être configuré dans Administration > paramètres. Supprimez l'onglet Compte du menu de navigation (Administration > Interface utilisateur).
-
- Supprimez les champs du compte de vos mises en page (Administation > Gestionnaire de mise en page). Désactivez un accès à l'étendue du compte pour tous vos rôles (Administration > Rôles). Supprimez le compte, des listes de sélection de tous les champs parents (Administration > Gestionnaire d'entités > {Réunion / Appel / Tâche / E-mail}> Champs> Parent
diff --git a/i18n/fr_FR/administration/entity-manager.md b/i18n/fr_FR/administration/entity-manager.md
deleted file mode 100644
index b8ef73eaa..000000000
--- a/i18n/fr_FR/administration/entity-manager.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Manageur d'Entité
-
-Le Manageur d'Entité est disponible dans le panneau de configuration Administratif. Il donne la possibilité de modifier votre instance d'EspoCRM. Vous pouvez ainsi accomplir les actions suivantes :
-
-* Ajouter de nouveaux types d'entités;
-
-* Customiser les types d'entités existantes: Changer les dénominations, l'ordre par défaut dans la vue liste, activer ou désactiver un courant.
-
-* Configurer les champs : Ajouter de nouveaux champs, customiser les champs existants.
-
-* Configurer les relations : Ajouter de nouvelles relations, changer les dénominations des relations existantes.
-
-
-## Création De Nouvelles Entités
-
-Cliquez sur le bouton 'Créer une Entité' ou `Create Entity` sur la page du Manageur d'Entité. Spécifiez le nom, les dénominations et le type. Si le type d'entité que vous choisissez est 'Personne' ou 'Person', votre entité aura des champs pour un Email, Téléphone, Prénom, Nom de Famille et Salutation. Cochez 'Courant' ou 'Stream' si vous voulez que votre entité ait un panneau de configuration courant et si vous voulez que les utilisateurs puissent suivre les entités de ce type.
-
-
-Types :
-
-* Base - Entité vide ayant seulement des champs basic comme Nom, Utilisateur Assigné, Equipes, Description.
-
-* Base Plus - Similaire au type Base mais avec les champs Activités, Historique, panneaux de Taches (disponible depuis la version 4.3.0).
-
-* Evènement - Champs pour Date de Début, Date de Fin, Durée, Parent et Statut. Disponible en Calendrier et dans le panneau des Activités (depuis la version 4.3.0, doit être activée avec Administration > Réglages)
-
-* Personne - Champs pour Email, Prénom, Nom de Famille, Salutation, et Adresse. Panneau pour les Activités, l'Historique, et les Taches.
-
-* Compagnie - Champs pour l'Email, le Téléphone, l'Adresse de Facturation, Adresse de Livraison. Panneaux pour les Activités, l'Historique, et les Taches.
-
-
-## Mettre À Jour Une Entité Existante
-
-Si vous cliquez sur le lien 'Modifié' ou 'Edit' sur une entité particulière, vous aurez la possibilité de changer certains des paramètres de cette entités.
-
-* Dénominations - Nom de l'entité au singulier ou au pluriel.
-
-* Les données de l'ordre par défaut sont organisées dans la vue liste.
-
-* Courant ou Stream - Indique si le Courant ou Stream est actif pour cette entité.
-
-* Désactivé - Vérifie si vous n'avez pas besoin de cette entité dans votre système.
-
-* Champs de Filtrage Textuel - Dans quels champs la recherche doit être effectuée pour le filtre textuel principal et la recherche globale.
-
-
-## Champs
-
-Cliquer sur le lien 'Champs' ou 'Fields' vous emmènera à une page différente. Sur cette page, vous aurez la possibilité de créer de nouveaux champs ou de mettre à jour des champs existants. Les types de champs suivants sont disponibles dans le Manageur d'Entité.
-
-* Adresse - adresse incluant la rue, la ville, l'état, le code postale et le pays ;
-
-* Série - Liste de valeurs, avec capacité de sélectionner multiples valeurs (pas une bonne option si vous avez besoin de faire une recherche basée sur ce champ) ; les utilisateurs peuvent ajouter leurs propres valeurs s'il n'y a pas d'option spécifiées.
-
-* Attachement Multiples - attachement de fichiers multiples;
-
-* Auto-increment ou Incrément -Automatiques - ne fait la lecture que de nombres générés;
-
-* Boolean ou Booléen - case à cocher, vrai ou faux;
-
-* Monnaie - pour les valeur monétaires;
-
-* Date;
-
-* DateTime;
-
-* Enum - case à sélectionner, avec la possibilité de ne sélectionner qu'une seule valeur;
-
-* File ou Fichier - Mise en ligne d'un fichier;
-
-* Float ou Nombre Flottant - nombre ayant une portion décimale;
-
-* Foreign ou Etranger - Un champ d'une entité reliée;
-
-* Image - Mise en ligne d'une image avec un aperçu de l'image;
-
-* Integer ou Nombre Entier - nombre entier;
-
-* Nombre - incrémentation automatique du nombre du type de série avec un préfixe possible et d'une longueur spécifique;
-
-* Multi-enum - Liste de valeur, avec la capacité de choisir de multiples valeurs (pas une bonne option si vous devez faire une recherche basée sur ce champ), similaire a la Série mais en plus joli.
-
-* Text ou Texte - section texte, pour des textes longs de plusieurs lignes ;
-
-* Url - pour les liens;
-
-* Varchar - texte court;
-
-* Wysiwyg - Similaire au champ de texte, avec la possibilité de formater le texte;
-
-
-Paramètres:
-
-* Requis - si le remplissage du champ est obligatoire.
-
-* Valeur Par Défaut - La valeur du champ établie lors de la création de la donnée.
-
-* Audité - les mises à jour du champ seront enregistrées dans le Courant ou Stream.
-
-**Remarque**: Après avoir ajouté un nouveau champ, vous devez mettre ce champ sur les plans ou [layouts](layout-manager.md) (Administration > Layout Manager ou Manageur des Plans)
-
-
-### Logique Dynamique
-
-Donne la possibilité de rendre les formulaires dynamiques. Il est possible de définir des conditions rendant certains champ visibles, requis, ou en lecture simple. Les conditions seront vérifiées automatiquement lorsque l'information dans le formulaire est modifiée.
-
-Pour Enum, la Série, et les champs Multi-Enum, il est possible de définir différentes collections d'options qui seront disponibles en fonction de la condition remplie. Obtenez plus d'informations [ici](dynamic-logic.md).
-
-
-## Relations
-
-Vous pouvez créer de nouvelles relations entre les entités out-of-box et les entités customisées. Il y a 3 types de relations disponibles:
-
-* One-to-Many ou Un-à-Plusieurs: après avoir créé cette relation, vous pouvez mettre un champ lien au plan détaillé de l'entité de droite et ajouter un panneau de relation à l'entité de gauche;
-
-* Many-to-One ou Plusieurs-à-Un: le même que celui du Un-à-Plusieurs mais en vice versa;
-
-* Many-to-Many ou Plusieurs-à-Plusieurs: panneaux de relations sur les deux côtés.
-
-Le paramètre 'Link Multiple Field' indique qu'un champ de type 'LinkMultiple' sera créé de même qu'une relation. Vous pouvez ajouter ce type de champ au plan. Il rend plus aisée le choix rapide de données reliées. Ceci n'est pas une bonne option si votre relation est sensée contenir une multitude de données qui peuvent ralentir le chargement de la vue détaillée de l'écran.
-
-Si le paramètre 'Audité' ou 'Audited' est coché, les mises à jours de la relation seront enregistrées dans le Courant ou Stream.
diff --git a/i18n/fr_FR/administration/workflows.md b/i18n/fr_FR/administration/workflows.md
deleted file mode 100644
index 1ff51ef33..000000000
--- a/i18n/fr_FR/administration/workflows.md
+++ /dev/null
@@ -1,177 +0,0 @@
-# Workflows
-
-La fonctionnalité Workflows est disponible dans l'[Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Les Workflows permettent aisément d'automatiser votre entreprise. Vous pouvez trouver cette fonction dans le panneau de configuration Administratif. La création d'une règle pour un workflow nécessitera de définir les éléments suivants:
-
-* Entité cible - A quel type d'entité le worklow doit être appliqué;
-
-* Type d'élément déclencheur - Quand est ce que le workflow devra être déclenchée;
-
-* Conditions - Conditions à remplir pour déclencher un workflow;
-
-* Actions - Que faire si un workflow est déclenché.
-
-
-## Types d'Eléments Déclencheurs
-
-### Apres Création d'une donnée
-
-Déclenché seulement après la création d'une donnée. Si les conditions spécifiées sont remplies, les actions seront exécutées.
-
-
-### Après la Sauvegarde d'une Donnée
-
-Déclenché lorsqu'une nouvelle donnée est créée ou lorsqu'une donnée existante est mise à jour. Si les conditions spécifiées sont remplies, les actions seront exécutées.
-
-Les règles de workflow ayant ce type d'élément déclencheur ont communément une condition qui vérifie si certains des champs ont été changées ou 'changed'. Exemple: Si le statut du Cas a changé, alors exécute certaines actions.
-
-
-### Programmé de Manière Temporelle
-
-Déclenché en fonction du programme temporel défini. Vous pouvez l'établir pour fonctionner chaque jour, chaque semaine, etc.. Les actions seront appliquées pour des données produites par le rapport d'une liste spécifiée. Par conséquent, vous devez aussi créer le rapport d'une liste.
-
-Le programme temporel est spécifié à partir d'une notation crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### Séquentielle
-
-Utilisée rarement. Supposée être lancée par un autre workflow. Donne la possibilité d'établir une logique complexe.
-
-Remarque: pour les workflow sequenciel, il est recommandee d'utiliser l'outil BPM ou [BPM tool](../../../docs/administration/bpm.md) plutôt que l'option workflow.
-
-
-## Conditions
-
-Vous pouvez spécifier les conditions qui doivent être remplies pour le déclenchement du workflow. Il y a deux manières de spécifier les conditions: avec le constructeur de condition sur Interface Utilisateur ou avec une formule.
-
-
-### Constructeur de Condition sur l'Interface Utilisateur
-
-Quelques types de condition disponibles:
-
-* _equals_ - le champ est égal a une valeur spécifique ou égal à la valeur d'un autre champ;
-
-* _was equal_ - le champ est égal a une valeur spécifique avant que le workflow n'ait été déclenché;
-
-* _not equals_ - le champ n'est pas égal a une valeur spécifique ou à la valeur d'un autre champ;
-
-* _was not equal_ - le champ n'était pas égal à une valeur spécifique avant que le workflow n'est été déclenché;
-
-* _empty_ - la valeur du champ est vide;
-
-* _not empty_ - la valeur du champ n'est pas vide;
-
-* _changed_ - le champ a été modifié;
-
-* _not changed_ - le champ n'a pas été modifié;
-
-
-### Conditions Basées sur une Formule
-
-L'utilisation d'une formule permet de définir des conditions de n'importe quelles complexités. Pour lire des informations sur la syntaxe d'une formule suivez [cet article](../../../docs/user-guide/reports.md).
-
-Remarque : Il ne doit y avoir aucune délimitation `;` employée dans le code de la formule lorsqu'elle détermine une condition.
-
-
-## Actions
-
-### Envoyer un Email
-
-Le système enverra un email en utilisant un message préconfiguré spécifié. L'adresse email du receveur peut être obtenue à partir des données de la cible, une donnée reliée, l'utilisateur actuel, ceux qui suivent l'utilisateur, équipe d'utilisateurs ou elle peut être spécifiée. Un message peut être envoyé immédiatement ou reportée à un intervalle spécifique.
-
-
-### Créer une Donnée
-
-Le système créera une nouvelle donnée de n'importe quelle entité. Il est possible de relier les données s'il existe une relation entre la donnée cible et la donnée créée.
-
-Il est possible de définir une formule pour le calcul des champs.
-
-
-### Créer une Donnée Reliée
-
-Le système créera une donnée reliée à la donne cible. Il est possible de définir une formule pour le calcul des champs.
-
-
-### Mise à Jour de la Donnée Cible
-
-Permet la modification de champs spécifiques de la donnée cible. Il est possible de définir une formule pour le calcul des champs.
-
-Si vous avez besoin d'ajouter de nouveau élément au champ Link-Multiple sans perdre des informations existantes (exemple: Equipes), vous devez utiliser une fonction formule entity\addLinkMultipleId. Exemple: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-
-### Mise à Jour de Données Reliées
-
-Permet la modification de champs spécifiques des données relies ou de données. Il est possible de définir une formule pour le calcul des champs.
-
-
-### Connection avec une Autre Donnée
-
-Relie ou connecte une entité cible avec une autre entité spécifique. Exemple: ajoute une équipe spécifique à la donnée.
-
-
-### Déconnection d'une Autre Donnée
-
-Retire le lien créé entre une entité cible et une entité spécifique. Exemple: retire une équipe spécifique de la donnée.
-
-
-### Applique la Règle Assignée
-
-Assigne la donnée cible a un utilisateur à partir d'une règle de distribution. Il y a deux règles disponibles : Round-Robin et Least-Busy
-
-* Round-Robin - les utilisateurs sont choisi du haut vers le bas d'une liste (équipe), le processus est ensuite répété.
-
-* Least-Busy - l'utilisateur ayant le moins de données assigne sera choisi pour l'assignation.
-
-_List Report_ - Détermine quelles sont les données à prendre en compte pour le calcul des données assignées pour la distribution Least-Busy. Exemple: Pour les Cas, seules les données ayant un statuts actif doivent être prises.
-
-
-### Créer une Notification
-
-Notifie d'un message des utilisateurs spécifiques. Il est possible d'utiliser des espaces réservés dans un message préconfigurée: {entity} - donnée cible, {user} - utilisateur présent.
-
-
-### Fait Suivre
-
-Emmène des utilisateurs spécifiques à suivre une entité cible ou une entité reliée spécifiée.
-
-
-### Déclenché un Autre Workflow
-
-Permet de créer des workflows séquentiels. Il est possible d'utiliser une conditions afin d'étendre le workflow: Vous pouvez établir le workflow de manière à déclencher deux autres workflows avec différentes conditions définie dans le workflow principal.
-
-Il est possible de reporter l'exécution d'un workflow séquentiel. À l'intérieur du workflow séquentiel, vous pouvez définir la condition qui vérifiera si des champs spécifiés ont été modifiés depuis l'enclenchement du workflow principale en utilisant les conditions de types _Changed_ and _Was Equal_.
-
-Remarque: Il est recommandé d'utiliser l'outil BPM ou [BPM tool](../../../docs/administration/bpm.md) pour les workflows séquentiels plutôt que l'option workflow.
-
-
-### Lancer l'Action Service
-
-Permet de lancer des scripts spécifiques de service. Les actions suivantes sont définies par défaut:
-
-* Envoyer des Invitations - pour Rendez-Vous/Appels;
-
-* Ajouter des éléments de Prix d'Offre - Pour les Prix d'Offres.
-
-Les développeurs peuvent écrire leurs propres actions de services. Obtenez [plus de détails](../../../docs/development/workflow-service-actions.md).
-
-
-## Emploi d'une Formule dans les Actions
-
-Il est possible de définir une formule pour calculer les champs pour la Création d'une Donnée, la Mise A Jour D'une Donnée Cible, la Création D'une Donnée Reliée, La Mise A Jour D'une Donnée Reliée. En ce qui concerne les deux dernières, vous devez utiliser la fonction `targetEntity\attribute` pour accéder aux attribues de l'entité cible qui a été établie avant que le déclenchement du workflow.
-
-Exemple:
-
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/fr_FR/user-guide/emails.md b/i18n/fr_FR/user-guide/emails.md
deleted file mode 100644
index 29affd582..000000000
--- a/i18n/fr_FR/user-guide/emails.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Recommandations Pour L'Utilisation Des Emails
-
-EspoCRM permet de quérir les emails placées dans la boite de réception IMAP. Cet atout permet à EspoCRM d'être utilisé comme un client de messagerie qui possède aussi des fonctionnalités spécifiques pour la gestion des relations avec la clientèle.
-
-## Comptes IMAP
-
-*Remarque : Afin d'assurer le bon fonctionnement de la réception d'emails, vous avez besoin d'avoir [cron](../../../docs/administration/server-configuration.md#setting-up-crontab) configuré correctement dans votre système.*
-
-L'utilisateur peut établir le compte IMAP sur la page des Comptes Emails Personnels (section Messages > menu en haut à droite > Comptes de Messages Personnels).
-
-Vous pouvez spécifier quels sont les dossiers à surveiller avec le champ Dossiers Surveillés. De manière générale, ce réglage est défini pour la boite de réception INBOX. Si vous utilisez des clients de messagerie externes pour envoyer des emails, vous pouvez ajouter le dossier des Messages Envoyés pour archiver ces messages.
-
-*Fetch Since* vous permet de choisir la date à partir de laquelle les messages doivent être archivés. Si vous avez besoin d'archiver des messages passés, choisissez une date antérieure à celle d'aujourd'hui.
-
-Vous pouvez spécifier un dossier ou *Folder* dans votre Compte Email Personnel. Les messages entrants seront placés dans ce dossier.
-
-## Comptes SMTP
-
-Les utilisateurs peuvent établir les paramètres SMTP dans leurs Préférences, de même que dans leurs Comptes de Messages Personnels. L'administrateur peut aussi permettre l'utilisation du système SMTP (en le rendant Partagé).
-
-Les utilisateurs ont la possibilité d'avoir plusieurs comptes SMTP (depuis la version 4.2.0). Ceci étant, les adresses emails que l'utilisateur peut utiliser pour l'envoi de messages sont définies dans les adresses emails attachées aux données de l'utilisateur, *User*.
-
-## Travailler avec des Emails
-
-Cron (application fonctionnant à l'arrière-plan) cherche les messages périodiquement après l'écoulement d'un certain nombre de minutes (cette durée peut être spécifiée par l'Administrateur).
-
-Vous pouvez voir tous vos messages dans la section Messages. Cette section contient les dossiers Boite de Réception, Messages Envoyés, et Messages Brouillons sur le côté gauche.
-
-Vous avez le champ *Status*. `Sent` signifie que le message a été envoyé à partir du CRM, `Archived` – message obtenue à partir du compte IMAP ou archivés manuellement, `Draft` – veut dire que cet email a été créé comme brouillon.
-
-Lorsqu'un message arrive, le système tente de reconnaitre les données qui corresponde à ce message. Il peut lier ce message avec le Compte, Lead, Opportunité, Cas (et Contact en mode B2C) etc. Si aucune reconnaissance n'est établie, l'utilisateur peut créer un lien manuellement en remplissant le champ *Parent*.
-
-Si un email est reçu d'un client potentiel, l'utilisateur peut le convertir en lead avec **convert it to Lead**. Ouvrez l'entrée Email et Cliquez sur Créer Un Lead dans le menu en haut à droite.
-
-Il est aussi possible de créer une tache ou un cas, **create Task or Case** à partir d'une donnée email.
-
-Si les adresses emails (de, a, cc) dans les données d'un email sont connus par le système, il montrera la personne à qui ces données sont liées (Contact, Lead, Utilisateur etc). Si une adresse email est nouvelle, vous pouvez créer un contact, **create contact** à cette étape.
-
-Tous les emails reliés à une donnée spécifique sont présentés dans le panneau de configuration de l'Historique de cette donnée. Si une adresse email par exemple est reliée à une opportunité alors que cette opportunité est aussi reliée à ce compte, la donnée sera montrée pour l'opportunité et le compte.
-
-## Envoi De Messages
-
-Vous pouvez composer des messages de plusieurs manières :
-
-* Bouton *Compose Email* dans la vue liste de Messages ;
-
-* en répondant à un autre message ;
-
-* en cliquant sur une adresse email attachée à certaines données ;
-
-* avec l'action *Compose Email* du panneau d'Activités.
-
-Vous avez la possibilité de choisir un message préconfiguré **select template** pour votre message.
-
-Vous pouvez mettre en place une signature pour vos messages **email signature** dans les Préférences.
-
-## Dossiers Emails
-
-Les utilisateurs peuvent créer leurs propres dossiers de messages pour y insérer des emails pour plus de commodité. La liste des dossier disponibles est accessible sur la page Messages à gauche. Dans le but de créer, éditer des dossiers veuillez suivre Messages > menu dépliant en haut à gauche > Dossiers. `Skip Notification` signifie que vous ne voulez pas recevoir de notification pour les messages entrant qui sont automatiquement placés dans un dossier spécifique. L'utilisation des Filtres de Messages permet de ranger automatiquement des emails dans des dossiers spécifiques en fonction de certains critères.
-
-## Filtres de Messages
-
-L'administrateur peut créer des filtres de messages ayant applicables globalement sur le système pour omettre des messages non désirés. Ces filtres sont disponibles dans Administration > Filtres de Messages.
-
-Un utilisateur peut généralement créer des filtres de messages pour son Compte Email Personnel. Ces filtres sont accessibles à Messages > menu dépliant en haut dans le coin droit > Filtres.
-
-Il y a deux types de filtres :
-
-* Ignorer - le message sera mis dans la corbeille *Trash* ou ne sera pas importé si le filtre est lié à un Compte Email Personnel ;
-
-* Insérer Dans Un Dossier - les messages importés seront automatiquement placés dans un dossier spécifié de l'utilisateur.
-
-## Messages Préconfigurés
-
-Les messages préconfigurés sont disponibles à Messages > menu dépliant dans le coin droit en haut > Messages Préconfigurés. Ils peuvent être utilisés pour l'envoi de messages en masse ou pour l'envoi de messages classiques. La case à cocher `One-off` veut dire que le message préconfiguré ne devra être utilisé qu'une fois, ce qui est la norme dans le domaine de la promotion par emails.
-
-Il est possible d'instaurer des espaces réservés à l'intérieur du texte d'un messages préconfiguré et dans le sujet du messages - exemple : {Account.name}, {Person.emailAddress}. Ces espaces réservés seront remplacés avec les valeurs des données reliées.
-
-Vous pouvez utiliser des espaces réservés additionnels dans le texte du message: {optOutUrl} et {optOutLink}.
-
-```
-Unsubscribe
-```
-
-Ceci est le lien de désinscription pour l'envoi de messages en masse.
diff --git a/i18n/fr_FR/user-guide/mass-email.md b/i18n/fr_FR/user-guide/mass-email.md
deleted file mode 100644
index dd5d5323c..000000000
--- a/i18n/fr_FR/user-guide/mass-email.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Envoi d'Emails En Masse
-
-## Comment envoyer des emails en masse
-
-Vous avez besoin d'avoir au moins une liste cible avec des informations cibles et un message préconfiguré dans votre crm.
-
-1. Créez une nouvelle Campagne avec le statut `Email` ou `Newsletter`. Sélectionnez une ou plusieurs listes cibles dans le champ de sélection `Target Lists`.
-
-2. Apres la création des informations de la Campagne, créez Mass Email pour cette campagne: Cliquez plus dans le panneau de Configuration Mass Email. Spécifiez une date de début avec _Date Start_ - pour définir la date d'envoi des emails, sélectionnez _Email Template_. Vérifiez que _Status_ est marqué `Pending`.
-
-Si tout est mis en place correctement, les messages devraient être envoyés automatiquement. Ils devront être envoyés en portion et à chaque heure (vous pouvez changer la taille des portions dans Administration > Outbound Emails). L'administrateur peut le changer en mettant à jour le champ `Scheduling` à l'intérieur des taches paramétrées `Check Group Email Accounts`.
-
-Vous pouvez vérifier l'envoi des emails à travers le panneau de configuration Log.
-
-## Tester ce qui va être envoyer aux destinataires
-
-Cliquez sur le menu déroulant à la droite du panneau de configuration de la rangée pour l'envoi d'emails en masse _Mass Email_. Ensuite cliquez sur _Send Test_.
-
-## Log
-
-Dans le log vous pouvez voir:
-
-* L'email envoyé;
-
-* Les emails ouverts par le destinataire;
-
-* Les lien cliqués par le destinataires;
-
-* Les destinataires qui se sont désinscrits;
-
-* Les emails retournés (non délivrés au destinataire).
-
-## Lien de désinscription (Opt-out)
-
-De manière générale, la possibilité de se désinscrire sera inclue dans tous les emails envoyés. Mais vous pouvez formuler cette possibilité de se désinscrire à votre façon.
-
-Exemple:
-
-```html
-
-Unsubscribe from the mailing list.
-
-```
-
-L'administrateur peut désactiver le lien de désinscription obligatoire ajouté au système avec Administration > Outbound Emails.
-
-## Lien de Traçage
-
-Si vous voulez savoir si le destinataire de votre message a ouvert le lien placé à l'intérieur de votre message, vous devez créer un lien de traçage. Spécifiez tout nom *_Name_* et lien *_URL* vers lesquels votre lien pointe. Ensuite, vous devrez coller le code généré dans votre message préconfiguré.
-
-Exemple:
-
-```html
-
-Testez notre démonstration
-
-```
-
-## Listes Cibles
-
-Les listes cibles contiennent les listes de comptes, contacts, leads et de données d'utilisateurs.
-
-Les utilisateurs peuvent insérer les listes cibles manuellement en utilisant _Select_ action dans le panneau de configuration correspondant à partir de la vue détaillée des listes cibles. Il est aussi possible de filtrer et de sélectionner ensuite tous les résultats d'une recherche.
-
-## Utiliser les Rapports pour insérer des listes cibles
-
-L'option [Reports](../../../docs/user-guide/reports.md#syncing-with-target-lists) permet d'insérer des données dans les listes cibles à partir de données qui correspondent à des critères spécifiques.
-
-## Exclure les Listes Cibles
-
-Afin d'éviter d'envoyer des emails en masse à certains destinataires, spécifiez des listes cibles à exclure. Si, il existe une donnée ayant l'adresse email d'une donnée à exclure, la première donnée sera elle aussi exclue.
-
-## Log de Campagne
-
-Le Log de campagne vous permet de voir les emails qui ont été envoyés, ouverts, retournés, desinscrits, ou ayant cliqués sur le lien inséré dans le message. Il est possible d'utiliser ce log pour créer des listes cibles (menu déroulant en haut à droite du panneau de configuration) en se basant sur les données présentées dans le Log.
-
-Par exemple, vous pouvez choisir des contacts qui ont cliqués sur le lien (lien de traçage).
-
-## Resolution d'Erreurs
-
-_For Administrators_
-
-#### Que faire si les emails ne sont pas envoyés.
-
-1. Vérifier que _Send Test_ fonctionne. Si il ne fonctionne pas, assurez-vous que les réglages du système SMTP sont correctes.
-
-2. Vérifiez si le cron a été réglé pour votre system.
-
-3. Assurez vous que la tache préconfigurée `Send Mass Emails` est marquée comme étant `Active` (Administration > Scheduled Jobs > Send Mass Emails). Vérifiez qu'il n'y pas pas d'erreur dans le Log.
-
-#### Que se passe t'il si le Lien de Traçage contient une adresse incorrecte qui ne mène pas à votre crm.
-
-Vérifiez le paramètre 'siteUrl' dans le fichier `data/config.php`. Il doit être établi comme URL de votre EspoCRM et être accessible au monde extérieur.
-
-#### Les emails retournées ne sont pas enregistrés
-
-Les emails retournées ne peuvent être gérés que par un compte email de groupe. Assurez vous que vous avez un compte email de groupe qui surveille les boites de réception auquel les emails retournés sont envoyés.
-
-Certaines compagnies de gestion d'adresses emails peuvent dévier de la norme, du coup, les emails retournés ne peuvent être reconnus.
diff --git a/i18n/hun_HUN/administration/emails.md b/i18n/hun_HUN/administration/emails.md
deleted file mode 100644
index 7578c617c..000000000
--- a/i18n/hun_HUN/administration/emails.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Az e-mailek használatára vonatkozó iránymutatások
-
-Az EspoCRM lehetővé teszi az e-mailek lekérését az IMAP-fiókból. Ez lehetővé teszi, hogy az EspoCRM e-mail klienst használja CRM-specifikus funkciókkal együtt.
-
-## IMAP-fiókok
-
-* Megjegyzés: Meg kell [cron](../../../docs/administration/server-configuration.md#setting-up-crontab) megfelelően van konfigurálva a rendszerben, hogy a bejövő e-mailek működjenek.
-
-A felhasználó beállíthatja az IMAP-fiókot a Személyes e-mail fiókok oldalon (E-mailek lap > jobb felső menü > Személyes e-mail fiókok).
-
-Adja meg, hogy milyen mappákat figyeljünk a Monitorált mappák mezőben. Alapértelmezés szerint INBOX-ra van állítva. Ha külsős e-mail klienst használ e-mailek küldéséhez, az e-mailek archiválásához hozzáadhatja az Elküldött mappát.
-
-*Fetch Since* lehetővé teszi, hogy kiválassza a dátum e-mailjeit archiválni kell. Állítsa be a mai napot megelőző dátumra, ha régi e-maileket szeretne archiválni.
-
-Lehetőség van megadni a *Folder* értéket a Persnoal Email Accountban. A bejövő e-mailek kerülnek a mappába.
-
-## SMTP-fiókok
-
-A felhasználók beállíthatják az SMTP beállításokat a Beállítások, valamint a Személyes e-mail fiókjaikon belül. Az adminisztrátor engedélyezheti a rendszer SMTP használatát is (megosztás céljából).
-
-A felhasználók több SMTP-fiókkal is rendelkezhetnek (a 4.2.0 verzió óta). De az e-mailek elküldéséhez használt e-mail címeket a * User * rekord e-mail címei határozzák meg.
-
-## Az e-mailek használata
-
-Az e-maileket a cron (a háttérben) néhány percenként (a rendszergazda által meghatározott időtartam) veszi fel.
-Az e-maileket az E-mailek lapon láthatja. Vannak szabványos mappák, a Beérkezett üzenetek, az Elküldött, e-mailek tervezése a bal oldalon.
-
-*Állapot* mező. Az `Elküldött` azt jelenti, hogy a CRM-ből érkezett, `Archived` - IMAP-fiókból előállított vagy manuálisan archivált `Draft` - azt jelenti, hogy az e-mailt vázlatként hozták létre.
-
-Amikor az új e-mail érkezik, a rendszer megpróbálja felismerni, hogy melyik rekordhoz tartozik ez az e-mail. Kapcsolja össze fiókjával, vezetőjével, lehetőségeivel, esetével (és az érintkezés B2C módban stb.). Ha nem ismerte fel, akkor a felhasználó manuálisan is összekapcsolhatja a *Szülői mező* kitöltésével.
-
-Ha egy e-mail egy új potenciális ügyfélfelhasználóból származik, akkor **átviheti Lead-ra**. Nyissa meg az E-mail bejegyzést, és kattintson a Vezeték létrehozása lehetőségre a jobb felső menüben.
-
-Lehetőség van **létrehozni a feladatot vagy a házat** egy e-mail rekordból.
-
-Ha az e-mail rekord e-mail címei (cc-től kezdve) ismerik a rendszert, megmutatja, hogy melyik személyhez kapcsolódnak (Kapcsolat, Lead, Felhasználó stb.). Ha néhány e-mail cím új, akkor ** csak kapcsolat létrehozása ** onnan.
-
-All emails related to specific record are shown in History panel of that record. If some email is related, for example, to opportunity but opportunity is related to the account, it will be shown both in opportunity and account.
-
-## E-mail küldése
-
-Néhány módon új e-mailt írhat:
-* *Írja be az Email* gombot e-mail lista nézetben;
-* válaszol egy másik e-mailen;
-* néhány rekord e-mail címére kattintva;
-* *Írja be az e-mailt* a Tevékenységek panel tevékenységét.
-
-Van lehetőség arra, hogy **válasszon sablont** az e-mailedből.
-
-Beállíthat **e-mail aláírást** a Beállítások menüben.
-
-## E-mail mappák
-
-A felhasználók létrehozhatják saját e-mail mappáikat, hogy néhány e-mailt a kényelem érdekében. A rendelkezésre álló mappák listája a bal oldalon található E-mailek oldalon található. Mappák létrehozásához vagy szerkesztéséhez kövesse az E-mailek > legördülő menü jobb felső sarka > mappáit. Az "Értesítés letiltása" azt jelenti, hogy nem kap értesítést a beérkező e-mailekről, amelyek az adott mappába esnek. Az e-mail szűrők használatával lehetséges, hogy az e-maileket automatikusan mappákba helyezi, meghatározott feltételek szerint.
-
-## E-mail szűrők
-
-Az adminisztrátor globális e-mail szűrőket hozhat létre, hogy kihagyja a nem kívánatos e-maileket. Ezek elérhetők az Adminisztráció> E-mail szűrők oldalon.
-
-A rendszeres felhasználó e-mail szűrőket hozhat létre személyes e-mail fiókjaikhoz vagy teljes bejövő postafiókjához. Ezek elérhetők az E-mailek> legördülő menüben a jobb felső sarokban> Szűrők.
-
-Kétféle szűrő létezik:
-* Átugrás - az e-mailt a *Trash* mappába helyezik, vagy nem importálják, ha a szűrő a személyes e-mail fiókhoz kapcsolódik;
-* Tegye be a mappába - az importált e-maileket automatikusan a megadott felhasználó mappájába helyezik.
-
-## E-mail sablonok
-
-E-mail sablonok elérhetőek az E-mailek> legördülő menüben a jobb felső sarokban> E-mail sablonok. Használhatók tömeges levélküldéshez és rendszeres e-mailekhez is. Az "Egyszeri" jelölőnégyzet azt jelenti, hogy az e-mail sablon csak egyszer használható fel, az e-mail marketinghez szokásos módon.
-
-Lehetőség van helyfoglalók használatára az e-mail sablon testében és a témában pl. {Account.name}, {Person.emailAddress}. Ezeket a kapcsolódó nyilvántartások értékével helyettesítik.
-
-A további sablontartományban további fenntartott helyőrzőket használhat: {optOutUrl} és {optOutLink}.
-```
-Unsubscribe
-```
-Ez a tömeges e-mail üzenetek leiratkozási linkje.
diff --git a/i18n/hun_HUN/administration/layout-manager.md b/i18n/hun_HUN/administration/layout-manager.md
deleted file mode 100644
index bef6b0097..000000000
--- a/i18n/hun_HUN/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Elrendezeskezelo
-
-Az elrendezeskezelo az adminisztracios panelben erheto el. Kepes testreszabni a reszletek megjeleniteset, a szerkesztest, a nezetek listajat, valamint a keresesi szuroket es mezoket a tomeges frissitesi urlapokhoz.
-
-## List
-
-A lista nezet fo elrendezese. Meghatarozza az oszlopokat es azok parametereit.
-
-
-
-Az oszlopokhoz rendelkezesre allo parameterek az alabbiak.
-
-### Szelesseg (%)
-
-Az oszlop szelessege szazalekban, ures az automatikus szelesseget jelenti.
-
-### Link
-
-Ha be van jelolve, akkor a mezo megjelenik a rekord reszletes nezetehez. Altalaban a nevmezoknel hasznalatos.
-
-### Nem sorthato
-
-Letiltja az oszlop rendezesenek kepesseget.
-
-### Igazitsa
-
-Illessze az oszlopot balra vagy jobbra.
-
-## Reszlet
-
-A reszletes nezet es a szerkesztesi nezet fo elrendezese. Meghatarozza a paneleket, sorokat es cellakat. A cellak mezoket tartalmaznak.
-
-A sor ket cellat vagy egy cellat tartalmazhat, amely a sor teljes szelessegere kiterjed. A sor bovitett cellahoz torteno hozzaadasahoz uj sorot kell hozzaadnia, es barmely minusz jelre kattintania.
-
-
-
-## Lista (kis)
-
-A kapcsolattarto panelek listajanak elrendezese. Szinten hasznalhato olyan helyeken is, ahol esszeru a szuklatoszogu listakat megjeleniteni.
-
-## Reszlet (kis)
-
-Reszletes nezet a gyors letrehozashoz, a gyors megtekinteshez es az urlapok gyors szerkesztesehez.
-
-## Keresesi szurok
-
-A lista nezetben elerheto mezok listaja a kereseshez.
-
-Tomeges frissites
-
-A Mass Update formaban elerheto mezok listaja.
-
-## Kapcsolattarto panelek
-
-A kapcsolattartok listaja a reszletes nezetben az aljan talalhato. A panelek atrendezhetok. Lehetoseg van a panel szinenek meghatarozasara a Style parameterrel.
-
-## Oldalso panelek
-
-Oldalso panelek reszletezeshez, szerkeszteshez, reszletes kis merethez, kis formak szerkesztesehez. Lehetoseget nyujt a tablak, a Tevekenysegek, a Tortenelem, a Feladatok es egyeb elemek elrejtesere vagy atrendelesere. A paneleket a Style parameter segitsegevel szinezheti.
-
-## Tovabbi elrendezesek
-
-Egyes entitas tipusok tovabbi elrendezeseket tartalmaznak: Atalakitas olom, Lista fiokhoz.
diff --git a/i18n/id_ID/administration/apache-server-configuration.md b/i18n/id_ID/administration/apache-server-configuration.md
deleted file mode 100644
index a72dfff8a..000000000
--- a/i18n/id_ID/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,91 +0,0 @@
-# Konfigurasi server Apache untuk EspoCRM
-
-Petunjuk ini sudah ditambahkan pada panduan [Konfigurasi Server](server-configuration.md). Harap dicatat bahwa semua pengaturan konfigurasi yang tercantum di sini dibuat pada server Ubuntu.
-
-
-## Persyaratan PHP
-
-Untuk menginstal semua perpustakaan yang diperlukan, jalankan command ini dalam terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Memperbaiki masalah “API Error: EspoCRM API is unavailable”:
-
-Ikuti langkah berikut. Periksa apakah masalah terpecahkan setelah langkah ini diikuti.
-
-### 1. Aktifkan dukungan "mod_rewrite" di Apache
-
-Untuk mengaktifkan "mod_rewrite", jalankan command ini dalam terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Aktifkan dukungan .htaccess
-
-Untuk mengaktifkan dukungan .htaccess, tambah/ubah Pengaturan Konfigurasi Server /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf atau /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Setelah itu, jalankan command berikut dalam terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Tambahkan path RewriteBase
-
-Buka file /ESPOCRM_DIRECTORY/api/v1/.htaccess dan ganti dengan baris berikut:
-
-```
-# RewriteBase /
-```
-
-dengan
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-dimana REQUEST_URI adalah bagian dari URL, contohnya untuk “http://example.com/espocrm/”, REQUEST_URI-nya adalah “espocrm”.
-
-
-## Aktifkan dukungan HTTP AUTHORIZATION (hanya untuk FastCGI).
-
-Secara default FastCGI tidak mendukung HTTP AUTHORIZATION. Jika Anda menggunakan FastCGI, Anda harus mengaktifkannya di VirtualHost Anda atau /etc/apache2/apache2.conf (httpd.conf) dengan menambahkan baris kode berikut:
-
-Untuk modul Fcgid:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Untuk modul FastCgi:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Untuk memeriksa modul mana yang saat ini sedang digunakan, jalankan command ini dan temukan modul:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/id_ID/administration/b2c.md b/i18n/id_ID/administration/b2c.md
deleted file mode 100644
index 181cd30ea..000000000
--- a/i18n/id_ID/administration/b2c.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Konfigurasi EspoCRM untuk B2C (Business-to-Client)
-
-Secara default EspoCRM dikonfigurasi untuk menggunakan bisnis B2B. Tetapi Anda dapat mengatur B2C dengan mudah.
-
-* Ganti `b2cMode` menjadi true di file konfigurasi `data/config.php`. Sejak versi 4.3.0 dapat dikonfigurasikan di administrasi > Pengaturan.
-* Hapus tab *Account* dari menu navigasi (Administrasi > Pengalaman Pengguna).
-* Hapus kolom *Account* dari tata letak Anda (Administation > Manajer Tata letak).
-* Nonaktifkan akses ke cakupan *Account* untuk semua peran Anda (Administrasi > Peran).
-* Remove Account from picklists of all parent fields (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
-* Hapus Akun dari pilihan kolom induk (Administrasi > Manajer Entitas > {Rapat/Panggil/Tugas/Surel} > Kolom > Induk).
diff --git a/i18n/id_ID/administration/backup-and-restore.md b/i18n/id_ID/administration/backup-and-restore.md
deleted file mode 100644
index aa2dd4f38..000000000
--- a/i18n/id_ID/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Backup and Restore
-
-## Bagaimana cara membackup EspoCRM secara manual
-
-EspoCRM terdiri dari file dan data database. Semua data ini dibutuhkan untuk membuat salinan lengkap EspoCRM. Berikut adalah petunjuk cara melakukannya di server Ubuntu dengan MySQL.
-
-### Langkah 1. Backup file
-
-Buat arsip isi direktori EspoCRM yang terinstal. Untuk Ubuntu jalur defaultnya adalah `/var/www/html`. Anda bisa menggunakan perintah ini:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Langkah 2. Backup database
-
-Untuk mencadangkan semua data Anda, Anda harus mengetahui nama database dan kredensial akses. Anda bisa menemukan nama database di file konfigurasi `/ESPOCRM_DIRECTORY/data/config.php` di bawah bagian `database`. Anda bisa menggunakan perintah ini untuk membuat backup database Anda:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Langkah 3. Salin backup
-
-Itu saja. Sekarang, Anda harus menyalin cadangan yang dibuat ke tempat yang aman.
-
-
-## Bagaimana cara membackup EspoCRM dengan skrip
-
-Anda bisa menggunakan script untuk membackup semua data yang dibutuhkan. Login via SSH dan jalankan perintah (tested on Ubuntu server).
-
-### Unduh skrip
-
-```bash
-wget ../../../_static/scripts/backup.sh
-```
-
-### Jalankan skrip
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-dimana
- * `PATH_TO_ESPOCRM` adalah jalur untuk menginstal direktori EspoCRM.
- * `BACKUP_PATH` adalah path ke direktori backup.
-
-Untuk server Ubuntu adalah:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Catatan: Jika pengguna MySQL Anda tidak memiliki hak yang diperlukan untuk membuang database Anda, Anda akan diminta untuk memasukkan kredensial pengguna MySQL lainnya.
-
-Setelah sukses, Anda akan mendapatkan path menuju backup yang telah dibuat.
-
-## Mengembalikan EspoCRM dari backup
-
-Anda dapat mengembalikan EspoCRM dari cadangan yang dibuat seperti dijelaskan di atas.
-
-### Langkah 1. Buka arsip file backup
-
-Untuk mmebuka arsip file, Anda dapat menggunakan Manajer Arsip atau menjalankan perintah di bawah ini. File harus ditempatkan di direktori web-server.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-dimana:
- * `/var/www/html` adalah direktori web-server.
-
-### Langkah 2. Tetapkan izin yang diperlukan
-
-File harus dimiliki oleh pengguna web-server dan memiliki izin yang benar. Mohon tetapkan izin yang diperlukan dengan mengikuti [instruksi ini](server-configuration.md#izin-yang-diperlukan-untuk-sistem-berbasis-unix).
-
-### Langkah 3. Impor database dump
-
-Database dump harus diimpor ke database yang sama dengan kredensial pengguna yang sama, jika tidak, koreksi harus dilakukan pada file konfigurasi `ESPOCRM_DIRECTORY/data/config.php`. Untuk mengimpor database Anda dari dump, jalankan perintah di bawah ini di terminal:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Langkah 4. Periksa/konfigurasikan crontab
-
-Periksa apakah crontab Anda dikonfigurasi dengan benar. Jalankan perintah di bawah ini dan periksa apakah path ke EspoCRM benar:
-
-```bash
-sudo crontab -l -u www-data
-```
-dimana:
- * `www-data` adalah pengguna web-server Anda.
-
-Jika Anda harus membuat perubahan, gunakan perintah ini:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Rincian lebih lanjut tentang mengonfigurasi crontab untuk EspoCRM dijelaskan di [sini](server-configuration.md#mengatur-crontab).
diff --git a/i18n/id_ID/administration/bpm.md b/i18n/id_ID/administration/bpm.md
deleted file mode 100644
index edd423bd3..000000000
--- a/i18n/id_ID/administration/bpm.md
+++ /dev/null
@@ -1,207 +0,0 @@
-# Manajemen Proses Bisnis
-
-Alat Manajemen Proses Bisnis (MPB) menyediakan kemampuan untuk memodelkan dan mengotomatisasi proses bisnis di EspoCRM. Ini adalah proses bisnis pelaksana mesin yang dijelaskan dalam standar BPMN 2.0. Alat BPM tersedia di ekstensi [Paket Lanjutan](https://www.espocrm.com/extensions/advanced-pack/).
-
-
-
-### Perbedaan alat Alur Kerja
-
-Alur kerja kerja ditujukan untuk otomatisasi aturan bisnis sederhana, selain item alur berurutan, jika tidak perlu menampilkan arus secara grafis.
-
-Alat MPB ditujukan untuk arus bisnis yang lebih kompleks, dimana ada arus divergen dan konvergen, penundaan eksekusi, interaksi pengguna. Tampilan alur kerja membuat proses bisnis lebih mudah dipahami bagi manusia, sebuah log memungkinkan untuk melihat bagaimana prosesnya dilakukan.
-
-## Proses Alur Kerja
-
-Tautan untuk memproses alur kerja tersedia dari panel administrasi. Ini juga bisa ditambahkan sebagai tab pada panel navigasi.
-
-Alur kerja ditujukan untuk pemodelan proses bisnis. Administrator dapat membuat dan mengedit alur kerja. Pengguna biasa hanya dapat melihat alur kerja.
-
-Setiap alur kerja memiliki tipe entitas khusus (bidang Tipe Sasaran). Alur kerja menentukan pelaksanaan contoh proses di kemudian. Ini terdiri dari elemen alur kerja dan koneksi antar elemen.
-
-Jika proses alur kerja memiliki bidang 'Aktif' yang tidak dicentang maka tidak akan melakukan proses instance.
-
-Untuk menampilkan rincian dan parameter elemen alur kerja tertentu Anda perlu mengkliknya. Dalam mode edit Anda dapat mengubah parameter.
-
-## Pengolahan
-
-Pengolahan tersedia dari panel administrasi. Tautan ini juga bisa ditambahkan sebagai tab pada panel navigasi.
-
-Pengolahan mewakili contoh proses bisnis. Saat diinisiasi akan mendapat status 'Dimulai'. Saat proses selesai akan mendapat status 'Berakhir'. Pengolahannya juga bisa dihentikan secara manual oleh pengguna yang memiliki akses untuk mengubah pengolahannya. Jika dihentikan secara manual, statusnya akan 'Berhenti'.
-
-Pengolahan dijalankan sesuai dengan alur kerja. Proses alur kerja tidak dapat diubah setelah proses dimulai.
-
-Pengolahan wajib berkaitan dengan catatan target tunggal.
-
-Pengolahan dapat dimulai secara otomatis (pada kondisi tertentu atau dengan penjadwalan) atau manual (setidaknya ada satu Perihal Awal di alur kerja). Untuk memulai proses secara manual, pengguna perlu mengklik tombol 'Mulai Pengolahan' pada daftar tampilan pengolahan.
-
-## Elemen Alur Kerja
-
-### Perihal
-
-Perihal ditampilkan pada alur kerja sebagai lingkaran.
-
-#### Memulai Perihal
-
-Tidak memiliki parameter. Ini adalah titik awal prosesnya. Memulai Perihal dapat dimulai secara manual oleh pengguna yang memiliki akses untuk membuat proses. Pengguna perlu mengklik tombol 'Mulai Proses' pada tampilan daftar proses.
-
-#### Memulai Perihal Bersyarat
-
-Titik awal proses. Ini seharusnya dipicu secara otomatis saat kondisi tertentu terpenuhi. Ada dua jenis pemicu: 'Setelah Rekaman Dibuat', 'Setelah Rekaman Disimpan'.
-
-#### Waktu Memulai Perihal
-
-Titik awal proses. Ini memulai proses dengan penjadwalan. Anda perlu menentukan daftar laporan yang mengembalikan rekaman untuk memulai proses dan penjadwalan dalam notasi *crontab*.
-
-#### Perihal Menengah Bersyarat
-
-Perihal ini menghentikan alur sampai kriteria tertentu terpenuhi.
-
-#### Perihal Waktu Menengah
-
-Acara ini menghentikan alur dan menunggu selama ditentukan oleh parameter perihal.
-
-Untuk pengaturan waktu yang lebih kompleks Anda bisa menggunakan [rumus](formula.md). Skrip rumus harus mengembalikan nilai Tanggal-Waktu (dalam zona waktu UTC). Setelah waktu ini tiba alur akan dilanjutkan ke elemen berikutnya.
-
-Dengan memanfaatkan fungsi rumus *datetime\closest*, Memungkinkan untuk menetapkan waktu ke waktu tertentu di masa mendatang, misalnya awal hari kerja berikutnya.
-
-#### Akhir Perihal
-
-Mengakhiri alur terkini. Ini tidak mengakhiri alur yang mengalir secara paralel. Saat alur mencapai akhir perihal dan tidak ada yang berjalan pada paralel maka prosesnya akan berakhir.
-
-#### Mengakhiri Perihal
-
-Mengakhiri semua alur. Perihal selanjutnya berakhir.
-
-### Gateway
-
-Gateway ditampilkan sebagai berlian.
-
-#### Gateway Eksklusif
-
-Bisa alur menyimpang atau menyatu.
-
-Dalam kasus divergen mendefinisikan satu alur (jalur) yang akan dipilih sesuai kriteria yang ditentukan. Kondisi pertama yang terpenuhi menentukan alur, kondisi selanjutnya dihilangkan. Ada kemampuan untuk menentukan alur default. Alur default dipilih jika tidak ada kondisi yang terpenuhi. Alur default ditandai dengan tanda garis miring.
-
-Jika konvergen hanya mengarahkan alur ke elemen keluar. Itu tidak tersumbat setelah arus datang, jadi alur sejajar tidak akan tergabung dalam alur tunggal.
-
-
-
-
-
-#### Gateway Inklusif
-
-Bisa alur menyimpang atau menyatu.
-
-Dalam kasus divergen, ia dapat mengarahkan ke satu atau beberapa alur sejajar (jalur), tergantung pada pemenuhan kriteria setiap alur. Alur default dipilih jika tidak ada kondisi yang terpenuhi. Alur default ditandai dengan tanda garis miring.
-
-Jika ada kebutuhan untuk menggabungkan alur yang dihasilkan oleh gateway inverging inklusif Anda perlu menggunakan gateway inklusif yang konvergen. Ini akan menunggu semua alur masuk dan kemudian melanjutkan ke elemen keluar.
-
-
-
-Catatan: Gateways diverging dan konvergen harus seimbang.
-
-Catatan: Jika salah satu alur telah berakhir karena beberapa alasan, maka gateway divergen tidak akan pernah diproses. Prosesnya akan diblokir. Hindari desain alur kerja yang bisa membawa situasi seperti itu.
-
-#### Gateway Paralel
-
-Bisa alur menyimpang atau menyatu.
-
-Dalam kasus divergen itu dibagi mengalir ke beberapa alur paralel. Tidak ada parameter untuk tipe gateway ini.
-
-Jika terjadi konvergen, menunggu sampai semua alur masuk kemudian berlanjut ke elemen keluar berikutnya.
-
-
-
-Catatan: Gateways divergen dan konvergen harus seimbang.
-
-Catatan: Jika salah satu alur paralel telah berakhir karena beberapa alasan, maka gateway divergen tidak akan pernah diproses. Prosesnya akan diblokir. Hindari desain alur kerja yang bisa membawa situasi seperti itu.
-
-#### Gateway Berdasarkan Perihal
-
-Hanya bisa alur menyimpang.
-
-Ini memberhentikan alur sampai ada kejadian keluar yang dipicu. Perihal yang dipicu menentukan alur tunggal. Perihal keluar lainnya akan ditolak.
-
-Hanya Perihal mengengah yang bisa berada di ujung alur deras keluar lainnya.
-
-
-
-### Aktivitas
-
-Aktifitas ditampilkan sebagai persegi panjang bulat.
-
-#### Tugas
-
-Tugas dapat melakukan tindakan berikut:
-
-* Buat Rekaman - membuat rekaman baru dari tipe entitas apa pun;
-* Buat Rekaman Terkait - membuat rekaman baru yang terkait dengan rekaman target;
-* Perbarui Target Rekaman;
-* Perbarui Rekaman Terkait - perbarui rekaman atau rekaman yang terkait dengan rekaman target;
-* Perbarui Rekaman yang Dibuat - memperbarui bidang spesifik dari setiap rekaman yang dibuat dalam proses saat ini;
-* Perbarui Proses Rekaman - dapat digunakan untuk menetapkan proses ke pengguna atau tim tertentu;
-* Tautan ke Rekaman Lain - menghubungkan rekaman target dengan rekaman yang ditentukan;
-* Batalkan Tautan dari Rekaman Lain - hapus rekaman sasaran dari rekaman yang ditentukan;
-* Terapkan Aturan Tugas - memberikan rekaman target, rekaman proses atau rekaman yang dibuat oleh proses sesuai dengan peraturan khusus;
-* Buat Pemberitahuan - buat pemberitahuan dalam aplikasi untuk pengguna tertentu;
-* Buat Diikuti - membuat pengguna tertentu mengikuti rekaman target, rekaman proses atau rekaman yang dibuat oleh proses;
-* Jalankan Tindakan - menjalankan tindakan layanan kustom yang dilakukan oleh pengembang.
-
-Tindakan yang tersedia untuk tugas hampir sama seperti pada fitur Alur Kerja. Lihat rincian lebih lanjut tentang [tindakan alur kerja](workflows.md#tindakan).
-
-#### Mengirim Pesan Tugas
-
-Mengirim pesan surel ke penerima tertentu.
-
-#### Tugas Pengguna
-
-Menyediakan kemampuan interaksi pengguna yang fleksibel. Ini berhenti eksekusi sampai pengguna (ditentukan secara eksplisit atau oleh aturan tugas) menyelesaikan tugasnya. Proses catatan Tugas Pengguna akan dibuat di sistem. Secara default ada tiga jenis tindakan: Setujui, Review, Diselesaikan.
-
-* Tipe setujui mengharuskan pengguna untuk memilih antara 'Disetujui' dan 'Ditolak'.
-* Tipe ulasan hanya memberikan satu pilihan: 'diulas'.
-* Tipe yang tersertifikasi memiliki dua pilihan: 'Selesai' dan 'Gagal'.
-
-Pengguna yang ditugaskan ke catatan Proses Tugas Pengguna yang dibuat akan menerima notifikasi dalam aplikasi. Administrator juga dapat mengaktifkan pemberitahuan surel.
-
-Pengguna juga dapat menambahkan dashlet Proses Tugas Pengguna di dasbor mereka untuk melihat proses aktual tugas pengguna mereka.
-
-Ini memungkinkan untuk membaca resolusi tugas pengguna yang lewat di dalam gateway yang berbeda atau kejadian bersyarat, yang membuat kerusakan dalam aliran proses.
-
-#### Tugas Skrip
-
-Eksekusi skrip dalam bahasa [rumus-espo](formula.md). Semua variabel yang diatur (`$variableName`) akan disimpan dan tersedia dalam proses.
-
-### Arus
-
-#### Urutan Arus
-
-Diwakili sebagai panah tebal. Menunjukkan urutan elemen proses yang akan dijalankan.
-
-## Kondisi
-
-Perihal bersyarat, gateway invergen eksklusif dan inklusif memiliki kondisi yang menentukan proses arus.
-
-Melalui UI ada kemampuan untuk memeriksa kondisi untuk catatan berikut:
-
-* Target rekaman;
-* Rekaman terkait dengan target melalui hubungan banyak-ke-satu dan hubungan antara anak-ke-induk;
-* Rekaman dibuat oleh proses melalui tugas;
-* Rekaman tugas pengguna, yang memungkinkan pengecekan resolusinya.
-
-Ini juga memungkinkan untuk mendefinisikan kondisi dalam bahasa [Rumus-espo](formula.md).
-
-Kondisi alat MPB sama seperti pada fitur Alur Kerja. Lihat rincian lebih lanjut tentang [kondisi alur kerja](workflows.md#kondisi).
-
-## Contoh
-
-### Contoh 1
-
-
-
-### Contoh 2
-
-
-
-### Contoh 3
-
-
diff --git a/i18n/id_ID/administration/emails.md b/i18n/id_ID/administration/emails.md
deleted file mode 100644
index 938a91b52..000000000
--- a/i18n/id_ID/administration/emails.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Surel
-
-> Penting. [Cron](server-configuration.md#mengatur-crontab) harus dikonfigurasi di sistem Anda untuk melakukan pengambilan surel. Anda dapat menemukan informasi di EspoCRM Anda di Administrasi> Pekerjaan Terjadwal.
-
-## Ikhtisar
-
-EspoCRM memiliki kemampuan untuk memantau kotak pesan IMAP. Surel dapat diarsipkan dalam dua cara: Akun Surel Grup dan Akun Surel Pribadi. Akun Tidak terikat Grup ditujukan untuk kotak pesan grup: kasus yang paling umum adalah kotak dukungan. Akun Surel Pribadi ditujukan untuk kotak pesan pribadi pengguna.
-
-Sebagai surel yang masuk sistem mencoba menautkannya dengan catatan yang sesuai (Akun, Pimpinan, Opportuniti, Kasus). Pengguna yang mengikuti rekaman tersebut akan menerima pemberitahuan tentang surel baru di sistem, meski tidak berada di Kepada atau CC.
-
-## Akun Surel Grup
-
-Hanya administrator yang dapat mengatur Akun Surel Grup. Akun Surel Grup dapat digunakan untuk menerima dan mengirim surel. Mengirim surel dari akun grup telah tersedia sejak versi 4.9.0.
-
-Bidang tim menentukan tim surel masuk mana yang akan ditugaskan.
-
-Jika akun surel grup memiliki SMTP dan dicentang sebagai bersama maka akses akan dikontrol oleh Peran melalui izin Akun Surel Grup. Tim lapangan akan digunakan jika level izin diatur ke 'tim'.
-
-Anda dibolehkan untuk membuat sistem mengirim balasan otomatis untuk email masuk.
-
-## Surel-ke-Kasus
-
-Ada pilihan untuk membuat sistem membuat kasus dari surel grup yang masuk.
-Fitur ini ditujukan untuk tim pendukung.
-Kasus dapat didistribusikan ke pengguna dari tim tertentu sesuai dengan cara berikut:
-`direct assignment`, ` round-robin` dan `less-busy`.
-Hanya surel pertama di lembaran yang menciptakan kasus baru.
-Setiap berikutnya akan dihubungkan dengan catatan kasus yang ada dan ditampilkan di panel Stream-nya.
-
-Saat pengguna ingin mengirim balasan kepada pelanggan yang mereka butuhkan untuk memastikan bahwa kasus tersebut dipilih sebagai induk dari surel yang sedang dikirim. Ini akan membuat pelanggan membalas alamat surel grup daripada ke pengguna sendiri.
-
-## Akun Surel Pribadi
-
-Pengguna bisa mengatur akun surel mereka sendiri yang perlu dipantau. Surel> Menu Tarik-ulur Kanan Atas> Akun Surel Pribadi. Administrator juga bisa mengatur akun surel pengguna.
-
-## Penyaringan Surel
-
-Ini memungkinkan penyaringan surel masuk sesuai dengan kriteria yang ditentukan. Misalnya jika Anda tidak ingin pesan pemberitahuan dikirim oleh beberapa aplikasi untuk diimpor ke EspoCRM Anda dapat membuat filter untuk membuat EspoCRM melewatkannya.
-
-Admin dapat membuat penyaringan umum, diterapkan ke semua akun surel. Pengguna dapat membuat penyaringan untuk akun surel pribadi mereka dan untuk keseluruhan kotak masuk.
diff --git a/i18n/id_ID/administration/entity-manager.md b/i18n/id_ID/administration/entity-manager.md
deleted file mode 100644
index ee50c59e4..000000000
--- a/i18n/id_ID/administration/entity-manager.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Manajer Entitas
-
-Manajer Entitas tersedia di panel Administrasi. Ini memberikan kemampuan untuk sangat menyesuaikan contoh EspoCRM Anda. Anda dapat melakukan hal berikut:
-
-* Menambahkan jenis entitas baru.
-* Menyesuaikan jenis entitas yang ada: ganti label, urutan default dalam tampilan daftar, aktifkan atau nonaktifkan siaran.
-* Mengkonfigurasi bidang: menambahkan, menyesuaikan yang sudah ada.
-* Mengkonfigurasi hubungan: menambahkan, ganti label yang sudah ada.
-
-## Membuat entitas baru
-
-Klik tombol `Buat Entitas` di halaman Manajer Entitas. Tentukan nama, label dan tipe. Jika Anda memilih tipe `Orang`, entitas Anda akan memiliki kolom Surel, Telepon, Nama Depan, Nama Belakang dan Salam. Centang `Siaran` jika Anda ingin entitas Anda memiliki panel siaran dan pengguna untuk dapat mengikuti entitas jenis ini.
-
-Tipe:
-
-* Basis - entitas kosong hanya dengan bidang dasar seperti Nama, Pengguna yang Ditugaskan, Tim, Deskripsi.
-* Basis Tambahan - seperti Basis tapi dengan Kegiatan, Sejarah, Panel tugas (tersedia sejak 4.3.0).
-* Event - Tanggal Mulai, Tanggal Akhir, Durasi, Induk, Bidang Status. Tersedia dalam panel Kalender dan Aktivitas (sejak 4.3.0, harus diaktifkan di Administrasi> Pengaturan).
-* Orang - Surel, Telepon, Nama Depan, Nama Belakang, Salam, Bidang Alamat. Aktifitas, Sejarah, Panel tugas.
-* Perusahaan - Surel, Telepon, Alamat Penagihan, Alamat Pengiriman. Aktifitas, Sejarah, Panel tugas.
-
-## Memperbarui entitas yang ada
-
-Jika Anda mengklik link `Ubah` pada entitas tertentu Anda akan dapat mengubah beberapa parameter dari entitas itu.
-
-* Label - nama singular dan plural dari entitas.
-* Catatan pesanan default diurutkan berdasarkan daftar tampilan.
-* Siaran - apakah fitur Siaran diaktifkan untuk entitas ini.
-* Dinonaktifkan - periksa apakah Anda tidak memerlukan entitas ini di siaran Anda.
-* Bidang Penyaringan Teks - bidang apa yang dicari di penyaringan teks utama dan pencarian umum.
-
-
-## Bidang
-
-Dengan mengklik link `Bidang` Anda akan dipindahkan ke halaman yang terpisah. Di sana Anda akan bisa membuat bidang baru atau memperbarui yang sudah ada. Jenis bidang berikut tersedia di Manajer Entitas:
-
-* Alamat - alamat dengan jalan, kota, negara bagian, kode pos dan negara;
-* Jajaran - daftar nilai, dengan kemampuan untuk memilih beberapa nilai (bukan pilihan yang baik jika Anda perlu mencari dengan bidang ini); pengguna dapat menambahkan nilai mereka sendiri jika opsi tidak ditentukan.
-* Lampiran Beberapa - melampirkan beberapa file;
-* Kenaikan-otomatis - hanya membaca nomor yang dihasilkan;
-* Boolean - kotak centang, benar atau salah;
-* Mata uang - untuk nilai mata uang;
-* Tanggal;
-* Tanggal Waktu;
-* Enum - kotak pilih, dengan kemampuan untuk memilih hanya satu nilai;
-* File - mengunggah satu file;
-* Float - angka dengan bagian desimal;
-* Asing - bidang entitas terkait;
-* Gambar - mengunggah file gambar dengan preview;
-* Integer - bilangan bulat;
-* Nomor - jumlah incrementing otomatis tipe string dengan awalan yang mungkin dan panjang tertentu;
-* Multi-enum - daftar nilai, dengan kemampuan untuk memilih beberapa nilai (bukan pilihan yang baik jika Anda perlu mencari dengan bidang ini), mirip dengan Jajaran tapi lebih bagus.
-* Text - text area, untuk teks multiline yang panjang;
-* Url - untuk tautan;
-* Varchar - teks pendek;
-* Wysiwyg - mirip dengan Area teks, dengan kemampuan untuk memformat teks.
-
-Parameter:
-* Diperlukan - apakah pengisian di lapangan adalah wajib.
-* Nilai Default - Nilai bidang yang ditetapkan saat membuat catatan baru.
-* Audit - pembaruan lapangan akan dicatat di Siaran.
-
-
-**Catatan**: Setelah menambahkan bidang baru, Anda perlu menempatkan bidang ini di [tata letak](layout-manager.md) (Administrasi> Manajer Tata letak).
-
-### Logika Dinamis
-
-Menyediakan kemampuan untuk membuat bentuk dinamis. Mungkin untuk menentukan kondisi yang membuat bidang tertentu terlihat, dibutuhkan atau hanya-baca. Kondisi akan diperiksa secara otomatis bila data dalam bentuk berubah.
-
-Untuk bidang Enum, Array dan Multi Enum, mungkin untuk menentukan rangkaian opsi yang berbeda yang akan tersedia untuk lapangan tergantung pada kondisi yang terpenuhi.
-
-
-## Hubungan
-
-Anda dapat membuat hubungan baru antara entitas yang beda dari biasanya dan custom. Ada 3 jenis hubungan yang tersedia:
-
-* Satu-ke-Banyak: setelah Anda membuat hubungan ini, Anda dapat memasukkan bidang tautan ke tata letak detail entitas yang benar dan menambahkan panel hubungan ke entitas kiri;
-* Banyak-ke-Satu: sama seperti Satu-ke-Banyak tetapi sebaliknya;
-* Banyak-ke-Banyak: panel hubungan di kedua sisi.
-
-Parameter 'Link Multiple Field' menyiratkan bahwa bidang tipe `linkMultiple` akan dibuat bersamaan dengan hubungan. Anda dapat menempatkan bidang semacam itu pada tata letak. Ini mudah untuk memilih catatan terkait dengan cepat. Ini bukan pilihan yang baik jika hubungan Anda dimaksudkan untuk memiliki banyak catatan terkait yang dapat memperlambat pemuatan layar tampilan detail.
-
-Jika parameter 'Diaudit' diperiksa maka pembaruan hubungan akan dicatat di Siaran.
-
diff --git a/i18n/id_ID/administration/extensions.md b/i18n/id_ID/administration/extensions.md
deleted file mode 100644
index bb2e34fd4..000000000
--- a/i18n/id_ID/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Mengelola ekstensi
-
-## Bagaimana cara memasang ekstensi
-
-Untuk memasang ekstensi EspoCRM (misalnya Paket Lanjutan, Integrasi VoIP):
-
-1. Masuk sebagai administrator.
-2. Masuk ke Administrasi> Ekstensi.
-3. Unggah paket ekstensi Anda (file zip).
-4. Klik tombol Install.
-
-
-## Bagaimana meng-upgrade ekstensi
-
-Untuk meningkatkan versi ekstensi yang sudah terpasang (misalnya, Paket Lanjutan, integrasi VoIP) ke versi yang lebih baru:
-
-1. Unduh versi baru dari ekstensi yang dibutuhkan.
-2. Masuk sebagai administrator.
-3. Pergi ke Administrasi> Ekstensi.
-4. Unggah paket ekstensi baru Anda (zip file) tanpa meng-uninstall versi yang sudah terinstal.
-5. Klik tombol Install.
-
-
-## Bagaimana cara meng-uninstall ekstensi
-
-Langkah-langkah untuk meng-uninstall pemasangan ekstensi yang terpasang:
-
-1. Login sebagai administrator.
-2. Masuk ke Administrasi> Ekstensi.
-3. Temukan ekstensi yang dibutuhkan pada daftar ekstensi yang tersedia.
-4. Klik tombol Uninstall.
-
-
-## Bagaimana cara menghapus ekstensi
-
-Bila ekstensi dicopot pemasangannya, sistem tersebut masih tersedia di sistem. Ini bisa benar-benar dihapus. Langkah-langkah untuk menghapus ekstensi:
-
-1. Masuk sebagai administrator.
-2. Masuk ke Administrasi> Ekstensi.
-3. Temukan ekstensi yang dibutuhkan dalam daftar ekstensi yang tersedia.
-4. Klik tombol Hapus.
diff --git a/i18n/id_ID/administration/formula.md b/i18n/id_ID/administration/formula.md
deleted file mode 100644
index 2d16c7262..000000000
--- a/i18n/id_ID/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Bidang yang Dihitung (Rumus)
-
-Pada entity manager dimungkinkan untuk mendefinisikan script (rumus) untuk tipe entitas tertentu. Script ini akan dieksekusi setiap saat sebelum rekaman disimpan.
-Ini menyediakan kemampuan untuk secara otomatis mengatur bidang tertentu (atribut) dengan nilai yang berasal dari perhitungan.
-
-Untuk mengedit rumus ikuti menu Administrasi > Manajer Entitas > tarik-ulur di sebelah kanan pada deretan entitas yang dibutuhkan > Rumus.
-
-Anda juga mungkin perlu mengatur bidang, yang seharusnya dihitung, Read-only melalui Manajer Entitas.
-
-
-## Sintaks
-
-Rumus EspoCRM ditulis dalam bahasa sederhana yang dirancang khusus untuk fitur ini.
-
-Ada operator, fungsi atribut dan nilai yang bisa digunakan dalam rumus. Ekspresi terpisah harus dibatasi oleh karakter `;`.
-
-### Operator
-
-* `=` - penempatan.
-* `||` - logika ATAU,
-* `&&` - logika DAN,
-* `!` - logika TIDAK,
-* `+`- penjumlahan numerik,
-* `-` - pengurangan numerik,
-* `*` - perkalian numerik,
-* `/` - divisi numerik,
-* `%` - modul numerik,
-* `==` - perbandingan sama dengan,
-* `!=` - perbandingan tidak sama dengan,
-* `>` - perbandingan lebih besar dari,
-* `<` - perbandingan lebih kurang dari,
-* `>=` - perbandingan lebih besar dari atau sama dengan,
-* `<=` - perbandingan kurang dari atau sama dengan.
-
-Prioritas operator:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Atribut
-
-Atribut mewakili nilai bidang dari entitas target. Anda bisa memasukkan atribut yang tersedia dengan mengklik tombol plus.
-
-Ini memungkinkan mengakses atribut entitas terkait dengan format berikut `linkName.attributeName`.
-
-
-### Fungsi
-
-Format fungsi yang digunakan: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Fungsi yang tidak biasa digunakan tercantum di bawah ini.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` Jika CONDITION terpenuhi maka lakukan CONSEQUENT. Jika tidak -- maka lakukan ALTERNATIVE.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` Jika CONDITION terpenuhi maka lakukan CONSEQUENT. Jika tidak - tidak melakukan apapun.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Menyatukan dua atau lebih string.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Ekstrak karakter dari STRING pada posisi START dan LENGTH.
-
-Jika LENGTH dihilangkan, substring mulai dari START sampai akhir STRING akan dikembalikan.
-
-Jika LENGTH negatif, maka banyak karakter akan dihilangkan dari akhir STRING.
-
-#### string\\trim
-`string\trim(STRING)` Strips whitespace dari awal dan akhir STRING.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Mengonversi huruf ke huruf kecil. (sejak versi 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Mengonversi huruf ke huruf besar. (sejak versi 5.0.0))
-
-#### datetime\\today
-`datetime\today()` Mengembalikan tanggal hari ini.
-
-#### datetime\now
-`datetime\now()` Mengembalikan waktu sekarang.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Mengonversi tanggal atau batas waktu VALUE menjadi string yang diformat sesuai dengan pengaturan aplikasi. TIMEZONE dan FORMAT dapat dihilangkan. Jika TIMEZONE dihilangkan maka zona waktu default akan digunakan. Jika FORMAT dihilangkan maka format default akan digunakan.
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Mengembalikan tanggal setiap bulan (1-31). `0` jika VALUE kosong. Jika TIMEZONE dihilangkan maka zona waktu sistem digunakan. (sejak versi 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Mengembalikan bulan (1-12). `0` jika VALUE kosong. Jika TIMEZONE dihilangkan maka zona waktu sistem digunakan. (sejak versi 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Mengembalikan tahun. `0` jika VALUE kosong. Jika TIMEZONE dihilangkan maka zona waktu sistem digunakan. (sejak versi 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Mengembalikan jam (0-23). `-1` jika VALUE kosong. Jika TIMEZONE dihilangkan maka zona waktu sistem digunakan. (sejak versi 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Mengembalikan menit (0-59). `-1` jika VALUE kosong. Jika TIMEZONE dihilangkan maka zona waktu sistem digunakan. (sejak versi 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Mengembalikan hari dalam seminggu (0-6). `-1` jika VALUE kosong `0` - untuk hari minggu. Jika TIMEZONE dihilangkan maka zona waktu sistem digunakan. (sejak versi 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Mengembalikan perbedaan antara dua tanggal atau datetimes. INTERVAL_TYPE dapat 'tahun', 'bulan', 'hari', 'jam', 'menit'. Kembalikan `null` jika gagal. Hasilnya akan negatif jika VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Menambah MINUTES ke nilai VALUE datanya. MINUTES bisa negatif.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Menambahkan JAM ke VALUE datetime. JAM bisa negatif.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Menambahkan DAYS ke tanggal atau datetime VALUE. HARI bisa negatif.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Menambahkan WEEKS sampai tanggal atau datetime VALUE. MINGGU bisa negatif.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Menambahkan BULAN ke tanggal atau datetime VALUE. BULAN bisa jadi negatif.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Menambahkan YEARS to date atau datetime VALUE. TAHUN bisa negatif
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` Mengembalikan tanggal terdekat atau datetime ke VALUE berdasarkan argumen yang diajukan. (sejak versi 5.0.0)
-
-JENIS bisa menjadi salah satu dari nilai berikut: 'waktu', 'menit', 'jam', 'tanggal', 'bulan', 'dayOfWeek'. TARGET adalah nilai integer atau nilai string. IS_PAST berarti menemukan yang terdekat di masa lalu. Jika TIMEZONE dihilangkan maka zona waktu default digunakan.
-
-Contoh:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Akan mengembalikan nilai datetime terdekat di masa depan dengan waktu 20:00.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Akan kembali ke`2017-11-01`, hari pertama setiap bulannya.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Akan kembali ke Senin depan (awal hari).
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Mengubah nilai numerik menjadi string yang diformat sesuai dengan format atau pengaturan aplikasi default tertentu. Jika DECIMALS, DECIMAL_MARK ATAU THOUSAND_SEPARATOR maka sistem default digunakan.
-
-Contoh:
-
-`number\format(2.666667, 2)` - hasilnya 2.67;
-
-`number\format(1000, 2)` - hasilnya 1,000.00;
-
-`number\format(10.1, 0)` - hasilnya 10.
-
-
-#### number\abs
-`number\abs(VALUE)` Nilai mutlak. Mengembalikan null jika VALUE tidak numerik.
-
-#### number\round
-`number\round(VALUE, PRECISION)` Mengembalikan nilai pembulatan VALUE ke PRECISION yang ditentukan (jumlah digit setelah titik desimal). KETEPATAN juga bisa negatif atau nol (default).
-
-#### number\floor
-`number\floor(VALUE)` Mengembalikan nilai integer terendah berikutnya dengan membulatkan nilai jika perlu. (sejak versi 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` Mengembalikan nilai integer tertinggi berikutnya dengan nilai pembulatan jika perlu. (sejak versi 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Mengembalikan TRUE jika entitas itu baru (dibuat) dan FALSE jika tidak (sedang diperbarui).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Mengembalikan TRUE jika ATTRIBUTE entitas diubah.
-
-Contoh:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Mengembalikan TRUE jika ATTRIBUTE entitas tidak berubah.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Atribut yang ditetapkan saat entitas target diambil dari database. Sebelum dimodifikasi.
-
-Contoh:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Menambahkan ID ke bidang Tautan Multiple. Misalnya, tambahkan bidang 'someTeamId' ke 'tim'.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Menambahkan daftar id. (sejak versi 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Cek apakah bidang Tautan Multiple memiliki ID khusus.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Menghapus ID khusus dari bidang Tautan Multiple.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Cek apakah entitas target terkait dengan entitas lain yang ditunjukkan oleh LINK dan ID.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Mengembalikan ATTRIBUTE pengguna saat ini.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Mengembalikan array. (sejak versi 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Mengembalikan nilai true jika LIST berisi VALUE. Bisa digunakan untuk bidang Array dan Multi-Enum. (sejak versi 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Menambahkan satu atau lebih elemen ke akhir array dan mengembalikan array baru. (sejak versi 5.0.0)
-
-#### array\length
-`array\length(LIST)` Mengembalikan hitungan elemen dalam DAFTAR. (sejak versi 4.8.1)
-
-
-### Nilai
-
-* Strings. Misalnya 'some string';
-* Integer numbers. Misalnya 1, 100, 40300.
-* Float numbers. Misalnya 5.2.
-
-### Variabel
-
-Memungkinkan untuk menentukan variabel khusus dalam formula.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Contoh
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Menggunakan rumus dalam Alur Kerja
-
-Anda dapat memanfaatkan rumus dalam kondisi lur kerja dan tindakan. Lihat [dokumentasi alur kerja](workflows.md#menggunakan-rumus-dalam-tindakan) untuk informasi lebih lanjut.
diff --git a/i18n/id_ID/administration/import.md b/i18n/id_ID/administration/import.md
deleted file mode 100644
index eee67d848..000000000
--- a/i18n/id_ID/administration/import.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Impor
-
-Impor hanya dapat diakses pleh pengguna admin. Administrasi > Impor. Anda hanya dapat mengimpor dari file CSV.
-
-## Langkah 1
-
-Pilih jenis catatan apa yang perlu Anda impor (bidang Tipe Entity).
-Pilih file CSV. File harus berformat `UTF-8`.
-Pilih `What to do?`. Pilihan yang tersedia: 'Buat Saja', 'Buat & Perbarui', 'Perbarui Saja'.
-
-* `Buat Saja` - pilih ini jika Anda hanya ingin rekaman dibuat saja.
-* `Buat & Perbarui` - rekaman akan dibuat tetapi jika rekaman sesuai dengan nilai bidang maka akan diperbarui. Anda dapat memeriksa bidang-bidang apa saja yang cocok dengan _Langkah 2_.
-* `Perbarui Saja` - only records with matching field values will be found it will be updated.
-hanya rekaman yang cocok dengan nilai bidang yang akan ditemukan yang akan diperbarui.
-
-Setelah Anda memilih file csv Anda dapat melihat bagaimana file tersebut harus diuraikan dalam panel Pratinjau. Jika Anda mengubah properties tinjauan akan diperbarui.
-
-* `Header Row` - Apakah CSV file berada pada baris pertama dalam nama bidang.
-* `Execute in idle` - disararankan jika Anda memiliki sekelompok besar rekaman yang akan diimpor. Impor akan diproses melalui cron. Status akan diatur ke 'Selesai' setelah proses impor selesai.
-* `Skip searching for duplicates` - hal ini dapat mengurangi jangka waktu impor.
-
-Klik tombol _Berikutnya_ untuk memproses ke _Langkah 2_.
-
-
-
-## Langkah 2
-
-Add default values you want new and updated records to set with. E.g. you can specify Assigned User or Teams fields.
-
-Tambahkan nilai-nilai default baru yang Anda inginkan dan catatan Anda akan diperbarui dengan Misalnya Anda dapat menentukan yang spesifik seperti bidang Ketetapan Pengguna atau Tim.
-
-Setelah impor dilakukan, Anda akan dapat kembali menciptakan rekaman, lihat duplikat dan catatan yang diperbarui. Duplikat berarti ada rekaman yang serupa dalam sistem. Anda dapat menghapus semua file impor duplikat sekaligus. Catatan: pemulihan tidak bekerja pada rekaman yang diperbarui.
-
-Click _Run Import_ button to proceed. It may take some time before an import process gets finished. If you want to import a large bunch of records (depends on you server configuration, usually if more than 200 records) you need to make sure that php parameter `set_time_limit` is large enough.
-Klik tombol _Jalankan Impor_ untuk melanjutkan. Mungkin diperlukan beberapa waktu sebelum proses impor selesai. Jika Anda ingin mengimpor sebagian besar rekaman (tergantung pada konfigurasi server Anda, biasanya jika lebih dari 200 catatan) Anda perlu memastikan bahwa php parameter 'set_time_limit' cukup besar.
-
-
-
-## Bagaimana mengimpor ke Daftar Target
-
-Bila Anda mengimpor kontak, Judul atau akun Anda dapat menambahkannya ke beberapa sasaran daftar. Pada langkah 2, Anda perlu menambahkan bidang daftar Target pada panel 'Nilai Default' dan pilih sebuah rekaman dari daftar target yang diperlukan. Anda juga dapat menggunakan impor 'hanya perbarui' atau 'Buat & Perbarui' untuk menambahkan target yang ada untuk daftar target.
diff --git a/i18n/id_ID/administration/installation.md b/i18n/id_ID/administration/installation.md
deleted file mode 100644
index 421dce6a2..000000000
--- a/i18n/id_ID/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Instalasi
-
-### Persyaratan
-EspoCRM berjalan pada penyedia layanan hosting. Persyaratannya meliputi:
-
-* PHP 5.5 atau versi terbaru dari PHP dengan ekstensi aktif pdo, json, GD library mcrypt (biasanya diaktifkan secara default);
-* MySQL 5.1 atau lebih tinggi.
-
-Lihat artikel [Konfigurasi Server](server-configuration.md) untuk informasi lebih lanjut.
-
-### 1. Unduh paket instalasi EspoCRM
-Untuk mendapatkan versi terbaru dari EspoCRM ikuti tautan [halaman unduh](http://www.espocrm.com/download/).
-
-### 2. Unggah file EspoCRM ke Server Anda
-
-Setelah unduhan selesai, unggah paket tersebut ke server web Anda.
-Untuk mengunggah, Anda dapat menggunakan SSH, FTP atau panel administrasi hosting.
-Ekstrak arsip ke direktori server web publik (misalnya, `public_html`, `www`, dll.).
-
-_Catatan: untuk FTP, Anda perlu mengekstrak Arsip unduhan sebelum mengunggah ke server web Anda._
-
-### 3. Buat Database MySQL yang akan digunakan untuk EspoCRM
-
-Pergi ke panel administrasi hosting Anda, atau ke SSH, dan buat database baru dan pengguna untuk EspoCRM (misalnya, `MySQL database` di cPanel).
-
-### 4. Jalankan proses instalasi EspoCRM
-
-Sekarang, buka browser web Anda, dan pergi ke URL file EspoCRM (misalnya, `http://yourdomain.com/espo`).
-
-Jika Anda melihat layar ini, Anda memiliki eror "Permission denied".
-Maka, Anda perlu menjalankan command tampilan di terminal melalui SSH, atau mengatur izin yang benar.
-Harusnya 755 untuk direktori, 644 untuk file, dan 775 untuk direktori `data`.
-Pastikan juga bahwa Anda memiliki _owner_ dan _group_ yang benar.
-
-
-
-Jika Anda melihat layar berikut, izin Anda benar dan Anda dapat memulai menginstal EspoCRM.
-
-
-
-Pada Halaman ini, Anda dapat membaca dan menyetujui Perjanjian Lisensi.
-
-
-
-Masukkan rincian untuk database MySQL yang baru Anda buat.
-
-
-
-Masukkan nama pengguna dan sandi Administrator EspoCRM.
-
-
-
-Pada Halaman ini Anda dapat menetapkan pengaturan default EspoCRM, seperti format tanggal dan waktu, zona waktu, mata uang, dan lain-lain.
-
-
-
-Masukkan Pengaturan SMTP untuk surel keluar, jika Anda menginginkan untuk mengirim surel.
-Langkah ini dapat dilewatkan dengan mengeklik tombol _Selanjutnya_.
-Semua pilihan ini dapat ditambahkan/berubah di EspoCRM setelah instalasi.
-
-
-
-Selamat! Instalasi sudah selesai.
-Hal terakhir adalah aturlah Tugas Terjadwal agar dapat dijalankan oleh sistem Anda. Hal ini dapat dilakukan dengan menjalankan `crontab -e` di linux cli dan _Windows Tasks Scheduler_ di sistem Windows.
-
-
-
-Kami berharap Anda dapat menikmati pekerjaan Anda di EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/id_ID/administration/layout-manager.md b/i18n/id_ID/administration/layout-manager.md
deleted file mode 100644
index 5d010581e..000000000
--- a/i18n/id_ID/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Manajer Layout
-
-Manajer Layout tersedia di panel administrasi. Menyediakan kemampuan untuk menyesuaikan tampilan detail, edit, daftar tampilan, serta filter pencarian dan kolom untuk formulir pembaruan massal.
-
-## Daftar
-
-Layout utama untuk daftar tampilan. Mendefinisikan kolom dan parameternya.
-
-
-
-Parameter yang tersedia untuk kolom tercantum di bawah ini.
-
-### Lebar (%)
-
-Lebar kolom dalam persen, kosong berarti lebar-otomatis.
-
-### Link
-
-Jika dicek maka lapangan akan ditampilkan sebagai link ke tampilan detail rekam. Biasanya digunakan untuk bidang nama.
-
-### Tidak Berurut
-
-Nonaktifkan kemampuan untuk mengurutkan kolom
-
-### Sejajar
-
-Mensejajarkan kolom ke kiri atau ke kanan.
-
-## Detail
-
-Layout utama untuk tampilan detail dan tampilan edit. Mendefinisikan panel, baris dan sel. Sel berisi bidang.
-
-Baris bisa berisi dua sel atau satu sel yang diperluas hingga lebarnya memenuhi baris. Untuk menambahkan baris dengan sel yang diperluas Anda perlu menambahkan baris baru dan mengklik tanda minus pada sel apapun.
-
-
-
-## Daftar (Kecil)
-
-Daftar layout untuk panel hubungan. Juga bisa digunakan di tempat lain yang memungkinkan untuk menampilkan daftar dalam tampilan kecil.
-
-## Detail (Kecil)
-
-Tampilan detail untuk buat cepat, tampilan cepat dan mengedit formulir cepat.
-
-## Filter Pencarian
-
-Daftar bidang yang tersedia dalam tampilan daftar untuk pencarian.
-
-## Pembaruan Massal
-
-Daftar bidang yang tersedia dalam pembaruan formulis secara Massal.
-
-## Panel Hubungan
-
-Daftar panel hubungan ditampilkan pada tampilan bagian bawah detail. Panel bisa diorder ulang. Anda bisa menentukan warna panel dengan parameter _Style_.
-
-## Panel Samping
-
-Panel samping untuk Detil, Edit, Detail Kecil, Edit formulir Kecil. Menyediakan kemampuan untuk menyembunyikan atau mengorder ulang daftar panel Kegiatan, Sejarah, Tugas dan lain-lain. Panel dapat diwarnai dengan parameter _Style_.
-
-## Layout Tambahan
-
-Beberapa tipe entitas berisi layout tambahan: Mengubah Lead, Daftar untuk Akun.
diff --git a/i18n/id_ID/administration/ldap-authorization-for-ad.md b/i18n/id_ID/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index a6b7e4415..000000000
--- a/i18n/id_ID/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Otorisasi LDAP untuk Direktori Aktif
-
-Contoh konfigurasi otorisasi LDAP untuk server Direktori Aktif. Panduan lengkap dari konfigurasi otorisasi LDAP dijelaskan [di sini](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
\ No newline at end of file
diff --git a/i18n/id_ID/administration/ldap-authorization-for-openldap.md b/i18n/id_ID/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 40558ca82..000000000
--- a/i18n/id_ID/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Otorisasi LDAP untuk OpenLDAP
-
-Contoh konfigurasi otorisasi LDAP untuk server OpenLDAP. Panduan lengkap dari konfigurasi otorisasi LDAP dijelaskan [di sini](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/id_ID/administration/ldap-authorization.md b/i18n/id_ID/administration/ldap-authorization.md
deleted file mode 100644
index b0b565934..000000000
--- a/i18n/id_ID/administration/ldap-authorization.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Otorisasi Ldap
-
-Dalam panduan ini, kami akan menunjukkan cara mengkonfigurasi otorisasi LDAP untuk EspoCRM. Ayo!
-
-Buka server LDAP Anda dan buat _base_ DN untuk pengguna EspoCRM seperti
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Kita harus membuat pengguna sistem yang memiliki akses ke pengguna DN (“cn=espo-users,ou=users,dc=espo,dc=local”). Jadi, DN yang lengkap untuk pengguna sistem ini akan menjadi
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Sekarang, kita dapat menambahkan pengguna LDAP untuk mengakses EspoCRM. Misalnya Espo Tester dengan nama pengguna “tester” di dalam DN “cn=espo-users,ou=users,dc=espo,dc=local”. Harap diperhatikan: Agar dapat menggunakan format login untuk EspoCRM ini, Anda harus menentukan opsi “Username Attribute” dan “Base DN”.
-
-Kemudian, buka pengaturan Otentikasi EspoCRM di panel Administrator, pilih metode `LDAP` dan isi rincian LDAP dengan:
-
-
-
-* Host – IP LDAP atau nama host.
-* Port – port koneksi.
-* Auth – akses kredensial untuk server LDAP:
- * Full User DN – pengguna sistem penuh DN memungkinkan untuk mencari pengguna lain.
- * Password – kata sandi untuk mengakses server LDAP.
-* Security – protokol TSL atau SSL.
-* Username Attribute – atribut untuk mengidentifikasi pengguna. Untuk Direktori Aktif dapat berupa “userPrincipalName” atau “sAMAccountName”.
-* Account Canonical Form – ketik formulir canonical akun Anda. Ada 4 opsi:
- * Dn – formulir dalam format `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – formulir `tester`.
- * Backslash – formulir `COMPANY\tester`.
- * Principal – formulir `tester@company.com`.
-* Bind Requires Dn – diperlukan jika ingin memformat nama pengguna di formulir DN.
-* Base Dn – base default DN yang digunakan untuk mencari pengguna
-* User Login Filter – filter yang memungkinkan untuk membatasi pengguna yang mengakses EspoCRM. Misalnya `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – Domain yang digunakan untuk otorisasi server LDAP.
-* Account Domain Name Short – Domain pendek yang digunakan untuk otorisasi server LDAP.
-* Try Username Split – opsi untuk membagi username dengan domain.
-* Opt Referrals – jika rujukan harus diikuti ke klien LDAP.
-* Create User in EspoCRM – opsi ini memungkinkan EspoCRM membuat pengguna dari LDAP.
- * User First Name Attribute – atribut LDAP yang digunakan untuk menentukan nama pertama pengguna.
- * User Last Name Attribute – atribut LDAP yang digunakan untuk menentukan nama terakhir pengguna.
- * User Title Attribute – atribut LDAP yang digunakan untuk menentukan gelar pengguna.
- * User Email Address Attribute – atribut LDAP yang digunakan untuk menentukan surel pengguna.
- * User Phone Number Attribute – atribut LDAP yang digunakan untuk menentukan nomor ponsel pengguna.
-
-Sekarang, masuk ke halaman login dan masukkan kredensial pengguna.
-
-
-
-Pengguna telah dikonfirmasi dan dibuat secara otomatis di EspoCRM.
-
-## Petunjuk konfigurasi berdasarkan server Anda:
-* [server Direktori Aktif](ldap-authorization-for-ad.md)
-* [server OpenLDAP](ldap-authorization-for-openldap.md)
-
-Informasi lebih lanjut tentang mengonfigurasi LDAP dapat Anda baca di laman [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/), karena EspoCRM menggunakan _library_ ini.
-
-
-
-
diff --git a/i18n/id_ID/administration/maps.md b/i18n/id_ID/administration/maps.md
deleted file mode 100644
index 4aa041535..000000000
--- a/i18n/id_ID/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Peta
-
-## Bagaimana menampilkan peta berdasarkan bidang alamat
-
-Setiap bidang ALamat memiliki bidang Peta yang cocok. Yang Anda butuhkan adalah menaruhnya pada layout Detail. Ini menggunakan layanan Google Maps.
-
-`Administration > Layout Manager > Choose entity (Account, Contact, Lead or custom one) > Detail > Drag & Drop Map field.`
-
-Buatlah lebar sel dengan tanda minus.
-
-Anda juga dapat mengkonfigurasi tinggi bidang Anda.
-
-`Administration > Entity Manager > Choose entity > Fields > find the map field and click on it > edit the height and save.`
-
-## Kunci Api
-
-Sejak EspoCRM versi 4.2.0 Anda harus menentukan Kunci Api untuk menggunakan Google Maps ((Administration > Integration > Google Maps).
-
diff --git a/i18n/id_ID/administration/moving-to-another-server.md b/i18n/id_ID/administration/moving-to-another-server.md
deleted file mode 100644
index 6269ce308..000000000
--- a/i18n/id_ID/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Memindahkan EspoCRM ke server lain
-
-Ikuti langkah berikut untuk memindahkan EspoCRM ke server lain:
-
-### Langkah 1. Backup file
-
-Buka file manager atau login via SSH untuk mengarsipkan file yang tersedia dari direktori EspoCRM. [Detail lebih lanjut](backup-and-restore.md#langkah-1-backup-file).
-
-### Lagkah 2. Backup database Anda
-
-Data yang tersimpan dalam database (MySQL, MariaDB) harus di-_backup_. Silakan ikuti [saran berikut](backup-and-restore.md#langkah-2-backup-database).
-
-### Langkah 3. Salin file dan backup database ke server lain
-
-Salin file backup database Anda ke server baru.
-
-### Langkah 4. Buka arsip file backup
-
-Untuk membuka arsip file backup, Anda dapat menggunakan Archive Manager atau [petunjuk berikut](backup-and-restore.md#langkah-1-buka-arsip-file-backup).
-Catatan: File harus berada dalam direktori web-server.
-
-### Langkah 5. Konfigurasi server
-
-Konfigurasikan server baru berdasarkan [rekomendasi ini](server-configuration.md).
-
-### Langkah 6. Koreksi izin
-
-Atur [izin](server-configuration.md#izin-yang-diperlukan-untuk-sistem-berbasis-unix) yang diperlukan dan pemilik file.
-
-### Langkah 7. Impor backup database Anda
-
-Pertama, Anda harus membuat database baru dengan pengguna di MySQL. Untuk mengimpor database dari backup, ikuti [langkah ini](backup-and-restore.md#langkah-3-impor-database-dump).
-
-### Langkah 8. Koreksi konfigurasi EspoCRM
-
-Setelah sukses mengimpor dan mengkonfigurasi server, silakan koreksi konfigurasi EspoCRM di dalam file `ESPOCRM_DIRECTORY/data/config.php`:
-
- * pengaturan koneksi database:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - jika nama domain Anda (URL) berubah:
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * pemilik file default (jika berbeda):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- dimana `www-data` adalah pengguna web-server Anda.
-
-### Langkah 9. Atur crontab
-
-Atur [crontab](server-configuration.md#mengatur-crontab).
-
-Catatan: ini harus dikonfigurasi dibawah pengguna web-server Anda.
-
-Itu saja. Sekarang EspoCRM Anda berjalan di server baru.
diff --git a/i18n/id_ID/administration/nginx-server-configuration.md b/i18n/id_ID/administration/nginx-server-configuration.md
deleted file mode 100644
index 15bdc0298..000000000
--- a/i18n/id_ID/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Konfigurasi server Nginx untuk EspoCRM
-
-Petunjuk ini sudah ditambahkan pada panduan [Konfigurasi Server](server-configuration.md). Harap dicatat bahwa semua pengaturan konfigurasi yang tercantum di sini dibuat pada server Ubuntu.
-
-## Persyaratan PHP
-
-Untuk menginstal semua perpustakaan yang diperlukan, jalankan command ini dalam terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Memperbaiki masalah “API Error: EspoCRM API is unavailable”:
-
-Ikuti langkah berikut. Periksa apakah masalah terpecahkan setelah langkah ini diikuti.
-
-### 1. Aktifkan dukungan "mod_rewrite" di Nginx
-
-Untuk mengaktifkan "mod_rewrite", jalankan command ini dalam terminal:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Jika Anda tidak memiliki file ini, Anda harus membuatnya. Caranya bukalah terminal dan jalankan command berikut:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Dan tambahkan kode yang tercantum di atas. Untuk selengkapnya tentang cara mengkonfigurasi Virtual Host baru pada Nginx, silahkan baca ini [panduan](nginx-virtual-host.md).
-
-Jalankan command berikut dalam terminal untuk memeriksa apakah semuanya baik-baik saja:
-
-```
-sudo nginx -t
-```
-
-Jika sudah, jalankan command untuk me-restart nginx server:
-
-```
-sudo service nginx restart
-```
-
-### 2. Tambahkan path RewriteBase
-
-Buka file /ESPOCRM_DIRECTORY/api/v1/.htaccess dan ganti dengan baris kode berikut:
-
-```
-# RewriteBase /
-```
-dengan
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-dimana REQUEST_URI adalah bagian dari URL, contohnya untuk “http://example.com/espocrm/”, REQUEST_URI-nya adalah “espocrm”.
diff --git a/i18n/id_ID/administration/nginx-virtual-host.md b/i18n/id_ID/administration/nginx-virtual-host.md
deleted file mode 100644
index 47e0eb1e2..000000000
--- a/i18n/id_ID/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Mengkonfigurasi Virtual Host di Nginx untuk EspoCRM
-
-Dalam panduan ini, kami akan menunjukkan cara mengkonfigurasi virtual host di Nginx untuk EspoCRM di server Ubuntu.
-
-## Buat file blok server
-
-Untuk membuat file ini, buka terminal dan jalankan command:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Sekarang buka file ini (/etc/nginx/sites-available/espocrm.conf) dan ubah kode berikut dengan mengikuti format yang tercetak dibawah ini (beberapa pengaturan mungkin berbeda berdasarkan konfigurasi Anda):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Aktifkan blok server ini
-
-Buat link symbolic:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-```
-
-Jalankan command ini untuk memeriksa apakah semuanya berjalan lancar:
-
-```
-sudo nginx -t
-```
-
-Dan restart server Nginx:
-
-```
-sudo service nginx restart
-```
-
-## Konfigurasi local hosts Anda (opsional, untuk domain lokal saja)
-
-Jika Anda menambahkan domain lokal, Anda harus mengkonfigurasnya di komputer lokal Anda (bukan di server). Untuk Ubuntu, buka file /etc/hosts dan tambahkan baris:
-
-```
-192.168.1.1 espocrm.local # specify the IP address of your Nginx server
-```
-
-Untuk Windows, silakan ikuti [petuntuk](http://support.microsoft.com/kb/923947) berikut.
diff --git a/i18n/id_ID/administration/roles-management.md b/i18n/id_ID/administration/roles-management.md
deleted file mode 100644
index 6b58fdc41..000000000
--- a/i18n/id_ID/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Peran Manajemen
-
-## Ikhtisar
-
-Untuk membatasi akses bagi beberapa pengguna, Anda perlu menggunakan Peran. Administrator dapat mengelola peran di panel Administrasi. Setiap peran mendefinisikan akses ke area tertentu (cakupan) yang diterapkan pada pengguna yang memiliki peran tersebut.
-
-Satu pengguna dapat memiliki banyak peran. Peran tersebut dapat dipilih untuk pengguna tertentu (bidang 'Peran' di entri Pengguna) dan/atau diwarisi dari tim yang menjadi milik pengguna.
-
-Jika pengguna memiliki banyak peran maka mereka akan digabungkan sehingga aturan permisif akan memiliki prioritas lebih tinggi. Itu memungkinkan administrator mengatur kontrol tingkat akses dengan mudah dan fleksibel.
-
-Anda dapat melihat izin apa yang diterapkan pada pengguna tertentu dengan mengeklik tombol 'Akses' pada tampilan detail pengguna.
-
-
-
-## Contoh
-
-Misalnya, pengguna milik tim 'Penjualan'. Tim itu memiliki peran tunggal 'Penjual'. Jadi semua pengguna dari tim ini akan mendapatkan peran 'Penjual'.
-
-Peran 'Penjual' didefinisikan sebagai berikut:
-
-Judul:
-```
-buat – ya
-baca – tim
-ubah – sendiri
-hapus – tidak
-siaran – tim
-```
-
-Opportuniti:
-```
-buat – ya
-baca – tim
-ubah – sendiri
-hapus – tidak
-siaran – tim
-```
-
-Pengguna hanya dapat membaca prospek dan peluang yang dimiliki tim 'Departemen Penjualan' (bidang 'Tim').
-Pengguna hanya dapat mengubah prospek dan peluang yang mereka tentukan atau yang telah mereka buat.
-Pengguna tidak dapat menghapus prospek atau peluang apa pun.
-
-Kami ingin memberikan lebih banyak hak kepada pengguna tertentu yang memegang posisi manajer penjualan di perusahaan. Karyawan ini harus memiliki kemampuan untuk membaca/mengubah/menghapus semua rekaman dari tim 'Penjualan'. Pengguna harus menjadi anggota tim 'Penjualan' kami. Namun, kami perlu membuat peran baru 'Manajer Penjualan' dan memilih peran ini untuk pengguna di bidang 'Peran'.
-
-Peran 'Manajer Penjualan' didefinisikan sebagai berikut:
-
-Judul:
-```
-buat – ya
-baca – tim
-ubah – tim
-hapus – tim
-siaran – tim
-```
-
-Opportunity:
-```
-buat – ya
-baca – tim
-ubah – tim
-hapus – tim
-siaran – tim
-```
-
-Our user will be able to manager all leads and opportunities from the ‘Sales’ team.
-
-## Izin Khusus
-
-### Izin Penugasan
-
-Tetapkan parameter ini untuk membatasi kemampuan untuk menetapkan ulang catatan ke pengguna dan/atau tim lain. Jika Anda menetapkan `tim` - maka akan memungkinkan untuk menetapkan hanya kepada pengguna dari tim sendiri. Jika `no` - pengguna tidak akan dapat menugaskan kembali sama sekali.
-
-Ini juga mendefinisikan apakah pengguna dapat mengirim ke pengguna lain/tim lain.
-
-### Izin Pengguna
-
-Memungkinkan untuk membatasi kemampuan pengguna untuk melihat aktivitas, kalender, dan arus pengguna lain.
-
-### Izin Portal
-
-Mendefinisikan akses ke informasi portal, kemampuan untuk mengirim pesan ke pengguna portal.
-
-### Izin Akun Surel Grup
-
-Mendefinisikan akses ke akun surel grup, kemampuan untuk mengirim surel dari grup SMTP.
-
-### Izin Mengekspor
-
-Mendefenisikan apakah pengguna memiliki kemampuan untuk mengekspor catatan. (sejak versi 4.9.0)
-
-## Izin secara Default
-
-Secara default (jika tidak ada pengguna yang diterapkan), pengguna dapat membaca dan mengedit semua catatan. Tetapi tidak dapat menghapus yang manapun kecuali yang telah mereka buat dan mereka ditugaskan pada saat bersamaan.
-
-Ada kemampuan untuk membatasi akses yang diterapkan secara default dengan mengaktifkan 'Mode Strict ACL' di Administrasi> Pengaturan.
-
-## Keamanan Tingkat Bidang
-
-Memungkinkan untuk mengontrol akses untuk bidang tertentu.
-
-Secara default user bisa membaca semua bidang jika seseorang bisa membaca rekaman. Pengguna bisa mengubah bidang mana pun jika bisa mengubah rekaman. Anda dapat membatasi akses ke bidang tertentu menggunakan Keamanan Tingkat Bidang.
-
-Pada tampilan mengubah catatan peran di kolom Level Bidang klik ikon plus disebelah scope spesifik lalu pilih bidang yang dibutuhkan. Kemudian Anda akan dapat menentukan tingkat akses untuk tindakan `baca` dan `edit`. Ada pilihan: `yes` dan` no`.
-
-
diff --git a/i18n/id_ID/administration/server-configuration.md b/i18n/id_ID/administration/server-configuration.md
deleted file mode 100644
index 0f9b63edd..000000000
--- a/i18n/id_ID/administration/server-configuration.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Konfigurasi Server untuk EspoCRM
-
-EspoCRM dapat diinstal di Apache ([intruksi](apache-server-configuration.md)), Nginx ([intruksi](nginx-server-configuration.md)), atau server IIS dengan dukungan versi PHP 5.6 atau lebih dan MySQL versi 5.1 atau yang lebih baru.
-
-## Rekomendasi Konfigurasi
-
-### Persyaratan PHP
-
-EspoCRM membutuhkan PHP 5,6 atau lebih, dengan ekstensi berikut diaktifkan:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – untuk mengakses MySQL di PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – sumber menggunakan format ini (metadata, tata letak, bahasa, dan lain-lain);
-* [GD](http://php.net/manual/en/book.image.php) – untuk memanipulasi gambar;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – untuk memastikan perlindungan tertinggi;
-* [Zip](http://php.net/manual/en/book.zip.php) – untuk mengupgrade EspoCRM dan memasang ekstensi;
-* [IMAP](http://php.net/manual/en/book.imap.php) – to memantau kotak masuk di EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Ini juga disarankan untuk memasang ekstensi pecl [mailparse](https://pecl.php.net/package/mailparse). Ini diperlukan untuk kelancaran fitur pengambilan email.
-
-
-pengaturan php.ini:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Persyaratan MySQL
-
-EspoCRM mendukung versi MySQL 5.1 atau yang lebih baru.
-Ini bukan kekhasan khusus. Semua pengaturan standar bagus untuk EspoCRM.
-
-## Izin yang diperlukan untuk Sistem Berbasis Unix
-
-File dan direktori harus memiliki izin berikut:
-
-* `/data`, `/custom`, `/client/custom` – harus dapat ditulis semua file, direktori dan subdirektori (664 untuk file, 775 untuk direktori, termasuk semua subdirektori dan file);
-* `/application/Espo/Modules`, `/client/modules` – harus dapat ditulis direktori saat ini (775 untuk direktori saat ini, 644 untuk file, 755 untuk direktori dan subdirektori);
-* Semua file dan direktori lainnya harus dibaca (644 untuk file, 755 untuk direktori).
-
-Untuk mengatur hak akses, jalankan perintah ini di terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Semua file harus dimiliki dan milik-kelompok oleh proses webserver. Bisa berupa "www-data", "daemon", "apache", "www", dll.
-Catatan: Di Bitnami Stack, file harus dimiliki dan milik-kelompok oleh pengguna "daemon".
-Catatan: Pada host bersama, file harus dimiliki dan milik-grup oleh akun pengguna Anda.
-
-Untuk mengatur pemilik dan milik-grup, jalankan perintah ini di terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## Mengatur crontab
-
-Untuk menyiapkan crontab pada sistem UNIX, lakukan langkah-langkah berikut:
-
-* 1. Login sebagai administrator ke contoh EspoCRM Anda.
-* 2. Pergi ke bagian Pekerjaan Terjadwal di panel administrator (Menu> Administrasi> Pekerjaan Terjadwal) dan salin string untuk crontab. Bentuknya seperti ini:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Buka terminal dan jalankan perintah ini:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER dapat menjadi salah satu berikut "www", "www-data", "apache", dll (tergantung pada server web Anda).
-* 4. Tempel string yang disalin (dari langkah 2) dan simpan file crontab (Ctrl+O, lalu Ctrl+X untuk editor nano).
-
-## Petunjuk konfigurasi berdasarkan server Anda:
-
-* [Konfigurasi server Apache](apache-server-configuration.md).
-* [Konfigurasi server Nginx](nginx-server-configuration.md).
diff --git a/i18n/id_ID/administration/troubleshooting.md b/i18n/id_ID/administration/troubleshooting.md
deleted file mode 100644
index 342d9fa98..000000000
--- a/i18n/id_ID/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Penyelesaian Masalah
-
-## Periksa log
-
-Untuk mengetahui masalahnya, Anda harus memeriksa file error log.
-
-#### Log kesalahan EspoCRM
-
-Log EspoCRM terletak di `/logs/*.log` dan berisi beberapa informasi kesalahan.
-
-#### Log kesalahan Apache
-
-Untuk server Ubuntu log kesalahan apache terletak di `/var/log/apache2/error.log` dan berisi semua informasi kesalahan. Lokasi file log bisa berbeda pada sistem lain.
-
-## Aktifkan mode debugging
-
-Untuk mengaktifkan mode debugging, masuk ke direktori EspoCRM yang terinstal, buka file `data/config.php` dan ubah nilainya:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-menjadi
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Pekerjaan Terjadwal tidak bekerja
-
-#### Masalah #1: Crontab Anda tidak dikonfigurasi
-
-1. Login melalui SSH ke server anda.
-
-2. Konfigurasikan crontab Anda dengan mengikuti [langkah-langkah berikut](server-configuration.md#mengatur-crontab).
-
-Catatan: Crontab harus dikonfigurasi di bawah pengguna server web, misalnya `crontab -e -u www-data`
-
-3. Tunggu beberapa saat dan periksa Pekerjaan Terjadwal untuk melihat apakah ada pekerjaan yang dieksekusi (lihat panel Log).
-
-#### Masalah #2. Crontab telah dikonfigurasi, namun Pekerjaan Terjadwal tidak berfungsi
-
-Untuk memastikan tidak ada kesalahan saat cron sedang berjalan, coba jalankan perintah cron di terminal:
-
-1. Login melalui SSH ke server anda.
-
-2. Masuk ke direktori tempat EspoCRM diinstal. Misalnya untuk direktori `/var/www/html/espocrm` perintahnya adalah:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Jalankan perintah crontab:
-
-```bash
-php cron.php
-```
-
-Catatan: Ini harus dijalankan di bawah pengguna web-server. Jika Anda login sebagai root, perintahnya seharusnya (misalnya untuk Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-dimana `www-data` adalah pengguna web-server.
-
-4. Jika tidak ada kesalahan, periksa Pekerjaan Terjadwal untuk melihat apakah ada pekerjaan yang dijalankan (lihat panel Log).
-
-## EspoCRM tidak loading setelah updgare
-
-Hal ini terkadang dapat terjadi pada beberapa shared hostings.
-
-Periksa izin file:
-/index.php
-/api/v1/index.php
-
-File tersebut harus 644. Jika salah satu dari file tersebut memiliki izin 664, Anda perlu mengubahnya menjadi 644. Gunakan panel kontrol atau perintah chmod hosting Anda.
-
-```
-chmod 644 /path/to/file
-```
-Informasi lebih lanjut tentang hak akses file: [disini](server-configuration.md#izin-yang-diperlukan-untuk-sistem-berbasis-unix).
diff --git a/i18n/id_ID/administration/upgrading.md b/i18n/id_ID/administration/upgrading.md
deleted file mode 100644
index d2c124b54..000000000
--- a/i18n/id_ID/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Bagaimana Meng-upgrade EspoCRM
-
-EspoCRM dapat diupgrade ke versi terbaru dengan mengikuti langkah berikut:
-
-### Langkah 1. Periksa versi Anda saat ini
-
-Untuk memeriksa versi Anda saat ini, masuk ke halaman Administrasi> Halaman upgrade.
-
-### Langkah 2. Download paket upgrade yang dibutuhkan
-
-Buka halaman upgrade https://www.espocrm.com/download/upgrades/ dan pusatkan versi paket download yang Anda gunakan saat ini.
-
-### Langkah 3. Buatlah cadangan (opsional)
-
-Buatlah cadangan file dan data EspoCRM Anda sebelum melakukan upgrade. Ikuti [petunjuk ini](backup-and-restore.md) untuk menyelesaikannya.
-
-### Step 4. Proses upgrade
-
-Buka Administrasi> Upgrade. Unggah dan instal satu demi satu paket upgrade.
-
-Anda dapat memeriksa apakah Anda memiliki versi terbaru di Menu> About.
-
-## Upgrade lewat CLI
-
-Anda juga bisa menjalankan upgrade lewat baris perintah antar muka. Anda perlu menjalankan perintah berikut dari direktori root EspoCRM:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/id_ID/administration/workflows.md b/i18n/id_ID/administration/workflows.md
deleted file mode 100644
index 792e8e52f..000000000
--- a/i18n/id_ID/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Alur Kerja
-
-Fitur alur kerja tersedia di [Paket Lanjutan](https://www.espocrm.com/extensions/advanced-pack/).
-
-Alur kerja mengotomatisasi proses bisnis Anda dengan mudah. Anda dapat menemukannya dalam Panel administrasi. Untuk membuat aturan alur kerja Anda perlu menentukan:
-
-* Target entitas - jenis alur kerja apa yang entitas diterapkan;
-* Jenis pemicu - ketika alur kerja akan dipicu;
-* Kondisi - kondisi yang harus dipenuhi untuk memicu alur kerja;
-* Tindakan - apa yang harus dilakukan jika alur kerja dipicu.
-
-
-## Tipe Pemicu
-
-### Setelah rekaman dibuat
-
-Dipicu hanya ketika rekaman baru diciptakan. Jika kondisi yang ditentukan terpenuhi maka tindakan akan dieksekusi.
-
-### Setelah rekaman disimpan
-
-Dipicu ketika catatan yang sudah ada baru dibuat atau diperbarui . Jika kondisi yang ditentukan terpenuhi maka tindakan akan dieksekusi.
-
-Untuk aturan alur kerja dengan jenis pemicu ini adalah praktik umum untuk memiliki kondisi yang memeriksa apakah beberapa bidang 'berubah'. Misalnya jika status Kasus diubah maka lakukan beberapa tindakan.
-
-### Terjadwal
-
-Dipicu menurut penjadwalan yang telah ditentukan. Anda dapat mengaturnya agar berjalan setiap hari, setiap minggu, dll. Tindakan akan diterapkan untuk catatan yang dikembalikan oleh daftar laporan yang ditentukan. Jadi Anda juga perlu membuat daftar laporan.
-
-Penjadwalan ditentukan dalam notasi crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### Sekuensial
-
-Jarang digunakan. Seharusnya dijalankan oleh alur kerja lain. Menyediakan kemampuan untuk membuat logika yang kompleks.
-
-Catatan: Untuk alur kerja sekuensial, disarankan untuk menggunakan [alat BPM](bpm.md) daripada fitur Alur kerja.
-
-## Kondisi
-
-Anda bisa menentukan kondisi yang harus dipenuhi untuk memicu alur kerja. Ada dua cara bagaimana kondisi bisa ditentukan: dengan pembangun kondisi UI dan dengan rumus.
-
-### Pembangunan kondisi UI
-
-Beberapa tipe kondisi yang tersedia:
-
-* _sama dengan_ - bidang sama dengan nilai tertentu atau nilai bidang lain;
-* _sudah sama_ - bidang sama dengan nilai tertentu sebelum alur kerja dipicu;
-* _tidak sama_ - bidang tidak sama dengan nilai tertentu atau nilai bidang lain;
-* _sudah tidak sama_ - bidang tidak sama dengan nilai spesifik sebelum alur kerja dipicu;
-* _kosong_ - nilai bidang kosong;
-* _tidak kosong_ - nilai field tidak kosong;
-* _berubah_ - bidang telah berubah;
-* _tidak berubah_ - bidang tidak berubah.
-
-### Kondisi rumus
-
-Rumus menyediakan kemampuan untuk menentukan kondisi kompleksitas apapun. Untuk membaca tentang sintaks rumus ikuti [artikel ini](formula.md).
-
-Catatan: Seharusnya tidak ada pembatas `;` yang digunakan dalam kode rumus saat menentukan suatu kondisi.
-
-## Tindakan
-
-### Mengirim surel
-
-Sistem akan mengirim surel menggunakan template surel yang ditentukan. Alamat surel penerima dapat diambil dari catatan target, catatan terkait, pengguna terkini, pengikut, pengguna tim atau yang ditentukan. Surel dapat dikirim segera atau tertunda untuk interval tertentu.
-
-### Buat rekaman
-
-Sistem akan membuat record baru dari tipe entitas manapun. Jika ada hubungan antara target rekaman dan menciptakan rekaman, memungkinkan untuk menghubungkan rekaman.
-
-Anda dibolehkan untuk mendefinisikan rumus untuk menghitung bidang.
-
-### Membuat Rekaman Terkait
-
-Sistem akan membuat rekaman yang berhubungan dengan target rekaman. Ini memungkinkan untuk mendefinisikan rumus untuk menghitung bidang.
-
-### Memperbarui Target Rekaman
-
-Memungkinkan perubahan bidang spesifik dari catatan target. Mungkin untuk mendefinisikan rumus untuk menghitung bidang.
-
-Jika Anda perlu menambahkan item baru ke bidang Tautan-Multiple tanpa kehilangan data yang ada (misalnya Tim) Anda perlu menggunakan fungsi rumus entity\addLinkMultipleId. Contoh: `entity \ addLinkMultipleId ('tim', 'teamId')`.
-
-### Memperbarui Rekaman Terkait
-
-Memungkinkan perubahan bidang spesifik catatan atau catatan terkait. Ini memungkinkan untuk mendefinisikan rumus untuk menghitung bidang.
-
-### Tautkan dengan Rekaman Lain
-
-Mengaitkan entitas target dengan entitas spesifik lainnya. Misalnya menambahkan tim tertentu ke catatan.
-
-### Batalkan Tautan dengan Rekaman Lain
-
-Tidak mengaitkan entitas target dari entitas spesifik lainnya. Misalnya menghapus tim tertentu dari catatan.
-
-### Terapkan Aturan Tugas
-
-Tetapkan catatan target kepada pengguna berdasarkan aturan distribusi. Ada dua aturan yang tersedia: Round-Robin dan Least-Busy.
-
-* Round-Robin - pengguna dipilih dari atas ke bawah daftar (tim) dan kemudian mulai lagi.
-* Least-Busy - pengguna yang memiliki lebih sedikit catatan yang ditugaskan akan dipilih untuk tugas.
-
-_Daftar Laporan_ - Untuk distribusi Least-Busy menentukan catatan apa yang akan diperhitungkan untuk menghitung jumlah catatan yang ditugaskan. Misalnya untuk Kasus kita hanya perlu mengambil catatan dengan status aktif.
-
-### Membuat Pemberitahuan
-
-Beritahu pengguna tertentu dengan pesan. Ini memungkinkan menggunakan placeholder dalam template pesan: {entitas} - target rekaman, {pengguna} - pengguna saat ini.
-
-### Membuat Diikuti
-
-Memaksa pengguna tertentu untuk mengikuti entitas target atau entitas terkait yang terkait.
-
-### Trigger Another Workflow Memicu Alur Kerja Lainnya
-
-Memungkinkan untuk membuat alur kerja berurutan. Ini memungkinkan dengan alur kerja cabang berdasarkan kondisi: Anda dapat mengatur alur kerja untuk memicu dua alur kerja dengan kondisi berbeda yang didefinisikan dalam alur kerja tersebut.
-
-Ini memungkinkan menunda eksekusi alur kerja sekuensial. Dalam alur logika berurutan Anda dapat menentukan kondisi yang memeriksa apakah bidang spesifikasi berubah karena alur kerja induk dipicu dengan menggunakan tipe kondisi _Berubah_ dan _Sudah Sama_.
-
-Catatan: Untuk alur kerja sekuensial, disarankan untuk menggunakan [alat BPM](bpm.md) daripada fitur Alur kerja.
-
-### Menjalankan Tindakan Layanan
-
-Mengizinkan untuk menjalankan skrip layanan tertentu. Secara default ada tindakan berikut yang tersedia:
-
-* Kirim Undangan - untuk Rapat/Panggilan;
-* Tambahkan Item Kutipan - untuk Penawaran.
-
-Pengembang dapat menulis tindakan layanan mereka sendiri. Lihat [selengkapnya](../ development / workflow-service-actions.md).
-
-## Menggunakan Rumus dalam Tindakan
-
-Ini memungkinkan untuk mendefinisikan rumus untuk menghitung bidang untuk Membuat Catatan, Memperbarui Target Catatan, Membuat catatan Terkait, Memperbarui Catatan Terkait. Untuk dua yang terakhir, untuk mengakses atribut entitas target Anda harus menggunakan Fungsi `targetEntity\attribute`. Untuk mengakses atribut entitas target yang telah ditentukan sebelum alur kerja dipicu gunakan fungsi `targetEntity\attributesFetched`.
-
-Contoh:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/id_ID/user-guide/browser-support.md b/i18n/id_ID/user-guide/browser-support.md
deleted file mode 100644
index 1120d2fc1..000000000
--- a/i18n/id_ID/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Browser support
-
-Kami merekomendasikan menggunakan versi terbaru dari Google Chrome atau Mozilla Firefox. EspoCRM bekerja sangat baik di browser ini. Kami rutin menguji semua fitur di browser ini.
-
-Microsoft Edge dan Safari juga didukung, namun ada tidak ada jaminan bahwa semuanya akan berjalan dengan lancar.
-
-Kami sangat tidak merekomendasikan menggunakan Internet Explorer 11.
diff --git a/i18n/id_ID/user-guide/emails.md b/i18n/id_ID/user-guide/emails.md
deleted file mode 100644
index 245282683..000000000
--- a/i18n/id_ID/user-guide/emails.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Panduan Menggunakan Email
-
-EspoCRM membolehkan untuk mengambil email dari kotak IMAP. Hal ini memungkinkan untuk menggunakan EspoCRM sebagai klien email dan juga fitur khusus CRM.
-
-## Akun IMAP
-
-*Catatan: Anda harus mempunyai [cron](../administration/server-configuration.md#mengatur-crontab) yang dikonfigurasi dengan benar di sistem Anda agar email masuk bekerja.*
-
-Pengguna dapat mengatur akun IMAP pada halaman Akun Email Pribadi (Tab email> menu kanan atas> Akun Email Pribadi).
-
-Tentukan folder mana yang akan dipantau pada kolom Folder Pantauan. Secara default itu diatur ke KOTAK MASUK. Jika Anda menggunakan beberapa klien email eksternal untuk mengirim email, Anda dapat menambahkan folder Terkirim untuk mengarsipkan email tersebut.
-
-*Fetch Since* mengizinkan Anda untuk memilih tanggal email dari mana yang harus diarsipkan. Tetapkan ke beberapa tanggal sebelum hari ini jika Anda perlu mengarsipkan email lama.
-
-Anda dibolehkan menentukan *Folder* dalam Akun Email Pribadi. Email masuk akan dimasukkan ke delam folder tersebut.
-
-## Akun SMTP
-
-Pengguna dapat mengatur pengaturan SMTP di Preferensi seperti di Akun Email Pribadi mereka. Administrator juga dapat mengizinkan untuk menggunakan sistem SMTP (bersamaan).
-
-Pengguna dapat mempunyai beberapa akun SMTP (sejak versi 4.2.0). Tetapi alamat email pengguna dapat digunakan untuk mengirim email dari yang sudah ditentukan oleh alamat email dari riwayat *Pengguna*.
-
-## Bekerja dengan Email
-
-Email diambil oleh cron (di latar belakang) setiap beberapa menit (periode dapat ditentukan oleh Administrator).
-Anda dapat melihat semua email Anda di tab Email. Disana ada folder standar Kotak Masuk, Terkirim, Draft di sebelah kiri.
-
-Kolom *Status*. `Terkirim` artinya dikirim dari CRM, `Diarsipkan` - diambil dari akun IMAP atau diarsipkan secara manual, `Draft` - artinya email dibuat sebagai draft.
-
-Ketika email baru masuk sistem akan mencoba mengenali catatan email mana yang menjadi miliknya. Ini dapat ditautkan dengan Akun, Judul, Kemungkinan, Kejadian (dan Kontak pada mode B2C) dll. Jika tidak dikenali maka pengguna bisa menautkannya secara manual dengan mengisi kolom *Utama*.
-
-Jika email berasal dari pengguna klien potensial baru dapat **Mengubahnya ke Judul**. Buka entri email dan klik Buat Judul di menu kanan atas.
-
-Ini juga memungkinkan untuk **membuat Task atau Kejadian** dari catatan sebuah email.
-
-Jika alamat email (dari, ke, cc) pada catatan email diketahui sistem akan menampilkan orang yang mereka kenal (Kontak, Pimpinan, Pengguna dll). Jika email tersebut baru Anda dapat **membuat kontak** langsung dari sana.
-
-Semua alamat email yang terkait dengan catatan tertentu ditampilkan di panel Riwayat catatan itu. Jika beberapa email saja yang terkait, misalnya, untuk kesempatan tetapi kesempatan akan terkait dengan akun, maka akan ditunjukan ke kesempatan dan akun.
-
-## Mengirim Email
-
-Anda dapat menulis email baru dengan cara berikut:
-* Tombol *Tulis Email* pada tampilan daftar Email;
-* membalas email lain;
-* mengklik alamat email dari beberapa catatan;
-* Tindakan *Tulis Email* pada panel Aktivitas.
-
-Ada pilihan untuk **memilih template** dari email anda.
-
-Anda dapat mengatur **tanda tangan email** di Preferensi.
-
-## Folder Email
-
-Pengguna dapat membuat folder email mereka sendiri untuk memasukkan beberapa email agar santai. Daftar folder yang tersedia tersedia di halaman Email di sisi kiri. Untuk membuat atau mengedit folder ikuti Email> geser kebawah di pojok kanan atas> Folder. `Lewati Notifikasi` artinya Anda tidak akan diberi tahu tentang email masuk yang masuk ke folder tertentu. Dengan memanfaatkan Email Filter, memungkinkan memasukkan email ke folder secara otomatis menurut kriteria tertentu.
-
-## Penyaring Email
-
-Administrator dapat membuat filter email global untuk melewatkan email yang tidak diinginkan. Penyaring email tersedia di Administrasi> Penyaring Email.
-
-Pengguna biasa dapat membuat filter email untuk Akun Email Pribadi mereka atau untuk keseluruhan kotak masuk mereka. Mereka tersedia di Email> geser kebawah di pojok kanan atas> Filter.
-
-Ada dua jenis penyaringan:
-* Lewati - email akan dimasukan dalam *Sampah* atau tidak diimpor jika penyaringna tersebut terkait dengan Akun Email Personal.
-* Masukkan ke Folder - email yang diimpor akan dimasukan ke folder tertentu pengguna secara otomatis.
-
-## Template Email
-
-Template email tersedia di Email> geser kebawah di pojok kanan atas> Template Email. Template Email dapat digunakan baik untuk pengiriman email massal dan untuk email biasa. Kotak centang `One-off` berarti template email seharusnya hanya digunakan sekali saja, seperti biasa digunakan untuk pemasaran email.
-
-Hal ini memungkinkan Anda untuk menggunakan folder tertentu di badan tempalte email dan subjek, misalnya {Account.name}, {Person.emailAddress}. Mereka akan diganti dengan nilai catatan terkait.
-
-Anda dapat menggunakan tambahan folder khusus di badan tempate: {optOutUrl} dan {optOutLink}.
-```
-Berhenti berlangganan
-```
-Ini adalah tautan berhenti berlangganan email massal.
diff --git a/i18n/id_ID/user-guide/markdown.md b/i18n/id_ID/user-guide/markdown.md
deleted file mode 100644
index e775ef4c6..000000000
--- a/i18n/id_ID/user-guide/markdown.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Sintaks Markdown
-
-Bidang teks mendukung sintaks markdown.
-
-## Kode
-```
-`contoh teks`
-```
-
-`contoh teks`
-
-## Kode multiline
-
-```
-``` contoh teks ```
-```
-
-```
-contoh teks
-```
-
-## Teks tebal
-
-```
-**contoh teks**
-```
-
-**contoh teks**
-
-## Teks miring
-
-```
-*contoh teks*
-```
-
-*contoh teks*
-
-## Teks tercoret
-
-```
-~~contoh teks~~
-```
-
-~~contoh teks~~
-
-## Kutipan
-
-```
-> contoh
-> teks
-```
-
-> contoh
-> teks
-
-## Tautan
-
-```
-[teks tautan](https://www.espocrm.com)
-```
-[teks tautan](https://www.espocrm.com)
-
-## Daftar bernomor
-
-```
-1. Contoh item
-2. Item lainnya
-```
-
-1. Contoh item
-2. Item lainnya
-
-## Daftar tidak bernomor
-
-```
-* Contoh item
-* Item lainnya
-```
-
-* Contoh item
-* Item lainnya
-
-## Garis horisontal
-
-```
-___
-```
-
diff --git a/i18n/id_ID/user-guide/mass-email.md b/i18n/id_ID/user-guide/mass-email.md
deleted file mode 100644
index 3809edc72..000000000
--- a/i18n/id_ID/user-guide/mass-email.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# Email massal
-
-## Bagaimana mengirim email massal
-
-Anda harus memiliki setidaknya satu Daftar Target dengan target catatan dan Email Template dalam crm anda.
-
-Jika semuanya benar setup email harus keluar. Mereka harus dikirim setiap jam dengan porsi (Anda dapat mengubah ukuran porsi di Administration > Outbound Emails). Administrator dapat mengubahnya dengan memperbarui bidang `Penjadwalan` dari` Periksa Akun Email' Pekerjaan Terjadwal.
-
-Anda dapat memeriksa apakah email yang dikirim dalam Log panel.
-
-
-## Tes apa yang akan dikirim ke penerima
-
-Klik kanan dropdown pada email massal baris di _Mass Email_ panel, dan kemudian klik _kirim Test_.
-
-
-## Log
-
-Dalam log, anda dapat melihat:
-* Mengirim email;
-* Email dibuka oleh penerima;
-* Tautan diklik oleh penerima;
-* Penerima yang memilih keluar;
-* Membangun email (tidak dikirimkan kepada penerima).
-
-
-## Tautan penyisihan
-
-Secara default sistem akan menambahkan opt-out untuk semua email yang dikirim. Tapi anda dapat menggunakan satu kustom di Template Email anda.
-
-Contoh:
-```html
-berhenti Berlangganan dari mailing list.
-```
-
-Administrator dapat menonaktifkan wajib opt-out link yang ditambahkan oleh sistem Administrasi > Email Keluar.
-
-
-## Melacak URL
-
- Jika anda ingin tahu bahwa penerima anda membuka link dari email anda, yang anda butuhkan untuk membuat URL Pelacakan. Menentukan _Name_
-dan _URL_ di mana link anda harus mengarah ke. Kemudian anda akan perlu untuk paste kode yang dihasilkan menjadi Template Email anda.
-
- Contoh:
- ```html
- Coba demo kami
- ```
-
-## Daftar Target
-
-Target berisi daftar Akun, Kontak, Memimpin dan Pengguna catatan.
-
-Pengguna dapat mengisi target daftar secara manual menggunakan _Select_ tindakan pada panel yang sesuai pada tampilan detail Daftar Target. Ada kemampuan untuk membuat penyaringan dan kemudian pilih semua hasil pencarian.
-
-
-## Mengisi daftar sasaran dengan Laporan
-
-[Laporan](reports.md#menyingkronkan-dengan-daftar-target) fitur ini memberikan kemampuan untuk mengisi daftar sasaran dengan catatan yang sesuai dengan kriteria tertentu.
-
-
-## Tidak termasuk Target Daftar
-
-Menentukan tidak Termasuk Target Daftar untuk menghindari mengirim email massal ke penerima tertentu. Jika ada record dengan alamat email yang sesuai dengan alamat email apapun termasuk catatan pertama akan dikeluarkan juga.
-
-
-## Log Kampanye
-
-Pada Kampanye Log anda dapat melihat email yang telah dikirim, membuka email, memantul email, yang memilih keluar, dan yang mengklik link dalam email. Itu mungkin untuk menggunakan log ini dengan membuat Daftar Target (dropdown di pojok kanan atas pada panel) yang didasarkan pada catatan dari log. Misalnya, anda memilih hanya kontak yang diklik pada link (url pelacakan).
-
-
-## Penyelesaian masalah
-
-_Untuk administrator_
-
-
-#### Apa yang harus dilakukan jika email tidak dikirim..
-
-1. Periksa apakah _kirim Test_ bekerja. Jika tidak bekerja, kemudian memeriksa apakah sistem pengaturan SMTP adalah benar.
-2. Periksa jika anda memiliki setup cron untuk sistem anda.
-3. Periksa apakah anda memiliki `Kirim Email Massal` Dijadwalkan Pekerjaan dan itu `Aktif` (Administrasi > Dijadwalkan Pekerjaan > Kirim Email Massal). Periksa jika ada sesuatu dalam Log.
-
-
-#### Bagaimana jika Url Pelacakan memiliki url yang salah yang tidak mengarah ke crm anda.
-
-Periksa 'siteUrl' parameter `data/config.php` file. Itu harus ditetapkan sebagai URL anda EspoCRM dapat diakses dari dunia luar
-
-
-#### email yang dipantulkan tidak masuk log
-
-Bangkit email dapat ditangani oleh kelompok akun email saja. Pastikan bahwa anda memiliki sebuah kelompok akun email yang monitores kotak memantul email yang dikirim.
-
-Juga beberapa mail server penyedia dapat menyimpang dari standar, sehingga terpental email tidak dapat dibedakan.
diff --git a/i18n/id_ID/user-guide/quotes.md b/i18n/id_ID/user-guide/quotes.md
deleted file mode 100644
index 94310482f..000000000
--- a/i18n/id_ID/user-guide/quotes.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Kutipan
-
-Fitur penawaran tersedia di [Paket Lanjutan](https://www.espocrm.com/extensions/advanced-pack/).
-
-Kutipan adalah kelompok produk atau layanan tertentu dengan jumlah dan harga yang Anda kutip kepada pelanggan.
-
-Kutipan memiliki hubungan dengan Opportuniti. Anda bisa menambahkan panel Kutipan ke detail Opportuniti lihat di Administrasi > Manajer Tata letak > Opportuniti > Hubungan. Saat membuat kutipan baru terkait dengan peluang, itu mengalihkan item peluang ke penawaran.
-
-Anda dapat menambahkan panel Kutipan ke tampilan detail Akun untuk dapat melihat kutipan terkait. Anda dapat melakukannya di Administrasi > Manajer Tata letak > Akun > Hubungan.
-
-## Item Kutipan
-
-Kutipan memppunyai daftar item. Setiap item dapat mewakili produk atau layanan tertentu dengan deskripsi, jumlah, tarif pajak, daftar harga dan harga satuan. Ini memungkinkan untuk memilah item secara manual.
-
-Anda dibolehkan untuk menambahkan bidang khusus untuk Item Kutipan yang menggunakan Manajer Entitas.
-
-## Template
-
-Secara default ada dua template yang tersedia: Kutipan and Faktur. Anda bisa membuat template baru (Tampilan daftar kutipan> menu dropdown kanan atas> Template) serta editan yang sudah ada.
-
-Untuk pengeditan yang lebih tepat, sebaiknya menggunakan mode Tampilan Kode.
-
-Anda dapat mencetak bidang catatan kutipan serta bidang catatan terkait dengan memanfaatkan placeholder di template Anda.
-
-Contoh:
-`{{accountName}}` – nama Akun
-
-`{{{billingAddressStreet}}}` – jalan,
-
-`{{account.type}}` – tipe Akun terkait,
-
-`{{assignedUser.lastName}}` – nama belakang pengguna yang ditetapkan.
-
-Jika item baris Anda adalah produk Anda dapat mencetak bidang produk.
-
-Contoh:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Panjang dan warna adalah bidang kustom entitas Produk dalam contoh.
-
-Perulangan melalui item kutipan:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-Memungkinan Anda untuk mencetak bidang gambar:
-
-```
-
-```
-dimana `imageId` – nama bidang gambar khusus pada entitas Kutipan yang digabungkan dengan akhiran `Id`.
-
-Untuk item produk:
-```
-
-```
-
-Untuk menampilkan nomor melayang (seperti quantity, harga unit dll) dengan bagian fraksional (sebagai integer) gunakan ungkapan berikut (sejak versi 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Format khusus untuk nilai mata uang (sejak versi 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Nilai `10000.5` akan dicetak sebagai `10 000,50`.
-
-Untuk menampilkan teks fileds (multiline) gunakan tiga petik: `{{{description}}}`.
-
-## Cetak ke PDF
-
-Kutipan dapat dicetak ke PDF. Tindakan ini tersedia dalam menu tarik-turun di samping tombol Edit pada tampilan detail kutipan. Kemudian Anda akan diminta untuk memilih Template.
-
-## Email Kutipan
-
-Kutipan PDF bisa di kirim lewat email sebagai lampiran. Buka catatan quote, klik tarik-turun di samping tombol Edit dan klik Email PDF.
-
-## Penomoran Otomatis
-
-Anda dapat membuat bagian Nomor via Manajer Entiti untuk tipe entiti Kutipan. Administrasi> Manajer Entiti> Kutipan> Area> Tambah Area> Nomor. Maka Anda perlu menempatkannya pada tampilan detail menggunakan Manajer Tata letak.
-
-Nilai akan bertambah dengan setiap kutipan baru. Ada kemampuan untuk menentukan nomor berikutnya sebagai awalan.
-
-## Pajak Default
-
-Tersedia sejak EspoCRM 4.8.0.
-
-1. Tentukan catatan Pajak default pada Administrasi> Manajer Entiti> Kutipan> area> Pajak> Default.
-2. Tentukan tingkat pajak default pada Administrasi> Manajer Entiti> Kutipan> area> tingkat pajak> Default.
-
-## Tagihan
-
-Kutipan bisa dianggap sebagai tagihan jika statusnya menjadi `Disetujui`. Kemudian area _Tanggal Tagihan_, _Nomor Tagihan_ muncul. Anda dapat menggunakan template yang berbeda untuk faktur untuk dicetak.
diff --git a/i18n/id_ID/user-guide/reports.md b/i18n/id_ID/user-guide/reports.md
deleted file mode 100644
index 6657e6444..000000000
--- a/i18n/id_ID/user-guide/reports.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Laporan
-
-Fitur laporan tersedia di [Paket Lanjutan](https://www.espocrm.com/extensions/advanced-pack/).
-
-Ada dua jenis laporan: List dan Grid.
-
-## Laporan List
-
-Hasil laporan list adalah list dari catatan yang memenuhi kriteria tertentu.
-
-Untuk membuat laporan list baru klik pada tab Report kemudian klik tolbol Buat Lapotan. Pilih Jenis Entitas yang dibutuhkan lalu klik tombol Buat di bagian Laporan List.
-
-Pada bidang _Kolom_ pilih bidang yang ingin Anda tampilkan. Di bawah ini Anda dapat menentukan parameter tampilan untuk setiap kolom mis. lebar dan sejajar
-
-Pilih sortir yang diinginkan pada bidang _Daftar Pesanan_.
-
-Pada bidang _Saring_ Anda dapat menentukan kriteria yang menentukan catatan apa yang akan tercantum dalam laporan Anda. Anda bisa menggunakan operator logika 'OR' dan 'AND' di sini.
-
-Bidang _Penyaringan Waktu_ memungkinkan Anda menentukan filter yang berbeda sebelum menjalankan laporan.
-
-Anda dapat __mengexport__ daftar hasil laporan ke format excel dan csv.
-
-## Laporan Grid
-
-Laporan Grid menghasilkan nilai ringkas yang dikelompokkan menurut bidang yang ditentukan. Laporan ini bisa ditampilkan sebagai bagan.
-
-
-
-Untuk membuat laporan grid baru klik pada tab Report kemudian klik tombol Buat Laporan. Pilih Tipe Entiti yang dibutuhkan lalu klik tombol Buat di bagian Laporan Grid.
-
-Di bidang _Grup Menurut_ pilih satu atau dua bidang yang Anda inginkan agar data laporan Anda dikelompokkan. Anda dapat mengelompokkan menurut tahun, bulan, hari untuk bidang tanggal. Jika Anda mengelompokkan dua kolom, laporan Anda akan dianggap tiga dimensi.
-
-Di bidang _Kolom_ pilih satu atau beberapa fungsi gabungan seperti COUNT, SUM (penjumlahan), MIN, MAX, AVG (rata-rata).
-
-Bidang _Sortir berdasarkan_ mendefinisikan bagaimana data laporan akan diurutkan.
-
-Pada bagian _Saring_ Anda dapat menentukan kriteria yang menentukan catatan apa yang akan digunakan dalam laporan Anda. Anda bisa menggunakan operator logika 'OR' dan 'AND' di sini.
-
-_Penyaringan Waktu_ memungkinkan Anda menentukan filter yang berbeda sebelum menjalankan laporan.
-
-Laporan grid memungkinkan menampilkan hasil dalam bentuk grafik. Ada jenis _tipe bagan_: Bar (Horizontal), Bar (Vertikal), Pie, Line.
-
-Ini memungkinkan untuk __mengexport__ hasil laporan grid ke format excel dan csv.
-
-## Penyaringan
-
-### Bagian penyaringan
-
-Sangat mudah untuk menggunakan jenis penyaringan. Anda juga dapat memilih bidang entitas target dan juga entitites terkait.
-
-
-
-### Grup OR
-
-OR berarti setidaknya satu kondisi di bawah kelompok harus dipenuhi.
-
-
-
-### Grup AND
-
-AND berarti bahwa semua kondisi di bawah kelompok harus dipenuhi.
-
-### Grup NOT
-
-Menyediakan kemampuan untuk menyaring catatan yang tidak memenuhi kriteria yang ditentukan. Misalnya daftar akun yang tidak memiliki peluang dengan status Closed Won atau Closed Lost.
-
-
-
-### Pernyataan Kompleks
-
-Untuk penggunaan lebih maju. Anda dapat menerapkan fungsi untuk kolom database tertentu dan membandingkannya dengan hasil ekspresi [formula](../administration/formula.md).
-
-Catatan: Jika Anda perlu membandingkan hanya dengan nilai string sederhana, Anda harus memasukkannya ke dalam tanda kutip tunggal `'beberapa string'`.
-
-Catatan: Fungsi yang dimaksudkan untuk berinteraksi dengan catatan entitas tidak akan bekerja disini karena formula tidak diterapkan pada record tertentu.
-
-
-
-## Menampilkan di Dasbor
-
-Anda dapat menampilkan laporan di dasbor. Untuk ini Anda perlu menambahkan Laporan dashlet dan kemudian memilih laporan yang diperlukan di opsi dashlet.
-
-## Pengiriman Email
-
-Ini memungkinkan sistem untuk mengirimkan hasil laporan kepada pengguna tertentu secara reguler sesuai waktu yang ditentukan. Ini harus dikonfigurasi untuk laporan tertentu secara terpisah.
-
-## Menyingkronkan dengan Daftar Target
-
-Ini memungkinkan daftar target disinkronkan dengan daftar hasil laporan. Ini lebih mudah untuk email massal jika Anda ingin mengirim email hanya ke kontak yang memenuhi beberapa kriteria pada saat pengiriman. Fitur ini tersedia pada tampilan detail daftar target di panel 'Singkron dengan Laporan'.
diff --git a/i18n/id_ID/user-guide/stream.md b/i18n/id_ID/user-guide/stream.md
deleted file mode 100644
index fa88a852a..000000000
--- a/i18n/id_ID/user-guide/stream.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Siaran
-
-Siaran di EspoCRM adalah umpan dimana Anda dapat melihat pembaruan dan penambahan baru untuk catatan yang Anda ikuti. Anda juga dapat mengeposkan siaran Anda sendiri dan melakukan siaran pada pengguna lain (sejak versi 3.8.0). Ada dua jenis siaran di EspoCRM: siaran rekaman dan siaran pengguna.
-
-Secara default, entitas berikut memiliki arus: Akun, Kontak, Prospek, Peluang, Kasus. Administrator dapat mengaktifkan atau menonaktifkan aliran untuk entitas tertentu di [Entity Manager](../administration/entity-manager.md).
-
-## Merekam Siaran
-
-Merekam Siaran ditampilkan di panel Siaran dari sebuah record tertentu pada tampilan detail. Pos, update dan tambahan baru yang terkait dengan rekaman saat ini digantikan disini.
-
-## Pengguna Siaran
-
-Pengguna dapat melihat siaran mereka di dashlet Stream dan juga di bawah tab Siaran. Pengguna juga dapat melihat aliran pengguna lain di tampilan detail pengguna, jika mereka memiliki akses yang dikendalikan oleh Aturan bidang `User Pemission`.
-
-Dalam siaran pengguna Anda dapat melihat posting, pembaruan dan penambahan baru yang terkait dengan catatan yang diikuti pengguna. Anda juga bisa melihat posting yang ditujukan ke pengguna. Pos tersebut tidak terkait dengan catatan apapun.
-
-## Notifikasi
-
-Anda akan menerima pemberitahuan tentang penambahan baru pada aliran Anda yang disebabkan oleh pengguna lain.
-
-## Postingan
-
-Anda bisa membuat postingan yang berhubungan dengan record tertentu. Anda juga bisa melampirkan beberapa file dan gambar ke postingan anda. Jika Anda ingin menyebutkan seseorang di pos Anda, Anda perlu mengetikkan simbol `@` dan mulai mengetikkan nama pengguna. Pengguna yang telah Anda sebutkan di pos Anda akan diberi tahu tentang hal itu.
-
-## Postingan ke pengguna
-
-_Fitur ini tersedia sejak versi 3.8.0._
-
-Pengguna dapat membuat posting ke pengguna tertentu, ke tim tertentu, ke semua pengguna dan untuk diri sendiri. Akses untuk kemampuan ini dikendalikan oleh Aturan bidang `Assignment Permission`.
-
-## Penyaringan
-
-Anda dapat menyaring apa yang akan ditampilkan di siaran: `Semua`,` Posting` atau `Pembaruan`.
-
diff --git a/i18n/it_IT/administration/bpm.md b/i18n/it_IT/administration/bpm.md
deleted file mode 100644
index 2b7ce4c19..000000000
--- a/i18n/it_IT/administration/bpm.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# Gestione dei processi aziendali
-
-Lo strumento Business Process Management (BPM) offre la possibilità di modellare e automatizzare i processi aziendali in EspoCRM. È un motore che esegue i processi aziendali descritti nello standard BPMN 2.0. Lo strumento BPM è disponibile nell'estensione [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-
-
-### Differenza dallo strumento Flussi di lavoro
-
-Lo strumento Flussi di lavoro è destinato all'automazione di semplici regole aziendali, senza elementi di flusso sequenziale, quando non è necessario visualizzare graficamente il flusso.
-
-Lo strumento BPM è destinato a flussi aziendali più complessi, in cui possono essere presenti flussi divergenti e convergenti, ritardi nell'esecuzione, interazioni dell'utente. Una vista del diagramma di flusso rende il processo aziendale più comprensibile per un essere umano, un registro consente di vedere come è stato tenuto il processo.
-
-## Elabora diagrammi di flusso
-
-Il link per elaborare i diagrammi di flusso è disponibile dal pannello di amministrazione. Può anche essere aggiunto come una scheda sul pannello di navigazione.
-
-I diagrammi di flusso sono destinati alla modellazione dei processi aziendali. L'amministratore può creare e modificare diagrammi di flusso. Gli utenti normali possono solo visualizzare i diagrammi di flusso.
-
-Ogni diagramma di flusso ha il suo tipo di entità specifico (campo Tipo di destinazione). Il diagramma di flusso determina l'esecuzione delle istanze di processo future. Comprende elementi del diagramma di flusso e connessioni tra gli elementi.
-
-Se il diagramma di flusso del processo ha il campo "È attivo" deselezionato, allora non avvierà le istanze di processo.
-
-Per mostrare dettagli e parametri di un determinato elemento del diagramma di flusso è necessario fare clic su di esso. In modalità modifica sarai in grado di modificare i parametri.
-
-## Processi
-
-I processi sono disponibili dal pannello di amministrazione. Il collegamento può anche essere aggiunto come una scheda sul pannello di navigazione.
-
-Il processo rappresenta un'istanza del processo di business. Quando viene avviato, ottiene lo stato 'Iniziato'. Quando il processo è finito, ottiene lo stato 'Fine'. Il processo può anche essere fermato manualmente da un utente che ha un accesso per modificare il processo. Se viene arrestato manualmente, ottiene lo stato "Arrestato".
-
-Il processo viene eseguito secondo il diagramma di flusso. Il diagramma di flusso del processo non può essere modificato dopo l'avvio del processo.
-
-Il processo è obbligatorio in relazione al singolo record di destinazione.
-
-I processi possono essere avviati automaticamente (in base a condizioni specifiche o in base alla pianificazione) o manualmente (dove è presente almeno un evento di avvio nel diagramma di flusso). Per avviare manualmente il processo, l'utente deve fare clic sul pulsante "Avvia processo" nella visualizzazione elenco dei processi.
-
-## Elementi del diagramma di flusso
-
-### eventi
-
-Gli eventi vengono visualizzati su un diagramma di flusso come cerchi.
-
-#### Avvia evento
-
-Non ha parametri. È un punto di partenza del processo. L'evento di inizio può essere avviato manualmente da un utente che ha accesso alla creazione di processi. L'utente deve fare clic sul pulsante "Avvia processo" nella visualizzazione elenco dei processi.
-
-#### Evento di inizio condizionato
-
-Un punto di partenza del processo. Dovrebbe essere attivato automaticamente quando vengono soddisfatte le condizioni specificate. Esistono due tipi di trigger: "Dopo record creato", "Dopo record salvato".
-
-#### Evento di avvio del timer
-
-Un punto di partenza del processo. Avvia i processi tramite la pianificazione. È necessario specificare il report elenco che restituisce i record per l'avvio dei processi e la pianificazione nella notazione crontab.
-
-#### Evento intermedio condizionale
-
-Questo evento arresta il flusso finché non vengono soddisfatti i criteri specificati.
-
-#### Evento intermedio del timer
-
-Questo evento arresta il flusso e attende fino a quando viene specificato dai parametri dell'evento.
-
-Per impostazioni del timer più complesse puoi utilizzare [formula](formula.md). Gli script di formula devono restituire il valore Date-Time (nel fuso orario UTC). Una volta giunto il momento, il flusso verrà trasferito all'elemento successivo.
-
-Utilizzando la funzione di formula data / ora più vicina è possibile impostare il timer in un momento specifico in futuro, ad es. l'inizio della prossima giornata lavorativa.
-
-#### Fine evento
-
-Termina il flusso corrente. Non finisce i flussi che corrono in parallelo. Quando il flusso raggiunge l'evento finale e non c'è nulla che funzioni in parallelo, il processo termina.
-
-#### TTermina evento finale
-
-Termina tutti i flussi. Il processo è successivamente terminato.
-
-### Gateway
-
-I gateway sono visualizzati come diamanti.
-
-#### Gateway esclusivo
-
-Può divergere o convergere i flussi.
-
-In caso di divergenza definisce un singolo flusso (percorso) che verrà scelto in base a criteri specifici. La prima condizione soddisfatta determina il flusso, le prossime condizioni sono omesse. C'è la possibilità di specificare il flusso predefinito. Il flusso predefinito viene scelto se non ci sono condizioni soddisfatte. Il flusso predefinito è contrassegnato da un segno di barra.
-
-In caso di convergenza dirige semplicemente il flusso verso l'elemento in uscita. Tuttavia, non viene bloccato dopo il flusso, quindi i flussi paralleli non verranno uniti nel flusso singolo.
-
-
-
-
-
-#### Gateway inclusivo
-
-Può divergere o convergere i flussi.
-
-In caso di divergenza, può dirigere verso uno o più flussi paralleli (percorsi), in base al raggiungimento dei criteri di ciascun flusso. Il flusso predefinito viene scelto se non ci sono condizioni soddisfatte. Il flusso predefinito è contrassegnato da un segno di barra.
-
-Se è necessario unire flussi paralleli prodotti da un gateway inclusivo divergente, è necessario utilizzare un gateway inclusivo convergente. Attenderà tutti i flussi in entrata e quindi continuerà con l'elemento in uscita.
-
-
-
-Nota: i gateway divergenti e convergenti devono essere bilanciati.
-
-Nota: se uno dei flussi paralleli è stato terminato per qualche motivo, il gateway divergente non verrà mai elaborato. Il processo sarà bloccato. Evitare un design del diagramma di flusso che possa provocare una situazione del genere.
-
-#### Gateway parallelo
-
-Può divergere o convergere i flussi.
-
-In caso di divergenza, divide il flusso in più flussi paralleli. Non ci sono parametri per questo tipo di gateway.
-
-In caso di convergenza, attende fino a quando tutti i flussi in arrivo arrivano e poi continua al prossimo elemento in uscita.
-
-
-
-Nota: i gateway divergenti e convergenti devono essere bilanciati.
-
-Nota: se uno dei flussi paralleli è stato terminato per qualche motivo, il gateway divergente non verrà mai elaborato. Il processo sarà bloccato. Evitare un design del diagramma di flusso che possa provocare una situazione del genere.
-
-#### Gateway basato su eventi
-
-Possono solo divergere i flussi.
-
-Arresta il flusso fino a quando non viene attivato nessuno degli eventi in uscita. L'evento innescato determina il singolo flusso. Altri eventi in uscita vengono rifiutati.
-
-Solo gli eventi intermedi possono essere dall'altra parte dei flussi di sequenza in uscita.
-
-
-
-### attività
-
-Le attività sono visualizzate come rettangoli arrotondati.
-
-#### Compito
-
-L'attività può essere eseguita seguendo le azioni:
-
-* Crea record: crea un nuovo record di qualsiasi tipo di entità;
-* Crea record correlato: crea un nuovo record correlato al record di destinazione;
-* Aggiorna record di destinazione;
-* Record correlato all'aggiornamento: aggiorna il record o i record relativi al record di destinazione;
-* Aggiorna record creato - aggiorna il campo specifico di qualsiasi record creato nel processo corrente;
-* Record processo di aggiornamento - può essere utilizzato per assegnare il processo a specifici utenti o team;
-* Link ad un altro record: collega il record di destinazione con un record specificato;
-* Scollega da un altro record: scollega il record di destinazione dal record specificato;
-* Applica regola di assegnazione: assegna il record di destinazione, il record di processo o qualsiasi record creato dal processo in base alla regola specifica;
-* Crea notifica: crea notifiche in-app per utenti specifici;
-* Make Followed: consente a utenti specifici di seguire il record di destinazione, il record del processo o qualsiasi record creato dal processo;
-* Esegui azione di servizio: esegue azioni di servizio personalizzate implementate dagli sviluppatori.
-
-Le azioni disponibili per l'attività sono quasi le stesse della funzione Flusso di lavoro. Vedi maggiori dettagli su [workflow's actions](workflows.md#azioni).
-
-#### Invia attività messaggio
-
-Invia un messaggio e-mail a un destinatario specifico.
-
-#### Task utente
-
-Fornisce una capacità flessibile di interazione dell'utente. Interrompe l'esecuzione fino a quando l'utente (specificato esplicitamente o in base alla regola di assegnazione) risolve l'attività. Il record del processo utente processo verrà creato nel sistema. Di default ci sono tre tipi di azione: Approva, Rivedi, Realizza.
-
-* Approva il tipo richiede all'utente di scegliere tra 'Approvato' e 'Rifiutato'.
-* Il tipo di revisione offre solo un'opzione: "Revisionata".
-* Compilare il tipo ha due opzioni: "Completato" e "Fallito".
-
-L'utente assegnato al record Process Process User creato riceverà una notifica in-app. L'amministratore può anche abilitare le notifiche e-mail.
-
-Gli utenti possono anche aggiungere un dashlet Task Process Task sul loro dashboard per vedere le loro effettive attività dell'utente del processo.
-
-È possibile leggere la risoluzione del compito utente passato all'interno di gateway divergenti o eventi condizionali, rendendo la ramificazione nel flusso del processo.
-
-#### Script Task
-
-Executes the script in [espo-formula](formula.md) language. All set variables (`$variableName`) will be stored and available within the process.
-
-### flussi
-
-#### Flusso di sequenza
-
-Rappresentato come una freccia solida. Indica l'ordine in cui verranno eseguiti gli elementi del processo.
-
-## condizioni
-
-Eventi condizionali, gateway divergenti esclusivi e inclusivi hanno condizioni che determinano il flusso del processo.
-
-Tramite l'interfaccia utente è possibile verificare le condizioni per i seguenti record:
-
-* Record di destinazione;
-* Record relativi all'obiettivo attraverso relazioni multi-to-uno e da bambini a genitore;
-* Record creati dal processo tramite attività;
-* Record dei compiti dell'utente, che consente di verificare la risoluzione.
-
-È anche possibile definire le condizioni in [Espo-formula](formula.md) linguaggio.
-
-Le condizioni nello strumento BPM sono le stesse della funzione Flusso di lavoro. Vedi maggiori dettagli su [condizioni del flusso di lavoro](workflows.md#condizioni).
-## Examples
-
-### Example 1
-
-
-
-### Example 2
-
-
-
-### Example 3
-
-
diff --git a/i18n/it_IT/administration/formula.md b/i18n/it_IT/administration/formula.md
deleted file mode 100644
index 28ff9ee56..000000000
--- a/i18n/it_IT/administration/formula.md
+++ /dev/null
@@ -1,362 +0,0 @@
-# I campi calcolati (Formula)
-
-Nel gestore di entità è possibile definire script (formula) specifico per il tipo di entità. Questo script viene eseguito ogni volta che il record è stato salvato.
-Esso fornisce una capacità di impostare automaticamente i campi specifici (attributi) con valori derivati da un calcolo.
-
-Per modificare la formula seguire Administration > Entity Manager > menu a discesa a destra sulla riga della entità necessaria > Formula.
-
-È possibile anche la necessità di impostare i campi, che dovrebbero essere calcolati, di sola lettura tramite Entity Manager.
-
-
-## Sintassi
-
-EspoCRM formula è scritta in un linguaggio semplice progettato specificamente per questa funzione.
-
-Ci sono operatori, funzioni di attributi e valori che possono essere utilizzati nella formula. Le espressioni separate devono essere delimitati dal carattere ';'.
-
-### Gli operatori
-
-* '=' - assegnazione.
-* '||' - logiche o,
-* '&&' - logica e,
-* '!' - non logica,
-* ' '- sommatoria numerico,
-* '-' - sottrazione numerico,
-* '*' - moltiplicazione numerico,
-* '/' - divisione numerico,
-* '%' - modulo numerico,
-* '==' - Confronto è uguale a,
-* '!=' - confronto non uguale a,
-* '>' - confronto maggiore,
-* '<' - confronto inferiore
-* '>=' - confronto maggiore di o uguale a,
-* '<=' - confronto a meno di o uguale a.
-
-Priorità degli operatori:
-* '=';
-* '||', '&&";
-* '==', '!=', '>', '<', '>=', '<=";
-* ' ', '-';
-* '*', '/', '%'.
-
-### funzioni
-
-Gli attributi gli attributi rappresentano i valori di campo delle entità bersaglio. È possibile inserire gli attributi disponibili facendo clic sul pulsante più (+).
-
-È possibile accedere a attributi di entità correlate con il seguente formato "linkName.NOMEATTRIBUTO'.
-### Il
-
-Formato delle funzioni della funzione utilizzare: `nomegruppo\functionName(argomento1, argomento2, ..., argumentN)`.
-
-Out-of-the-box le funzioni sono elencate di seguito.
-
-#### IfThenElse
-`ifThenElse(condizione, conseguente, alternativa)`
-
-Se la condizione è soddisfatta allora fare conseguente. Se non -- quindi fare alternativa.
-
-#### IfThen
-`ifThen(condizione, conseguente)`
-
-Se la condizione è soddisfatta allora fare conseguente. Se non -- non fare nulla.
-
-#### La stringa\concatenare
-`string\concatenate(stringa_1, stringa_2)`
-
-Concatena due o più stringhe.
-
-#### La stringa\sottostringa
-`string\substring(String, START, lunghezza)`
-
-Estrae i caratteri di una stringa da posizione iniziale e la lunghezza.
-
-Se la lunghezza è omesso, la sottostringa a partire dall'inizio fino alla fine della stringa sarà restituito.
-
-Se la lunghezza è negativo, allora, che molti caratteri verranno omesse dalla fine della stringa.
-
-#### String\\rivestimento
-`string\trim(STRING)`
-
-Strisce degli spazi dall'inizio e dalla fine della stringa.
-
-#### String\\minuscolo
-`string\lowerCase(STRING)`
-
-Converte le lettere in minuscolo. (Sin dalla versione 5.0.0)
-
-#### string\\lettere maiuscole
-`string\upperCase(STRING)`
-
-Converte le lettere in maiuscolo. (Sin dalla versione 5.0.0)
-
-#### datetime\\oggi
-`datetime\today()`
-
-Restituisce la data odierna.
-
-#### Datetime\ora
-`datetime\now()`
-
-Ritorna datetime corrente.
-
-#### Datetime formato\
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])`
-
-Converte la data o un valore datetime in una stringa formattata in base alle impostazioni dell'applicazione. Il fuso orario e il formato può essere omesso. Se il fuso orario viene omesso allora fuso orario predefinito verrà utilizzato. Se format è omesso allora formato predefinito verrà utilizzato.
-
-Esempi:
-
-`datetime\format(closeDate, 'America/New_York', 'MM/DD/YYYY')`
-
-`datetime\format(dateStart, 'America/New_York', 'MM/DD/YYYY hh:mma')`
-
-`datetime\format(dateStart, 'Europe/Amsterdam', 'DD/MM/YYYY HH:mm')`
-
-#### Datetime\data
-`atetime\data(VALORE, [TIMEZONE]))`
-
-Restituisce la data del mese (1-31). "0" se il valore è vuoto. Se il fuso orario viene omesso allora il fuso orario del sistema è utilizzato. (Sin dalla versione 4.7.0)
-
-#### datetime\mese
-`datetime\month(VALORE, [TIMEZONE])`
-
-Restituisce il mese (1-12). "0" se il valore è vuoto. Se il fuso orario viene omesso allora il fuso orario del sistema è utilizzato. (Sin dalla versione 4.7.0)
-
-#### datetime\anno
-`datetime\year(VALORE, [TIMEZONE])`
-
-Restituisce l'anno. "0" se il valore è vuoto. Se il fuso orario viene omesso allora il fuso orario del sistema è utilizzato. (Sin dalla versione 4.7.0)
-
-#### datetime\ora
-`datetime\hour(VALORE, [TIMEZONE])`
-
-Restituisce ora (0-23). '-1' se il valore è vuoto. Se il fuso orario viene omesso allora il fuso orario del sistema è utilizzato. (Sin dalla versione 4.7.0)
-
-#### datetime\minuto
-
-`datetime\minute(VALORE, [TIMEZONE])`
-
-Restituisce minuto (0-59). '-1' se il valore è vuoto. Se il fuso orario viene omesso allora il fuso orario del sistema è utilizzato. (Sin dalla versione 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALORE, [TIMEZONE])`
-
-Restituisce il giorno della settimana (0-6). '-1' se il valore è vuoto. '0' - per la domenica. Se il fuso orario viene omesso allora il fuso orario del sistema è utilizzato. (Sin dalla versione 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALORE_1, VALORE_2, Intervallo_Tipo)`
-
-Restituisce la differenza tra due date o datetime. Intervallo_Tipo può essere 'Anni', 'months', 'giorni', 'ore', 'Minuti'. Restituisce null' se guasto. Il risultato sarà negativo se il valore_1 < valore_2.
-
-#### Datetime\addMinutes
-`datetime\addMinutes(VALORE, MINUTI)`
-
-Aggiunge minuti al valore datetime. Minuti può essere negativo.
-
-#### Datetime\addHours
-`datetime\addHours(VALORE, ORE)`
-
-Aggiunge ore di valore datetime. Ore può essere negativo.
-
-#### Datetime\addDays
-`datetime\addDays(VALORE, GIORINI)`
-
-Aggiunge giorni per data o un valore datetime. Giorni può essere negativo.
-
-#### Datetime\addWeeks
-`datetime\addWeeks(VALORE, SETTIMANE)`
-
-Aggiunge settimane alla data o un valore datetime. Settimane può essere negativo.
-
-#### Datetime\addMonths
-`datetime\addMonths(VALORE, MESI)`
-
-Aggiunge mesi alla data o un valore datetime. Mesi può essere negativo.
-
-#### Datetime\addYears
-`datetime\addYears(VALORE, ANNI)`
-
-Aggiunge anni alla data o un valore datetime. Anni può essere negativo.
-
-#### Datetime\closest
-`datetime\closest(VALORE, TIPO, TARGET, [è_passato], [TIMEZONE])`
-
-Restituisce la data più vicina o datetime in valore basato su argomenti passati. (Sin dalla versione 5.0.0)
-
-Tipo può essere uno dei seguenti valori: 'tempo', 'minute', 'Ora', 'date', 'Mese', 'dayOfWeek'. Il bersaglio è un valore intero o un valore di stringa. È_passato significa per trovare il più vicino in passato. Se il fuso orario viene omesso allora fuso orario predefinito è utilizzato.
-
-Esempi:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` restituirà il più vicino valore datetime in futuro con 20:00 tempo.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` restituirà '2017-11-01', il primo giorno del mese.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` restituirà il prossimo lunedì (l'inizio del giorno).
-
-#### Numero\formato
-`number\format(VALORE, [DECIMALI], [VALORE DECIMAL_MARK], [MILLE_SEPARATORE])`
-
-Converte il valore numerico in una stringa formattata in base a un formato specifico o le impostazioni predefinite dell'applicazione. Se i decimali, decimale_mark o mille_SEPARATOR quindi i valori di default del sistema sono utilizzati.
-
-Esempi:
-
-`number\format(2.666667, 2)` - risultati 2,67;
-
-`number\format(1000, 2)` - risultati 1,000.00;
-
-`number\format(10.1, 0)` - risultati 10.
-
-
-#### Numero\abs
-`number\abs(VALORE)`
-
-Valore assoluto. Restituisce Null se non è un valore numerico.
-
-#### Numero\round
-`number\round(VALORE, PRECISIONE)`
-
-Restituisce il valore arrotondato di valore alla precisione specificata (numero di cifre dopo il punto decimale). Precisione può anche essere negativo o zero (predefinito).
-
-#### Numero\piano
-`number\floor(VALORE)`
-
-Restituisce il prossimo valore intero più basso arrotondando il valore se necessario. (Sin dalla versione 4.9.0)
-
-#### numero\ceil
-`number\ceil(VALORE)`
-
-Restituisce il successivo più alto valore integer con arrotondamento valore se necessario. (Sin dalla versione 4.9.0)
-
-#### entità\isNew
-`entity\isNew()`
-
-Restituisce TRUE se l'entità è nuovo (essendo creato) e False se non (aggiornato).
-
-#### Entità\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTO)`
-
-Restituisce TRUE se un attributo di entità è stata modificata.
-
-Esempio:
-
-`entity\isAttributeChanged('Status')`
-
-#### entità\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTO)`
-
-Restituirà TRUE se un attributo di entità non è cambiato.
-
-#### Entità\attributeFetched
-`entity\attributeFetched(ATTRIBUTO)`
-
-Attributo che è stata impostata quando entità bersaglio è stato recuperato dal database. Prima che esso è stato modificato.
-
-Esempio:
-
-`entity\attributeFetched('assignedUserId')`
-
-#### entità\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)`
-
-ID aggiunge al collegamento del campo multiplo. Per esempio, aggiungere "omeTeamId' a 'teams' campo.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)`
-
-Aggiunge l'elenco di ID. (Sin dalla versione 4.8.3)
-
-#### entità\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)`
-
-Controlla se il collegamento di più ha il campo ID specifico.
-
-#### Entità\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)`
-
-Rimuove un ID specifico dal collegamento del campo multiplo.
-
-#### Entità\isRelated
-`entity\isRelated(LINK, ID)`
-
-controlla se entità bersaglio è correlato con un altro soggetto rappresentato da LINK E ID.
-
-#### Env\userAttribute
-`env\userAttribute(ATTRIBUTO)`
-
-Restituisce un attributo di utente corrente.
-
-#### Lista
-`elenco(valore-1, ... Il valore N)` restituisce array. (Sin dalla versione 4.7.0)
-
-#### schiera\include
-`array\includes(LISTA, VALORE)`
-
-Restituisce VERO se l'elenco contiene il valore. Può essere utilizzato per array e Multi-Enum campi. (Sin dalla versione 4.7.0)
-
-#### schiera\push
-`array\push(LISTA, VALORE1 [, VALORE2 ...])`
-
-Aggiunge uno o più elementi al fine di una matrice e restituisce il nuovo array. (Sin dalla versione 5.0.0)
-
-#### Schiera\lunghezza
-`array\length(elenco)`
-
-Restituisce il conteggio degli elementi nell'elenco. (Sin dalla versione 4.8.1)
-
-
-### Valore
-
-* i valori delle stringhe. Ad esempio 'Some stringa';
-* numeri interi. Ad esempio 1, 100, 40300.
-* I numeri con la virgola. Ad esempio 5.2.
-
-### Variabili
-
-è possibile definire le variabili personalizzate in formula.
-
-```
-$someVariableName = 'Test';
-descrizione = $prova;
-```
-
-## esempi
-
-```
-ifThen(
-entità\isNew() && assignedUserId == null,
-assignedUserId = 'managerId'
-);
-
-ifThen(
-entità\isNew() && closeDate == null && stage == 'Closed Won",
-datetime\oggi()
-);
-```
-
-```
-IMPORTO = prodotto.listPrice - (prodotto.listPriceConverted * Sconto / 100,0);
-amountCurrency = "USD";
-```
-
-```
-someField = stringa\CONCATENA(FirstName, "'", middleName, """, Cognome);
-```
-
-```
-ifThenElse(
-entità\isNew() && status == 'PIANIFICATO' && dateStart == null,
-dateStart = datetime\addDays(datetime\ADESSO(), 10),
-ifThen(
-stato = 'In attesa' && dateStart == null,
-dateStart = datetime\ADESSO()
-)
-);
-
-```
-
-## usando la formula nei flussi di lavoro
-
-<<<<<<< HEAD
-è possibile utilizzare la formula in condizioni di flusso di lavoro e le azioni. Vedere i flussi di lavoro [documentazione](workflows.md#usando-la-formula-nelle-azioni) per ulteriori informazioni.
-=======
-è possibile utilizzare la formula in condizioni di flusso di lavoro e le azioni. Vedere [i flussi di lavoro documentazione](workflows.md#usando-la-formula-nelle-azioni) per ulteriori informazioni.
->>>>>>> upstream/master
diff --git a/i18n/it_IT/administration/maps.md b/i18n/it_IT/administration/maps.md
deleted file mode 100644
index 70e3da7fc..000000000
--- a/i18n/it_IT/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Mappe
-
-## Come mostrare la mappa basata su un campo di indirizzo di
-
-indirizzo di ogni campo è il suo corrispondente campo Mappa. Tutto ciò di cui avete bisogno è quello di metterla in dettaglio il layout. Esso utilizza il servizio Google Maps.
-
-"Amministrazione > Layout Manager > Scegliere entità (Account, Contatto, piombo o uno personalizzato) > Dettaglio > Drag & Drop Mappa campo.'
-
-fare la cella ampia utilizzando il segno meno.
-
-È possibile anche configurare l'altezza del vostro campo.
-
-"Amministrazione > Entity Manager > Scegli entità > Campi > trovare la mappa del campo e fare clic su di esso > Modifica l'altezza e salvare."
-
-## API Key
-
-poiché EspoCRM versione 4.2.0 è necessario specificare la chiave API per utilizzare Google Maps (Amministrazione > Integrazione > Google Maps).
-
diff --git a/i18n/it_IT/administration/moving-to-another-server.md b/i18n/it_IT/administration/moving-to-another-server.md
deleted file mode 100644
index cf1a09b26..000000000
--- a/i18n/it_IT/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# EspoCRM mobile a un altro server
-
-Seguire questi passi per spostare EspoCRM a un altro server:
-
-### Passo 1. I file di backup
-
-consente di aprire un file manager o il login via SSH per archiviare tutti i file dalla directory EspoCRM. Maggiori [dettagli](../../../docs/administration/backup-and-restore.md#step-1-backup-files).
-
-### Passo 2. Eseguire il backup del database
-
-i dati memorizzati nel database (MySQL, MariaDB) dovrebbe essere eseguito il backup. Si prega di seguire questa [raccomandazione](../../../docs/administration/backup-and-restore.md#step-2-backup-database).
-
-### Passo 3. Copia di file e backup di database a un altro server di
-
-backup di copia dei file e dei database in un nuovo server.
-
-### Passo 4. Unarchive file di backup
-
-per unarchive file di backup, è possibile utilizzare Archive Manager o questa [istruzione](../../../docs/administration/backup-and-restore.md#step-1-unarchive-backup-files).
-Nota: i file devono essere inseriti nel server web directory.
-
-### Passo 5. Configurare un server di
-
-configurazione di un nuovo server basato sulle [raccomandazioni qui](server-configuration.md).
-
-### Passo 6. Correggere le autorizzazioni
-
-impostate le autorizzazioni necessarie e i file [proprietario](server-configuration.md#le-autorizzazioni-necessarie-per-i-sistemi-basati-su-unix).
-
-### Passo 7. Importare il backup del database
-
-prima di tutto è necessario creare un nuovo database con un utente in MySQL. Per importare il database dal backup, seguire le [instuction](../../../docs/administration/backup-and-restore.md#step-3-import-database-dump).
-
-### Passo 8. Correggere le configurazioni EspoCRM
-
-dopo aver completato l'importazione e la configurazione del server, si prega di correggere EspoCRM configurazioni nel file 'ESPOCRM_DIRECTORY/dati/config.php':
-
-* Impostazioni di connessione al database:
-
-'''Php
-'database' => [
-'driver' => 'pdo_mysql',
-'dbname' => 'IL VOSTRO_database_name',
-'Utente' => 'IL VOSTRO_utente',
-'password' => 'IL VOSTRO_database_password',
-'host' => 'localhost',
-'porta' => ''
-],
-'''
-
-* "SiteUrl" - se il vostro nome di dominio (URL) è cambiato:
-
-'''Php
-'siteUrl' => 'https://new-link.com',
-'''
-
-* I file predefiniti proprietario (solo se diverso):
-
-'''Php
-'defaultPermissions' => [
-'utente' => 'www-dati',
-'Gruppo' => 'www-dati'
-]
-'''
-
-Dove 'www-dati' è il vostro web-server user.
-
-### Passo 9. Impostazione di una
-
-configurazione di crontab di un [crontab](server-configuration.md#setup-di-un-crontab).
-Nota: deve essere configurata sotto il vostro web-server user.
-
-Questo è tutto. Ora, la vostra EspoCRM istanza è in esecuzione su un nuovo server.
diff --git a/i18n/it_IT/administration/portal.md b/i18n/it_IT/administration/portal.md
deleted file mode 100644
index 71c99914f..000000000
--- a/i18n/it_IT/administration/portal.md
+++ /dev/null
@@ -1,85 +0,0 @@
-
-# Portale
-
-Portale fornisce una capacità di accesso a specifici dati CRM e funzioni per i vostri clienti e partner. L'amministratore può creare più portali. Ogni portale può avere le proprie impostazioni, dashlboard, elenco utenti e le impostazioni di controllo degli accessi.
-
-Per creare il portale seguire Administration > Portali, fare clic su Crea pulsante Portale.
-
-* 'Attivo'. In caso contrario controllare il portale non sarà disponibile per chiunque.
-* 'È predefinito'. Significa che il portale sarà disponibile entro breve url: http(s)://la_vostra_ESPO_URL/portale.
-* 'Ruoli'. Specificare uno o più ruoli del portale che verrà applicato agli utenti registrati nel portale. Ulteriori informazioni sui ruoli del portale è riportato di seguito.
-* 'Tab elenco'. Le linguette che verrà mostrato nella barra di navigazione.
-* 'Dashboard Layout'. Specificare dashlets che verrà visualizzato sulla home page del portale. Notare che gli utenti del portale non è in grado di configurare il proprio cruscotto.
-* 'URL'. Campo di sola lettura che visualizza il link è possibile accedere al portale con l.
-
-## Gli utenti del Portale
-
-gli amministratori possono creare gli utenti del portale.
-
-1. Amministrazione > Utenti.
-2. Fai clic con il pulsante destro menu a discesa accanto a creare l'utente.
-3. Fare clic su Crea utente del portale.
-4. Selezionare il contatto al portale utente sarà legata a.
-5. Compilare il modulo e fare clic su Salva.
-
-Utente del portale deve essere legata al record del portale per essere in grado di accedere a questo portale.
-
-## Portale
-
-portale ruoli i ruoli sono simili ai ruoli regolari in EspoCRM ma con alcune distinzioni.
-
-* 'Non-set' livello nega accesso..
-* 'Propria' livello significa che il record viene creato dall'utente. Ad esempio utente portale incassato qualche caso e in questo caso è di proprietà di questo utente.
-* 'Account' livello significa che il record è relativo al conto dell'utente del portale è correlato a.
-* 'Contatto' livello significa che il record è relativo al contatto il portale utente è correlato a.
-
-Utente assegnato i team e i campi sono di sola lettura per gli utenti del portale.
-
-### Esempio
-
-"Portale gli utenti dovrebbero essere in grado di creare casi, visualizzare i casi relativi al loro account; essi dovrebbero essere in grado di visualizzare la base della conoscenza."
-
-1. Aprire Crea ruolo Portale forma (Amministrazione > Portale ruoli > Crea ruolo).
-2. Abilitare l'accesso ai casi, impostare: "creare - sì, leggere - account, modifica - no, eliminare - no, stream - account'.
-3. Consentono di accedere alla Knowledge Base, impostare 'crea - no, leggere - account, modifica - no, eliminare - no'.
-4. Modificare il record del portale (Amministrazione > Portali). Seleziona il tuo portale ruolo nel campo dei ruoli e quindi salvare.
-# Accesso al portale
-
-potrete trovare l'url per il tuo portale in 'URL' campo del record del portale. Inoltre è possibile utilizzare gli strumenti di configurazione del server (tali mod_rewrite) per essere in grado di accedere da diversi url. In questo caso è necessario riempire in 'URL personalizzato' campo.
-
-### Il portale di accesso tramite URL personalizzato per il server Apache
-
-URL personalizzato: my-portal-host-name.com.
-
-#### Crm.portal.conf
-'''
-
-DocumentRoot /percorso/al/espocrm/esempio/
-ServerName my-portal-host-name.com
-
-
-Options Indexes FollowSymLinks
-AllowOverride tutti
-per consentire,negare
-lasciare da tutti
-
-
-ErrorLog ${APACHE_LOG_DIR}/error.log
-CustomLog ${APACHE_LOG_DIR}/access.log combinati
-
-
-ServerAlias my-portal-host-name.com
-
-'''
-
-#### mod rewrite regole
-
-specificano portal ID record invece di '{PORTAL_ID}'. Record del portale ID può è disponibile nella barra degli indirizzi del browser web quando si apre la vista dettagli del record del portale. Come: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9HM41C069e6j24 è un record del portale id.
-
-'''
-RewriteCond %{HTTP_HOST} ^portal-host-name.com$
-RewriteRule ^client - [L]
-
-RewriteCond %{HTTP_HOST} ^portal-host-name.com$
-RewriteCond %{REQUEST_URI} !^/portale/{PORTAL_ID}/.*$
-RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
\ No newline at end of file
diff --git a/i18n/it_IT/administration/server-configuration.md b/i18n/it_IT/administration/server-configuration.md
deleted file mode 100644
index 9b828cabc..000000000
--- a/i18n/it_IT/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Configurazione del server per EspoCRM
-
-EspoCRM può essere installato su Apache ([istruzioni](../../../docs/administration/apache-server-configuration.md)), Nginx ([istruzioni](../../../docs/administration/nginx-server-configuration.md)), o server IIS con supporto PHP versione 5.6 o superiore e la versione di MySQL 5.1 o superiore.
-
-## Consigli per la configurazione
-
-### Requisiti PHP
-
-EspoCRM richiede PHP 5.6 o superiore con le seguenti estensioni abilitato:
-
-* [DOP](http://php.net/manual/en/book.pdo.php) - per accedere a MySQL in PHP;
-* [JSON](http://php.net/manual/en/book.json.php) - risorse utilizzano questo formato (metadati, layout, lingue e altri);
-* [gd](http://php.net/manual/en/book.image.php) - per manipolare le immagini;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) - per garantire la massima protezione;
-* [zip](http://php.net/manual/en/book.zip.php) - per essere in grado di aggiornare EspoCRM e installare le estensioni;
-* [IMAP](http://php.net/manual/en/book.imap.php) - monitore cassette postali in EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Si raccomanda inoltre di avere [mailparse](https://pecl.php.net/package/mailparse) estensione pecl installato. È necessario per il corretto funzionamento del recupero di posta elettronica funzione.
-
-php.ini impostazioni:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M di
-upload_max_filesize = 50M
-```
-
-
-### Requisiti MySQL
-
-EspoCRM supporta la versione di MySQL 5.1 o superiore.
-Queste sono senza particolari peculiarità. Tutte le impostazioni di default sono buone per EspoCRM.
-
-## Le autorizzazioni necessarie per i sistemi basati su Unix
-
-i file e le directory devono disporre delle autorizzazioni seguenti:
-
-* `/data`, `/custom`, `/client/custom` - deve essere scrivibile tutti i file, directory e sottodirectory (664 per file, 775 per directory, incluse tutte le sottodirectory e file);
-* `/applicazione/Espo/modules`, `/client/modules` - deve essere scrivibile la directory corrente (775 per la directory corrente, 644 per i file, 755 per le directory e sottodirectory);
-* Tutti gli altri file e directory dovrebbe essere leggibile (644 per file, 755 per le directory).
-
-Per impostare le autorizzazioni, eseguire questi comandi in Terminale:
-
-```
-cd
-Trova . -Type d -exec chmod 755 {} && find . -Tipo f -exec chmod 644 {} ;
-trovare dati personalizzata - tipo d -exec chmod 775 {} && trovare dati personalizzata - tipo f -exec chmod 664 {} ;
-```
-
-tutti i file devono essere di proprietà del gruppo e controllata dal webserver processo. Essa può essere "www-data", "daemon", "Apache", "www", ecc.
-Nota: su Bitnami Stack, i file devono essere di proprietà del gruppo e di proprietà di "daemon" utente.
-Nota: su host condiviso, i file devono essere di proprietà del gruppo e controllata dal tuo account utente.
-
-Per impostare il proprietario e il gruppo-proprietario, eseguire questi comandi in Terminale:
-
-```
-cd
-chown -R : .;
-```
-
-## Setup di un crontab
-
-per impostare un crontab su un sistema UNIX, segui i passaggi seguenti:
-
-* 1. Login come amministratore nel tuo EspoCRM istanza.
-* 2. Vai all'area Lavori pianificati sezione nel pannello amministratore (Menu > Amministrazione > Lavori pianificati) e copiare la stringa per il crontab. Sembra che questo: uno
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Aprire un terminale ed eseguire questo comando:
-```
-crontab -e -u serverweb_utente
-```
-serverweb_utente può essere di uno dei seguenti "www", "www-data", "Apache", etc (dipende dal vostro webserver).
-* 4. Incolla la stringa (dal passo 2) e salvare il file crontab (Ctrl O, quindi Ctrl X per l'editor nano).
-
-## Istruzioni di configurazione basati sul tuo server:
-
-* [Apache server configuration](../../../docs/administration/apache-server-configuration.md).
-* [Nginx server configuration](../../../docs/administration/nginx-server-configuration.md).
diff --git a/i18n/it_IT/administration/troubleshooting.md b/i18n/it_IT/administration/troubleshooting.md
deleted file mode 100644
index 4ede95317..000000000
--- a/i18n/it_IT/administration/troubleshooting.md
+++ /dev/null
@@ -1,89 +0,0 @@
-Risoluzione dei problemi di #
-
-## i registri di controllo
-
-per scoprire il problema, è necessario verificare i file di registro degli errori.
-
-#### EspoCRM error logs
-
-EspoCRM registri si trovano in '/Logs/*.log' e contengono alcune informazioni sull'errore.
-
-#### Apache log di errore
-
-per Ubuntu server un registro errori Apache si trova in '/var/log/apache2/error.log' e contiene tutte le informazioni sull'errore. La posizione dei file di registro può essere diverso su altri sistemi.
-
-## Abilita la modalità di debug
-
-per attivare la modalità di debug, andare a installato EspoCRM directory, aprire il file 'data/config.php" e modificare il valore:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-A
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## I processi pianificati non funzionano
-
-#### Problema n. 1: il crontab non è configurato
-
-1. Login via SSH al server.
-
-2. Configurare il proprio crontab seguendo [questi passaggi](server-configuration.md#setup-di-un-crontab).
-
-Nota: il comando crontab dovrebbe essere configurata sotto web-server user, ad es. 'Crontab -e -u www-dati'.
-
-3. Attendere per un pò e controllare i processi pianificati per vedere se tutti i lavori sono stati eseguiti (vedere un registro centrale).
-
-#### Problema #2. Crontab è configurato, ma i processi pianificati non sono
-
-al lavoro per accertarsi che non vi siano errori di cron è in esecuzione, provare a eseguire il comando cron in un terminale:
-
-1. Login via SSH al server.
-
-2. Andare nella directory dove EspoCRM è installato. Ad esempio per '/var/www/html/espocrm' directory il comando è:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Eseguire il comando crontab:
-
-```bash
-php cron.php
-```
-
-Nota: deve essere eseguito sotto web-server user. Se si è effettuato il login come utente root, il comando deve essere (per esempio per Ubuntu):
-
-```bash
-sudo -u www-dati php cron.php
-```
-
-dove 'www-dati' è un web-server user.
-
-4. Se non ci sono errori, controllare i processi pianificati per vedere se un lavoro è stato eseguito (vedere un registro centrale).
-
-## EspoCRM non è carico dopo updgare
-
-questo può accadere a volte su alcuni hostings condivisa.
-
-Controllare le autorizzazioni del file:
-/index.php
-/api/v1/index.php
-
-devono essere 644. Se uno qualsiasi di questi file ha permesso 664 Hai bisogno di cambiare di 644. Utilizzare il tuo hosting del pannello di controllo o comando chmod .
-
-```
-Chmod 644 /percorso/al/file
-```
-
-ulteriori informazioni sulle autorizzazioni per i file: [qui](server-configuration.md#le-autorizzazioni-necessarie-per-i-sistemi-basati-su-unix).
diff --git a/i18n/it_IT/administration/upgrading.md b/i18n/it_IT/administration/upgrading.md
deleted file mode 100644
index 2d086b181..000000000
--- a/i18n/it_IT/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Come aggiornare EspoCRM
-
-EspoCRM può essere aggiornato alla versione più recente tramite le seguenti fasi:
-
-### Passo 1. Verificare la versione corrente
-
-per controllare la vostra versione attuale andare a Amministrazione > pagina di aggiornamento.
-
-### Passo 2. È necessario scaricare i pacchetti di aggiornamento
-
-vai alla pagina [upgrade](https://www.espocrm.com/download/upgrades/) e basato sulla vostra attuale versione download pacchetti richiesti.
-
-### Passo 3. Creare una copia di backup (opzionale)
-
-consente di creare un backup del vostro EspoCRM dei file e dei dati prima di eseguire l'aggiornamento. [Seguire queste istruzioni](../../../docs/administration/backup-and-restore.md) per averlo fatto.
-
-### Passo 4. Processo di aggiornamento
-
-Vai su Amministrazione > Aggiornamento. Caricare e installare uno per uno i pacchetti di aggiornamento.
-
-È possibile verificare se si dispone della versione più recente in corrispondenza di Menu > Informazioni su.
-
-## Upgrade tramite CLI
-
-è anche possibile eseguire upgrade tramite interfaccia a riga di comando. È necessario eseguire il seguente comando da root EspoCRM directory:
-
-'''
-php upgrade.php /percorso/al/aggiornamento/package.zip
-'''
diff --git a/i18n/it_IT/administration/workflows.md b/i18n/it_IT/administration/workflows.md
deleted file mode 100644
index e33cd5c31..000000000
--- a/i18n/it_IT/administration/workflows.md
+++ /dev/null
@@ -1,145 +0,0 @@
-# I flussi di lavoro
-
-dei flussi di lavoro è disponibile in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Flussi di lavoro per automatizzare il processo aziendale di un modo semplice. Lo si può trovare nel pannello di amministrazione. Per creare una regola del flusso di lavoro è necessario definire:
-
-* entità bersaglio - che cosa il tipo di entità del flusso di lavoro è applicato a;
-* Tipo di Trigger - quando il flusso di lavoro verrà attivato;
-* condizioni - le condizioni devono essere soddisfatte per attivare un flusso di lavoro;
-* Azioni - che cosa fare se il flusso di lavoro viene attivato.
-
-
-## Tipi di trigger
-
-### dopo record creato
-
-scatterà solo quando viene creato un nuovo record. Se specificate le condizioni sono soddisfatte quindi azioni verranno eseguite.
-
-### Dopo record salvato
-
-attivato quando viene creato un nuovo record o un record esistente viene aggiornato. Se specificate le condizioni sono soddisfatte quindi azioni verranno eseguite.
-
-Per le regole di flusso di lavoro con questo tipo di trigger è una pratica comune per avere una condizione che controlla se qualche campo era "cambiato". Ad esempio Nel caso in cui lo stato è cambiato poi di eseguire alcune azioni.
-
-### Programmato
-
-attivato secondo la pianificazione definita. È possibile impostare la funzione per eseguire ogni giorno, ogni settimana, ecc. Le azioni saranno applicati per i record restituiti da una lista specifica relazione. Pertanto è necessario anche per la creazione di un report ad elenco.
-
-La pianificazione è specificato in una notazione crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | -- Anno (intervallo: 1900-3000)
-| | | | ---- il giorno della settimana (intervallo: da 1 a 7, 1 in piedi per lunedì)
-| | | ------ mese dell'anno (intervallo: 1-12)
-| | -------- giorno del mese (intervallo: 1-31)
-| ---------- Ora (intervallo: 0-23)
------------- minuto (intervallo: 0-59)
-```
-
-### sequenziale
-
-raramente usato. Dovrebbe essere gestito da un altro flusso di lavoro. Fornisce la capacità di rendere una logica complessa.
-
-Nota: per i flussi di lavoro sequenziali si consiglia di utilizzare [BPM strumento](bpm.md) piuttosto che una funzione di flussi di lavoro.
-
-## Condizioni
-
-è possibile specificare le condizioni che devono essere soddisfatte per attivare il flusso di lavoro. Ci sono due modi di come le condizioni possono essere specificati: con la condizione di UI builder e con formula.
-
-### Condizione UI builder
-
-sono disponibili alcuni tipi di condizione:
-
-* _equivale a_ - il campo è uguale a un valore specifico o di un valore di un altro campo;
-* _era pari_ - il campo era uguale a un determinato valore prima del flusso di lavoro è stato attivato;
-* _non equivale a_ - il campo non è uguale a un valore specifico o di un valore di un altro campo;
-* _non era uguale_ - il campo non era uguale al valore di specifica prima che il flusso di lavoro è stato attivato;
-* _vuoto_ - il valore del campo è vuoto;
-* _non_ vuoto - il valore del campo non è vuoto;
-* _cambiato_ - il campo è stato cambiato;
-* _non_ è cambiato - il campo non è stato modificato.
-
-### In condizioni di Formula
-
-Formula fornisce una capacità di definire le condizioni di qualsiasi complessità. Per saperne di più su la sintassi della formula seguire [questo articolo](formula.md).
-
-Nota: non ci deve essere alcun ';' delimitatore utilizzato nella formula del codice quando si determina una condizione.
-
-## Azioni
-
-### Invio di messaggi di posta elettronica
-
-Il sistema invierà un messaggio di posta elettronica utilizzando un determinato modello di posta elettronica. Un indirizzo di posta elettronica del destinatario può essere preso dal record di destinazione, qualsiasi record correlato, l'utente corrente, seguaci, team di utenti o specificato. I messaggi di posta elettronica possono essere inviati immediatamente o ritardato di un intervallo specifico.
-
-### Crea Record
-
-System consentirà di creare il nuovo record di qualsiasi tipo di entità. Se non vi è una relazione tra il record di destinazione e la creazione di record che è possibile correlare i record.
-
-Vi è una possibilità di definire la formula per calcolare i campi.
-
-### Di creare record correlati
-
-sistema crea il record correlati al record di destinazione. È possibile definire la formula per calcolare i campi.
-
-### Aggiornamento record di destinazione
-
-consente il cambiamento di specifici campi del record di destinazione. È possibile definire la formula per calcolare i campi.
-
-Se avete bisogno di aggiungere nuovi elementi al campo Link-Multiple w/o perdere i dati esistenti (es. I team) è necessario utilizzare le funzione di formula entità\addLinkMultipleId. Esempio: 'entità\addLinkMultipleId('squadre', 'teamId')'.
-
-### Aggiornamento record correlati
-
-consente la modifica di campi specifici del record correlato o record. È possibile definire la formula per calcolare i campi.
-
-### Link con un altro record
-
-si riferisce l'entità bersaglio con un altro ente specifico. Ad esempio aggiunge team specifico per il record.
-
-### Scollega con un altro record
-Unrelates l'entità bersaglio da un altro ente specifico. Ad esempio rimuove un team specifico dal record.
-
-### Di applicare la regola di assegnazione
-
-assegnare il record di destinazione per l'utente dalla regola di distribuzione. Vi sono due regole disponibili: il round robin e Least-Busy.
-
-* Il Round Robin - gli utenti vengono scelte dalla parte superiore alla parte inferiore di un elenco (team) e quindi avviare di nuovo.
-* Least-Busy - utente che dispone di un minor numero di record assegnati saranno scelti per l'assegnazione.
-
-_Elenco Report_ - per la distribuzione Least-Busy determina quali record saranno presi in considerazione per calcolare il numero di record assegnati. Ad esempio per i casi di cui abbiamo bisogno per prendere solo i record con stato attivo.
-
-### Creare Notifica
-
-Notifica utenti specifici con il messaggio. È possibile utilizzare i segnaposto nel modello di messaggio: {entità} - record di destinazione, {user} - Utente corrente.
-
-### Make seguito
-
-costringe gli utenti specifici per seguire l'entità bersaglio o un specificied entità correlate.
-
-### Trigger un altro flusso di lavoro
-
-consente di realizzare flussi di lavoro sequenziali. È possibile per il flusso di lavoro di diramazione dalla condizione: è possibile configurare il flusso di lavoro per attivare due flussi di lavoro con diverse condizioni definite per il fatto che i flussi di lavoro.
-
-È possibile ritardare l'esecuzione del flusso di lavoro sequenziale. In wokflow sequenziale è possibile definire la condizione che verifica se i campi specifiec sono state modificate poiché il flusso di lavoro principale sono state innescate dall utilizzo di _cambiato_ e _era pari_ tipi di condizione.
-
-Nota: per i flussi di lavoro sequenziali si consiglia di utilizzare [BPM strumento](bpm.md) piuttosto che una funzione di flussi di lavoro.
-
-### Esegui azione di servizio
-
-consente di eseguire il servizio specifico di script. Per impostazione predefinita non ci sono le seguenti azioni disponibili:
-
-* Invia gli inviti - per riunioni/chiamate;
-* aggiungere voci del preventivo - per citazioni.
-
-Gli sviluppatori possono scrivere i propri interventi di manutenzione. Vedere [dettaglio](../../../docs/development/workflow-service-actions.md).
-
-## Usando la formula nelle azioni
-
-è possibile definire la formula per calcolare i campi per creare record, aggiornare il record di destinazione, creare record correlati e aggiornare i record correlati. Per gli ultimi due, per accedere a attributi di entità di destinazione è necessario utilizzare la funzione 'targetEntity\attribute'. Per accedere a attributi di entità bersaglio che è stato impostato prima del flusso di lavoro è stato attivato la funzione uso 'targetEntity\attributeFetched'.
-
-Esempio:
-```
-nome = stringa\CONCATENA(targetEntity\attribute('nome'), ' ', datetime\oggi());
-```
diff --git a/i18n/pl_PL/README.md b/i18n/pl_PL/README.md
deleted file mode 100644
index ef843823e..000000000
--- a/i18n/pl_PL/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Dokumentacja EspoCRM
-
-### Administration
-* [Konfiguracja serwera](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/server-configuration.md)
- * [Apache](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/apache-server-configuration.md)
- * [Nginx](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/nginx-server-configuration.md)
-* [Instalacja](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/installation.md)
-* [Aktualizacja](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/upgrading.md)
-* [Zarządzanie Rolami (kontrola dostępu)](https://github.com/espocrm/i18n/pl_PL/documentation/blob/master/administration/roles-management.md)
-* [Wiadomości Email](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/emails.md)
-* Dostosowywanie
- * [Menadżer jednostek: jednostki, pola, relacje](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/entity-manager.md)
- * [Menadżer Szablonów](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/layout-manager.md)
- * [Rozszerzenia](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/extensions.md)
-* Automatyzacja
- * [Zarządzanie Procesami Biznesowymi (BPM)](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/bpm.md)
- * [Przepływ informacji](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/workflows.md)
- * [Obliczenia (Wzór)](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/formula.md)
-* [Import danych](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/import.md)
-* [Portal](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/portal.md)
-* [Autoryzacja LDAP](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/ldap-authorization.md)
- * [Aktywne katalogi](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/ldap-authorization-for-ad.md)
- * [OpenLDAP](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/ldap-authorization-for-openldap.md)
-* [Rozwiązywanie problemów](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/troubleshooting.md)
-* Inne
- * [Mapy](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/maps.md)
- * [Model B2C](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/b2c.md)
- * [Kopia zapasowa i przywracanie](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/backup-and-restore.md)
- * [Przenoszenie na inny serwer](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/moving-to-another-server.md)
-
-
-### Podręcznik Użytkownika
-* [Wiadomości Email](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/user-guide/emails.md)
-* [Strumień danych](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/user-guide/stream.md)
-* [Wiadomości masowe](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/user-guide/mass-email.md)
-* [Raporty](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/user-guide/reports.md)
-* [Cytaty](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/user-guide/quotes.md)
-* [Składnia Markdown](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/user-guide/markdown.md)
-* Inne
- * [Wsparcie przeglądarek internetowych](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/user-guide/browser-support.md)
-
-### Rozwój aplikacji
-* [API](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/api.md)
-* [ORM: Jak zarządzać jednostkami](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/orm.md)
-* [Metadane](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/metadata.md)
-* [Niestandardowe Widoki](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/custom-views.md)
-* [Dynamiczne Formularze](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/dynamic-forms.md)
-* [Łączenie wiele pól z pierwotnymi rekordami](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/link-multiple-with-primary.md)
-* [Paczki Rozszerzeń](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/extension-packages.md)
-* [Hooks](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/hooks.md)
-* [Tworzenie niestandardowych planowanych zadań](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/scheduled-job.md)
-* [Definiowanie nowych funkcji dla Wzoru](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/new-function-in-formula.md)
-* [Niestandardowe rodzaje pól](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/development/custom-field-type.md)
-
-
-[Dokumentacja na stronie internetowej](https://www.espocrm.com/documentation/)
diff --git a/i18n/pl_PL/administration/apache-server-configuration.md b/i18n/pl_PL/administration/apache-server-configuration.md
deleted file mode 100644
index 62c0818c5..000000000
--- a/i18n/pl_PL/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Apache server configuration for EspoCRM
-
-These instructions are supplementary to the [Server Configuration](server-configuration.md) guideline. Please note that all configuration settings listed here are made on Ubuntu server.
-
-## PHP requirements
-
-To install all necessary libraries, run these commands in a terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Fixing the issue “API Error: EspoCRM API is unavailable”:
-
-Take only necessary steps. After each step check if the issue is solved.
-
-### 1. Enable “mod_rewrite” support in Apache
-
-To enable “mod_rewrite,” run these commands in a terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Enable .htaccess support
-
-To enable .htaccess support, add/edit the Server Configuration Settings /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf or /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Afterward, run this command in a terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Add RewriteBase path
-
-Open a file /ESPOCRM_DIRECTORY/api/v1/.htaccess and replace the following line:
-
-```
-# RewriteBase /
-```
-
-with
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-where REQUEST_URI is a part of URL, e.g. for “http://example.com/espocrm/”, REQUEST_URI is “espocrm”.
-
-
-## Enable HTTP AUTHORIZATION support (only for FastCGI).
-
-FastCGI does not support HTTP AUTHORIZATION by default. If you use FastCGI, you have to enable it in your VirtualHost or /etc/apache2/apache2.conf (httpd.conf) by adding the following code:
-
-For Fcgid module:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-For FastCgi module:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-To check which module is currently being used, run this command and find the module:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/pl_PL/administration/b2c.md b/i18n/pl_PL/administration/b2c.md
deleted file mode 100644
index 883c93c45..000000000
--- a/i18n/pl_PL/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#Configuring EspoCRM for B2C (Business-to-Client)
-
-By default EspoCRM is configured to use for B2B business. But you can easily setup it for B2C.
-
-* Change `b2cMode` to true in your config file `data/config.php`. Since version 4.3.0 it can be configured at Administration > Seetings.
-* Remove *Account* tab from the navigation menu (Administration > User Interface).
-* Remove *Account* fields from your layouts (Administation > Layout Manager).
-* Disable an access to *Account* scope for all your roles (Administration > Roles).
-* Remove Account from picklists of all parent fields (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
diff --git a/i18n/pl_PL/administration/backup-and-restore.md b/i18n/pl_PL/administration/backup-and-restore.md
deleted file mode 100644
index 9ea0977ed..000000000
--- a/i18n/pl_PL/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Backup and Restore
-
-## How to backup EspoCRM manually
-
-EspoCRM consists of files and database data. All these data are needed in order to create a full backup of EspoCRM. Here are instructions on how to do it on Ubuntu server with MySQL.
-
-### Step 1. Backup files
-
-Create an archive of the directory content of installed EspoCRM. For Ubuntu the default path is `/var/www/html`. You may use this command:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Step 2. Backup database
-
-To backup all your data, you have to know the database name and access credentials. You can find the database name in the configuration file `/ESPOCRM_DIRECTORY/data/config.php` under section `database`. You can use this command to backup your database:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Step 3. Copy the backup
-
-That's all. Now, you have to copy the created backup to a safe place.
-
-
-## How to backup EspoCRM with a script
-
-You can use a script to backup all needed data. Login via SSH and run the commands (tested on Ubuntu server).
-
-### Download a script
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Run the script
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-where
- * `PATH_TO_ESPOCRM` is a path to installed EspoCRM directory.
- * `BACKUP_PATH` is a path to backup directory.
-
-For Ubuntu server it is:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Note: If your MySQL user doesn't have needed rights to dump your database, you will be promted to enter credentials of another MySQL user.
-
-After successful creation, you will get a path to the created backup.
-
-## Restore EspoCRM from a backup
-
-You can restore EspoCRM from the backup created as described above.
-
-### Step 1. Unarchive backup files
-
-To unarchive files, you can use Archive Manager or run the below command. Files need to be placed in the web-server directory.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-where:
- * `/var/www/html` is a web-server directory.
-
-### Step 2. Set required permissions
-
-The files should be owned by a web-server user and have correct permissions. Please set required permissions by following this instruction: [www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### Step 3. Import database dump
-
-Database dump should be imported to the same database with the same user credentials, otherwise the correction should be made in the configuration file `ESPOCRM_DIRECTORY/data/config.php`. To import your database from the dump, run the command below in a terminal:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Step 4. Check/configure crontab
-
-Check if your crontab is configured properly. Run the command below and check if a path to EspoCRM is correct:
-
-```bash
-sudo crontab -l -u www-data
-```
-where:
- * `www-data` is your web-server user.
-
-If you have to make any changes, use this command:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-More details about configuring crontab for EspoCRM is described here [www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
diff --git a/i18n/pl_PL/administration/bpm.md b/i18n/pl_PL/administration/bpm.md
deleted file mode 100644
index 86f82cb8f..000000000
--- a/i18n/pl_PL/administration/bpm.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# Business Process Management
-
-Business Process Management (BPM) tool provides the ability to model and automate business processes in EspoCRM. It's an engine executing business processes described in BPMN 2.0 standard. BPM tool is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) extension.
-
-
-
-### Difference from Workflows tool
-
-Workflows tool is intended for automation of simple business rules, w/o sequential flow items, when there is no need to display the flow graphically.
-
-BPM tool is intended for more complex business flows, where there can be diverging and converging flows, execution delays, user interactions. A flowchart view makes the business process more comprehensible for a human, a log allows to see how the process was held.
-
-## Process Flowcharts
-
-The link to process flowcharts is available from administration panel. It also can be added as a tab on the navigation panel.
-
-Flowcharts are intended for business processes modeling. Administrator can create and edit flowcharts. Regular users can only view flowcharts.
-
-Every flowchart has its specific entity type (Target Type field). The flowchart determines execution of future process instances. It comprises flowchart elements and connections between elements.
-
-If process flowchart has the unchecked 'Is Active' field then it won't initiate process instances.
-
-To show details and parameters of a certain flowchart element you need to click on it. In edit mode you will be able to edit parameters.
-
-## Processes
-
-Processes are available from administration panel. The link also can be added as a tab on the navigation panel.
-
-Process represents business process instance. When it's initiated it gets the status 'Started'. When process is finished it gets the status 'Ended'. The process can also be stopped manually by a user who has an access to edit the process. If it's stopped manually it gets status the 'Stopped'.
-
-The process is executed according the flowchart. Flowchart of process can't be changed after process is started.
-
-The process obligatorily is related to single target record.
-
-Processes can be started automatically (upon specific conditions or by scheduling) or manually (where there is at least one Start Event in the flowchart). To start process manually the user needs to click 'Start Process' button on the list view of processes.
-
-## Flowchart Elements
-
-### Events
-
-Events are displayed on a flowchart as circles.
-
-#### Start Event
-
-Doesn't have parameters. It's a starting point of the process. Start Event can be initiated manually by a user who has an access to create processes. The user needs to click 'Start Process' button on the list view of processes.
-
-#### Conditional Start Event
-
-A starting point of the process. It's supposed to be triggered automatically when specified conditions are met. There are two types of trigger: 'After record created', 'After record saved'.
-
-#### Timer Start Event
-
-A starting point of the process. It initiates processes by scheduling. You need to specify the list report that returns records for initiating processes and scheduling in crontab notation.
-
-#### Conditional Intermediate Event
-
-This event stops the flow until specified criteria is met.
-
-#### Timer Intermediate Event
-
-This event stops the flow and waits as long as is specified by event's parameters.
-
-For more complex timer settings you can utilize [formula](formula.md). Formula scripts should return Date-Time value (in UTC timezone). Once this time comes the flow will be proceeded to the next element.
-
-By utilizing datetime\closest formula function it's possible to set the timer to a specific time in the future, e.g. the beginning of the next working day.
-
-#### End Event
-
-Ends the current flow. It doesn't end flows running in parallel. When the flow reaches the end event and there is no anything running in parallel then process ends.
-
-#### Terminate End Event
-
-Ends all flows. Process is subsequently ended.
-
-### Gateways
-
-Gateways are displayed as diamonds.
-
-#### Exclusive Gateway
-
-Can diverge or converge flows.
-
-In case of diverging it defines a single flow (path) that will be chosen according specified criteria. The first met condition determines the flow, next conditions are omitted. There is an ability to specify default flow. Default flow is chosen if there are no any met conditions. Default flow is marked with a slash sign.
-
-In case of converging it just directs the flow to the outgoing element. It doesn't get blocked after the flow come though, so parallel flows won't be merged into the single flow.
-
-
-
-
-
-#### Inclusive Gateway
-
-Can diverge or converge flows.
-
-In case of diverging, it can direct to one or multiple parallel flows (paths), depending on accomplishment of criteria of each flow. Default flow is chosen if there are no any met conditions. Default flow is marked with a slash sign.
-
-If there is a necessity to merge parallel flows produced by a diverging inclusive gateway you need to use a converging inclusive gateway. It will wait for all incoming flows and then continue to the outgoing element.
-
-
-
-Note: Diverging and converging gateways must be balanced.
-
-Note: If one of parallel flows has been ended for some reason then diverging gateway will never be processed. The process will be blocked. Avoid a flowchart design that can bring about such a situation.
-
-#### Parallel Gateway
-
-Can diverge or converge flows.
-
-In case of diverging it splits flow into multiple parallel flows. There are no parameters for this gateway type.
-
-In case of converging it waits until all incoming flows come and then continues to the next outgoing element.
-
-
-
-Note: Diverging and converging gateways must be balanced.
-
-Note: If one of parallel flows has been ended for some reason then diverging gateway will never be processed. The process will be blocked. Avoid a flowchart design that can bring about such a situation.
-
-#### Event Based Gateway
-
-Can only diverge flows.
-
-It stops the flow until any of outgoing events gets triggered. Triggered event determines the single flow. Other outgoing events get rejected.
-
-Only intermediate events can be on the other end of outgoing sequence flows.
-
-
-
-### Activities
-
-Activities are displayed as rounded rectangles.
-
-#### Task
-
-Task can execute following the actions:
-
-* Create Record - creates new record of any entity type;
-* Create Related Record - creates new record related to the target record;
-* Update Target Record;
-* Update Related Record - updates the record or records related to the target record;
-* Update Created Record - updates specific field of any record created in the current process;
-* Update Process Record - can be used to assign the process to specific user or team;
-* Link to Another Record - links the target record with a specified record;
-* Unlink from Another Record - unlinks the target record from the specified record;
-* Apply Assignment Rule - assigns the target record, the process record or any record created by the process according to the specific rule;
-* Create Notification - creates in-app notification for specific users;
-* Make Followed - makes specific users follow the target record, the process record or any record created by the process;
-* Run Service Action - runs custom service actions implemented by developers.
-
-Actions available for task are almost the same as in Workflow feature. See more details about [workflow's actions](workflows.md#actions).
-
-#### Send Message Task
-
-Sends email message to specific recipient.
-
-#### User Task
-
-Provides a flexible ability of user interaction. It stops execution until the user (specified explicitly or by assignment rule) resolves the task. Process User Task record will be created in the system. By default there are three action types: Approve, Review, Accomplish.
-
-* Approve type requires the user to chose between 'Approved' and 'Declined'.
-* Review type gives only one option: 'Reviewed'.
-* Accomplish type has two options: 'Completed' and 'Failed'.
-
-
-The user assigned to the created Process User Task record will receive in-app notification. Administrator can also enable email notifications.
-
-Users can also add Process User Tasks dashlet on their dashboard to see their actual process user tasks.
-
-It's possible to read the resolution of the passed user task within diverging gateways or conditional events, making ramification in the process flow.
-
-#### Script Task
-
-Executes the script in [espo-formula](formula.md) language. All set variables (`$variableName`) will be stored and available within the process.
-
-### Flows
-
-#### Sequence Flow
-
-Represented as a solid arrow. Indicates the order in which process elements will be executed.
-
-## Conditions
-
-Conditional events, exclusive and inclusive diverging gateways have conditions that determine the flow of the process.
-
-Through UI there is an ability to check conditions for the following records:
-
-* Target record;
-* Records related to the target through many-to-one and children-to-parent relationships;
-* Records created by the process via tasks;
-* User task records, which allows checking the resolution.
-
-It's also possible to define conditions in [Espo-formula](formula.md) language.
-
-Conditions in BPM tool are the same as in Workflow feature. See more details about [workflow's conditions](workflows.md#conditions).
-
-## Examples
-
-### Example 1
-
-
-
-### Example 2
-
-
-
-### Example 3
-
-
diff --git a/i18n/pl_PL/administration/email-fetching.md b/i18n/pl_PL/administration/email-fetching.md
deleted file mode 100644
index 1d23f41cc..000000000
--- a/i18n/pl_PL/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Emails
-
-The document is moved to [here](emails.md).
diff --git a/i18n/pl_PL/administration/emails.md b/i18n/pl_PL/administration/emails.md
deleted file mode 100644
index f0dcee22d..000000000
--- a/i18n/pl_PL/administration/emails.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Emails
-
-> Important. [Cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) should be configured in your system to make email fetching work. You can find the information in your EspoCRM at Administration > Scheduled Jobs.
-
-## Overview
-
-EspoCRM has an ability to monitor IMAP mailboxes. Email can be archived in two ways: Group Email Accounts and Personal Email Accounts. Group Inbound Accounts are intended for group mailboxes: the most common case is a support box. Personal Email Accounts are intended for users’ personal mailboxes.
-
-As an email is coming the system tries to link it with the appropriate record (Accounts, Lead, Opportunity, Case). Users who follow that record will receive notification about a new email in the system, even if they are not in To or CC.
-
-## Group Email Accounts
-
-Only administrator can setup Group Email Accounts. Group Email Accounts can be used for both receiving and sending emails. Sending emails from group accounts has been available since 4.9.0 version.
-
-Teams field determines which teams incoming emails will be assigned to.
-
-If the group email account has SMTP and it's checked as shared then an access will be controlled by Roles through Group Email Account permission. Teams field will be used if permission level is set to 'team'.
-
-There is an ability to make the system send an auto-reply for incoming emails.
-
-## Email-to-Case
-
-There is an option to make the system create cases from incoming group emails.
-This feature is intended for support teams.
-Cases can be distributed to users from a specified team according to these ways:
-`direct assignment`, `round-robin` and `less-busy`.
-Only the first email in the thread creates a new case.
-Every subsequent one will be linked to the existing case record and displayed in its Stream panel.
-
-When users want to send a reply to the customer they need to make sure that the case is selected as a parent of the email that is being sent. It will make the customer reply to the group email address rather than to the user’s own.
-
-## Personal Email Accounts
-
-Users can setup their own email accounts that need to be monitored. Emails > Top Right Dropdown Menu > Personal Email Accounts. Administrator also can manage users' email accounts.
-
-## Email Filters
-
-These allow the filtering of incoming emails according to specified criteria. E.g. if you don't want notification messages sent by some application to be imported to EspoCRM you can create filter to make EspoCRM skip them.
-
-Admin can create global filters, applied to all email accounts. Users can create filters for their own personal email account and for entire inbox.
diff --git a/i18n/pl_PL/administration/entity-manager.md b/i18n/pl_PL/administration/entity-manager.md
deleted file mode 100644
index a8fcd6b69..000000000
--- a/i18n/pl_PL/administration/entity-manager.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Entity Manager
-
-Entity Manager is available in Administration panel. It provides an ability to highly customize your EspoCRM instance. You are able to do the following:
-
-* Add new types of entities.
-* Customize existing types of entities: change labels, default order in list view, enable or disable stream.
-* Configure fields: add new, customize existing ones.
-* Configure relationships: add new, change labels of existing ones.
-
-## Creating new entity
-
-Click `Create Entity` button on Entity Manager page. Specify name, labels and type. If you select `Person` type, your entity will have Email, Phone, First Name, Last Name and Salutation fields. Check `Stream` if you want your entity to have stream panel and users to be able to Follow entities of this type.
-
-Types:
-
-* Base - empty entity only with basic fields like Name, Assigned User, Teams, Description.
-* Base Plus - like Base but with Activities, History, Tasks panels (available since 4.3.0).
-* Event - Date Start, Date End, Duration, Parent, Status fields. Available in Calendar and Activities panel (since 4.3.0, must be enabled at Administration > Settings).
-* Person - Email, Phone, First Name, Last Name, Salutation, Address fields. Activities, History, Tasks panels.
-* Company - Email, Phone, Billing Address, Shipping Address fields. Activities, History, Tasks panels.
-
-## Update existing entity
-
-If you click `Edit` link on a certain entity you will be able to change some parameters of that entity.
-
-* Labels - singular and plural name of the entity.
-* Default order records are sorted by in list views.
-* Stream - whether Stream feature is enabled for this entity.
-* Disabled - check if you don't need this entity in your system.
-* Text Filter Fields - what fields to search in for the main text filter and global search.
-
-
-## Fields
-
-By clicking `Fields` link you will be moved to a separate page. There you will be able to create new fields or update existing ones. The following types of fields are available in Entity Manager:
-
-* Address - address with street, city, state, postal code and country;
-* Array - list of values, with the ability to select multiple values (not a good option if you need to search by this field); users can add their own values if options are not specified.
-* Attachment Multiple - multiple file attachments;
-* Auto-increment - read only generated number;
-* Boolean - checkbox, true or false;
-* Currency - for currency values;
-* Date;
-* DateTime;
-* Enum - selectbox, with the ability to select only one value;
-* File - uploading one file;
-* Float - number with a decimal part;
-* Foreign - a field of related entity;
-* Image - uploading image file with a preview;
-* Integer - whole number;
-* Number - auto-incrementing number of string type with a possible prefix and a specific length;
-* Multi-enum - list of values, with the ability to select multiple values (not a good option if you need to search by this field), similar to Array but nicer.
-* Text - text area, for long multiline texts;
-* Url - for links;
-* Varchar - short text;
-* Wysiwyg - similar to Text field, with the ability to format text.
-
-Parameters:
-* Required - whether filling in of the field is mandatory.
-* Default Value - Value of the field set upon creating new record.
-* Audited - updates of the field will be logged in Stream.
-
-**Note**: After you have added the new field you need to put this field on [layouts](layout-manager.md) (Administration > Layout Manager).
-
-### Dynamic Logic
-
-Provides an ability to make forms dynamic. It's possible to define conditions making certain fields visible, required or read-only. Conditions will be checked automatically when data in the form is changed.
-
-For Enum, Array and Multi Enum fields it's possible to define different sets of options that will be available for the field depending on which condition is met.
-
-
-## Relationships
-
-You can create new relationships between both out-of-box and custom entities. There are 3 available relationship types:
-
-* One-to-Many: after you have created this relationship you can put a link field to the detail layout of the right entity and add relationship panel to the left entity;
-* Many-to-One: the same as One-to-Many but vice versa;
-* Many-to-Many: relationship panels on both sides.
-
-Parameter 'Link Multiple Field' implies that the field of `linkMultiple` type will be created along with relationship. You can put such a field on the layout. It's convenient for quick picking of related records. It's not a good option if your relationship is intended to have a lot of linked records that can slow down loading of detail view screen.
-
-If parameter 'Audited' is checked then updates of the relationship will be logged in Stream.
-
diff --git a/i18n/pl_PL/administration/extensions.md b/i18n/pl_PL/administration/extensions.md
deleted file mode 100644
index fa3c80740..000000000
--- a/i18n/pl_PL/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Manage extensions
-
-## How to install an extension
-
-In order to install EspoCRM extension (e.g. Advanced Pack, VoIP Integration):
-
-1. Login as an administrator.
-2. Go to Administration > Extensions.
-3. Upload your extension package (zip file).
-4. Click Install button.
-
-
-## How to upgrade an extension
-
-In order to upgrade an already installed extension (e.g. Advanced Pack, VoIP integration) to a newer version:
-
-1. Download the new version of needed extension.
-2. Login as an administrator.
-3. Go to Administration > Extensions.
-4. Upload your new extension package (zip file) without uninstalling the already installed version.
-5. Click Install button.
-
-
-## How to uninstall an extension
-
-Steps to uninstall an installed extension:
-
-1. Login as an administrator.
-2. Go to Administration > Extensions.
-3. Find needed extension on the list of available extensions.
-4. Click Uninstall button.
-
-
-## How to delete an extension
-
-When an extension is uninstalled, it is still available in the system. It can be completely deleted. Steps to delete an extension:
-
-1. Login as an administrator.
-2. Go to Administration > Extensions.
-3. Find the needed extension in the list of available extensions.
-4. Click Remove button.
diff --git a/i18n/pl_PL/administration/formula.md b/i18n/pl_PL/administration/formula.md
deleted file mode 100644
index 7a089209b..000000000
--- a/i18n/pl_PL/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Calculated Fields (Formula)
-
-In entity manager it's possible to define script (formula) for specific entity type. This script will be executed every time before record is saved.
-It provides an ability to automatically set specific fields (attributes) with values derived from calculation.
-
-To edit formula follow Administration > Entity Manager > dropdown menu at the right on the row of needed entity > Formula.
-
-You also might need to set fields, that are supposed to be calculated, Read-only via Entity Manager.
-
-
-## Syntax
-
-EspoCRM formula is written in the simple language designed specifically for this feature.
-
-There are operators, functions attributes and values that can be used in formula. Separated expressions must be delimited by character `;`.
-
-### Operators
-
-* `=` - assignment.
-* `||` - logical OR,
-* `&&` - logical AND,
-* `!` - logical NOT,
-* `+`- numeric summation,
-* `-` - numeric subtraction,
-* `*` - numeric multiplication,
-* `/` - numeric division,
-* `%` - numeric modulo,
-* `==` - comparison equals,
-* `!=` - comparison not equals,
-* `>` - comparison greater than,
-* `<` - comparison less than,
-* `>=` - comparison greater than or equals,
-* `<=` - comparison less than or equals.
-
-Priority of operators:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Attributes
-
-Attributes represent field values of the target entity. You can insert available attributes by clicking on the plus button.
-
-It's possible to access attributes of related entities with the following format `linkName.attributeName`.
-
-
-### Functions
-
-Format of function use: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Out-of-the-box functions are listed below.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` If CONDITION is met then do CONSEQUENT. If not -- then do ALTERNATIVE.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` If CONDITION is met then do CONSEQUENT. If not -- do nothing.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Concatenates two or more strings.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Extracts the characters from a STRING by START position and LENGTH.
-
-If LENGTH is omitted, the substring starting from START until the end of the STRING will be returned.
-
-If LENGTH is negative, then that many characters will be omitted from the end of STRING.
-
-#### string\\trim
-`string\trim(STRING)` Strips whitespace from the beginning and end of STRING.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Converts letters to lower case. (since version 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Converts letters to upper case. (since version 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Returns today's date.
-
-#### datetime\now
-`datetime\now()` Returns current datetime.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Converts date or datetime VALUE into string formatted according to application settings. TIMEZONE and FORMAT can be omitted. If TIMEZONE is omitted then default time zone will be used. If FORMAT is omitted then default format will be used.
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Returns date of the month (1-31). `0` if VALUE is empty. If TIMEZONE is omitted then system timezone is used. (since version 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Returns month (1-12). `0` if VALUE is empty. If TIMEZONE is omitted then system timezone is used. (since version 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Returns year. `0` if VALUE is empty. If TIMEZONE is omitted then system timezone is used. (since version 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Returns hour (0-23). `-1` if VALUE is empty. If TIMEZONE is omitted then system timezone is used. (since version 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Returns minute (0-59). `-1` if VALUE is empty. If TIMEZONE is omitted then system timezone is used. (since version 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Returns day of the week (0-6). `-1` if VALUE is empty. `0` - for Sunday. If TIMEZONE is omitted then system timezone is used. (since version 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Returns difference between two dates or datetimes. INTERVAL_TYPE can be 'years', 'months', 'days', 'hours', 'minutes'. Returns `null` if failure. Result will be negative if VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Adds MINUTES to datetime VALUE. MINUTES can be negative.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Adds HOURS to datetime VALUE. HOURS can be negative.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Adds DAYS to date or datetime VALUE. DAYS can be negative.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Adds WEEKS to date or datetime VALUE. WEEKS can be negative.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Adds MONTHS to date or datetime VALUE. MONTHS can be negative.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Adds YEARS to date or datetime VALUE. YEARS can be negative.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` Returns closest date or datetime to VALUE based on passed arguments. (since version 5.0.0)
-
-TYPE can be one of the following values: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. TARGET is an integer value or a string value. IS_PAST means to find closest in the past. If TIMEZONE is omitted then default timezone is used.
-
-Examples:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Will return the closest datetime value in the future with 20:00 time.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Will return `2017-11-01`, the first day of the month.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Will return the next Monday (the beginning of the day).
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Converts numeric VALUE into string formatted according to a specific format or default application settings. If DECIMALS, DECIMAL_MARK OR THOUSAND_SEPARATOR then system defaults are used.
-
-Examples:
-
-`number\format(2.666667, 2)` - results 2.67;
-
-`number\format(1000, 2)` - results 1,000.00;
-
-`number\format(10.1, 0)` - results 10.
-
-
-#### number\abs
-`number\abs(VALUE)` Absolute value. Returns null if VALUE is not numeric.
-
-#### number\round
-`number\round(VALUE, PRECISION)` Returns the rounded value of VALUE to specified PRECISION (number of digits after the decimal point). PRECISION can also be negative or zero (default).
-
-#### number\floor
-`number\floor(VALUE)` Returns the next lowest integer value by rounding down value if necessary. (since version 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` Returns the next highest integer value by rounding up value if necessary. (since version 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Returns TRUE if the entity is new (being created) and FALSE if not (being updated).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Returns TRUE if ATTRIBUTE of the entity was changed.
-
-Example:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Return TRUE if ATTRIBUTE of the entity was not changed.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Attribute that was set when target entity was fetched from database. Before it was modified.
-
-Example:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Adds ID to Link Multiple field. For example, add 'someTeamId' to 'teams' field.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Adds the list of ids. (since version 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Checks whether Link Multiple field has specific ID.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Removes a specific ID from the Link Multiple field.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Checks whether target entity is related with another entity represented by LINK and ID.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Returns ATTRIBUTE of the current user.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Returns array. (since version 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Returns true if LIST contains VALUE. Can be used for Array and Multi-Enum fields. (since version 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Adds one or more elements to the end of an array and returns the new array. (since version 5.0.0)
-
-#### array\length
-`array\length(LIST)` Returns count of elements in LIST. (since version 4.8.1)
-
-
-### Values
-
-* Strings. E.g. 'some string';
-* Integer numbers. E.g. 1, 100, 40300.
-* Float numbers. E.g. 5.2.
-
-### Variables
-
-It's possible to define custom variables in formula.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Examples
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Using formula in Workflows
-
-You can utilize formula in workflow conditions and actions. See [workflows documentation](workflows.md) for more information.
diff --git a/i18n/pl_PL/administration/import.md b/i18n/pl_PL/administration/import.md
deleted file mode 100644
index d0bbc1737..000000000
--- a/i18n/pl_PL/administration/import.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Import
-
-Import is accessible only for admin users. Administration > Import. You are able to import only from CSV files.
-
-## Step 1
-
-Select what type of records you need to import (Entity Type field).
-Select a CSV file. A file should be formated with `UTF-8`.
-Select `What to do?`. Available options: 'Create Only', 'Create & Update', 'Update Only'.
-
-* `Create Only` - select it if you want record be only created.
-* `Create & Update` - records will be created but if records with matching field values will be found it will be updated. You will be able to check what fields to match by on the _Step 2_.
-* `Update only` - only records with matching field values will be found it will be updated.
-
-Once you select a csv file you will be able to see how it should be parsed in Preview panel. When you change properties the preview will be updated.
-
-* `Header Row` - whether CSV file has the first row with field names.
-* `Execute in idle` - recommended if you have a big bunch of records to be imported. Import will be processed via cron. Status will be set to 'Complete' when import process is finished.
-* `Skip searching for duplicates` - it will decrease import runtime.
-
-Click _Next_ button to preceed to the _Step 2_.
-
-
-
-## Step 2
-
-Setup the field mapping: how fields correspond to columns of the csv file. You can skip not needed columns here.
-In cases of 'Create & Update' and 'Update only' you need to check fields by which records that should be updated will be found.
-Add default values you want new and updated records to set with. E.g. you can specify Assigned User or Teams fields.
-
-After the import is done you will be able to revert created records, see duplicates and updated records. Duplicate means that there was the similar record in the system. You can remove all imported duplicates at once. Note: Revert doesn't work with updated records.
-
-Click _Run Import_ button to proceed. It may take some time before an import process gets finished. If you want to import a large bunch of records (depends on you server configuration, usually if more than 200 records) you need to make sure that php parameter `set_time_limit` is large enough.
-
-
-
-## How to import into Target List
-
-When you import Contacts, Leads or Accounts you can add them to some target list. On the Step 2 you need to add Target List field on `Default Values` panel and select a needed target list record. You can also use `Update only` or `Create & Update` import to add existing targets to a target list.
diff --git a/i18n/pl_PL/administration/installation.md b/i18n/pl_PL/administration/installation.md
deleted file mode 100644
index e2c628739..000000000
--- a/i18n/pl_PL/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Installation
-
-### Requirements
-EspoCRM runs on the most hosting providers. Requirements include the following:
-
-* PHP 5.6 or latest version of PHP with enabled pdo, json, GD library, mcrypt extensions (usually enabled by default);
-* MySQL 5.5.3 or higher.
-
-See [Server Configuration](server-configuration.md) article for more information.
-
-### 1. Download the EspoCRM installation package
-To get the latest version of EspoCRM follow [download page](http://www.espocrm.com/download/) link.
-
-### 2. Upload the EspoCRM Files to Your Server
-
-Once the download is complete, upload the package to your web server.
-To upload it you can use SSH, FTP or the hosting administration panel.
-Extract the archive to your public web server directory (e.g., `public_html`, `www`, etc.).
-
-_Note: For FTP, you need to extract the archive before uploading to your web server._
-
-### 3. Create a MySQL Database for EspoCRM to use
-
-Go to your hosting administration panel, or to SSH, and create a new database and user for EspoCRM (e.g., `MySQL Databases` in cPanel).
-
-### 4. Run EspoCRM installation process
-
-Now, open your web browser, and go to the URL with EspoCRM files (e.g., `http://yourdomain.com/espo`).
-
-If you see this screen, you have a "Permission denied" error.
-So, you need to execute the displayed command in the terminal via SSH, or set the correct permission.
-It should be 755 for directories, 644 for files, and 775 for `data` directory.
-Also make sure that you have the correct _owner_ and _group_.
-
-
-
-If you see the following screen, the permission is correct and you can start installing EspoCRM.
-
-
-
-On this page, you can read and accept the License Agreement.
-
-
-
-Enter the details for your newly created MySQL database.
-
-
-
-Enter the user name and password of Administrator EspoCRM.
-
-
-
-On this page you can set the default settings of EspoCRM, such as date and time format, timezone, currency and others.
-
-
-
-Enter SMTP settings for outgoing emails, if you want to have the ability to send emails.
-This step can be skipped by clicking the _Next_ button.
-All of these options can be added/changed in EspoCRM after installation.
-
-
-
-Congratulation! Installation is complete.
-The last thing to setup Scheduled Tasks to be run by your system. It can be done by running `crontab -e` in linux cli and in _Windows Tasks Scheduler_ in Windows systems.
-
-
-
-We hope you will enjoy working in EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/pl_PL/administration/layout-manager.md b/i18n/pl_PL/administration/layout-manager.md
deleted file mode 100644
index c855660f9..000000000
--- a/i18n/pl_PL/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Layout Manager
-
-Layout Manager is available in administration panel. Provides an ability to customize appearance of detail, edit, list views as well as search filters and fields for mass-update forms.
-
-## List
-
-The main layout for the list view. Defines columns and their parameters.
-
-
-
-Available parameters for columns are listed below.
-
-### Width (%)
-
-Width of column in percent, empty means auto-width.
-
-### Link
-
-If checked then the field will be displayed as a link to the detail view of the record. Usually used for name fields.
-
-### Not Sortable
-
-Disables an ability to sort the column.
-
-### Align
-
-Align the column to the left or to the right.
-
-## Detail
-
-The main layout for the detail view and the edit view. Defines panels, rows and cells. Cells contain fields.
-
-The row can contain two cells or one cell that is expanded to the full width of the row. To add the row with an expanded cell you need to add the new row and click on a minus sign on any cell.
-
-
-
-## List (Small)
-
-The list layout for relationship panels. Also can be used in other places where it's reasonable to display lists in the narrow view.
-
-## Detail (Small)
-
-The detail view for quick create, quick view and quick edit forms.
-
-## Search Filters
-
-The list of fields available in the list view to search by.
-
-## Mass Update
-
-The list of fields availabe in the Mass Update form.
-
-## Relationship Panels
-
-The list of relationship panels displayed on the detail view at the bottom. Panels can be re-ordered. It's possible to define the color of panel with the Style parameter.
-
-## Side Panels
-
-Side panels for Detail, Edit, Detail Small, Edit Small forms. Provides an ability to hide or re-order panels list Activities, History, Tasks and others. Panels can be colorized by the Style parameter.
-
-## Additional Layouts
-
-Some entity types contain additional layouts: Convert Lead, List for Account.
diff --git a/i18n/pl_PL/administration/ldap-authorization-for-ad.md b/i18n/pl_PL/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index 8e8e0025b..000000000
--- a/i18n/pl_PL/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# LDAP authorization for Active Directory
-
-Example of configuration LDAP authorization for the Active Directory server. The full guide of configuration LDAP authorization is described [here](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/pl_PL/administration/ldap-authorization-for-openldap.md b/i18n/pl_PL/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 6eba88088..000000000
--- a/i18n/pl_PL/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# LDAP authorization for OpenLDAP
-
-Example of configuration LDAP authorization for OpenLDAP server. The full guide of configuration LDAP authorization is described [here](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/pl_PL/administration/ldap-authorization.md b/i18n/pl_PL/administration/ldap-authorization.md
deleted file mode 100644
index c6b84c495..000000000
--- a/i18n/pl_PL/administration/ldap-authorization.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Ldap Authorization
-
-In this guide, we will show how to configure LDAP authorization for EspoCRM. Let’s go.
-
-Go to your LDAP server and create a base DN for the EspoCRM users like
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-We have to create a system user which will have access to the users DN (“cn=espo-users,ou=users,dc=espo,dc=local”). So, the full DN for this system user will be
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Now, we can add LDAP user to access to EspoCRM. E.g. Espo Tester with the username “tester” inside the “cn=espo-users,ou=users,dc=espo,dc=local” DN. Please note: to be able to use this login format for EspoCRM, you have to specify the “Username Attribute” and “Base DN” options.
-
-Then, go to EspoCRM Authentication settings in the Administrator panel, select `LDAP` method and fill in the LDAP details:
-
-
-
-* Host – LDAP IP or host name.
-* Port – connection port.
-* Auth – access credentials for the LDAP server:
- * Full User DN – the full system user DN which allows to search other users.
- * Password – the password to access the LDAP server.
-* Security – SSL or TSL protocol.
-* Username Attribute – the attribute to identify the user. For Active Directory it can be “userPrincipalName” or “sAMAccountName”.
-* Account Canonical Form – type of your account canonical form. There are 4 options:
- * Dn – the form in the format `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – the form `tester`.
- * Backslash – the form `COMPANY\tester`.
- * Principal – the form `tester@company.com`.
-* Bind Requires Dn – if need to format the username in the DN form.
-* Base Dn – the default base DN which is used for searching users.
-* User Login Filter – the filter which allows to restrict users who are able to use EspoCRM. E.g. `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – The domain which is used for authorization the LDAP server.
-* Account Domain Name Short – The short domain which is used for authorization the LDAP server.
-* Try Username Split – the option to split a username with the domain.
-* Opt Referrals – if referrals should be followed to the LDAP client.
-* Create User in EspoCRM – this option allows EspoCRM to create a user from the LDAP.
- * User First Name Attribute – LDAP attribute which is used to determine the user first name.
- * User Last Name Attribute – LDAP attribute which is used to determine the user last name.
- * User Title Attribute – LDAP attribute which is used to determine the user title.
- * User Email Address Attribute – LDAP attribute which is used to determine the user email address.
- * User Phone Number Attribute – LDAP attribute which is used to determine the user phone number.
-
-Now, go to the login page and enter user credentials.
-
-
-
-User has been authenticated and automatically created in the EspoCRM.
-
-##Configuration instructions based on your server:
-* [Active Directory server](ldap-authorization-for-ad.md)
-* [OpenLDAP server](ldap-authorization-for-openldap.md)
-
-More information about configuring LDAP you can read on the [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/) page, as EspoCRM uses this library.
-
-
-
-
diff --git a/i18n/pl_PL/administration/maps.md b/i18n/pl_PL/administration/maps.md
deleted file mode 100644
index d2182618f..000000000
--- a/i18n/pl_PL/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Maps
-
-## How to show the map based on an address field
-
-Every Address field has its corresponding Map field. All you need is to put it on Detail layout. It uses Google Maps service.
-
-`Administration > Layout Manager > Choose entity (Account, Contact, Lead or custom one) > Detail > Drag & Drop Map field.`
-
-Make the cell wide using the minus sign.
-
-You can also configure the height of your field.
-
-`Administration > Entity Manager > Choose entity > Fields > find the map field and click on it > edit the height and save.`
-
-## Api Key
-
-Since EspoCRM version 4.2.0 you need to specify Api Key to use Google Maps (Administration > Integration > Google Maps).
-
diff --git a/i18n/pl_PL/administration/moving-to-another-server.md b/i18n/pl_PL/administration/moving-to-another-server.md
deleted file mode 100644
index 89307db55..000000000
--- a/i18n/pl_PL/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Moving EspoCRM to another server
-
-Follow these steps to move EspoCRM to another server:
-
-### Step 1. Backup files
-
-Open a file manager or login via SSH to archive all available files from the EspoCRM directory. More details: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### Step 2. Backup your database
-
-The data stored in database (MySQL, MariaDB) should be backed up. Please follow this recommendation: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### Step 3. Copy files and database backups to another server
-
-Copy backups of files and of your database to a new server.
-
-### Step 4. Unarchive backup files
-
-To unarchive backup files, you can use Archive Manager or this instruction: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-Note: Files need to be placed in the web-server directory.
-
-### Step 5. Configure a server
-
-Configure a new server based on the recommendations here: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### Step 6. Correct permissions
-
-Set required permissions and files owner, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### Step 7. Import your database backup
-
-First, you have to create a new database with a user in MySQL. To import your database from the backup, follow the instuction: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### Step 8. Correct EspoCRM configurations
-
-After successfully importing and configuring the server, please correct EspoCRM configurations in the file `ESPOCRM_DIRECTORY/data/config.php`:
-
- * database connection settings:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - if your domain name (URL) is changed:
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * default files owner (only if different):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- where `www-data` is your web-server user.
-
-### Step 9. Setup a crontab
-
-Setup a crontab, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-Note: it should be configured under your web-server user.
-
-That's all. Now, your EspoCRM instance is running on a new server.
diff --git a/i18n/pl_PL/administration/nginx-server-configuration.md b/i18n/pl_PL/administration/nginx-server-configuration.md
deleted file mode 100644
index 676f73499..000000000
--- a/i18n/pl_PL/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Nginx server configuration for EspoCRM
-
-These instructions are supplementary to the [Server Configuration](server-configuration.md) guideline. Please note that all configuration settings listed here are made on Ubuntu server.
-
-## PHP requirements
-
-To install all necessary libraries, run these commands in a terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Fixing the issue “API Error: EspoCRM API is unavailable”:
-
-Take only necessary steps. After each step check if the issue is solved.
-
-### 1. Enable rewrite rules in Nginx server
-
-Add this code to your Nginx server block config file (/etc/nginx/sites-available/YOUR_SITE) inside “server” block:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-If you don’t have this file, you have to create it. For this open a terminal and run the command:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-And add the code listed above. For more information on how to configure a new Virtual Host on Nginx, please read this [ guideline](nginx-virtual-host.md).
-
-Run this command in a terminal to check if everything is fine:
-
-```
-sudo nginx -t
-```
-
-If so, run the command to restart nginx server:
-
-```
-sudo service nginx restart
-```
-
-### 2. Add RewriteBase path
-
-Open a file /ESPOCRM_DIRECTORY/api/v1/.htaccess and replace the following line:
-
-```
-# RewriteBase /
-```
-with
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-where REQUEST_URI is a part of URL, e.g. for “http://example.com/espocrm/”, REQUEST_URI is “espocrm”.
diff --git a/i18n/pl_PL/administration/nginx-virtual-host.md b/i18n/pl_PL/administration/nginx-virtual-host.md
deleted file mode 100644
index db1b766d6..000000000
--- a/i18n/pl_PL/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Configuring a Virtual Host on Nginx for EspoCRM
-
-In this guide we will show how to configure a virtual host on Nginx for EspoCRM on Ubuntu server.
-
-## Create a server block file
-
-To create this file, open a terminal and run the command:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Now, open this file (/etc/nginx/sites-available/espocrm.conf) and modify the code following the format printed below (some settings may be different based on your configuration):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Enable this server block
-
-Create a symbolic link:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Run this command to check if everything is fine:
-
-```
-sudo nginx -t
-```
-
-And restart Nginx server:
-
-```
-sudo service nginx restart
-```
-
-## Configure your local hosts (optional, for a local domain only)
-
-If you added a local domain, you have to configure it on your local computer (not on the server). For Ubuntu, open the file `/etc/hosts` and add the line:
-
-```
-192.168.1.1 espocrm.local # specify the IP address of your Nginx server
-```
-
-For Windows, please follow these [instructions](http://support.microsoft.com/kb/923947).
diff --git a/i18n/pl_PL/administration/portal.md b/i18n/pl_PL/administration/portal.md
deleted file mode 100644
index 412f80d6b..000000000
--- a/i18n/pl_PL/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Portal
-
-Portal provides an ability to access specific crm data and functions for your customers and partners. Administrator can create multiple portals. Each portal can have its own settings, dashlboard, user list, access control settings.
-
-To create portal follow Administration > Portals, click Create Portal button.
-
-* `Is Active`. If not check portal won't be available for anybody.
-* `Is Default`. Means that portal will be available by shorter url: http(s)://YOUR_ESPO_URL/portal.
-* `Roles`. Specify one or multiple portal roles that will be applied to users logged into portal. More information about portal roles is below.
-* `Tab List`. Tabs which will be shown in navigation bar.
-* `Dashboard Layout`. Specify dashlets that will be displayed on the home page of the portal. Note that portal users can't configure their dashboard.
-* `URL`. Read only field that displays the link you can access the portal with.
-
-## Portal Users
-
-Administrators can create portal users.
-
-1. Administration > Users.
-2. Click right dropdown next to Create User.
-3. Click Create Portal User.
-4. Select Contact the portal user will be linked with.
-5. Fill the form and click save.
-
-Portal user should be linked to Portal record to be able to access that portal.
-
-## Portal Roles
-
-Portal roles are similar to regular roles in EspoCRM but with a few distinctions.
-
-* `not-set` level denies an access.
-* `own` level means that the record is created by the user. E.g. portal user cased some case and this case is owned by this user.
-* `account` level means that the record is related to the account the portal user is related to.
-* `contact` level means that the record is related to the contact the portal user is related to.
-
-Assigned User and Teams fields are read only for portal users.
-
-### Example
-
-`Portal users should be able to create cases, view cases related to their account; they should be able to view knowledge base.`
-
-1. Open Create Portal Role form (Administration > Portal Roles > Create Role).
-2. Enable access to Cases, set: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. Enable access to Knowledge Base, set `create - no, read - account, edit - no, delete - no`.
-4. Edit your portal record (Administration > Portals). Select your portal role in Roles field and then save.
-
-## Access to Portal
-
-You can find the url for your portal in 'URL' field of the portal record. Also it's possible to use server configuration tools (such mod_rewrite) to be able to access by different url. For this case you need to fill in 'Custom URL' field.
-
-### Access portal by Custom URL for Apache server
-
-Custom URL: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Mod rewrite rules
-
-Specify portal record ID instead of `{PORTAL_ID}`. Portal record ID can is avaialble in address bar of your web browser when you open detail view of the portal record. Like: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 is a portal record id.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/pl_PL/administration/roles-management.md b/i18n/pl_PL/administration/roles-management.md
deleted file mode 100644
index 00c7e36bc..000000000
--- a/i18n/pl_PL/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Roles Management
-
-## Overview
-
-In order to restrict access for some users you need to use Roles. Administrator can manage roles in Administration panel. Each role defines an access to certain areas (scopes) which is applied to users who own that role.
-
-One user can have multiple roles. Those roles can be selected for a specific user (‘Roles’ field in User entry) and/or be inherited from the teams that user belongs to.
-
-If a user has multiple roles then they will be merged so that permissive rule will have a higher priority. That allows administrator to manage access level control easily and flexibly.
-
-It's possible to see what permissions is applied to a certain user by clicking 'Access' button on the user's detail view.
-
-
-
-## Example
-
-For example, user belongs to team ‘Sales’. That team has single role ‘Salesman’. So all users from this team will obtain ‘Salesman’ role.
-
-‘Salesman’ role is defined the following way:
-
-Lead:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Users will be able to read only those leads and opportunities which belong to ‘Sales Department’ team (‘Teams’ field).
-User will be able to edit only those leads and opportunities which they are assigned to or those they have created.
-Users won’t be able to remove any leads or opportunities.
-
-We want to give more rights to a certain user who holds sales manager position in the company. This employee must have an ability to read/edit/delete all records from ‘Sales’ team. The user should belong to our ‘Sales’ team. But we need to create the new role ‘Sales Manager’ and select this role for that user in ‘Roles’ field.
-
-‘Sales Manager’ role is defined the following way:
-
-Lead:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Our user will be able to manager all leads and opportunities from the ‘Sales’ team.
-
-## Special Permissions
-
-### Assignment Permission
-
-Set this parameter to restrict ability to re-assign records to another user and/or teams. If you set `team` - then it will be possible to assign only to users from own team(s). If `no` - users won't be able to re-assign at all.
-
-It also defines whether user is able to post to stream of another users/teams.
-
-### User Permission
-
-Allows to restrict an ability for users to view activities, calendar and stream of other users.
-
-### Portal Permission
-
-Defines an access to portal information, ability to post messages to portal users.
-
-### Group Email Account Permission
-
-Defines an access to group email accounts, an ability to send emails from group SMTP.
-
-### Export Permission
-
-Defenies whether user have an ability to export records. (since version 4.9.0)
-
-## Permissions by Default
-
-By default (if there are no any applied) users can read and edit all records. But can't delete any ones except those they have created and they are assigned to at the same time.
-
-There is an ability to restrict an access applied by default by enabling 'ACL Strict Mode' at Administration > Settings.
-
-## Field Level Security
-
-Allows to control an access for a specific fields.
-
-By default user can read all fields if one can read the record. User can edit any field if one can edit the record. You can restrict access to specific fields using Field Level Security.
-
-In edit view of a role record in Field Level section click plus icon next to the specific scope then select needed field. Then you will be able to specify the access level for `read` and `edit` actions. There are to options: `yes` and `no`.
-
-
diff --git a/i18n/pl_PL/administration/server-configuration.md b/i18n/pl_PL/administration/server-configuration.md
deleted file mode 100644
index 69825bd03..000000000
--- a/i18n/pl_PL/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Konfiguracja serwera dla EspoCRM
-
-EspoCRM może być zainstalowany na serwerze Apache ([instrukcje](apache-server-configuration.md)), Nginx ([instrukcje](nginx-server-configuration.md)), lub IIS ze wsparciem dla PHP 5.6 lub wyżej oraz MySQL wersja 5.1 lub wyżej.
-
-## Zalecana Konfiguracja
-
-### Wymagania PHP
-
-EspoCRM wymaga PHP 5.6 lub wyżej, z następującymi aktywnymi rozszerzeniami:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – do dostępu do bazy danych MySQL w PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – zasoby korzystają z tego formatu (metadane, szablon, języki, i inne);
-* [GD](http://php.net/manual/en/book.image.php) – do zarządzania obrazkami;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – aby zapewnić najlepszą ochronę;
-* [Zip](http://php.net/manual/en/book.zip.php) – aby można było zaktualizować EspoCRM i zainstalować rozszerzenia;
-* [IMAP](http://php.net/manual/en/book.imap.php) – aby monitorować skrzynkę pocztową w EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Zalecane jest również posiadanie [mailparse](https://pecl.php.net/package/mailparse) zainstalowanego rozszerzenia pecl. Jest wymagane dla sprawnego pobierania wiadomość email.
-
-php.ini settings:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Wymagania MySQL
-
-EspoCRM wspiera MySQL w wersji 5.1 lub wyższej.
-Nie ma specjalnych wymagań. Wszystkie domyśle ustawienia są odpowiednie.
-
-## Required Permissions for Unix-based Systems
-
-Pliki i katalogi powinny posiadać następujące zezwolenia:
-
-* `/data`, `/custom`, `/client/custom` – should be writable all files, directories and subdirectories (664 for files, 775 for directories, including all subdirectories and files);
-* `/application/Espo/Modules`, `/client/modules` – should be writable the current directory (775 for the current directory, 644 for files, 755 for directories and subdirectories);
-* Wszystkie pozostałe pliki i katalogi powinny być tylko do odczytu (644 dla plików, 755 dla katalogów).
-
-To set the permissions, execute these commands in the terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Wszystkie pliki powinny należeć do grupy procesu serwera sieciowego. Może to być “www-data”, “daemon”, “apache”, “www”, itd.
-Note: On Bitnami Stack, files should be owned and group-owned by “daemon” user.
-Note: On shared hosts, files should be owned and group-owned by your user account.
-
-Aby ustawić właściciela o grupę właścicieli, uruchom w terminalu tę komendę :
-
-```
-cd
-chown -R : .;
-```
-
-## Setup a crontab
-
-To setup a crontab on a UNIX system, take the following steps:
-
-* 1. Login as administrator into your EspoCRM instance.
-* 2. Go to the Scheduled Jobs section in the administrator panel (Menu > Administration > Scheduled Jobs) and copy the string for the crontab. It looks like this one:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Open a terminal and run this command:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER can be one of the following “www”, “www-data”, “apache”, etc (depends on your webserver).
-* 4. Paste the copied string (from step 2) and save the crontab file (Ctrl+O, then Ctrl+X for nano editor).
-
-## Configuration instructions based on your server:
-
-* [Apache server configuration](apache-server-configuration.md).
-* [Nginx server configuration](nginx-server-configuration.md).
diff --git a/i18n/pl_PL/administration/troubleshooting.md b/i18n/pl_PL/administration/troubleshooting.md
deleted file mode 100644
index 8eef503e8..000000000
--- a/i18n/pl_PL/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Rozwiązywanie problemów
-
-## Sprawdzanie logów
-
-Aby odnaleźć problem, musisz sprawdzić plik z logami błędów.
-
-#### Logi błędów EspoCRM
-
-Logi błędów EspoCRM znajdują się w `/logs/*.log` i zawierają pewne informację o błędach.
-
-#### Logi błędów serwera Apache
-
-Logi błędów dla Ubuntu oraz serwera Apache znajdują się w `/var/log/apache2/error.log` i zawierają pewne informację o błędach. Lokalizacja logów może się różnić na innych systemach.
-
-## Włączenie tryby debugowania
-
-Aby włączyć tryb debugowania, idź do katalogu z zainstalowanym EspoCRM, otwórz plik `data/config.php` i zmień wartość:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-na
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Planowane Zadania nie działają
-
-#### Problem #1: Twój crontab nie jest skonfigurowany
-
-1. Zaloguj się przez SSH na swój serwer.
-
-2. Skonfiguruj swój crontab podążając za tą instrukcją: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-Uwaga: Crontab powinien być konfigurowany przez użytkownika web-servera, np. `crontab -e -u www-data`.
-
-3. Poczekaj chwilę i sprawdź czy jakieś zaplanowane zadania zostały wykonane (zobacz w panelu logowania zdarzeń).
-
-#### Problem #2. Crontab jest skonfigurowany, ale Planowane Zadanie nie działają
-
-Aby mieć pewność, że nie występują żadne błędy podczas działania crona, spróbuj uruchomić komendy crona z wiersza poleceń:
-
-1. Zaloguj się przez SSH na swój serwer.
-
-2. Idźdo katalogu gdzie zainstalowany jest EspoCRM. Np. dla katalogu `/var/www/html/espocrm` komenda wygląda następująco:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Uruchom komendę crontab:
-
-```bash
-php cron.php
-```
-
-Uwaga: Komenda powinna być wywoływana jako użytkownik web-server. Jeśli jesteś zalogowany jako root, komenda powinna wyglądać (np. dla Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-gdzie `www-data` jest użytkownikiem.
-
-4. Jeśli nie występują tam błędy, sprawdź Planowane Zadania aby zobaczyć czy żadne zadanie się nie wywołało (zobacz w panelu logowania zdarzeń).
-
-## EspoCRM nie ładuje się po aktualizacji
-
-Czasami się to zdaża przy współdzielonych hostingach.
-
-Sprawdź uprawnienia dla pliku:
-/index.php
-/api/v1/index.php
-
-Muszą wynosić 644. Jeśli któryś z plików ma zezwolenie 664 musisz je zamienić na 644. Użyj do tego swojego panelu hostingowego lub komendy chmod.
-
-```
-chmod 644 /path/to/file
-```
-Więcej informacji o zezwoleniach dla plików: [tutaj](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/pl_PL/administration/upgrading.md b/i18n/pl_PL/administration/upgrading.md
deleted file mode 100644
index ac7ebcf93..000000000
--- a/i18n/pl_PL/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Jak zaktualizować EspoCRM
-
-EspoCRM można zaktualizować do najnowszej wersji w następujący sposób:
-
-### Krok 1. Sprawdź swoją aktualną wersję
-
-Aby sprawdzić aktualną wersję idź do Administracja > Aktualizacje.
-
-### Krok 2. Pobierz wymaganą aktualizację
-
-Idź do strony aktualizacyjnej https://www.espocrm.com/download/upgrades/ i bazując na twojej aktualnej wersji pobierz wymagane paczki.
-
-### Krok 3. Stwórz kopię zastępczą (opcjonalne)
-
-Zanim zaktualizujesz EspoCRM stwórz kopię zapasową swoich plików oraz danych. Podążaj [za tą instrukcją](https://github.com/espocrm/documentation/blob/master/i18n/pl_PL/administration/backup-and-restore.md) aby to wykonać.
-
-### Krok 4. Aktualizacja
-
-Idź do Administracja > Aktualizuj. Wysyłaj i instaluj wszystkie pobrane paczki jedna po drugiej.
-
-Możesz sprawdzić, czy masz najnowszą wersję w Menu> O mnie.
-
-## Aktualizacja przez CLI
-
-Możesz również uruchomić aktualizację za pomocą interfejsu wiersza poleceń. Musisz wykonać następujące polecenie z katalogu głównego EspoCRM:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/pl_PL/administration/workflows.md b/i18n/pl_PL/administration/workflows.md
deleted file mode 100644
index e35c1f779..000000000
--- a/i18n/pl_PL/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Workflows
-
-Workflows feature is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Workflows automate your business process an easy way. You can find it in the Administration panel. To create a workflow rule you need to define:
-
-* Target Entity - what entity type workflow is applied to;
-* Trigger Type - when workflow will be triggered;
-* Conditions - conditions need to be met to trigger workflow;
-* Actions - what to do if workflow is triggered.
-
-
-## Trigger Types
-
-### After record created
-
-Triggered only when a new record is created. If specified conditions are met then actions will be executed.
-
-### After record saved
-
-Triggered when a new record is created or an existing record is updated. If specified conditions are met then actions will be executed.
-
-For workflow rules with this type of trigger it's a common practice to have a condition that checks whether some field was 'changed'. E.g. If Case's status is changed then execute some actions.
-
-### Scheduled
-
-Triggered according to the defined scheduling. You can setup it to run every day, every week, etc. Actions will be applied for records returned by a specified list report. So you need also to create a list report.
-
-Scheduling is specified in a crontab notation.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### Sequential
-
-Used rarely. Supposed to be run by another workflow. Provides an ability to make a complex logic.
-
-Note: For sequential workflows it's recommended to utilize [BPM tool](bpm.md) rather than a Workflows feature.
-
-## Conditions
-
-You can specify conditions that must be met to trigger the workflow. There are two ways how conditions can be specified: with the UI condition builder and with formula.
-
-### UI condition builder
-
-Some available condition types:
-
-* _equals_ - the field equals to a specific value or a value of another field;
-* _was equal_ - the field was equal to a specific value before the workflow was triggered;
-* _not equals_ - the field does not equal to a specific value or a value of another field;
-* _was not equal_ - the field was not equal to specific value before the workflow was triggered;
-* _empty_ - the field value is empty;
-* _not empty_ - the field value is not empty;
-* _changed_ - the field was changed;
-* _not changed_ - the field was not changed.
-
-### Formula conditions
-
-Formula provides an ability to define conditions of any complexity. To read about formula syntax follow [this article](formula.md).
-
-Note: There should not be any `;` delimiter used in formula code when it determines a condition.
-
-## Actions
-
-### Send Email
-
-System will send an email using a specified email template. A recipient’s email address can be taken from the target record, any related record, the current user, followers, team users or specified. Email can be sent immediately or delayed for a specific interval.
-
-### Create Record
-
-System will create the new record of any entity type. If there is a relationship between the target record and creating record it's possible to relate records.
-
-There is an ability to define formula to calculate fields.
-
-### Create Related Record
-
-System will create the record related to the target record. It's possible to define formula to calculate fields.
-
-### Update Target Record
-
-Allows changing of specific fields of the target record. It's possible to define formula to calculate fields.
-
-If you need to add new items to the Link-Multiple field w/o loosing existing data (e.g. Teams) you need to utilize formula function entity\addLinkMultipleId. Example: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### Update Related Record
-
-Allows changing of specific fields of the related record or records. It's possible to define formula to calculate fields.
-
-### Link with Another Record
-
-Relates the target entity with another specific entity. E.g. adds specific team to the record.
-
-### Unlink with Another Record
-
-Unrelates the target entity from another specific entity. E.g. removes a specific team from the record.
-
-### Apply Assignment Rule
-
-Assign the target record to user by distribution rule. There are two available rules: Round-Robin and Least-Busy.
-
-* Round-Robin - users are choosen from the top to the bottom of a list (team) and then starting again.
-* Least-Busy - user who has fewer assigned records will be chosen for assignment.
-
-_List Report_ - For Least-Busy distribution determines what records will be taken into account to calculate the number of assigned records. E.g. for Cases we need to take only records with active status.
-
-### Create Notification
-
-Notify specific users with the message. It's possible to use placeholders in message template: {entity} - target record, {user} - current user.
-
-### Make Followed
-
-Forces specific users to follow the target entity or a specificied related entity.
-
-### Trigger Another Workflow
-
-Allows to make sequential workflows. It's possible to branch workflow by condition: you can setup the workflow to trigger two workflows with different conditions defined in that workflows.
-
-It's possible to delay executing of sequential workflow. In the sequential wokflow you can define the condition that checks whether specifiec fields were changed since the parent workflow were triggered by using _Changed_ and _Was Equal_ condition types.
-
-Note: For sequential workflows it's recommended to utilize [BPM tool](bpm.md) rather than a Workflows feature.
-
-### Run Service Action
-
-Allows to run specific service scripts. By default there are following actions available:
-
-* Send Invitations - for Meetings/Calls;
-* Add Quote Items - for Quotes.
-
-Developers can write their own service actions. See [more detail](../development/workflow-service-actions.md).
-
-## Using Formula in Actions
-
-It's possible to define formula to calculate fields for Create Record, Update Target Record, Create Related Record, Update Related Record. For the last two, to access attributes of target entity you should use function `targetEntity\attribute`. To access attributes of target entity that was set before workflow was triggered use function `targetEntity\attributeFetched`.
-
-Example:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/pl_PL/development/api.md b/i18n/pl_PL/development/api.md
deleted file mode 100644
index 7e08fe671..000000000
--- a/i18n/pl_PL/development/api.md
+++ /dev/null
@@ -1,223 +0,0 @@
-# REST API
-
-EspoCRM jest aplikacją typu SPA - Single Page Application, Część klienta komunikuje sięz częścią serwerową za pomocą REST API.
-Wszystkie operacje, które wykonujesz korzystając z UI możesz zaimplementować poprzez odwoływanie się za pomocą swojego języka programowania do API.
-Możesz nauczyć się jak działa API, jeśli będziesz śledził co się dzieje w zakładce Sieć w konsoli swojej przeglądarki internetowej.
-
-Większość funkcji API zwraca JSON. POST, PATCH wywołania zazwyczaj wymagają danych w formacie JSON w ładunku zapytania.
-
-Bazowym adresem URL EspoCRM API jest: `api/v1/`. Musisz przełożyć to przed wyrażeniem w odwołaniu. Przykład:
-
-`GET http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Autentykacja
-
-EspoCRM API uses [Basic Authentication](http://en.wikipedia.org/wiki/Basic_access_authentication). Username and password/token are passed through `Authorization` header encoded in base64.
-
-`"Authorization: Basic " + base64Encode(username + ':' + password)`
-
-
-Kiedy pracuje się z API, dużo lepiej jest wykorzystać tokeny zamiast haseł do autoryzacji. W tym przypadku, musisz dostarczyć nazwe użytkownika oraz hasło/token w nagłówku `Espo-Authorization`.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-
-1. Uzyskaj token dostępu przez `GET App/user` żadanie z nazwą użytkownika oraz hasłem przekazne w nagłówku `Espo-Authorization`.
-2. Wykorzystaj ten token zamiast hasła w nagłówku `Espo-Authorization` w każdych kolejnych żądaniach.
-3. Jeśli żądanie zwróci błąd 403, oznacza to, że nazwa użytkownika/hasło jest błędne lub token nie jest już ważny.
-
-#### Authentication Token / User Specific Data
-
-`GET App/user`
-
-Zwracane dane:
-
-* `token` - token dostępu;
-* `acl` - informacje o dostępie użytkownika;
-* `preferences` - preferencje użytkownika;
-* `user` - user record attributes.
-
-
-## Operacje CRUD
-
-#### Elementy Listy
-
-`GET {entityType}`
-
-Parametry żądania GET:
-
-* `offset` - (liczba całkowita) offset;
-* `maxSize` - (liczba całkowita) maksymalny rozmiar;
-* `where` - (tablica) filtry;
-* `sortBy` - (ciąg znaków) field to sort by;
-* `asc` - (wartość binarna) kierunek sortowania.
-
-_Example_
-
-`GET Account?offset=0&maxSize=20`
-
-Zwracane wartości:
-```
-{
- "list": [... tablica rekordów...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Read Entity
-
-`GET {entityType}/{id}`
-
-Zwraca atrybuty jako obiekt JSON.
-
-_Example_
-
-`GET Account/5564764442a6d024c`
-
-#### Stwórz Obiekt
-
-`POST {entityType}`
-
-Payload: Object of entity attributes.
-
-Zwraca entity attributes in JSON object.
-
-_Example_
-
-`POST Account`
-
-Payload:
-```
-{
- "name": "Test",
- "assignedUserId": "1"
-}
-```
-
-#### Aktualizuj Obiekt
-
-`PATCH {entityType}/{id}`
-
-lub
-
-`PUT {entityType}/{id}`
-
-Payload: Object of entity attributes needed to be changed.
-
-Zwraca atrybuty jako obiekt JSON.
-
-_Example_
-
-`PATCH Account/5564764442a6d024c`
-
-Payload:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Usuń obiekt
-
-`DELETE {entityType}/{id}`
-
-_Example_
-
-`DELETE Account/5564764442a6d024c`
-
-
-## Related Entities
-
-#### List Related Entities
-
-`GET {entityType}/{id}/{link}`
-
-* `offset` - (int) offset;
-* `maxSize` - (int) max size;
-* `where` - (array) filters;
-* `sortBy` - (string) field to sort by;
-* `asc` - (bool) sort direction.
-
-_Example_
-
-`GET Account/5564764442a6d024c/opportunities`
-
-Returns:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Link Entity
-
-`POST {entityType}/{id}/{link}`
-
-Payload:
-
-1. `id` attribute.
-2. `ids` array attribute.
-3. `"massRelate": true` and `"where": {...}` to relate multiple records by search criterias.
-
-_Example_
-
-`POST Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Unlink Entity
-
-`DELETE {entityType}/{id}/{link}`
-
-Payload:
-
-1. JSON with `id` attribute.
-2. JSON with `ids` array attribute.
-
-_Example_
-
-`DELETE Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-## Stream
-
-#### List stream entries for the current user
-
-`GET Stream`
-
-Get parameters:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) max size;
-
-#### List stream entries related to a specific record
-
-`GET {entityType}/{id}/stream`
-
-Get parameters:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) max size;
-
-#### Follow record
-
-`PUT {entityType}/{id}/subscription`
-
-#### Unfollow record
-
-`DELETE {entityType}/{id}/subscription`
-
-
-
diff --git a/i18n/pl_PL/development/custom-field-type.md b/i18n/pl_PL/development/custom-field-type.md
deleted file mode 100644
index ff4c02612..000000000
--- a/i18n/pl_PL/development/custom-field-type.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Creating Custom Field Type
-
-### Field Definition
-
-Create a file `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` with needed parameters.
-```
-{
- "view": "custom:views/fields/{field-type}"`
-}
-```
-
-Use out-of-the-box field types as examples: `/application/Espo/Resources/metadata/fields`.
-
-### Translation
-
-The label is used in Entity Manager can be set in `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` in section `fieldTypes`.
-If you need to add translation to other language, use needed language [language code](https://en.wikipedia.org/wiki/ISO_639-1)_[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) instead of `en_US`. In `data/config.php` in section `languageList` you can find the list of included languages.
-
-### View
-
-Create the view for the field `client/custom/src/views/fields/{field-type}.js` and define its templates
-```
-Espo.define('custom:views/fields/[field-type]', 'views/fields/base', function (Dep) {
-
- return Dep.extend({
-
- });
-});
-```
-
-Use out-of-the-box field types as examples:
-- `/client/src/views/fields` - views;
-- `/client/res/templates/fields` - templates.
-
-Then you need to run rebuild at the administration panel.
diff --git a/i18n/pl_PL/development/custom-views.md b/i18n/pl_PL/development/custom-views.md
deleted file mode 100644
index d938479b1..000000000
--- a/i18n/pl_PL/development/custom-views.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Spersonalizowane widoki
-
-## Widoki rekordów
-
-Framework EspoCRM dostarcza elastyczne możliwości definiowania spersonalizowanych widoków dla konkrentych rekordów. Muszą być zdefioniowane w kategorii matadanych `clientDefs`.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-Rekord/Szczegółowy widok zawiera wszystkie panele z polami, relacjami i innymi danymi, które możesz zobaczyćw widoku szczegółowym. Nie zawiera nagłówka i przycisków w górnym prawym narożniku.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Tu jest Twój spersonalizowany szablon. Omiń to jeśli go nie potrzebujesz.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Tu jest Twój spersonalizowany widok. Omiń to jeśli go nie potrzebujesz.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Tu jest Twój spersonalizowany widok. Omiń to jeśli go nie potrzebujesz.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Tu jest Twój spersonalizowany widok. Omiń to jeśli go nie potrzebujesz.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Custom initalization logic here. Like binding listening to model changes.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Custom code to be invoked right after rendering, when DOM is avaiable.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-Spersonalizowany szablon możesz stworzyć pod tym linkiem:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-Widok szczegółowy zawiera widok rekordu/szczegółów i nagłówek.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-Tak samo jak w szczegółach ale jest wykorzystywane kiedy rekord został stworzony lub zedytowany nie w trybie edycji bezpośredniej.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-Widok list zawiera widok Rekordu/Listy, Nagłówek oraz widok Formularza Wyszukującego.
-
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-Widok Listy/Rekordu zawiera wiersze z rekordami.
-
-
-Warto wspomnieć, że musisz dziedziczyć klasę widoku z klasy konkretnego podmiotu, jeśli już istnieje.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Widoki Pól
-
-Sperfonalizowane widoki pól powinny być zdefiniowane w sekcji matadanych entityDefs.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
-
diff --git a/i18n/pl_PL/development/dynamic-forms.md b/i18n/pl_PL/development/dynamic-forms.md
deleted file mode 100644
index 1b5c75f54..000000000
--- a/i18n/pl_PL/development/dynamic-forms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Dynamiczne Formularze
-
-Uwaga: Od wersji 4.3.0 możliwe jest tworzenie dynamicznych formularzy poprzez UI administratora w Menadżerze Jednostek.
-
-W EspoCRM istnieje możliwość definiowania zachowania formularza.
-
-## Przykład
-
-> Pokaż pole _nextStep_ w szczegółowym widoku Okazji, jeśli etap jest 'Closed Won'.
->
-
-Stwórz plik `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Oznacza to, że pole _nextStep_ domyślnie zostanie schowane i pokażę się, gdy etap będzie równy 'Closed Won'.
-
-Lista dostępnych akcji: `show`, `hide`, `setRequired`, `setNotRequired`.
-
-Istnieje również możliwość ukrycia/pokazania paneli. Określi nazwę paneli w `panels`, atrybuty w ten sam sposób jak `fields`.
diff --git a/i18n/pl_PL/development/extension-packages.md b/i18n/pl_PL/development/extension-packages.md
deleted file mode 100644
index 15d9699b7..000000000
--- a/i18n/pl_PL/development/extension-packages.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Extension Packages
-
-Extensions allow you to add extra functionality to EspoCRM. They can be installed by Administrator panel under `Customization` section.
-
-## How to create extension package
-
-A File structure of package:
-
-* `/manifest.json` – a file that contains extension properties;
-* `/files` – a directory that contains the extension files;
-* `/scripts` – contains the extension scripts.
-
-### Manifest
-```json
-{
- "name": "Extension Name",
- "version": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "author": "Your Name",
- "description": "Description of your extension",
- "delete": []
-}
-```
-
-* Syntax of `version` and `acceptableVersions` is described by the v2.0.0 specification found at http://semver.org.
-* `delete` - is the list of core files that need to be deleted. This parameter is not recommended to use. You can omit it.
-
-### Files
-
-All extension files should be placed in `files` directory. They will be copied to EspoCRM core directory.
-
-### Scripts
-
-For different purposes EspoCRM supports the following types of scripts. All of them should be placed in `scripts` directory.
-
-* `BeforeInstall.php` – a script executed before an installation process;
-* `AfterInstall.php` – executed once the installation process is finished;
-* `BeforeUninstall.php` – executed before uninstallation process;
-* `AfterUninstall.php` – executed once the uninstallation process is finished.
-
-Example:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Package
-
-At the end, we need to pack all these files into a .zip archive.
diff --git a/i18n/pl_PL/development/hooks.md b/i18n/pl_PL/development/hooks.md
deleted file mode 100644
index 118d659e8..000000000
--- a/i18n/pl_PL/development/hooks.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Hooks
-
-## Create a Hook
-To create a hook, you need to:
-- create a file `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- declare hook type action;
-- clear Cache in Administration.
-
-## Hook Types
-
-The main hook types are:
-
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove;
-- afterRelate;
-- afterUnrelate;
-- afterMassRelate.
-
-### New Hook Type
-You can use your own hook type and trigger it with
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Hook Order
-If you have several hooks, related to one Entity Type and with the same hook type, and running order is important, you can set a `public static $order` property in an integer value.
-
-Ascending order - the hook with the smallest order number runs first.
-
-## Example
-This example sets Account Name for new Leads, if it is not set.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-use Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Global Hooks
-If you need to apply a hook for all entities, you can use common hooks. To do this, put your hook class in Common directory, e.g. `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/pl_PL/development/how-to-create-a-dashlet.md b/i18n/pl_PL/development/how-to-create-a-dashlet.md
deleted file mode 100644
index 7c99f1082..000000000
--- a/i18n/pl_PL/development/how-to-create-a-dashlet.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# How to create a dashlet
-
-Create a file `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` with your dashlet configuration.
-
-Here you need to define `"view"`, and you could set `"aclScope"`, `"entityType"`, and `"options"`.
-
-If it's typical list dashlet, use `"view":"views/dashlets/abstract/record-list"`, if not, create own view (https://github.com/espocrm/documentation/blob/master/development/custom-views.md).
-
-## Options
-By default in dashlet options you can set _Title_ and _Auto-refresh Interval_.
-
-Additional option fields you can set in `"options"` > `"fields"`.
-
-To define fields position set the layout in in `"options"` > `"layout"` > `"rows"`
-
-Also you can define other options, if your view needs more data.
-
-## Example
-
-`application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json`
-
-```
-{
- "view":"views/dashlets/abstract/record-list",
- "aclScope": "Case",
- "entityType": "Case",
- "options": {
- "fields": {
- "title": {
- "type": "varchar",
- "required": true
- },
- "autorefreshInterval": {
- "type": "enumFloat",
- "options": [0, 0.5, 1, 2, 5, 10]
- },
- "displayRecords": {
- "type": "enumInt",
- "options": [3,4,5,10,15]
- },
- "expandedLayout": {
- "type": "base",
- "view": "views/dashlets/fields/records/expanded-layout"
- }
- },
- "defaults": {
- "sortBy": "createdAt",
- "asc": false,
- "displayRecords": 5,
- "expandedLayout": {
- "rows": [
- [
- {
- "name": "number"
- },
- {
- "name": "name",
- "link": true
- },
- {
- "name": "type"
- }
- ],
- [
- {
- "name": "status"
- },
- {
- "name": "priority"
- }
- ]
- ]
- },
- "searchData": {
- "bool": {
- "onlyMy": true
- },
- "primary": "open"
- }
- },
- "layout": [
- {
- "rows": [
- [
- {"name": "title"}
- ],
- [
- {"name": "displayRecords"},
- {"name": "autorefreshInterval"}
- ],
- [
- {"name": "expandedLayout"},
- false
- ]
- ]
- }
- ]
- }
-}
-```
-There you can see some examples `application/Espo/Modules/Crm/Resources/metadata/dashlets`.
-
-## Translation
-
-Translation to dashlet is in `Global` scope, in `"dashlets"` section.
-
-__After all don't forget to Clear Cache in Administration.__
diff --git a/i18n/pl_PL/development/link-multiple-with-primary.md b/i18n/pl_PL/development/link-multiple-with-primary.md
deleted file mode 100644
index 0a4b5b0c4..000000000
--- a/i18n/pl_PL/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Link Multiple field with Primary
-
-~For EspoCRM 3.6.0 and greater.~
-
-Sometimes you have `hasMany` relationship and need to have an ability to select primary record among related ones. As example, `Contacts` field of Case entity.
-
->Need to create `contacts` linkMultiple field with a primary for our custom entity `Stock`.
->
-
-###Step 1
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-###Step 2
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-###Step 3
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-###Step 4
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-###Step 5
-Run Rebuild
-
-###Step 6
-Execute SQL query
-```sql
-UPDATE stock
-JOIN contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
-
diff --git a/i18n/pl_PL/development/metadata.md b/i18n/pl_PL/development/metadata.md
deleted file mode 100644
index 3ef626960..000000000
--- a/i18n/pl_PL/development/metadata.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Metadata
-
-Metadata is intended for: storing system data such as entity's fields and relationships; specifying frontend controllers, views, panels; defining fields, dashlets; and other data needed for the application.
-
-
-## How to access
-
-#### Backend
-
-Metadata object of `Espo\Core\Utils\Metadata` class can be access from Container. Path to a needed parameter is specified using dots `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-will return `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-will return an associative array of all fields.
-
-#### Frontend
-
-Metadata object is accessible from all view objects by method `#getMetadata`. It works the same way as backend's one.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## How is it stored
-
-Metadata is stored in JSON files that can be located in different places:
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-When you access data by path `clientDefs.Account.views.edit` the first lexeme `clientDefs` corresponds to dir name, the second `Account` to file name `Account.json`. All following lexemes correspond to path in the JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-All JSON files from these directories get merged recursively into a single php array and stored in a cache file.
-
-
-## Extending
-
-Since metadata is merged recursively you can easily redefine json objects and arrays in _custom_ and in your _module_. Also you can append to existing arrays by using `__APPEND__` (since version 2.6.0) as the first element of array.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/pl_PL/development/new-function-in-formula.md b/i18n/pl_PL/development/new-function-in-formula.md
deleted file mode 100644
index 683a84693..000000000
--- a/i18n/pl_PL/development/new-function-in-formula.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Defining new funtions for Formula
-
-EspoCRM provides the possibility to create custom functions that can be used in formula.
-
-If your function is related to the one of groups like String, Logic, Date, create a file in __{GroupName}Group__ folder, named __{FunctionName}Type.php__ with __{FunctionName}Type__ class declaration. You need to define the method __'process'__.
-
-For example, let's create a new string function for checking if a string (HAYSTACK) contains another string (NEEDLE) with a possible offset (OFFSET).
-
-Create a file `application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` with the code:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-use \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Adding the function to the list
-
-In order to add the created function to the function list of formula, create a file `custom/Espo/Custom/Resources/metadata/app/formula.json` and add the code:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Clear cache__ and use this function in formula. You can type it `string\contains(HAYSTACK, NEEDLE, OFFSET)` or select from function list, if you add it.
-
diff --git a/i18n/pl_PL/development/orm.md b/i18n/pl_PL/development/orm.md
deleted file mode 100644
index 94efd95ac..000000000
--- a/i18n/pl_PL/development/orm.md
+++ /dev/null
@@ -1,227 +0,0 @@
-# ORM, How to manage entities and perform queries
-
-EspoCRM has built-in own ORM (Object-relational mapping). It’s very simple to create, update, read, delete and search entities. All these operations available through EntityManager object. EntityManager is available in record Services by method `#getEntityManager()`.
-
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Create new entity
-```php
-$account = $entityManager->getEntity('Account')
-```
-or
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Fetch existing
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-or
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Get value
-```php
-$fieldValue = $account->get('fieldName');
-```
-
-#### Has value
-```php
-$fieldNameIsSet = $account->has('fieldName'); // true or false
-```
-
-#### Set value
-```php
-$account->set('fieldName', 'Test Account');
-```
-
-```php
-$account->set(array(
- 'name' => 'Test Account',
- 'assignedUserId' => '1'
-));
-```
-
-#### Store
-```php
-$entityManager->saveEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Remove
-```php
-$entityManager->removeEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Find
-```php
-$accountList = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer'
-])->find();
-```
-
-Descending order:
-
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', true)->find();
-```
-
-Ascending order:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt')->find();
-```
-
-or:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', 'DESC')->find();
-```
-
-#### Find the first one
-```php
-$account = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer',
-])->findOne();
-```
-
-#### Find related
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
-```
-
-#### Relate entities
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
-```
-
-#### Unrelate entities
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
-```
-
-### Select Query Paramaters
-
-#### Where clause
-
-##### Comparison operators
-
-Supported comparison operators: `>`, `<`, `>=`, `<=`, `=`, `!=`.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'amount>=' => 100
-])->find();
-```
-
-##### IN and NOT IN operators
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage' => ['Closed Lost', 'Closed Won']
- ])->find();
-```
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage!=' => ['Closed Lost', 'Closed Won']
-])->find();
-```
-
-##### LIKE operators
-
-Supported operators:
-* `*` - LIKE,
-* `!*` -- NOT LIKE.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'name*' => '%service%'
-])->find();
-```
-
-##### OR, AND operators
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- [
- 'OR' => [
- ['stage' => 'Closed Won'],
- ['stage' => 'Closed Lost']
- ],
- 'AND' => [
- 'amountConverted>' => 100,
- 'amountConverted<=' => 999
- ]
- ]
-])->findOne();
-```
-
-#### Distinct
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->distinct()->where(...)->find();
-```
-
-#### Join
-
-```
-$contactList = $entityManager->getRepository('Contact')->distinct()->join('opportunities')->where([
- 'opportunities.stage' => 'Closed Won'
-])->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()->leftJoin('opportunities')->where(...)->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()
-->join(['opportunities', 'aliasForJoinedTable'])
-->where([
- 'aliasForJoinedTable.stage' => 'Closed Won'
-])->find();
-```
-
-#### Group By
-
-```
-$selectParams = [
- 'select' => ['MONTH:closeDate', 'SUM:amountConverted']
- 'groupBy' => ['MONTH:closeDate'],
- 'whereClause' => [
- 'stage' => 'Closed Won'
- ],
- 'orderBy' => 1 // ordering by the first column
-];
-
-// applying left joins for currency convertion
-$this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams);
-
-$pdo = $this->getEntityManager()->getPDO();
-$sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams);
-$sth = $pdo->prepare($sql);
-$sth->execute();
-
-// results
-$rowList = $sth->fetchAll(\PDO::FETCH_ASSOC);
-```
diff --git a/i18n/pl_PL/development/scheduled-job.md b/i18n/pl_PL/development/scheduled-job.md
deleted file mode 100644
index 04123a825..000000000
--- a/i18n/pl_PL/development/scheduled-job.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Tworzenie Planowanych Prac
-
-Aby utworzyć niestandardową Zaplanowaną Prace stwórz plik `custom/Espo/Custom/Jobs/{JOB_NAME}.php` z zawartością.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //all the logic needs to be defined in the method run
- }
-}
-```
-
-Możesz również swtorzyć etykietę dla swojej pracy(`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-Aby zaimplementować zmiany, idź do panelu administratora i wyczyść Cache.
diff --git a/i18n/pl_PL/development/workflow-service-actions.md b/i18n/pl_PL/development/workflow-service-actions.md
deleted file mode 100644
index 2ce3216d2..000000000
--- a/i18n/pl_PL/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Adding custom service action for Workflow
-
-Workflows allow to create custom service actions. This example will show how this can be done for a Call entity.
-
-## Step 1. Create service class
-
-```php
- Clear Cache. Now the service action is available for Workflows in the Run Service Action form.
diff --git a/i18n/pl_PL/user-guide/browser-support.md b/i18n/pl_PL/user-guide/browser-support.md
deleted file mode 100644
index c37b0651f..000000000
--- a/i18n/pl_PL/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Wsparcie przeglądarek internetowych
-
-Zalecamy korzystanie z najnowszych wersji przeglądarek internetowych, taki jak: Google Chrome lub Mozilla Firefox. EspoCRM najlepiej współpracuje z tymi przeglądarkami. Regularnie testujemy wszystkie funkcjonalności na tych przeglądarkach.
-
-Microsoft Edge oraz Safari również są wspierane, ale jest mniejsza gwarancja, że wszystko będzie działało płynnie.
-
-Zdecydowanie nie zalecamy korzystania z przeglądarki Internet Explorer 11.
diff --git a/i18n/pl_PL/user-guide/emails.md b/i18n/pl_PL/user-guide/emails.md
deleted file mode 100644
index 3ed791afb..000000000
--- a/i18n/pl_PL/user-guide/emails.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Wytyczne korzystania z wiadomości email
-
-EspoCRM udostępnia możliwość pobierania wiadomości email z IMAP. Umożliwia to wykorzystanie EspoCRM jako klienta poczty wraz z funkcjami specyficznymi dla CRM.
-
-## Konta IMAP
-
-*Uwaga: Musisz mieć [cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) właściwie skonfigurowany w swoim systemie aby poprawnie działały przychodzące wiadomości e-mail.*
-
-Użytkownik może ustawić konto IMAP na stronie: Osobiste Konta Email (Zakładka Email > górne-prawe menu > Osobiste konta email).
-
-Określ jaki folder sprawdzać w polu Monitorowane Foldery. Domyślnie jest ustawiona skrzynka odbiorcza. Jeśli korzystasz z zewnętrznego klienta do wysyłania wiadomości email możesz dodać folder z wysłanymi wiadomościami aby zarchiwizować te emaile.
-
-*Pobierz od* umożliwia ustawienie daty od której wiadomości email będą archiwizowane. Ustaw jakąś wcześniejszą datę jeśli chcesz zarchiwizować stare wiadomości.
-
-Istnieje możliwość określenia *Folderu* w Osobistych Kontach Email. Przychodzące wiadomości będą umieszczane w tym katalogu.
-
-## Konta SMTP
-
-Użytkownicy mogą ustawić ustawienia SMTP w Preferencjach, tak samo jak w swoich Osobistych Kontach Email. Administrator również może zezwolić na używanie systemu SMTP (udostępnić go).
-
-Użytkownicy mogą mieć wiele kont SMTP (od wersji 4.2.9). Ale adresy z których użytkownik może wysyłać wiadomości email są definiowane przez adres email z rekordu *Użytkownika* .
-
-## Praca z wiadomościami Email
-
-Wiadomości Email są pobierane przez cron'a (w tle) co kilka minut (okres czasu jest ustawiany przez administratora).
-Wszystkie swoje wiadomości email możesz zobaczyć w zakładce Email. Są tam standardowe foldery: Skrzynka odbiorcza, Wysłane, Szkice wiadomości po lewej stronie.
-
-Polce *status*. `Wysłane` oznacza, że wiadomość została wysłana z CRM, `Zarchiwizowano` – pobrano z konta IMPA lub zarchiwizowano ręcznie, `Szkic` – oznacza, że wiadomość została stworzona jako szkic.
-
-Kiedy do systemu przyjdzie nowy email, system próbuje rozpoznać do której części należy ta wiadomość. Może połączyć go z Kontem, Kontaktem, Zdarzeniem, Sprawą (i Kontraktem w trybie B2C) itd. Jeśli nie został rozpoznany, użytkownik może połączyć go ręcznie przez wypełnienie pola *Rodzic*.
-
-Jeśli wiadomość przyszła od nowego potencjalnego klienta, użytkownik może **zmienić ją w Kontakt**. Otwórz wiadomość i naciśnij Stwórz Kontakt w prawym górnym menu.
-
-Możliwe jest również **tworzenie Zadań i Warunków** z wiadomości email.
-
-Jeśli adres wiadomości(od, do, cc) w wiadomości istnieją w systemie, system pokaże osobę powiązaną z (Kontaktem, Wiadomością, Użytkownikiem itd). Jeśli adres jest nowy, możesz z tego miejsca **stworzyć kontakt**.
-
-Wszystkie wiadomości email powiązane z specyficznym rekordem, są pokazane w panelu Historii tego rekordu. Jeśli jakaś wiadomość jest powiązana, na przykład, ze zdarzeniem ale zdarzenie jest powiązana z kontem, zostanie pokazana zarówno w zdarzeniu oraz w koncie.
-
-## Wysyłanie wiadomości Email
-
-Możesz tworzyć wiadomość na kilka sposobów:
-* *Utwórz wiadomości Email* przycisk na liście wiadomości
-* odpowiadanie na inną wiadomość;
-* kliknięcie na adres poczty email któregoś z rekordów;
-* *Utwórz wiadomości Email* akcja w panelu Działania.
-
-Istnieje możliwość **wybrania szablonu** swojej wiadomości.
-
-Możesz ustawić **podpis wiadomości email** w Preferencjach.
-
-## Folder Email
-
-Użytkownicy mogą tworzyć swoje własne foldery email, aby umieszczać tam niektóre ze swoich wiadomości. Lista dostępnych folderów jest widoczna po lewej stronie strony Wiadomości Email. Aby stworzyć lub edytować folder postępuj następująco Wiadomości Email > rozwijane menu w prawym górnym rogu > Foldery. `Pomiń Powiadomienia` oznacz, że nie będziesz powiadamiany o przyjściu nowej wiadomości, która trafi do określonego folderu. Filtry poczty umożliwiają automatyczne umieszczanie wiadomości email w folderach według określonych kryteriów.
-
-## Filtry Wiadomości Email
-
-Administrator może stworzyć globalny filtr, który pominie niepożądane wiadomości email. Jest to dostępne w Administracja > Filtry Wiadomości Email.
-
-Zwykły użytkownik może stworzyć filtr dla swoich Osobistych Kont Email lub dla całej Skrzynki odbiorczej. Jest to dostępne w Wiadomości Email > rozwijane menu w górnych prawym narożniku > Filtry.
-
-Istnieją dwa rodzaje filtrów:
-* Pomiń - wiadomość zostanie umieszczona w *Koszu* lub nie zostanie zaimportowane, jeśli filtr jest powiązany z Osobistym Kontem Email;
-* Umieść w folderze - zaimportowane wiadomości zostaną automatycznie umieszczone w konkretnym folderze.
-
-## Szablony Wiadomości
-
-Szablony wiadomości są dostępne w Wiadomości Email > rozwijane menu w górnym prawym narożniku > Szablony Wiadomości. Mogą być używane zarówno w wiadomościach wysyłanych masowo oraz w zwykłych emailach. `One-off` checkbox oznacza, że szablon powinien zostać wykorzystany tylko raz, jest to popularne w wiadomościach marketingowych.
-
-Możliwe jest wykorzystanie symboli zastępczych w treści szablonów wiadomości oraz tytule np. {Account.name}, {Person.emailAddress}. Zostaną zastąpione wartościami powiązanymi z rekordem.
-
-Możesz wykorzystać dodatkowe zarezerwowane symbole zastępcze w treści szablonu: {optOutUrl} oraz {optOutLink}.
-```
-Anuluj subskrypcję
-```
-Link do anulowania subskrypcji dla masowych wiadomości email
diff --git a/i18n/pl_PL/user-guide/markdown.md b/i18n/pl_PL/user-guide/markdown.md
deleted file mode 100644
index 2e800027a..000000000
--- a/i18n/pl_PL/user-guide/markdown.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Składnia Markdown
-
-Pola tekstowe wspierają składnie Markdown
-
-## Kod
-```
-`jakiś tekst`
-```
-
-`jakiś tekst`
-
-## Wieloliniowy kod
-
-```
-``` jakiś tekst ```
-```
-
-```
-jakiś tekst
-```
-
-## Pogrubiony tekst
-
-```
-**jakiś tekst**
-```
-
-**some text**
-
-## Podkreślony tekst
-
-```
-*jakiś tekst*
-```
-
-*jakiś tekst*
-
-## Skreślony tekst
-
-```
-~~jakiś tekst~~
-```
-
-~~jakiś tekst~~
-
-## Długi cytat
-
-```
-> jakiś
-> test
-```
-
-> jakiś
-> tekst
-
-## Link
-
-```
-[tekst odnośnika](https://www.espocrm.com)
-```
-[tekst odnośnika](https://www.espocrm.com)
-
-## Numerowana lista
-
-```
-1. jakiś przedmiot
-2. inny przedmiot
-```
-
-1. Some item
-2. Another item
-
-## Nienumerowana lista
-
-```
-* Jakiś przedmiot
-* Inny przedmiot
-```
-
-* Jakiś przedmiot
-* Inny przedmiot
-
-## Linia pozioma
-
-```
-___
-```
-
diff --git a/i18n/pl_PL/user-guide/mass-email.md b/i18n/pl_PL/user-guide/mass-email.md
deleted file mode 100644
index 022993bb8..000000000
--- a/i18n/pl_PL/user-guide/mass-email.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Masowe Wiadomości Email
-
-## Jak wysyłać masowe wiadomości email
-
-Musisz mieć przynajmniej jedną listę docelową z docelowymi rekordami i szablonem wiadomości email w swoim CRM.
-
-1. Stwórz nową akcję ze statusem `Email` lub `Newsletter`. Wybierz jedną lub kilka docelowych list w polu `Target Lists`.
-2. Po akcji jest tworzona masowa wiadomość email dla tej akcji: naciśnij przycisk plus w panelu Wiadomości Masowych. Ustaw _Date Start_ - kiedy wiadomość powinna być wysłana, i wybierz _Email Template_. Upewnij się, że _Status_ jest ustawiony na `Pending`.
-
-Jeśli wszystko jej poprawnie ustawione wiadomość email powinna zostać wysłana. Powinny być wysyłane porcjami co godzinę (możesz zmienić rozmiar porcji w Administracja > Wychodzące wiadomości Email). Administrator możę zmienić to przez aktualizację pola `Scheduling` z `Check Group Email Accounts` Zaplanowanych zadań.
-
-W panelu Logów możesz sprawdzić czy wiadomości zostały wysłane.
-
-## Testowanie co zostanie wysłane do odbiorców
-
-Naciśnij prawym przyciskiem w wierszu masowe wiadomości email na _Mass Email_ panel następnie naciśnij _Send Test_.
-
-## Zapisy
-
-W zapisach możesz zobaczyć:
-* Wysłane wiadomości;
-* Wiadomości email otwarte przez odbiorców;
-* Odnośniki kliknięte przez odbiorców;
-* Odbiorcy, którzy zrezygnowali;
-* Odrzucone wiadomości (nie dostarczone do odbiorców).
-
-## Link rezygnacji
-
-Domyślnie system doda link z adresem do rezygnacji do wszystkich wysłanych wiadomości email. Możesz wykorzystać go zmienić na niestandardowy w swoim szablonie wiadomości.
-
-Przykład:
-```html
-Wypisz się z listy mailingowej.
-```
-
-Administrator może wyłączyć obowiązkowy adres do rezygnacji dodawany przez system w Administracja > Wychodzące wiadomości.
-
-## Link monitorujący
-
-Jeśli chcesz wiedzieć, czy odbiorca wszedł w link z Twojej wiadomości email, musisz stworzyć link monitorujący. Określić _Name_
- oraz _URL_ gdzie powinien prowadzić Twój link. Następnie musisz wkleić wygenerowany kod do szablonu wiadomości.
-
- Przykład:
- ```html
-Wypróbuj naszą wersje demonstracyjną
- ```
-
-## Listy docelowe
-
-Listy docelowe zawierają listy z Kontami, Kontaktami, Wskazówkami i Użytkownikami.
-
-Użytkownicy mogą wypełniać te listy ręcznie poprzez akcję _Select_ w panelu korespondencji w szczegółach Listy docelowej . Jest możliwość filtrowania oraz wybrania wszystkich wyszukanych rezultatów.
-
-## Uzupełnianie listy docelowej z raportami
-
-[Raporty](reports.md#syncing-with-target-lists) funkcja umożliwiająca uzupełnienie listy docelowej z rekordami spełniającymi określone kryteria.
-
-## Lista pominiętych osób
-
-Określanie listy pominiętych osób w listach docelowych aby uniknąć wysyłania masowych wiadomości do określonych odbiorców. Jeśli jest tam rekord z adresem email zawierającym się w liście pominiętych odbiorców, pierwszy rekord zostanie również pominięty.
-
-## Dziennik kamapanii
-
-W dzienniku kampanii możesz zobaczyć adresy email do których została wysłana wiadomość, otworzyli wiadomości email, pominięte wiadomości, kto zrezygnował, oraz kto wszedł w link z wiadomości email. Jest możliwe wykorzystanie dziennika logów przez stworzenie Listy docelowej (rozwijane menu w prawym górnym narożniku panelu) bazującym na rekordach z dziennika. Na przykład, wybierasz tylko kontakty, które weszły w link z wiadomości (link monitorujący).
-
-## Rozwiązywanie problemów
-
-_Dla Administratorów_
-
-#### Co zrobić jak wiadomość nie została wysłana.
-
-1. Sprawdź czy działa _Wysyłanie Testowe_. Jeśli nie działa, sprawdź, czy ustawienia systemu SMTP są poprawne.
-2. Sprawdź czy masz ustawiony Cron w swoim systemie.
-3. Sprawdź czy masz zaplanowane zadanie `Wyślij masowe wiadomości email` i jest ono `Aktywne` (Administracja > Zaplanowane Zadania > Wysyłanie Wiadomości Masowych). Sprawdź czy jest coś w dzienniku logowania.
-
-
-#### Co w przypadku gdy link docelowy jest zły i nie prowadzi do Twojego CRM.
-
-Sprawdź parametr 'siteUrl' w pliku `data/config.php`. Musi być ustawiony publiczny adres Twojego EspoCRM.
-
-#### Odrzucone wiadomości email nie są zapisywane w dzienniku logowania
-
-Odrzucone wiadomości mogą być obsłużone tylko przez konta grupowych wiadomości email. Upewnij się, że masz konto grupowych wiadomości email, które monitoruje wysyłanie wiadomości.
-
-Niektóre serwery mailingowe mogą różnić się od standardowych, więc odrzucane wiadomości mogą nie być odróżniane.
diff --git a/i18n/pl_PL/user-guide/quotes.md b/i18n/pl_PL/user-guide/quotes.md
deleted file mode 100644
index d845954c4..000000000
--- a/i18n/pl_PL/user-guide/quotes.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Quotes
-
-Quotes feature is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Quotes are specific group of products or services with their quantities and prices that you quote to customers.
-
-Quotes has a relationship with Opportunity. You can add Quotes panel to Opportunity detail view at Administration > Layout Manager > Opportunities > Relationships. When creating a new quote linked to an opportunity it transfers opportunity items to the quote.
-
-You can add Quotes panel to Accunt's detail view to be able to see related quotes. You can do it at Administration > Layout Manager > Accounts > Relationships.
-
-## Quote Items
-
-Quote has a list of items. Each item can represent a certain product or a service with description, quantity, tax rate, list price and unit price fields. It's possible to sort items manually.
-
-There is an ability to add custon fields for Quote Item entity using Entity Manager.
-
-## Templates
-
-By default there are two available templates: Quote and Invoice. You can create new templates (Quotes list view > top-right dropdown menu > Templates) as well as edit existing ones.
-
-For more precise editing it's recommended to use Code View mode.
-
-You can print fields of Quote record as well as fields of related records by utilizing placeholders in your template.
-
-Examples:
-`{{accountName}}` – Account name,
-
-`{{{billingAddressStreet}}}` – street,
-
-`{{account.type}}` – type of related Account,
-
-`{{assignedUser.lastName}}` – last name of the assigned user.
-
-If your line item is a product you can print product’s fields.
-
-Examples:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Length and color are custom fields of Product entity in examples.
-
-Looping through quote items:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-It's possible to print image fields:
-
-```
-
-```
-where `imageId` – the name of custom image field in Quote entity concatenated with the suffix `Id`.
-
-For product line item:
-```
-
-```
-
-To display float numbers (like quantity, unitPrice etc.) w/o fractional part (as integer) use following expressions (since version 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Custom formatting for currency values (since version 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Value `10000.5` will be printer as `10 000,50`.
-
-To display text fileds (multiline) use triple braces: `{{{description}}}`.
-
-## Print to PDF
-
-Quotes can be printed to PDF. This action is available in dropdown next to Edit button on the quote’s detail view. Then you will be prompted to select Template.
-
-## Email Quote
-
-Quote PDF can be send in email as an attachment. Open quote record, click dropdown next to Edit button and the click Email PDF.
-
-## Automatic numbering
-
-You can create a Number field via Entity Manager for Quote entity type. Administration > Entity Manager > Quote > Fields > Add Filed > Number. Then you need to place it in on detail view using Layout Manager.
-
-The value will be incremented by every new quote. There is an ability to specify the next number as well as prefix.
-
-## Default tax
-
-Available since EspoCRM 4.8.0.
-
-1. Specify default Tax record at Administration > Entity Manager > Quotes > fields > Tax > Default.
-2. Specify default tax rate at Administration > Entity Manager > Quotes > fields > Tax Rate > Default.
-
-## Invoices
-
-Quote can be treated as an invoice if its status became `Approved`. Then _Date Invoiced_, _Invoice Number_ fields show up. You can use different template for invoices for printing.
diff --git a/i18n/pl_PL/user-guide/reports.md b/i18n/pl_PL/user-guide/reports.md
deleted file mode 100644
index dbf14cb3b..000000000
--- a/i18n/pl_PL/user-guide/reports.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Raporty
-
-Funkcjonalność raportów jest dostępna w [Zaawansowany pakiet](https://www.espocrm.com/extensions/advanced-pack/).
-
-Są dwa rodzaje raportów: Lista i Siatka.
-
-## Lista raportów
-
-Lista raportów wyświetla listę rekordów, które spełniają określone kryteria.
-
-Aby stworzyć nową listę raportów naciśnij na zakładkę Raporty a następnie naciśnij przycisk Stwórz Raport. Wybierz potrzebny rodzaj jednostki i następnie naciśnij Stwórz Raport w sekcji Lista Raportów.
-
-W polu _Columns_ wybierz pola, które chciałbyś wyświetlić. Poniżej możesz określić parametry wyświetlania dla każdej kolumny np. szerokość i wyrównanie.
-
-Wybierz sortowanie w polu _List Order_.
-
-W sekcji _Filters_ możesz określić kryteria, które determinują jakie rekordy będą wylistowane w raporcie. Możesz używać operatorów logicznych 'OR' i 'AND'.
-
-_Runtime Filters_ pozwalają określać inne filtry zanim uruchomisz raport.
-
-Możesz __export__ rezultaty z listy raportów do pliku CSV lub Excela.
-
-## Grid Reports
-
-Grid reports result summarized values grouped by specified fields. These reports can be displayed as a chart.
-
-
-
-To create new grid report click on Reports tab and then click Create Report button. Choose needed Entity Type then click Create button at Grid Report section.
-
-At _Group By_ field pick one or two fields you want your report data be grouped by. It's possible to group by year, month, day for date fields. If you group by two fields your report will be considered as three-dimensional.
-
-At _Columns_ field select one or more aggregate functions like COUNT, SUM (summation), MIN, MAX, AVG (average).
-
-_Order by_ field defines how report data will be sorted.
-
-At _Filters_ section you can specify criteria that determines what records will be used in your report. You can use logical operators 'OR' and 'AND' here.
-
-_Runtime Filters_ allows you to specify different filters before you run the report.
-
-Grid report allows displaying results in a chart form. There are following _chart types_: Bar (Horizontal), Bar (Vertical), Pie, Line.
-
-It's possible to __export__ grid report results to excel and csv formats.
-
-## Filtry
-
-### Filtr polowy
-
-Prosty typ filtru w użyciu. Możesz również wybrać pola docelowej jednostki tak samo jak powiązanych jednostek.
-
-
-
-### Wyrażenie OR
-
-OR oznacza, że co najmniej jeden z warunków musi zostać spełniony.
-
-
-
-### Wyrażenie AND
-
-AND oznacza, że wszystkie warunki muszą być spełnione.
-
-### Wyrażenie NOT
-
-Umożliwia filtrowanie rekordy, które nie spełniają określonych kryteriów. Np. lista kont, które nie mają statusu Wygrane Zamknięte lub Stracone Zamknięte.
-
-
-
-### Złożone wyrażenia
-
-Dla bardziej zaawansowanych zastosowań. Możesz zastosować funkcje dla pewnej kolumny bazy danych i porównać ją z rezultatem wyrażenia [wzór](../administration/formula.md).
-
-Uwaga: Jeśli chcesz porównać proste ciągi znakowe powinieneś umieścić je w pojedyncze apostrofy `'some string'`.
-
-Uwaga: Funkcje przeznaczone do interakcji z jednostkami rekordów nie będą tutaj działać ponieważ wzór nie jest przeznaczony do określnych rekordów.
-
-
-
-## Wyświetlanie na panelu
-
-Każdy raport możesz wyświetlić w panelu. Aby to zrobić musisz dodać raport do szybkiego dostępu i następnie wybrać potrzebny raport w opcjach szybkiego dostępu.
-
-## Wysyłanie wiadomości email
-
-Możliwe jest zrobienie systemu do wysyłania raportów do określonych użytkowników w określonym czasie. Musi to być skonfigurowane dla każdego raportu indywidualnie.
-
-## Synchronizowanie z listami docelowymi
-
-Możliwe jest synchronizowanie listy docelowych rezultatami listy raportów. Jest to wygodne dla masowych wiadomości e-mail, gdy chcesz wysyłać wiadomości tylko do osób, które spełniają kryteria w momencie wysyłania. Funkcja jest dostępna w widoku szczegółów każdej listy docelowej w panelu 'Synchronizuj z Raportami'.
diff --git a/i18n/pl_PL/user-guide/stream.md b/i18n/pl_PL/user-guide/stream.md
deleted file mode 100644
index 8faf500b7..000000000
--- a/i18n/pl_PL/user-guide/stream.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Strumień
-
-Strumień w EspoCRM jest kanałem, gdzie możesz zobaczyć aktualizacje i nowo dodane rzeczy dla rekordów, które śledzisz. Możesz również tworzyć nowe posty zarówno w swoim strumieniu jak i innych użytkowników (od wersji 3.8.0). W EspoCRM są dwa rodzaje strumieni: strumień rekordów oraz strumień użytkownika.
-
-Domyślnie strumień posiadają takie podmioty jak: Konta, Kontakty, Tropy, Możliwości, Sprawy. Administratorzy mogą aktywować lub dezaktywować strumienie dla poszczególnych podmiotów w [Menadżer Podmiotów](../administration/entity-manager.md).
-
-## Strumień Rekordów
-
-Strumień rekordów znajduje się w panelu Strumieni poszczególnych rekordów w widoku szczegółowym. Są tutaj wyświetlane posty, aktualizacje oraz nowo dodane rzeczy związane z aktualnym rekordem.
-
-## Strumień Użytkownika
-
-Użytkownicy mogą zobaczyć swój strumień w karcie Strumieni tak samo jak w zakładce Strumieni. Użytkownicy mogą również zobaczyć strumień innych użytkowników w widoku szczegółowym tego użytkownika, jeśli posiadają oni do tego dostęp, który ustala się za pomocą pola `Zezwolenie Użytkowników` w Rolach.
-
-W strumieniu użytkownika możesz zobaczyć posty, aktualizacje oraz nowo dodane rzeczy związane z rekordami, które ten użytkownik śledzi. Możesz również zobaczyć posty zaadresowane do tego użytkownika. Posty te nie są powiązane z żadnymi rekordami.
-
-## Powiadomienia
-
-Otrzymasz powiadomienia o nowych rzeczach dodanych przez innych użytkowników do Twojego strumienia.
-
-## Posty
-
-Możesz tworzyć posty związane z konkretnymi rekordami. Możesz dołączyć do postu wiele plików i obrazków. Jeśli chcesz o kimś wspomnieć w swoim poście musisz przed jego nazwą użytkownika wpisać symbol `@`. Użytkownik o którym wspomniałeś w swoim poście zostanie o tym powiadomiony.
-
-## Posty do użytkowników
-
-_Funkcja jest dostępna od wersji 3.8.0._
-
-Użytkownicy mogą tworzyć posty skierowane do konkretnych użytkowników, do konkretnych zespołów, do wszystkich użytkowników i do siebie. Dostęp do tym funkcjonalności jest kontrolowany przez pole `Przypisywanie Uprawnień` w zakładce Role.
-
-## Filtrowanie
-
-Możesz filtrować to co chcesz zobaczyć w swoim strumieniu: `Wszystko`, `Posty` lub `Aktualizacje`.
-
diff --git a/i18n/pt_BR/administration/apache-server-configuration.md b/i18n/pt_BR/administration/apache-server-configuration.md
deleted file mode 100644
index 485d89181..000000000
--- a/i18n/pt_BR/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Configuração do servidor Apache para EspoCRM
-
-Essas instruções são suplementares às orientações [Configuração do Servidor](server-configuration.md). Por favor, note que todas as configurações listadas aqui são feitas em servidor Ubuntu.
-
-## Requerimentos de PHP
-
-Para instalar todas as bibliotecas necessárias, execute esses comandos em um terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Reparando o erro “API Error: EspoCRM API is unavailable”:
-
-Siga apenas os passos necessários. Após cada passo, verifique se o problema foi resolvido.
-
-### 1. Habilitar o suporte “mod_rewrite” em Apache
-
-Para habilitar “mod_rewrite,” execute esses comandos no terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Habilitar o suporte .htaccess
-
-Para habilitar o suporte .htaccess, adicione/edite as Configurações do Servidor /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf ou /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Em seguida, execute esse comando em um terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Adicionar o caminho RewriteBase
-
-Abrir um arquivo /ESPOCRM_DIRECTORY/api/v1/.htaccess e substituir a seguinte linha:
-
-```
-# RewriteBase /
-```
-
-por
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-onde, REQUEST_URI é uma parte de uma URL, por exemplo, para “http://example.com/espocrm/”, REQUEST_URI é “espocrm”.
-
-
-## Habilitar o suporte HTTP AUTHORIZATION (somente para FastCGI).
-
-FastCGI não suporta HTTP AUTHORIZATION por padrão. Se você usa FastCGI, você tem que habilitar seu VirtualHost ou /etc/apache2/apache2.conf (httpd.conf) adicionando o código:
-
-Para o módulo Fcgid:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Para o módulo FastCgi:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Para verificar qual módulo está sendo usado, execute esse comando e ache o módulo:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/pt_BR/administration/b2c.md b/i18n/pt_BR/administration/b2c.md
deleted file mode 100644
index eda9f6b52..000000000
--- a/i18n/pt_BR/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#Configurando EspoCRM para B2C (Business-to-Client)
-
-Por padrão, EspoCRM está configurado para usar como negócios B2B. Entretanto, você pode facilmente configurá-lo para B2C.
-
-* Mude `b2cMode` para 'true' em seu arquivo de configuração `data/config.php`. Desde a versão 4.3.0, isso pode ser configurado em Administration > Seetings.
-* Remova a aba *Account* do menu de navegação (Administration > User Interface).
-* Remova os campos *Account* de seus layouts (Administation > Layout Manager).
-* Desabilite um acesso para o escopo *Account* para todas as suas funções (Administration > Roles).
-* Remova a conta das listas de seleção para todos os campos principais (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
diff --git a/i18n/pt_BR/administration/backup-and-restore.md b/i18n/pt_BR/administration/backup-and-restore.md
deleted file mode 100644
index 5b7b7f56a..000000000
--- a/i18n/pt_BR/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Cópia de Segurança e Restauração
-
-## Como fazer uma cópia de segurança do EspoCRM manualmente
-
-EspoCRM consiste em arquivos e informações da base de dados. Todas essas informações são necessárias para criar uma cópia de segurança completa do EspoCRM. Aqui estão as instruções de como fazer isso em servidor Ubuntu com MySQL.
-
-### Passo 1. Cópia de segurança dos arquivos
-
-Criar um arquivo com o conteúdo do diretório do EspoCRM instalado. Para Ubuntu o caminho padrão é `/var/www/html`. Você pode usar esse comando:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Passo 2. Cópia de segurança da base de dados
-
-Para salvar todas as suas informações, você deve saber o nome e as credenciais de acesso da base de dados. Você pode encontrar o nome da base de dados no arquivo de configuração `/ESPOCRM_DIRECTORY/data/config.php` sob a sessão `database`. Você pode usar esse comando para salvar seu banco de dados:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Passo 3. Copiar a cópia de segurança
-
-Isso é tudo. Agora, você deve copiar a cópia de segurança criada para um local seguro.
-
-
-## Como fazer uma cópia de segurança do EspoCRM com um script
-
-Você pode usar um script para salvar todas as informações necessárias. Faça login através de SSH e execute os comandos (testados em servidor Ubuntu).
-
-### Baixe um script
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Execute o script
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-onde
- * `PATH_TO_ESPOCRM` é um caminho para o diretório do EspoCRM instalado.
- * `BACKUP_PATH` é um caminho para o diretório da cópia de segurança.
-
-Para servidor Ubuntu é:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Nota: Se seu usuário MySQL não tem os direitos necessários para despejar sua base de dados, será solicitado que você entre com as credenciais de outro usuário MySQL.
-
-Após a criação bem-sucedida, você receberá um caminho para a cópia de segurança criada.
-
-## Restauração do EspoCRM a partir de uma cópia de segurança
-
-Você pode restaurar EspoCRM de uma cópia de segurança criada como descrito acima.
-
-### Passo 1. Extraia os arquivos da cópia de segurança
-
-Para extrair arquivos, você pode usar o Archive Manager ou executar o comando abaixo. Os arquivos precisam ser colocados em um diretório de servidor na web.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-onde:
- * `/var/www/html` é um diretório do servidor da web.
-
-### Passo 2. Definir permissões requeridas
-
-Os arquivos deveriam ser propriedade de um usuário do servidor da web e ter as permissões corretas. Por favor, defina as permissões necessárias através das instruções: [www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### Passo 3. Importar o despejo da base de dados
-
-O despejo da base de dados deve ser importando para a mesma base de dados com a mesma credencial de usuário, caso contrário a correção deve ser feita no arquivo de configuração `ESPOCRM_DIRECTORY/data/config.php`. Para importar seu banco de dados do despejo, execute o comando abaixo em um terminal:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Passo 4. Verificar/configurar crontab
-
-Verifique se seu crontab está configurado apropriadamente. Execute o comando abaixo e verifique se o caminho para EspoCRM está correto:
-
-```bash
-sudo crontab -l -u www-data
-```
-onde:
- * `www-data` é seu usuário do servidor de web.
-
-Se você tem que fazer quaisquer mudanças, use esse comando:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Mais detalhes sobre configurar crontab para EspoCRM está descrito aqui [www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
diff --git a/i18n/pt_BR/administration/bpm.md b/i18n/pt_BR/administration/bpm.md
deleted file mode 100644
index 0cf9ded69..000000000
--- a/i18n/pt_BR/administration/bpm.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# Business Process Management
-
-A ferramenta Business Process Management (BPM) dá a habilidade de modelar e automatizar os processos de negócios no EspoCRM. É um motor que executa processos de negócios descrito no BPMN 2.0 padrão. A ferramenta BPM está disponível na extensão [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-
-
-### Diferença da ferramenta Workflows
-
-A ferramenta Workflows está destinada para automação de regras simples de negócios, sem fluxo sequencial de itens, quando não há necessidade de mostrar o fluxo em gráficos.
-
-A ferramenta BPM é destinada a fluxos de negócios mais complexos, onde pode haver fluxos divergindo e convergindo, atrasos na execução, interações do usuário. Um fluxograma faz os processos do negócio mais compreensivos para um humano, um log permite ver como o processo foi mantido.
-
-## Fluxogramas dos Processos
-
-O link para os fluxogramas dos processos está disponível no painel de administração. Isso também pode ser adicionado como uma aba no painel de navegação.
-
-Fluxogramas são destinados para a modelagem de processos de negócios. Administradores podem criar e editar fluxogramas. Usuários comuns podem somente ver os fluxogramas.
-
-Cada fluxograma tem seu tipo de entidade específica (campo Target Type). O fluxograma determina a execução de instâncias de processos futuros. Ele consiste de elementos do fluxograma e conexões entre elementos.
-
-Se os processos do fluxograma têm o campo 'Is Active' desmarcado, ele não iniciará as instâncias dos processos.
-
-Para mostrar detalhes e parâmetros de certo elemento do fluxograma, você precisa clicar nele. Em modo de edição você é capaz de editar parâmetros.
-
-## Processos
-
-Os processos estão disponíveis no painel de administração. O link também pode ser adicionado à aba no painel de navegação.
-
-Os processos representam instâncias de processos de negócios. Quando ele é iniciado, seu estado para a ser 'Started'. Quando o processo é finalizado, seu estado passa a ser 'Ended'. O processo pode também ser parado manualmente por um usuário que tenha acesso à edição de processos. Se ele é parado manualmente, seu estado passa a ser 'Stopped'.
-
-O processo é executado de acordo com o fluxograma. O processo de fluxograma não pode ser mudado depois que o processo é iniciado.
-
-O processo obrigatoriamente está relacionado a um único registro alvo.
-
-Os processos podem ser iniciados automaticamente (sob condições específicas ou através de agendamento) ou manualmente (onde há pelo menos um 'Iniciar Evento' no fluxograma). Para começar processos manualmente o usuário precisa clicar no botão 'Iniciar Processo' na lista de processos.
-
-## Elementos dos Fluxogramas
-
-### Eventos
-
-Eventos são mostrados nos fluxogramas como círculos.
-
-#### Iniciar Evento
-
-Não tem parâmetros. É um ponto de início do processo. Iniciar Evento pode ser iniciado manualmente por um usuário que tenha acesso para criar processos. O usuário precisa clicar no botão 'Iniciar Processo' na lista de processos.
-
-#### Iniciar Evento Condicional
-
-Um ponto de início do processo. É suposto para ser acionado automaticamente quando condições específicas são atendidas. Há dois tipos de acionamentos: 'Depois de um registro criado', 'Depois de um registro salvo'.
-
-#### Iniciar Processo Agendado
-
-Um ponto de início do processo. Isso inicia processos por agendamento. Você precisa especificar a lista de reporte que retorna registros para iniciar processos e agendar na notação do crontab.
-
-#### Evento Intermediário Condicional
-
-Esse evento para o fluxo até que critérios específicos sejam atendidos.
-
-#### Evento Intermediário Agendado
-
-Esse evento para o fluxo e esperar o quanto for especificado pelos parâmetros dos eventos.
-
-Para agendamentos mais complexos você pode utilizar [fórmula](formula.md). Scripts de fórmula devem retornar um valor Data-Tempo (em fuso horário UTC). Uma vez que esse tempo chega, o fluxo procederá para o próximo elemento.
-
-Através da utilização da função de fórmula datetime\closest, é possível definir o relógio para uma hora específica no futuro, por exemplo, o início do próximo dia de trabalho.
-
-#### Fim de Evento
-
-Finaliza o fluxo atual. Ele não finaliza fluxos sendo executados em paralelo. Quando o fluxo chega ao fim do evento e não há qualquer coisa executando em paralelo, o processo finaliza.
-
-#### Fim de Evento Conclusivo
-
-Finaliza todos os fluxos. Processo é subsequentemente finalizado.
-
-### Entradas
-
-Entradas são mostrados como diamantes.
-
-#### Entrada Exclusiva
-
-Pode divergir ou convergir fluxos.
-
-No caso de divergência, ela define um único fluxo (caminho) que será escolhido de acordo com critérios específicos. A primeira condição atendida determina o fluxo, próximas condições são omitidas. Há uma habilidade de especificar fluxo padrão. O fluxo padrão é escolhido se não existem quaisquer condições atendidas. O fluxo padrão está marcado com um sinal de barra.
-
-No caso de convergência, ela apenas direciona o fluxo para o elemento de saída. Ela não é bloqueada após o fluxo passar através, então fluxos paralelos não serão unidos em um único fluxo.
-
-
-
-
-
-#### Entrada Inclusiva
-
-Pode divergir ou convergir fluxos.
-
-No caso de divergência, ela pode direcionar um ou múltiplos fluxos paralelos (caminhos), dependendo do atendimento de critérios de cada fluxo. O fluxo padrão é escolhido se não existem quaisquer condições atendidas. O fluxo padrão está marcado com um sinal de barra.
-
-Se há necessidade de unir fluxos paralelos produzidos por uma entrada inclusiva divergente, você precisa usar uma entrada inclusiva convergente. Ela vai esperar for todos os fluxos de entrada e então seguir para o elemento de saída.
-
-
-
-Nota: Entradas divergentes e convergentes devem ser balanceadas.
-
-Nota: Se um dos fluxos paralelos foi finalizado por algum motivo então a entrada divergente nunca será processada. O processo será bloqueado. Evite um design de fluxograma que possa trazer tal situação.
-
-#### Entrada Paralela
-
-Pode divergir ou convergir fluxos.
-
-Em caso de divergência, ela divide o fluxo em múltiplos fluxos paralelos. Não há parâmetros para esse tipo de entrada.
-
-Em caso de convergência, ela espera até todos os fluxos de entrada venham e então continua para o próximo elemento de saída.
-
-
-
-Nota: Entradas divergentes e convergentes devem ser balanceadas.
-
-Nota: Se um dos fluxos paralelos foi finalizado por algum motivo então a entrada divergente nunca será processada. O processo será bloqueado. Evite um design de fluxograma que possa trazer tal situação.
-
-#### Entrada Baseada em Evento
-
-Pode somente divergir fluxos.
-
-Ela para o fluxo até qualquer dos eventos de saída seja disparado. O evento disparado determina o único fluxo. Outros eventos de saída são rejeitados.
-
-Somente eventos intermediários podem estar na outra saído do fluxo de sequência de saída.
-
-
-
-### Atividades
-
-Atividades são mostradas como retângulos arredondados.
-
-#### Tarefas
-
-Tarefas podem executar as ações seguintes:
-
-* Criar Registro - cria um novo registro de qualquer tipo de entidade;
-* Criar Registro Relacionado - cria um novo registro relacionado ao registro alvo;
-* Atualizar Registro Alvo;
-* Atualizar Registro Relacionado - atualiza o registro ou registros relacionados ao registro alvo;
-* Atualizar Registro Criado - atualiza um campo específico de qualquer registro criado no processo atual;
-* Atualizar Processo de Registro - pode ser usado para designar o processo a um usuário ou time específico;
-* Ligar a Outro Registro - liga o registro alvo com um registro específico;
-* Romper Ligação de Outro Registro - rompe a ligação do registro alvo do registro especificado;
-* Aplicar Regra de Designação - designa o registro alvo, o registro do processo ou qualquer registro criado pelo processo de acordo com a regra específica;
-* Criar Notificação - cria notificação dentro do aplicativo para usuários específicos;
-* Fazer Seguido - faz um usuário específico seguir o registro alvo, o registro do processo ou qualquer registro criado pelo processo;
-* Executar Ação de Serviço - executa ações de serviços personalizados implementados por desenvolvedores.
-
-Ações disponíveis para tarefas são quase as mesmas como na característica Fluxo de Trabalho. Veja mais detalhes sobre [ações de fluxo de trabalho](workflows.md#actions).
-
-#### Enviar Mensagem de Tarefa
-
-Envia mensagem por email para um receptor específico.
-
-#### Tarefa de Usuário
-
-Providencia uma habilidade flexível de interação de usuário. Ela para a execução até que o usuário (explicitamente especificado ou por regra de designação) conclua a tarefa. O registro da Tarefa do Processo do Usuário será criado no sistema. Por padrão, existem três tipos de ações: Aprovar, Rever e Concluir.
-
-* As do tipo Aprovar exige que o usuário escolha entre 'Aprovada' ou 'Recusada'.
-* As do tipo Revisar somente dão uma opção: 'Revisado'.
-* As do tipo Concluir possuem duas opções: 'Completada' e 'Falhada'.
-
-
-O usuário designado a criar o registro da Tarefa do Processo do Usuário receberá uma notificação dentro do aplicativo. O administrador pode também ativar notificações por email.
-
-Usuários podem também adicionar Tarefas do Usuário do Processo como pequenas informações em seu painel de controle para ver tarefas do usuário do processo atual deles.
-
-É possível ler a resolução da tarefa de usuário passada dentro de uma entrada divergente ou eventos condicionais, fazendo ramificação no fluxo do processo.
-
-#### Tarefa de Script
-
-Executa o script na linguagem [espo-fórmula](formula.md) Todas as variáveis definidas (`$variableName`) serão guardadas e estarão disponíveis dentro do processo.
-
-### Fluxos
-
-#### Sequência de Fluxos
-
-Representadas como uma flecha sólida. Indica a ordem em que os elementos do processo serão executados.
-
-## Condições
-
-Entradas de eventos condicionais, exclusivas e inclusivas divergentes, possuem condições que determinam o fluxo do processo.
-
-Através da UI há uma habilidade de verificar condições para os seguintes registros:
-
-* Registro Alvo;
-* Registros relacionados ao alvo através de relacionamentos muitos-para-um e filho-para-pai;
-* Registros criados pelos processos através de tarefas;
-* Registros de tarefas de usuários, que permitem a verificação da resolução.
-
-É possível também definir condições na linguagem [Espo-fórmula](formula.md).
-
-Condições na ferramenta BPM são as mesmas como na característica Fluxo de Trabalho. Veja mais detalhes sobre isso em [condições dos fluxos de trabalhos](workflows.md#conditions).
-
-## Exemplos
-
-### Exemplo 1
-
-
-
-### Exemplo 2
-
-
-
-### Exemplo 3
-
-
diff --git a/i18n/pt_BR/administration/email-fetching.md b/i18n/pt_BR/administration/email-fetching.md
deleted file mode 100644
index d1b252e5c..000000000
--- a/i18n/pt_BR/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Emails
-
-O documento agora está [aqui](emails.md).
diff --git a/i18n/pt_BR/administration/emails.md b/i18n/pt_BR/administration/emails.md
deleted file mode 100644
index 3535b44ee..000000000
--- a/i18n/pt_BR/administration/emails.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Emails
-
-> Importante. [Cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) deveria ser configurado em seu sistema para fazer buscas de email funcionar. Você pode achar as informações em seu EspoCRM em Administration > Scheduled Jobs.
-
-## Panorama
-
-EspoCRM tem uma habilidade de monitorar caixas de email IMAP. O email pode ser arquivado de dois modos: Grupo de Contas de Email e Contas de Email Pessoais. Contas de Entrada para Grupo são pretendidas para caixas de email de grupos: o caso mais comum é uma caixa para o suporte. Contas de Email Pessoal são pretendidas para as caixas de email pessoais dos usuários.
-
-Enquanto um email está sendo recebido, o sistema tenta ligá-lo com o registro apropriado (Contas, Condução, Oportunidade, Caso). Os usuários que seguem aquele registro vão receber notificação sobre um novo email no sistema, mesmo que ele não esteja no 'Para' ou 'CC'.
-
-## Grupo de Contas de Email
-
-Somente o administrador pode configurar Grupo de Contas de Email. Os Grupo de Contas de Email podem ser usados para emails que estão sendo recebidos ou enviados. Enviar emails de contas de grupos está disponível desde a versão 4.9.0.
-
-O campo 'times' determina a quais times serão atribuídos os emails que estão chegando.
-
-Se o grupo de contas de email tem SMTP e está verificado como divididos, então um acesso será controlado por Papéis através da permissão do Grupo de Contas de Email. O campo 'times' será usado se o nível de permissão estiver definido como 'time'.
-
-Existe uma habilidade de fazer o sistema enviar uma mensagem automática para emails recebidos.
-
-## Email-para-Caixa
-
-Há uma opção de fazer o sistema criar caixas de emails de grupo recebidos.
-Essa característica é intencionada para times de suporte.
-As caixas podem ser distribuídas para usuários de um time específico de acordo com esses caminhos: 'atribuição direta', 'um usuário por turno' e 'menos ocupado'.
-Somente o primeiro email na sequência cria uma nova caixa.
-Cada email subsequente será ligado a um registro de caixa existente e mostrado no seu painel 'Transmissão'.
-
-Quando usuários querem enviar uma resposta para o cliente, eles precisam ter certeza que a caixa está selecionada como um superior do email que está sendo enviado. Isso fará com que o cliente responda para o endereço de email do grupo em vez de para o email do usuário.
-
-## Contas de Email Pessoal
-
-Os usuários podem configurar as suas próprias contas de email que necessitem de monitoramento. Emails > Top Right Dropdown Menu > Personal Email Accounts. O administrador também pode gerenciar as contas de email dos usuários.
-
-## Filtros de Email
-
-Esses permitem que ocorra a filtragem dos emails recebidos de acordo com critérios específicos Por exemplo, se você não quer mensagens de notificação enviadas por alguma aplicação seja importada para o EspoCRM, você pode criar um filtro para fazer EspoCRM ignorá-las.
-
-O administrador pode criar filtros globais, aplicados para todas as contas de email. Os usuários podem criar filtros para suas próprias contas de email e para uma caixa de entrada inteira.
diff --git a/i18n/pt_BR/administration/entity-manager.md b/i18n/pt_BR/administration/entity-manager.md
deleted file mode 100644
index 0dfa33bbe..000000000
--- a/i18n/pt_BR/administration/entity-manager.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Gerenciador de Entidades
-
-O Gerenciador de Entidades está disponível através do painel 'Administração'. Ele fornece uma capacidade altamente personalizar sua instância de EspoCRM. Você é capaz de fazer o seguinte:
-
-* Adicionar novos tipos de entidades.
-* Personalizar tipos de entidades existentes: mudas rótulos, ordem padrão visto como lista, habilitar ou desabilitar transmissão.
-* Configurar campos: adicionar novo, personalizar os existentes.
-* Configurar relacionamentos: adicionar novo, mudar rótulos dos existentes.
-
-## Criando novas entidades
-
-Clique no botão 'Criar Entidade' na página do Gerenciador de Entidades Especificar nome, rótolo e tipo. Se você selecionar o tipo 'Pessoa', sua entidade vai ter os campos Email, Telefone, Primeiro Nome, Último Nome e Saudação. Marque 'Transmissão' se você quer que sua entidade tenha um painel de transmissão e os usuários sejam capazes de 'Seguir' entidades desse tipo.
-
-Tipos:
-
-* Básico - apenas uma entidade vazia com campos básicos como Nome, Usuário Designado, Times, Descrição.
-* Básico Maior - como o Básico, porém com os painéis Atividades, Histórico e Tarefas (disponível desde a versão 4.3.0).
-* Evento - campos Data de Início, Data de Fim, Duração, Superior, Estado. Disponível no painel Calendário e Atividades (desde 4.3.0, deve estar habilitada em Administração > Opções).
-* Pessoa - campos Email, Telefone, Primeiro Nome, Último Nome, Saudação, Endereço. Painéis Atividades, Histórico, Tarefas.
-* Companhia - campos Email, Telefone, Endereço de Cobrança, Endereço de Entrega. Painéis Atividades, Histórico, Tarefas.
-
-## Atualizar entidade existente
-
-Se você clicar no link 'Editar' em uma certa entidade, você será capaz de mudar alguns parâmetros daquela entidade.
-
-* Rótulos - nomes singular e plural da entidade.
-* Os registros de ordem padrão são organizados nas visualizações de listas.
-* Transmissão - se o recurso Transmissão está ativado para esta entidade.
-* Desabilitado - marque se você não precisa dessa entidade em seu sistema.
-* Filtros de Campos de Texto - quais campos 'pesquisar por' para o filtro de texto principal e pesquisa global
-
-
-## Campos
-
-Ao clicar no link 'Campos' você será direcionado para uma página separada. Lá você será capaz de criar novos campos ou atualizar os existentes. Os tipos seguintes de campos estão disponíveis no Gerenciador de Entidades:
-
-* Endereço - endereço com rua, cidade, estado, código postal e país;
-* Arranjo - lista de valores, com a capacidade de selecionar valores múltiplos (não é uma boa opção se você precisa pesquisar através desse campo); os usuários podem adicionar seus próprios valores se as opções não foram especificadas.
-* Anexar Múltiplo - anexar vários arquivos;
-* Auto-incremento - lê o número gerado;
-* Booleano - caixa para marcar, verdadeiro ou falso;
-* Moeda - para valores monetários;
-* Data;
-* Hora;
-* Enum - caixa de seleção, com a capacidade de selecionar somente um valor;
-* Arquivo - carregar um arquivo;
-* Decimal - número com casas decimais;
-* Externo - um campo de uma entidade relacionada;
-* Imagem - carregar um arquivo de imagem com pré-visualização;
-* Inteiro - número inteiro;
-* Número - número em uma sequência de caracteres que se auto-incrementa, com um possível prefixo e um tamanho específico;
-* Multi-enum - lista de valores, com a capacidade de selecionar valores múltiplos (não é uma boa opção se você necessita pesquisar nesse campo), similar ao Arranjo mas melhor.
-* Texto - área de texto, para longos textos de multilinhas;
-* URL - para links;
-* Varchar - texto curto;
-* Wysiwyg - parecido com o campo Texto, com a capacidade de formatar texto.
-
-Parâmetros:
-* Requeridos - se o preenchimento do campo é obrigatório.
-* Valor Padrão - Valor do campo definido através da criação de um novo registro.
-* Auditado - atualizações do campo serão registradas na Transmissão
-
-**Nota**: Após você ter adicionar um novo campo, você precisa colocar esse campo em [layouts](layout-manager.md) (Administração > Gerenciador de Layout).
-
-### Lógica Dinâmica
-
-Fornece uma capacidade de fazer formulários dinâmicos. É possível definis condições fazendo certos campos visíveis, obrigatórios ou somente leitura. Condições serão verificadas automaticamente quando os dados nos formulários mudarem.
-
-Para os campos Enum, Arranjo e Multi-enum, é possível definir diferentes conjuntos de opções que estarão disponíveis para o campo dependendo em qual condição foi satisfeita.
-
-
-## Relacionamentos
-
-Você pode criar novos relacionamentos entre ambos fora-da-caixa ou entidades personalizadas. Existem 3 tipos de relacionamentos disponíveis:
-
-* Um-Para-Muitos: após você ter criado esse relacionamento você pode colocar um campo para link para os detalhes do layout da entidade da direita e adicionar um painel de relacionamento à entidade da esquerda;
-* Muitos-Para-Um: o mesmo que Um-Para-Muitos, porém ao contrário;
-* Muitos-Para-Muitos: painéis de relacionamento em ambos os lados.
-
-O parâmetro 'Ligar Vários Campos' implica que o campo do tipo 'linkMultiple' será criado junto ao relacionamento. Você pode colocar tal campo no layout. É conveniente para rápida escolha de registros relacionados. Não é uma boa opção se seu relacionamento é intencionado para ter muitos registros ligados, que pode causar lentidão no carregamento de detalhes na tela de visualização.
-
-Se o parâmetro 'Auditado' está marcado, então as atualizações dos relacionamentos serão registradas na Transmissão.
-
diff --git a/i18n/pt_BR/administration/extensions.md b/i18n/pt_BR/administration/extensions.md
deleted file mode 100644
index 2e792116b..000000000
--- a/i18n/pt_BR/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Gerenciar Extensões
-
-## Como instalar uma extensão
-
-Para instalar extensões para EspoCRM (ex: Pacote Avançado, Integração VoIP):
-
-1. Entre como um administrador.
-2. Vá em Administração > Extensões.
-3. Carregar seu pacote da extensão (arquivo zip).
-4. Clique no botão instalar.
-
-
-## Como atualizar uma extensão
-
-Para atualizar uma extensão já instalada (ex: Pacote Avançado, integração VoIP) para uma versão mais nova:
-
-1. Baixe a nova versão da extensão necessária.
-2. Entre como um administrador.
-3. Vá em Administração > Extensões.
-4. Carregue o pacote de sua nova extensão (arquivo zip) sem desinstalar a versão já instalada.
-5. Clique no botão instalar.
-
-
-## Como desinstalar uma extensão
-
-Passos para desinstalar uma extensão instalada:
-
-1. Entre como um administrador.
-2. Vá em Administração > Extensões.
-3. Ache a extensão desejada na lista de extensões disponíveis.
-4. Clique no botão Desinstalar.
-
-
-## Como apagar uma extensão
-
-Quando uma extensão é desinstalada, ela ainda fará parte do sistema. Ela pode ser completamente removida. Passos para remover uma extensão:
-
-1. Entre como um administrador.
-2. Vá em Administração > Extensões.
-3. Ache a extensão desejada na lista de extensões disponíveis.
-4. Clique no botão Remover
diff --git a/i18n/pt_BR/administration/formula.md b/i18n/pt_BR/administration/formula.md
deleted file mode 100644
index d8d2ffca7..000000000
--- a/i18n/pt_BR/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Campos com Cálculos (Fórmulas)
-
-No gerenciador de entidades é possível definir um script (fórmula) para entidades de tipos específicos. Esse script será executado todas as vezes antes do registro ser salvo.
-Ele garante a capacidade de automaticamente definir campos específicos (atributos) com valores derivados dos cálculos.
-
-Para editar uma fórmula siga Administração > Gerenciador de Entidades > Menu deslizante à direita na linha da entidade desejada > Fórmula.
-
-Você também pode precisar definir campos, que são deveriam ser calculados, Somente Leitura através do Gerenciador de Entidades.
-
-
-## Sintaxe
-
-As fórmulas em EspoCRM é escrita em uma única linguagem designada especificamente para essa característica.
-
-Há operadores, atributos de funções e valores que podem ser usados nas fórmulas. Expressões separadas devem ser delimitadas por caractere ';'.
-
-### Operadores
-
-* `=` - designação.
-* `||` - é o OU lógico,
-* `&&` - é o E lógico,
-* `!` - é o NÃO lógico,
-* `+`- soma numérica,
-* `-` - subtração numérica,
-* `*` - multiplicação numérica,
-* `/` - divisão numérica,
-* `%` - módulo numérico,
-* `==` - comparação de igualdade,
-* `!=` - comparação de diferença,
-* `>` - comparação de maior que,
-* `<` - comparação de menor que,
-* `>=` - comparação de maior que ou igual a,
-* `<=` - comparação de menor que ou igual a.
-
-Priority of operators:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Atributos
-
-Atributos representam campos de valores da entidade visada. Você pode inserir atributos disponíveis ao clicar no botão mais.
-
-É possível acessar atributos de entidades relacionadas com o formato seguinte: `linkName.attributeName`.
-
-
-### Funções
-
-Formato de uso das funções: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Funções fora-da-caixa estão listadas abaixo.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` Se a CONDITION está satisfeita, então faça CONSEQUENT. Se não está -- então faça ALTERNATIVE.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` Se a CONDITION está satisfeita, então faça CONSEQUENT. Se não está -- não faça nada.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Concatena duas ou mais sequências de caracteres.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Extrai os caracteres da STRING na posição START e LENGTH.
-
-Se LENGTH for omitida, será retornada a subsequência de caracteres iniciada em START até o fim da STRING.
-
-Se LENGTH for negativo, então aquela quantidade de caracteres serão omitidos do final da STRING.
-
-#### string\\trim
-`string\trim(STRING)` Retira espaço em branco do início e do fim da STRING.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Converte as letras para minúsculas. (desde a versão 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Converte as letras para maiúsculas. (desde a versão 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Retorna a data de hoje.
-
-#### datetime\now
-`datetime\now()` Retorna a data e hora atual.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Converte a data ou data e hora VALUE em uma sequência de caracteres formatada de acordo com as configurações do aplicativo. TIMEZONE e FORMAT podem ser omitidos. Se o TIMEZONE for omitida, então o fuso horário padrão será usado. Se o FORMAT for omitido, então o formato padrão será usado.
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Retorna a data do mês (1-31). `0` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Retorna o mês (1-12). `0` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Retorna o ano. `0` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Retorna a hora (0-23). `-1` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Retorna os minutos (0-59). `-1` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Retorna o dia da semana (0-6). `-1` se VALUE estiver vazio. `0` - para domingo. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (since version 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Retorna a diferença entre duas datas ou datas e horas. INTERVAL_TYPE pode ser 'anos', 'meses', 'dias', 'horas', 'minutos'. Retorna `nulo` se falhar. O resultado será negativo se VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Adiciona MINUTES à data e hora VALUE. MINUTES podem ser negativo.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Adiciona HOURS à data e hora VALUE. HOURS pode ser negativo.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Adiciona DAYS à data ou data e hora VALUE. DAYS pode ser negativo.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Adiciona WEEKS à data ou data e hora VALUE. WEEKS pode ser negativo.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Adiciona MONTHS à data ou data e hora VALUE. MONTHS pode ser negativo.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Adiciona YEARS à data ou data e hora VALUE. YEARS pode ser negativo.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` Retorna a data ou data e hora mais próxima do VALUE baseada nos argumentos passados. (desde a versão 5.0.0)
-
-TYPE pode ser one dos seguintes valores: 'horário', 'minuto', 'hora', 'data', 'mês', 'diaDaSemana'. TARGET é um valor inteiro ou uma sequência de caracteres. IS_PAST significa achar o mais próximo no passado. Se TIMEZONE for omitida, então o fuso horário padrão é usado.
-
-Exemplos:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Retornará o valor de data e hora mais próximo no futuro com o horário 20:00.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Retornará `2017-11-01`, o primeiro dia do mês.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Retornará a próxima segunda-feira (o início do dia).
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Converte VALUE numérico em sequência de caracteres formatada de acordo com um formato específico ou configurações do aplicativo padrão. Se DECIMALS, DECIMAL_MARK OR THOUSAND_SEPARATOR então os padrões do sistema serão usados.
-
-Exemplos:
-
-`number\format(2.666667, 2)` - resultará 2.67;
-
-`number\format(1000, 2)` - resultará 1,000.00;
-
-`number\format(10.1, 0)` - resultará 10.
-
-
-#### number\abs
-`number\abs(VALUE)` Valor absoluto. Retorna nulo se VALUE não é numérico.
-
-#### number\round
-`number\round(VALUE, PRECISION)` Retorna um valor arredondado de VALUE a uma PRECISION especificada (o número de dígitos depois do ponto decimal). PRECISION também pode ser negativo ou zero (padrão).
-
-#### number\floor
-`number\floor(VALUE)` Retorna o próximo inteiro de menor valor através do arredondamento para baixo, se necessário. (desde a versão 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` Retorna o próximo inteiro de maior valor através do arredondamento para cima, se necessário. (desde a versão 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Retorna TRUE se a entidade é nova (está sendo criada) e FALSE se não está (está sendo atualizada).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Retorna TRUE se o ATTRIBUTE da entidade mudou.
-
-Exemplo:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Retorna TRUE se o ATTRIBUTE da entidade não obteve mudanças.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Atributo que foi definido quando a entidade visada foi buscada na base de dados. Antes dela ser modificada.
-
-Exemplo:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Adiciona ID para o campo Links Múltiplos. Por exemplo, adiciona 'someTeamId' ao campo 'teams'.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Adiciona a lista de IDs. (desde a versão 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Verifica se o campo Links Múltiplos tem um ID específico.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Remove um ID específico do campo Links Múltiplos.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Verifica se a entidade visada está relacionada com outra entidade representada por LINK e ID.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Retorna o ATTRIBUTE do usuário atual.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Retorna arranjo. (desde a versão 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Retorna verdadeiro se LIST contêm VALUE. Pode ser usado pelos campos Arranjo e Multi-enum. (desde a versão 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Adiciona um ou mais elementos no final de um arranjo e retorna o novo arranjo. (desde a versão 5.0.0)
-
-#### array\length
-`array\length(LIST)` Retorna a contagem dos elementos em LIST. (desde a versão 4.8.1)
-
-
-### Valores
-
-* Sequências de caracteres. Ex: 'uma sequência de caracteres qualquer';
-* Números inteiros. Ex: 1, 100, 40300.
-* Números decimais. Ex: 5.2.
-
-### Variáveis
-
-É possível definir variáveis padronizadas nas fórmulas.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Exemplos
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Usando fórmulas em Fluxos de Trabalho
-
-Você pode utilizar fórmulas nas condições e ações dos fluxos de trabalhos. Veja [documentação dos fluxos de trabalho](workflows.md) para mais informações.
diff --git a/i18n/pt_BR/administration/import.md b/i18n/pt_BR/administration/import.md
deleted file mode 100644
index 1f449eebe..000000000
--- a/i18n/pt_BR/administration/import.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Importar
-
-Importar é acessível somente a usuários administradores. Administração > Importar. Você será capaz de importar somente arquivos CSV.
-
-## Passo 1
-
-Selecione qual o tipo de registro você precisa importar (campo Tipo de Entidade).
-Selecione um arquivo CSV. Um arquivo deveria estar formatado com 'UTF-8'.
-Selecione 'O que fazer?'. Opções disponíveis: 'Somente Criar', 'Criar & Atualizar', 'Somente Atualizar'.
-
-* `Somente Criar` - selecione se você quiser que o registro seja apenas criado.
-* `Criar & Atualizar` - os registros serão criados, mas se registros campo de valores coincidentes forem encontrados, eles serão atualizados. Você será capaz de verificar quais campos coincidir no _Passo 2_.
-* `Somente Atualizar` - apenas registros com valores de campos coincidentes serão encontrados e serão atualizados.
-
-Uma vez que você selecionar um arquivo csv, você será capaz de ver como ele deveria ser analisado no painel de pré-visualização. Quando você muda as propriedades, a pré-visualização será atualizada.
-
-* `Linha do Cabeçalho' - se o arquivo CSV tem a primeira linha com nomes dos campos.
-* `Executar em segundo plano' - recomendado se você tem uma grande quantidade de registros a serem importados. Importar será processado através de cron. O estado será definido como 'Completo' quando o processo de importação finalizar.
-* `Pular pesquisa por duplicações` - isso vai diminuir o tempo de execução da importação.
-
-Clique no botão _Próximo_ para seguir para o _Passo 2_.
-
-
-
-## Passo 2
-
-Configure o mapeamento de campo: como os campos correspondem à colunas no arquivo CSV. Você pode pular colunas não necessárias aqui.
-Em caso de 'Criar & Atualizar' e 'Somente Atualização' você precisa verificar os campos pelos quais os registros que devem ser atualizados serão encontrados.
-Adicione valores padrões novos que você deseja e atualize os registros para defini-los. Ex: você pode especificar os campos Usuário Designado ou Times.
-
-Após completar a importação você será capaz de reverter registros criados, ver duplicatas e atualizar registros. Duplicata significa que existia um registro similar no sistema. Você pode remover todas as duplicatas importadas de uma vez. Nota: Reverter não funciona com registros atualizados.
-
-Clique no botão _Executar Importação_ para seguir. Pode levar algum tempo até que o processo de importação seja finalizado. Se você precisar importar uma grande quantidade de registros (dependendo das configurações do servidor, normalmente mais que 200 registros) você precisa ter certeza que o parâmetro php 'set_time_limit' tem tamanho suficiente.
-
-
-
-## Como importar para Listas Destino
-
-Quando você importa Contatos, Conduções ou Contas, você pode adicioná-las a uma lista destino. No Passo 2 você precisa adicionar o campo Lista Destino no painel 'Valores Padrões' e selecionar um registro de lista destino desejada. Você pode também usar a importação 'Somente Atualizar' ou 'Criar & Atualizar' para adicionar destinos existentes a uma lista destino.
diff --git a/i18n/pt_BR/administration/installation.md b/i18n/pt_BR/administration/installation.md
deleted file mode 100644
index 2c401f3c4..000000000
--- a/i18n/pt_BR/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Instalação
-
-### Requisitos
-EspoCRM é executado na maioria dos fornecedores de hospedagem. Os requisitos são os seguintes:
-
-* PHP 5.6 ou versão mais recente de PHO com pdo habilitado, json, biblioteca GD, extensões mcrypt (normalmente habilitado por padrão);
-* MySQL 5.5.3 ou mais recente.
-
-Veja o artigo [Configurações do Servidor](server-configuration.md) para mais informações.
-
-### 1. Baixe o pacote de instalação do EspoCRM
-Para baixar a última versão do EspoCRM, acesso o link [página de download](http://www.espocrm.com/download/)
-
-### 2. Faça o upload dos arquivos do EspoCRM para Seu Servidor.
-
-Uma vez que o download esteja concluído, faça o upload do pacote para seu servidor de web.
-Para fazer o upload você pode usar SSH, FTP ou o painel de administração da hospedagem.
-Extraia os arquivos para o diretório de seu servidor de web público (ex: `public_html`, `www`, etc.).
-
-_Nota: Para FTP, você precisará extrair os arquivos antes de fazer o upload para seu servidor de web._
-
-### 3. Criar um Banco de Dados MySQL para o EspoCRM usar
-
-Vá para o painel de administração da hospedagem, ou para o SSH, e crie um novo banco de dados e um usuário para o EspoCRM (ex: 'Banco de Dados MySQL' no cPanel).
-
-### 4. Execute o processo de instalação do EspoCRM.
-
-Agora, abra seu navegador e vá para a URL com os arquivos do EspoCRM (ex: 'http://seudominio.com/espo`).
-
-Se você ver essa tela, você teve um erro "Permissão negada".
-Logo, você precisa executar o comando mostrado no terminal através de SSH, ou definir as permissões corretas.
-Deveria ser 755 para diretórios, 644 para arquivos, e 755 para o diretório 'dados'.
-Além disso, tenha certeza que você tem o _proprietário_ e o _grupo_ corretos.
-
-
-
-Se você ver a tela seguinte, o problema com a permissão foi resolvido e você pode começar a instalação do EspoCRM.
-
-
-
-Nessa página, você pode ler e aceitar os Termos de Uso.
-
-
-
-Digite os detalhes para seu recém-criado banco de dados MySQL.
-
-
-
-Digite o seu nome de usuário e senha de Administrador EspoCRM.
-
-
-
-Nessa página você pode definir as configurações padrões do EspoCRM, como formato de data e hora, fuso horário, moeda e outros.
-
-
-
-Digite as configurações SMTP para a saída de emails, se você deseja que seja possível o envio de emails.
-Esse passo pode ser pulado ao clicar no botão _Próximo_.
-Todas essas opções podem ser adicionadas/modificadas no EspoCRM após a instalação.
-
-
-
-Parabéns! A instalação foi finalizada.
-O último item é configurar as Tarefas Agendadas para serem executadas pelo seu sistema. Isso pode ser feito através da execução 'crontab -e' em linux cli e em _Agendador de Tarefas do Windows_ nos sistemas Windows.
-
-
-
-Nós esperamos que você fique satisfeito ao trabalhar com o EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/pt_BR/administration/layout-manager.md b/i18n/pt_BR/administration/layout-manager.md
deleted file mode 100644
index 876fcebfd..000000000
--- a/i18n/pt_BR/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Gerenciador de Layout
-
-O Gerenciador de Layout está disponível no painel de administração. Ele permite personalizar a aparência de detalhes, editar, listas de visualização assim como filtros de pesquisas e campos para formulário de atualizações em massa.
-
-## Listas
-
-O layout principal para a lista de visualização. Define as colunas e seus parâmetros.
-
-
-
-Os parâmetros disponíveis para colunas estão listadas abaixo.
-
-### Largura (%)
-
-A largura da coluna em percentagem, vazio significa largura automática.
-
-### Link
-
-Se marcado, o campo será mostrado como um link para a visualização de detalhes dos registros. Normalmente usado para nomes dos campos.
-
-### Não Organizável
-
-Desabilita a capacidade de organizar as colunas.
-
-### Alinhamento
-
-Alinha a coluna à esquerda ou à direita.
-
-## Detalhes
-
-O layout principal para a visualização de detalhes e editar visualização. Formata painéis, linhas e células. Células contêm campos.
-
-As linhas podem conter duas células ou uma células que está expandida à largura máxima da linha. Para adicionar linhas com uma célula expandida, você precisa adicionar a nova linha e clicar no sinal de menos em qualquer célula.
-
-
-
-## Lista (Pequena)
-
-O layout de lista para painéis de relacionamentos. Também pode ser usado em outros locais onde é aceitável mostrar listas em uma visualização estreita.
-
-## Detalhes (Pequeno)
-
-A visualização de detalhes para criar rapidamente, ver rapidamente ou editar rapidamente os fomulários.
-
-## Filtros de Pesquisa
-
-A lista de campos disponíveis na visualização de lista para serem pesquisados.
-
-## Atualização em Massa
-
-A lista de campos disponíveis no fomulário de Atualização em Massa.
-
-## Painéis de Relacionamento
-
-A lista de painéis de relacionamentos mostrada na visualização detalhada na parte inferior. Painéis podem ser reordenados. É possível definir as cores dos painéis com o parâmetro Estilo.
-
-## Painéis Laterais
-
-Painéis laterais para Detalhes, Editar, Detalhes Menor, Editar Menor. Dá a capacidade de esconde ou reordenar painéis em lista como: Atividades, Histórico, Tarefas e outros. Painéis podem ser coloridos pelo parâmetro Estilo.
-
-## Layouts Adicionais
-
-Alguns tipos de entidades contém layouts adicionais: Converter Condução, Lista para Conta.
diff --git a/i18n/pt_BR/administration/ldap-authorization-for-ad.md b/i18n/pt_BR/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index 8f65ec147..000000000
--- a/i18n/pt_BR/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Autorização LDAP para Active Directory
-
-Exemplo de configuração de autorização LDAP para o servidor do Active Directory. O guia completo de configuração de configuração LDAP está descrito [aqui](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/pt_BR/administration/ldap-authorization-for-openldap.md b/i18n/pt_BR/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 96f83e70c..000000000
--- a/i18n/pt_BR/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Autorização LDAP para OpenLDAP
-
-Exemplo de configuração de autorização LDAP para servidor OpenLDAP. O guia completo de configuração de configuração LDAP está descrito [aqui](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/pt_BR/administration/ldap-authorization.md b/i18n/pt_BR/administration/ldap-authorization.md
deleted file mode 100644
index 00633dcd5..000000000
--- a/i18n/pt_BR/administration/ldap-authorization.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Autorização LDAP
-
-Nesse guia, nós vamos mostrar como configurar a autorização LDAP para EspoCRM. Vamos lá.
-
-Vá para seu servidor LDAP e crie uma base DN para os usuários EspoCRM como a seguinte:
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Nós temos que criar um usuário para o sistema que vai ter acesso aos usuários DN (“cn=espo-users,ou=users,dc=espo,dc=local”). Sendo assim, o DN completo para esse usuário do sistema será
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Agora, nós podemos adicionar o usuário LDAP para acessar o EspoCRM. Ex: Teste de Espo com o usuário 'teste' dentro do “cn=espo-users,ou=users,dc=espo,dc=local” DN. Por favor, note que: para ser capaz de usar esse formato de login para o EspoCRM, você deve especificar as opções para o "Atributo Nome de Usuário" e para "Base DN".
-
-Então, vá até as configurações da Autenticação EspoCRM no painel Administrador, selecione o método 'LDAP' e preencha os detalhes no LDAP:
-
-
-
-* Host – LDAP IP ou nome da hospedagem.
-* Port – porta de conexão.
-* Auth – credenciais de acesso para o servidor LDAP:
- * Full User DN – o usuário DN do sistema completo que vai permitir pesquisar por outros usuários.
- * Password – a senha de acesso para o servidor LDAP.
-* Security – protocolo SSL ou TSL.
-* Username Attribute – o atributo para identificar o usuário. Para o Active Directory, ele pode ser “userPrincipalName” ou “sAMAccountName”.
-* Account Canonical Form – tipo de sua conta em formulário canônico. Existem 4 opções:
- * Dn – o formulário no formato `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – o formulário 'teste'.
- * Backslash – o formulário `COMPANHIA\teste`.
- * Principal – o formulário `teste@companhia.com`.
-* Bind Requires Dn – se for necessário formatar o nome de usuário no formulário DN.
-* Base Dn – a base DN padrão usada para pesquisas de usuários.
-* User Login Filter – o filtro que permite restringir usuários que são capazes de usar o EspoCRM. Ex: `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – O domínio em que a autorização do servidor LDAP está sendo usada.
-* Account Domain Name Short – O domínio curto em que a autorização do servidor LDAP está sendo usada.
-* Try Username Split – a opção para separar um nome de usuário com o domínio
-* Opt Referrals – se referidos devem ser seguidos até o cliente LDAP..
-* Create User in EspoCRM – essa opção permite o EspoCRM criar um usuário do LDAP.
- * User First Name Attribute – atributo LDAP que é usado para determinar o primeiro nome do usuário.
- * User Last Name Attribute – atributo LDAP que é usado para determinar o último nome do usuário.
- * User Title Attribute – atributo do LDAP que é usado para determinar o título do usuário.
- * User Email Address Attribute – atributo LDAP que é usado para determinar endereço de email do usuário.
- * User Phone Number Attribute – atributo LDAP que é usado para determinar o número de telefone do usuário.
-
-Agora, vá para a página de login e digite as credenciais do usuário.
-
-
-
-O usuário foi autenticado e automaticamente criado no EspoCRM.
-
-## Instruções de configuração baseadas em seu servidor:
-* [Servidor Active Directory](ldap-authorization-for-ad.md)
-* [Servidor OpenLDAP](ldap-authorization-for-openldap.md)
-
-Para mais informações sobre como configurar LDAP podem ser lidas na página da [biblioteca Zend\Ldap](https://zendframework.github.io/zend-ldap/intro/), visto que EspoCRM usa essa biblioteca.
-
-
-
-
diff --git a/i18n/pt_BR/administration/maps.md b/i18n/pt_BR/administration/maps.md
deleted file mode 100644
index ff81c8043..000000000
--- a/i18n/pt_BR/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Mapas
-
-## Como mostrar o mapa baseado em seu campo endereço
-
-Cada campo Endereço tem seu campo Mapa correspondente. Tudo o que você precisa fazer é colocá-lo no layout Detalhes. Ele usa o serviço do Google Maps.
-
-`Administração > Gerenciador de Layout > Escolher entidade (Conta, Contato, Condução ou personalizado) > Detalhes > Arrastar & Soltar o campo Mapa.`
-
-Faça a célula larga usando o sinal de menos.
-
-Você pode também configurar a altura do seu campo.
-
-`Administração > Gerenciador de Entidade > Escolher entidade > Campos > ache o campo mapa e clique nele > edite a altura e salve.`
-
-## Chave de API
-
-Desde a versão 4.2.0 do EspoCRM, você precisa especificar uma Chave de API para usar Google Maps (Administração > Integração > Google Maps).
-
diff --git a/i18n/pt_BR/administration/moving-to-another-server.md b/i18n/pt_BR/administration/moving-to-another-server.md
deleted file mode 100644
index 8c8ab5391..000000000
--- a/i18n/pt_BR/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Movendo o EspoCRM para outro servidor
-
-Sigua esses passos para mover o EspoCRM para outro servidor:
-
-### Passo 1. Cópia de segurança dos arquivos
-
-Abra um gerenciador de arquivos ou faça login através de SSH para arquivar todos os arquivos disponíveis do diretório EspoCRM. Para mais detalhes: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### Passo 2. Faça uma cópia de segurança de seu banco de dados
-
-Os dados guardados no banco de dados (MySQL, MariaDB) devem ser salvos em uma cópia de segurança. Por favor, siga essa recomendação: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### Passo 3. Copie os arquivos e cópias de segurança dos bancos de dados para outro servidor
-
-Copie os arquivos da cópia de segurança e seu banco de dados para um novo servidor.
-
-### Passo 4. Extraia os arquivos da cópia de segurança
-
-Para extrair os arquivos da cópia de segurança, você pode usar o Gerenciador de Arquivos ou essas intruções: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-Nota: Os arquivos precisam ser colocados no diretório do servidor da web.
-
-### Passo 5. Configure um servidor
-
-Configure um novo servidor baseado nas recomendações aqui: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### Passo 6. Corrija as permissões
-
-Defina as permissões requeridas e proprietários dos arquivos, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### Passo 7. Importe a sua cópia de segurança do banco de dados
-
-Primeiro, você deve criar um novo banco de dados com um usuário no MySQL. Para importar seu banco de dados da cópia de segurança, siga as instruções: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### Passo 8. Corrija as configurações do EspoCRM
-
-Após importar com sucesso e configurar o servidor, por favor, corrija as configurações do EspoCRM no arquivo `ESPOCRM_DIRECTORY/data/config.php`:
-
- * configurações de conexão do banco de dados:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'NOME_DO_BANCO_DE_DADOS',
- 'user' => 'SEU_USUÁRIO',
- 'password' => 'SENHA_DO_BANCO_DE_DADOS',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - se o nome de seu domínio (URL) mudou:
-
- ```php
- 'siteUrl' => 'https://novo-link.com',
- ```
-
- * proprietário padrão dos arquivos (somente se há diferença):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- onde `www-data` é seu usuário do servidor da web.
-
-### Passo 9. Configure um crontab
-
-Configure um crontab, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-Nota: ele deveria ser configurado pelo usuário do servidor da web.
-
-Isso é tudo. Agora sua instância do EspoCRM está sendo executada em um novo servidor.
diff --git a/i18n/pt_BR/administration/nginx-server-configuration.md b/i18n/pt_BR/administration/nginx-server-configuration.md
deleted file mode 100644
index 1c5037280..000000000
--- a/i18n/pt_BR/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Configuração de servidor Nginx para EspoCRM
-
-Essas instruções são suplementares às orientações [Configuração do Servidor](server-configuration.md). Por favor, note que todas as configurações listadas aqui são feitas em servidor Ubuntu.
-
-## Requerimentos de PHP
-
-Para instalar todas as bibliotecas necessárias, execute esses comandos em um terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Reparando o erro “API Error: EspoCRM API is unavailable”:
-
-Siga apenas os passos necessários. Após cada passo, verifique se o problema foi resolvido.
-
-### 1. Habilite sobrescrever regras no servidor Nginx
-
-Adicione esse código para o arquivo de configuração do bloco de seu servidor Nginx (/etc/nginx/sites-available/SEU_SITE) dentro do bloco “server”:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Se você não possui esse arquivo, você deve criá-lo. Para isso, abra um terminal e execute o comando:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Adicione o código listado acima. Para mais informações em como configurar um novo Virtual Host em Nginx, por favor, leia esse [guia](nginx-virtual-host.md).
-
-Execute esse comando em um terminal para verificar se tudo está bem:
-
-```
-sudo nginx -t
-```
-
-Se estiver, execute o comando para reinicializar o servidor Nginx:
-
-```
-sudo service nginx restart
-```
-
-### 2. Adicionar o caminho RewriteBase
-
-Abrir um arquivo /ESPOCRM_DIRECTORY/api/v1/.htaccess e substituir a seguinte linha:
-
-```
-# RewriteBase /
-```
-por
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-onde, REQUEST_URI é uma parte de uma URL, por exemplo, para “http://exemplo.com/espocrm/”, REQUEST_URI é “espocrm”.
diff --git a/i18n/pt_BR/administration/nginx-virtual-host.md b/i18n/pt_BR/administration/nginx-virtual-host.md
deleted file mode 100644
index cc5ff2ff6..000000000
--- a/i18n/pt_BR/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Configurando um Host Virtual em Nginx para EspoCRM
-
-Nesse guia, nós vamos mostrar como configurar um host virtual em Nginx para EspoCRM em servidor Ubuntu.
-
-## Crie um arquivo de bloco do servidor
-
-Para criar esse arquivo, abra o terminal e execute o comando:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Agora, abra esse arquivo (/etc/nginx/sites-available/espocrm.conf) e modifique o código seguindo o formato mostrado abaixo (algumas configurações podem ser diferentes baseadas na configuração do seu servidor):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Substitua espocrm.local pelo nome de seu domínio
- root /var/www/html/espocrm; # Especifique a raiz do documento de seu EspoCRM
-
- index index.php index.html index.htm;
-
- # Configuração SSL
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Especificar seu PHP (php-cgi or php-fpm) baseado em suas configurações
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # Com apenas o php7.0-cgi:
- # fastcgi_pass 127.0.0.1:9000;
-
- # Com o php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Adicionar sobrescrever regras
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Habilitar o bloco desse servidor
-
-Crie uma ligação simbólica:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Execute esse comando para verificar se tudo está certo:
-
-```
-sudo nginx -t
-```
-
-E reinicialize o servidor Nginx:
-
-```
-sudo service nginx restart
-```
-
-## Configure seus hosts locais (opcional, somente para um domínio local)
-
-Se você adicionou um domínio local, você deve configurá-lo em seu computador local (não no servidor). Para Ubuntu, abra o arquivo `/etc/hosts` e adicione essa linha:
-
-```
-192.168.1.1 espocrm.local # especifique o endereço de IP do seu servidor Nginx
-```
-
-Para Windows, por favor, siga essas [instruções](http://support.microsoft.com/kb/923947).
diff --git a/i18n/pt_BR/administration/portal.md b/i18n/pt_BR/administration/portal.md
deleted file mode 100644
index 5daaedd6f..000000000
--- a/i18n/pt_BR/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Portal
-
-Portal fornece uma capacidade de acessar dados de crm e funções específicas para seus clientes e parceiros. O Administrador pode criar múltiplos portais. Cada portal pode ter suas próprias configurações, painel de controle, lista de usuários, configurações de controle de acesso.
-
-Para criar um portal vá em: Administração > Portais, clique no botão Criar Portal.
-
-* `Está Ativo`. Se não for marcado, o portal não estará disponível para ninguém.
-* `É Padrão`. Significa que o portal estará disponível através de uma URL mais curta: http(s)://SUA_ESPO_URL/portal.
-* `Funções`. Especifique um ou múltiplas funções do portal que serão aplicados aos usuários logados no portal. Mais informações sobre funções do portal estão abaixo.
-* `Lista de Abas`. Abas que serão mostradas na barra de navegação.
-* `Layout do Painel de Controle`. Especifica dashlets que serão mostradas na página inicial do portal. Note que os usuários do portal não podem configurar o painel de controle deles.
-* `URL`. Campo somente leitura que mostra o link pelo qual você pode acessar o portal.
-
-## Usuários do Portal
-
-Administradores podem criar usuários do portal.
-
-1. Administração > Usuários
-2. Clique no menu suspenso à direita próximo a Criar Usuário.
-3. Clique em Criar Usuário do Portal.
-4. Selecione o contato em que o usuário do portal vai estar ligado.
-5. Preencha o formulário e clique em salvar.
-
-O usuário do portal deve estar ligado ao registro do Portal para ser capaz de acessar aquele portal.
-
-## Funções do Portal
-
-As funções do portal são similares à funções regulares no EspoCRM, mas com algumas distinções
-
-* o nível `não-definido` nega um acesso.
-* o nível `próprio` significa que o registro é criado pelo usuário. Ex: o usuário do portal empacotou um caso e esse caso é propriedade desse usuário.
-* o nível `conta` significa que o registro está relacionado à conta que o usuário do portal está relacionado.
-* o nível 'contato' significa que aquele registro está relacionado ao contato que usuário do portal está relacionado.
-
-Os campos Usuário Designado e Times são somente leitura para usuários do portal.
-
-### Exemplo
-
-`Os usuários do portal devem ser capazes de criar casos, ver casos relacionados à conta deles; eles devem ser capazes de ver a base de conhecimentos.`
-
-1. Abra o fomulário Criar Função do Portal (Administração > Funções do Portal > Criar Função).
-2. Habilitar acesso aos Casos, defina: `criar - sim, ler - conta, editar - não, apagar - não, transmitir - conta`.
-3. Habilitar acesso à Base de Conhecimentos, defina: `criar - não, ler - conta, editar - não, apagar - não`.
-4. Editar seu registro no portal (Administração > Portais). Selecione a função de seu portal no campo Funções e então salve.
-
-## Acesso ao Portal
-
-Você pode encontrar a URL para seu portal no campo 'URL' no registro do portal. Também é possível usar as ferramentas de configuração do servidor (como mod_rewrite) para ser capaz de acessar através de uma URL diferente. Nesse caso, você precisa preencher o campo 'URL Personalizada'.
-
-### Acessar o portal através de uma URL Personalizada para servidor Apache
-
-URL Personalizada: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Regras de sobrescrita mod
-
-Especifique o ID do registro do portal em vez de `{PORTAL_ID}`. O ID do registro do portal está disponível na barra de endereços de seu navegador quando você abre a visualização detalhada do registro do portal. Como em: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 é um ID de registro do portal.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/pt_BR/administration/roles-management.md b/i18n/pt_BR/administration/roles-management.md
deleted file mode 100644
index e06854d3e..000000000
--- a/i18n/pt_BR/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Gerenciamento de Funções
-
-## Panorama
-
-Para restringir o acesso de alguns usuários, você precisa usar as Funções. O administrador pode gerenciar as funções no painel de administração. Cara função define um acesso a certas áreas (escopo) que é aplicada a usuários que possuem aquela função.
-
-Um usuário pode ter várias funções. Essas funções podem ser selecionadas para um usuário em específico (campo 'Funções' na entidade Usuário) e/ou ser herdada de times que o usuário faz parte.
-
-Se um usuário tem várias funções, elas serão unidas de forma que as regras permissivas tenham maior prioridade. Isso permite ao administrador gerenciar o controle do nível de acesso facilmente e flexivelmente.
-
-É possível ver o quais permissões estão aplicadas a certos usuários ao clicar no botão 'Acesso' na vista detalhada do usuário.
-
-
-
-## Exemplo
-
-Por exemplo, o usuário pertence ao time 'Vendas'. Esse time tem uma única função 'Vendedor'. Então todos os usuários desse time obterão a função 'Vendedor'.
-
-A função 'Vendedor' está definida da seguinte forma:
-
-Condução:
-```
-criar - sim
-ler – time
-editar – próprio
-apagar – não
-transmitir - time
-```
-
-Oportunidade:
-```
-criar - sim
-ler – time
-editar – próprio
-apagar – não
-transmitir - time
-```
-
-Os usuários irão ser capazes de ler somente as conduções e oportunidade que pertencem ao time 'Departamento de Vendas' (campo 'Times').
-O usuário será capaz de editar somente aquelas conduções e oportunidades que eles são designados ou aqueles que eles criaram.
-Os usuários não serão capazes de remover quaisquer conduções ou oportunidades.
-
-Nós querendo dar mais direitos para certo usuário que está no cargo de gerente de vendas na companhia. Esse empregado deve ter uma capacidade de ler/editar/apagar todos os registros do time 'Vendas'. O usuário deveria pertencer ao nosso time 'Vendas'. Mas nós precisamos criar uma nova função 'Gerente de Vendas' e selecionar essa função para aquele usuário no campo 'Funções'.
-
-A função 'Gerente de Vendas' está definida da seguinte forma:
-
-Condução:
-```
-criar - sim
-ler – time
-editar – time
-apagar – time
-transmitir - time
-```
-
-Oportunidade:
-```
-criar - sim
-ler – time
-editar – time
-apagar – time
-transmitir - time
-```
-
-Nosso usuário será capaz de gerenciar todas as conduções e oportunidades do time 'Vendas'.
-
-## Permissões Especiais
-
-### Atribuição de Permissões
-
-Defina esse parâmetro para restringir a habilidade de reatribuir registros para outro usuário e/ou times. Se você definir 'time' - então será possível atribuir somente a usuários do próprio time(s). Se 'não' - os usuários não serão capazes de reatribuir de qualquer forma.
-
-Isso também define se o usuário é capaz de transmitir uma publicação para outros usuários/times.
-
-### Permissões de Usuários
-
-Permite restringir uma capacidade do usuário de ver atividades, calendário e transmissões de outros usuários.
-
-### Permissão de Portal
-
-Define um acesso para a informação portal, capacidade de publicar mensagens para usuários do portal.
-
-### Permissão para a Conta de Email do Grupo
-
-Define um acesso para as contas de email do grupo, uma capacidade de enviar emails do SMTP do grupo.
-
-### Exportar Permissão
-
-Define se o usuário tem uma capacidade de exportar registros. (desde a versão 4.9.0)
-
-## Permissões Padrões
-
-Por padrão (se não houver qualquer uma aplicada), os usuários podem ler e editar todos os registros. Mas não podem apagar nenhum deles, exceto aqueles que eles mesmos criaram e são atribuídos a eles ao mesmo tempo.
-
-Existe uma capacidade de restringir um acesso aplicado por padrão ao habilitar o 'Modo Estrito ACL' em Administração > Configurações.
-
-## Segurança ao Nível do Campo
-
-Permite controlar um acesso para campos específicos.
-
-Por padrão, o usuário pode ler todos os campos se ele puder ler o registro. O usuário pode editar qualquer campo se ele puder editar o registro. Você pode restringir o acesso a campos específicos usando a Segurança ao Nível do Campo.
-
-Na visualização da edição de um registro de função na sessão Nível do Campo, clique no ícone 'mais' próximo ao escopo específico, então selecione o campo desejado. Então você será capaz de especificar o nível de acesso para as ações 'ler' e 'editar'. Há duas opções: 'sim' e 'não'.
-
-
diff --git a/i18n/pt_BR/administration/server-configuration.md b/i18n/pt_BR/administration/server-configuration.md
deleted file mode 100644
index 6e7985f20..000000000
--- a/i18n/pt_BR/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Configuração de Servidor para EspoCRM
-
-EspoCRM pode ser instalado no Apache ([instruções](apache-server-configuration.md)), Nginx ([instruções](nginx-server-configuration.md)), ou servidor IIS com suporte para PHP versão 5.6 ou superior e MySQL versão 5.1 ou superior.
-
-## Recomendações de Configuração
-
-### Requisitos PHP
-
-EspoCRM requer PHP versão 5.6 ou superior, com as seguintes extensões habilitadas:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – para acessar MySQL em PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – os recursos usam este formato (metadados, layout, idiomas, e outros);
-* [GD](http://php.net/manual/en/book.image.php) – para manipular imagens;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – para garantir o maior nível de proteção;
-* [Zip](http://php.net/manual/en/book.zip.php) – para ser capaz de atualizar o EspoCRM e instalar extensões;
-* [IMAP](http://php.net/manual/en/book.imap.php) – para monitorar caixas de correspondência no EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Também é recomendado ter a extensão pecl [mailparse](https://pecl.php.net/package/mailparse) instalada. É necessário para um trabalho fluído do recurso de busca de email
-
-configurações php.ini:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Requisitos MySQL
-
-EspoCRM suporta MySQL versão 5.1 ou superior.
-Esses não são peculiaridades especiais. Todas as configurações padrões são boas para o EspoCRM.
-
-## Permissões Requeridas para Sistemas Baseados em Unix
-
-Os arquivos e diretórios devem ter as seguintes permissões:
-
-* `/data`, `/custom`, `/client/custom` – devem poder modificar todos os arquivos, diretórios e subdiretórios (664 para arquivos, 775 para diretórios, incluindo todos os subdiretórios e arquivos);
-* `/application/Espo/Modules`, `/client/modules` – devem poder modificar o diretório atual (775 para o diretório atual, 644 para arquivos, 755 para diretórios e subdiretórios);
-* Todos os outros arquivos e diretórios devem poder serem lidos (644 para arquivos, 755 para diretórios).
-
-Para definir permissões, execute esses comandos no terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Todos os arquivos devem pertencer e grupo-pertencer ao processo do servidor de web. Ele pode ser “www-data”, “daemon”, “apache”, “www”, etc.
-Nota: No Bitnami Stack, os arquivos devem pertencer e grupo-pertencer ao usuário "daemon".
-Nota: Em hosts compartilhados, os arquivos devem pertencer e grupo-pertencer à conta de seu usuário.
-
-Para definir o proprietário e grupo-proprietário, execute esses comandos no terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## Configure um crontab
-
-Para configurar um crontab em um sistema UNIX, siga os seguintes passos:
-
-* 1. Faça login como um administrador em sua instância EspoCRM
-* 2. Vá para a sessão Trabalhos Agendados no painel de administrador (Menu > Administração > Trabalhos Agendados) e copie a sequência de caracteres para o crontab. Ela se parece com isso:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Abra um terminal e execute esse comando:
-```
-crontab -e -u USUARIO_SERVIDOR_DA_WEB
-```
-USUARIO_SERVIDOR_DA_WEB pode ser um dos seguintes “www”, “www-data”, “apache”, etc (dependendo do seu servidor da web).
-* 4. Cole a sequência de caracteres copiada (do passo 2) e salve o arquivo crontab (Ctrl+O, então Ctrl+X para o editor nano).
-
-## Instruções de configuração baseadas em seu servidor:
-
-* [Configuração em servidor Apache](apache-server-configuration.md).
-* [Configuração em servidor Nginx](nginx-server-configuration.md).
diff --git a/i18n/pt_BR/administration/troubleshooting.md b/i18n/pt_BR/administration/troubleshooting.md
deleted file mode 100644
index 85344fcf7..000000000
--- a/i18n/pt_BR/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Resolução de Problemas
-
-## Verificar logs
-
-Para achar o problemas, você deve verificar o arquivo do log de erros.
-
-#### Logs de erro do EspoCRM
-
-Os logs do EspoCRM estão localizados no `/logs/*.log` e contém algumas informações sobre erros.
-
-#### Logs de erro do Apache
-
-Para o servidor Ubuntu um log de erro apache está localizado em `/var/log/apache2/error.log` e contém todas as informações de erro. A localização dos arquivos de log podem ser diferentes em outros sistemas.
-
-## Habilitar modo de depuração
-
-Para habilitar o modo de depuração, vá para o diretório onde está instalado o EspoCRM, abra o arquivo `data/config.php` e mude o valor:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-para
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Tarefas Agendadas não estão funcionando
-
-#### Problema #1: Seu crontab não está configurado
-
-1. Faça login através do SSH para seu servidor.
-
-2. Configure seu crontab seguindo os seguintes passos: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-Nota: Crontab deve ser configurado por um usuário do servidor da web, ex: `crontab -e -u www-data`.
-
-3. Espere por um tempo e verifique os Trabalhos Agendados para ver se qualquer trabalho foi executado (veja um painel de Log).
-
-#### Problema #2. Crontab está configurado, mas os Trabalhos Agendados não estão funcionando
-
-Para ter certeza que não existem erros quando cron está sendo executado, tente executar o comando cron em um terminal:
-
-1. Faça login através do SSH para seu servidor.
-
-2. Vá para o diretório onde o EspoCRM está instalado. Ex: para o diretório `/var/www/html/espocrm` o comando é:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Execute o comando crontab::
-
-```bash
-php cron.php
-```
-
-Nota: Ele deve ser executado por um usuário do servidor da web. Se você está logado como root, o comando deve ser (ex: para Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-onde `www-data` é um usuário do servidor da web.
-
-4. Se não há erros, verifique os Trabalhos Agendados para ver se qualquer trabalho foi executado (ver um painel de Log).
-
-## EspoCRM não está carregando após updgare
-
-Isso pode acontecer algumas vezes em algumas hospedagens compartilhadas.
-
-Verifique os arquivos de permissões:
-/index.php
-/api/v1/index.php
-
-Eles devem ser 644. Se qualquer desses arquivos tem permissão 664, você precisa mudá-la para 644. Use seu painel de controle da hospedagem ou comando chmod.
-
-```
-chmod 644 /path/to/file
-```
-Mais informação sobre permissões de arquivos: [aqui](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/pt_BR/administration/upgrading.md b/i18n/pt_BR/administration/upgrading.md
deleted file mode 100644
index 852f1e713..000000000
--- a/i18n/pt_BR/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Como atualizar o EspoCRM
-
-O EspoCRM pode ser atualizado para sua última versão seguindo os seguintes passos:
-
-### Passo 1. Verifique sua versão atual
-
-Para verificar sua versão atual, vá para a página Administração > Atualizar.
-
-### Passo 2. Baixe os pacotes de atualizações necessários
-
-Vá para a página de atualização https://www.espocrm.com/download/upgrades/ e, baseado em sua versão atual, baixe os pacotes necessários.
-
-### Passo 3. Crie uma cópia de segurança (opcional)
-
-Crie uma cópia de segurança de seus arquivos do EspoCRM e dados antes de atualizar. Siga [essas instruções](https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md) para concluir esse processo.
-
-### Passo 4. Processo de atualização
-
-Vá para Administração > Atualizar. Faça o upload e instale os pacotes de atualizações um por um.
-
-Você pode verificar se you tem a última versão em Menu > Sobre.
-
-## Atualização através de CLI
-
-Você pode também executar a atualização através da interface da linha de comando. Você precisa executar os seguintes comandos do diretório raiz do EspoCRM:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/pt_BR/administration/workflows.md b/i18n/pt_BR/administration/workflows.md
deleted file mode 100644
index 99e1beb67..000000000
--- a/i18n/pt_BR/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Fluxos de Trabalho
-
-O recurso Fluxos de Trabalho está disponível em [Pacote Avançado](https://www.espocrm.com/extensions/advanced-pack/).
-
-Fluxos de Trabalho automatiza seus processos de negócios de uma forma fácil. Você pode achá-la no painel de Administração. Para criar uma regra de fluxos de trabalho, você precisa definir:
-
-* Entidade Alvo - a qual tipo de entidade o fluxos de trabalho é aplicado;
-* Tipo de Acionamento - quando o fluxo de trabalho será acionado;
-* Condições - condições precisam ser satisfeitas para acionar o fluxo de trabalho;
-* Ações - o que fazer se o fluxo de trabalho é acionado.
-
-
-## Tipos de Acionamentos
-
-### Após criar um registro
-
-Acionado apenas quando um novo registro é criado. Se as condições específicas forem satisfeitas, então as ações serão executadas.
-
-### Após salvar um registro
-
-Acionado quando um novo registro é criado ou um registro existente é atualizado. Se as condições específicas forem satisfeitas, então as ações serão executadas.
-
-Para as regras de fluxos de trabalho com esse tipo de acionamento, é uma prática comum ter uma condição que verifica se algum campo 'mudou'. Ex: Se o estado de Caso mudou, então execute algumas ações.
-
-### Agendamento
-
-Acionado de acordo com a agenda definida. Você pode configurá-lo para executar todo dia, toda semana, etc. Ações serão aplicadas para registros retornados por uma lista relatório especificada. Então você precisa também criar uma lista relatório.
-
-Agendar está especificado em uma notação crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Ano (amplitude: 1900-3000)
-| | | | +---- Dia da Semana (amplitude: 1-7, 1 significa Segunda-feira)
-| | | +------ Mês do Ano (amplitude: 1-12)
-| | +-------- Dia do Mês (amplitude: 1-31)
-| +---------- Hora (amplitude: 0-23)
-+------------ Minuto (amplitude: 0-59)
-```
-
-### Sequencial
-
-Raramente usado. Deveria ser executado por outro fluxo de trabalho. Gera uma capacidade de fazer uma lógica complexa.
-
-Nota: Para fluxos de trabalho sequenciais, é recomendado utilizar a [ferramenta BPM](bpm.md) em vez do recurso Fluxos de Trabalho.
-
-## Condições
-
-Você pode especificar condições que devem ser satisfeitas para acionar o fluxo de trabalho. Existem duas maneiras como as condições podem ser especificadas: com o construtor de condições UI e com fórmula.
-
-### Construtor de condições UI
-
-Alguns tipos de condições disponíveis:
-
-* _iguais_ - o campo é igual a um valor específico ou um valor de outro campo;
-* _era_igual_ - o campo era igual a um valor específico antes do fluxo de trabalho ser acionado;
-* _nao_igual_ - o campo não é igual a um valor específico ou um valor de outro campo;
-* _nao_era_igual_ - O campo não era igual a um valor específico antes do fluxo de trabalho ser acionado;
-* _vazio_ - o valor do campo está vazio;
-* _nao vazio_ - o valor do campo não está vazio;
-* _alterado_ - o campo foi alterado;
-* _nao alterado_ - o campo não foi alterado.
-
-### Condições para Fórmulas
-
-As fórmulas dão a capacidade de definir condições de qualquer complexidade. Para ler sobre a sintaxe de fórmulas, veja [esse artigo](formula.md).
-
-Nota: Não deve haver qualquer delimitador ';' usado no código da fórmula quando ela determina uma condição.
-
-## Ações
-
-### Enviar Email
-
-O sistema vai enviar um email usando um modelo de email específico. Um endereço de email do destinatário pode ser pego do registro visado, qualquer registro relacionado, do usuário atual, seguidores, time de usuários ou especificado. Os emails podem ser enviados imediatamente ou atrasados por um intervalo específico.
-
-### Criar Registro
-
-O sistema vai criar o novo registro de qualquer tipo de entidade. Se existe um relacionamento entre o registro alvo e o registro sendo criado, é possível relacionar os registros.
-
-Há uma capacidade para definir fórmula para calcular campos.
-
-### Criar Registro Relacionado
-
-O sistema vai criar o registro relacionado ao registro visado. É possível definir fórmula para calcular campos.
-
-### Atualizar Registro Alvo
-
-Permite alteração de um campo específico do registro visado. É possível definir fórmula para calcular campos.
-
-Se você precisa adicionar novos itens para o campo Link-Múltiplo sem perder os dados existentes (ex: Times), você precisa utilizar a função fórmula entity\addLinkMultipleId. Exemplo: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### Atualizar Registro Relacionado
-
-Permite alteração de campos específicos do registro ou registros relacionados. É possível definir fórmula para calcular campos.
-
-### Vincular com Outro Registro
-
-Relaciona a entidade visada com outra entidade específica. Ex: adiciona um time específico para o registro.
-
-### Desvincular com Outro Registro
-
-Acaba com a relação da entidade visada e outra entidade específica. Ex: remove um time específico do registro.
-
-### Aplicar Regra de Atribuição
-
-Atribui o registro alvo ao usuário pela função de distribuição. Existem duas regras disponíveis: Um-por-Turno e Menos-Ocupado.
-
-* Um-por-Turno - os usuários são escolhidos de uma lista (time) do início ao fim e então começa novamente.
-* Menos-Ocupado - o usuário que tem menos registros de atribuições será escolhido para a atribuição.
-
-_Lista Relatório_ - Para a distribuição Menos-Ocupado, determina quais registros serão levados em consideração para calcular o número de registros atribuídos. Ex: para os Casos nós precisamos pegar somente registros com o estado ativo.
-
-### Criar Notificação
-
-Notificar usuários específicos com a mensagem. É possível usar espaços reservados nas mensagens modelo: {entidade} - registro visado, {usuário} - usuário atual.
-
-### Fazer Seguido
-
-Força usuários específicos a seguir a entidade alvo ou uma entidade relacionada.
-
-### Acionar Outro Fluxo de Trabalho
-
-Permite fazer fluxos de trabalho sequenciais. É possível remificar fluxo de trabalho por condição: você pode configurar o fluxo de trabalho para acionar dois fluxos de trabalho com diferentes condições definidas naqueles fluxos de trabalho.
-
-É possível atrasar a execução de fluxo de trabalho sequencial. Em fluxo de trabalho sequencial, você pode definir a condição que verifica se campos específicos foram alterados desde o fluxo de trabalho superior foi acionado ao usar os tipos de condição _Alterado_ e _Era Igual_.
-
-Nota: Para fluxos de trabalho sequenciais, é recomendado utilizar a [ferramenta BPM](bpm.md) em vez do recurso Fluxos de Trabalho.
-
-### Execute a Ação de Serviço
-
-Permite executar scripts de serviços específicos. Por padrão existem as seguintes ações disponíveis:
-
-* Mandar Convite - para Reuniões/Chamadas;
-* Adicionar Itens Citados - para Citações.
-
-Os desenvolvedores podem escrever suas próprias ações de serviço. Veja [mais detalhes](../development/workflow-service-actions.md).
-
-## Usando Fórmula em Ações
-
-É possível definir fórmula para calcular campos para Criar Registro, Atualizar Registro Alvo, Criar Registro Relacionado, Atualizar Registro Relacionado. Para os últimos dois, para acessar os atributos da entidade alvo, você deve usar a função `targetEntity\attribute`. Para acessar atributos da entidade alvo que foi definida antes do fluxo de trabalho, `targetEntity\attributeFetched`.
-
-Exemplo:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/pt_BR/development/api.md b/i18n/pt_BR/development/api.md
deleted file mode 100644
index 67443c23f..000000000
--- a/i18n/pt_BR/development/api.md
+++ /dev/null
@@ -1,220 +0,0 @@
-# REST API
-
-EspoCRM é um aplicativo de página única para que um frontend use a API REST para se conectar a um backend.
-Todas as operações que você executa usando UI você pode implementar através de chamadas de API usando seu idioma de programação.
-Você pode aprender como funciona a API se você rastrear o que está acontecendo na guia de rede no console do navegador.
-
-A maioria das funções api retorna JSON. As chamadas POST, PATCH geralmente precisam de alguns dados JSON na carga útil.
-
-O URL básico da API EspoCRM é: `api/v1/`. Você precisa compará-lo com as expressões nesta referência. Exemplo:
-
-`OBTER http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Autenticação
-
-A API do EspoCRM usa [Autenticação Básica](http://en.wikipedia.org/wiki/Basic_access_authentication). Nome de usuário e senha/token são passados pelo cabeçalho 'Autorização' codificado em base64.
-
-`"Autorização: Básico " + base64Encode(usuário + ':' + senha)`
-
-É melhor usar o token de autenticação em vez da senha quando você trabalha com api. Neste caso, você precisará fornecer nome de usuário e senha/token no cabeçalho `Espo-Autorization`.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-1. Obter token de acesso pela solicitação 'OBTER App/usuário' com nome de usuário e senha passados no cabeçalho `Espo-Autorization`.
-2. Use este token em vez de senha no cabeçalho `Espo-Authorization` para todas as solicitações adicionais.
-3. Se o erro do pedido retornar 403 significa que o nome de usuário/senha é errado ou o token já não é válido.
-
-#### Token de Autenticação / Dados Específicos do Usuário
-
-`OBTER App/usuário`
-
-Retorna:
-
-* `token` - token de acesso para usar;
-* `acl` - informações sobre acesso de usuários;
-* `preferências` - preferências de usuário;
-* `usuário` - atributos de registro de usuário.
-
-
-## CRUD Operações
-
-#### Entidades de Lista
-
-`OBTER {entidadeTipo}`
-
-OBTER parâmetros:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-* `onde` - (array) filtros;
-* `sortBy` - (string) campo para classificar por;
-* `asc` - (bool) direção de classificação.
-
-_Exemplo_
-`OBTER Conta?offset=0&maxSize=20``
-
-Retorna:
-```
-{
- "lista": [... variedade de registros...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Ler Entidade
-
-`OBTER {entidadeTipo}/{id}`
-
-Retorna atributos no objeto JSON.
-
-_Exemplo_
-
-`OBTER Conta/5564764442a6d024c`
-
-#### Criar Entidade
-
-`POST {entidadeTipo}`
-
-Carga útil: atributos de objeto de entidade.
-
-Retorna os atributos da entidade no objeto JSON.
-
-_Exemplo_
-
-`POST Conta`
-
-Carga útil:
-```
-{
- "nome": "Teste",
- "assignedUserId": "1"
-}
-```
-
-#### Entidade de atualização
-
-`REMENDO {entityType}/{id}`
-
-ou
-
-`COLOCAR {entidadeTipo}/{id}`
-
-Carga útil: os atributos do objeto de entidade precisam ser alterados.
-
-Retorna atributos no objeto JSON.
-
-_Exemplo_
-
-`REMENDO Conta/5564764442a6d024c`
-
-Carga útil:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Eliminar Entidade
-
-`Eliminar {entidadeTipo}/{id}`
-
-_Exemplo_
-
-`ELIMINAR Conta/5564764442a6d024c`
-
-
-## Entidades Relacionadas
-
-#### Entidades Relacionadas à Lista
-
-`OBTER {entidadeTipo}/{id}/{link}`
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-* `onde` - (array) filtros;
-* `ordenarPor` - (string) campo para classificar por;
-* `asc` - (bool) direção de classificação.
-
-_Exemplo_
-
-`OBTER Conta/5564764442a6d024c/oportunidades`
-
-Retorna:
-```
-{
- "lista": [... variedade de registros...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Link Entidade
-
-`POST {entidadeTipo}/{id}/{link}`
-
-Carga útil:
-
-1. `id` atributo.
-2. `ids` atributo de matriz.
-3. `"massRelate": verdade` e `"onde": {...}` relacionar registros múltiplos por critérios de pesquisa.
-
-_Exemplo_
-
-`POST Conta/5564764442a6d024c/oportunidades`
-
-Carga útil:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Entidade Desvinculada
-
-`EXCLUIR {entidadeTipo}/{id}/{link}`
-
-Carga útil:
-
-1. JSON with `id` attribute.
-2. JSON with `ids` array attribute.
-
-_Exemplo_
-
-`EXCLUIR Conta/5564764442a6d024c/oportunidades`
-
-Carga útil:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-## Stream
-
-#### Lista de entradas de Stream luxo para o usuário atual
-
-`OBTER Stream`
-
-OBTER parâmetros:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-
-#### Lista de entradas de Stream relacionadas a uma gravação específica
-
-`OBTER {entidadeTipo}/{id}/stream`
-
-OBTER parâmetros:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-
-#### Acompanhe o registro
-
-`COLOCA {entidadeTipo}/{id}/inscrição`
-
-#### Desativar registro
-
-`ELIMINAR {entidadeTipo}/{id}/inscrição`
-
-
-
diff --git a/i18n/pt_BR/development/custom-field-type.md b/i18n/pt_BR/development/custom-field-type.md
deleted file mode 100644
index eb131f465..000000000
--- a/i18n/pt_BR/development/custom-field-type.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Criando tipo de campo personalizado
-
-### Definição de campo
-
-Criar um arquivo `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` com os parâmetros necessários.
-```
-{
- "visão": "personalizado:visão/campos/{campo-tipo}"`
-}
-```
-
-Utilize os tipos de campo fora da caixa como exemplos: `/aplicação/Espo/Recursos/metadata/campos`.
-
-### Tradução
-
-O rótulo é usado no Gerenciador de Entidade pode ser configurado em `personalizado/Espo/personalizado/Recursos/i18n/en_US/Admin.json` na seção `camposTipos
-Se você precisar adicionar tradução para outro idioma, use o idioma necessário [código de idioma](https://en.wikipedia.org/wiki/ISO_639-1)_[código do país](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) ao invés de`en_US`. Na `data/config.php` Na seção `languageList` você pode encontrar a lista de idiomas incluídos.
-
-### Visão
-
-Crie a vista para o campo `cliente/personalizado/src/visão/campos/{campo-tipo}.js` e define seus modelos
-```
-Espo.define('personalizado:visão/campos/[campo-tipo]', 'visão/campos/base', função (Dep) {
-
- retorna Dep.extend({
-
- });
-});
-```
-
-Use exemplos de tipos de campo excluídos:
-- `/cliente/src/visão/campos` - visão;
-- `/cliente/res/modelos/campos` - modelos.
-
-Então você precisa executar a reconstrução no painel de administração.
diff --git a/i18n/pt_BR/development/custom-views.md b/i18n/pt_BR/development/custom-views.md
deleted file mode 100644
index 35be272f8..000000000
--- a/i18n/pt_BR/development/custom-views.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Visualizações personalizadas
-
-## Registro de Visualizações
-
-O framework EspoCRM oferece habilidades flexíveis para definir visualizações personalizadas para determinados tipos de entidades. Eles devem ser definidos como categoria de metadados `clientDefs`.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-A exibição de registro/detalhe contém todos os painéis com campos, relações e outros dados que você pode ver na visualização detalhada. Não contém cabeçalho e botões no canto superior direito.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Aqui está o seu modelo personalizado. Omita se você não precisa disso.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Aqui está a sua visão personalizada. Omita se você não precisa disso.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Aqui está a sua visão personalizada. Omita se você não precisa disso.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Aqui está a sua visão personalizada. Omita se você não precisa disso.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Aqui está a lógica de inicialização personalizada. Como ligar ouvindo mudanças no modelo.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Código personalizado a ser invocado logo após a renderização, quando DOM estiver disponível.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-Você pode criar um modelo personalizado com o seguinte caminho:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-A exibição de detalhes contém exibição de Registro/Detalhe e cabeçalho.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-O mesmo que o detalhe, mas é usado quando o registro está sendo criado ou editado não no modo de edição inline.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-A exibição de lista contém exibição de Registro/Lista, cabeçalho e formulário de pesquisa.
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-A exibição Lista/Registro contém linhas de registros.
-
-
-Vale a pena mencionar que você precisa herdar sua classe de visualização de uma classe específica para sua entidade se já existe.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Visualizações de Campo
-
-As visualizações personalizadas para campos específicos devem ser especificadas na seção entityDefs dos metadados.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
diff --git a/i18n/pt_BR/development/dynamic-forms.md b/i18n/pt_BR/development/dynamic-forms.md
deleted file mode 100644
index 17893a070..000000000
--- a/i18n/pt_BR/development/dynamic-forms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Formulários Dinâmicos
-
-Nota: desde a versão 4.3.0, é possível definir a forma dinâmica através da UI do administrador no Entity Manager.
-
-Existe a capacidade de definir um comportamento de formulário no EspoCRM.
-
-## Exemplo
-
-> Precisa mostrar o campo _nextStep_ numa visualização de detalhes da Oportunidade somente se o estágio for 'Fechado Vencido'.
->
-
-Criar ficheiro `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Isso significa que o campo _nextStep_ será escondido por padrão e mostrado se o palco igual a 'Ganho Fechado'.
-
-A lista de ações disponíveis: `show`,` hide`, `setRequired`,` setNotRequired`.
-
-Existe também a capacidade de ocultar/mostrar painéis. Especifica ps nomes do painel em `painéis', atribui o mesmo modo como `campos'.
diff --git a/i18n/pt_BR/development/extension-packages.md b/i18n/pt_BR/development/extension-packages.md
deleted file mode 100644
index a1a674e77..000000000
--- a/i18n/pt_BR/development/extension-packages.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Pacotes de extensão
-
-As extensões permitem adicionar funcionalidades adicionais ao EspoCRM. Elas podem ser instaladas pelo painel Administrador na seção `Personalização`.
-
-
-
-## Como criar o pacote de extensão
-
-Uma estrutura de Arquivo do pacote:
-
-* `/manifest.json` – um arquivo que contém propriedades de extensão;
-* `/files` – um diretório que contém os arquivos de extensão;
-* `/scripts` – contém os scripts da extensão.
-
-### Manifesto
-```json
-{
- "nome": "Nome da Extensão",
- "versão": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "autor": "Teu Nome",
- "descrição": "Descrição da sua extensão",
- "eliminar": []
-}
-```
-
-* A Sintaxe da `versão' e 'acceptableVersions` é descrita pela especificação v2.0.0 encontrada em http://semver.org.
-* `eliminar` - é a lista de arquivos principais que precisam ser excluídos. Este parâmetro não é recomendado para usar. Tu podes omiti-lo.
-
-### Arquivos
-
-Todos os arquivos de extensão devem ser colocados no diretório `arquivos`. Eles serão copiados para o diretório principal do EspoCRM.
-
-### Scripts
-
-Para diferentes fins, o EspoCRM suporta os seguintes tipos de scripts. Todos devem ser inseridos no diretório `scripts`.
-
-* `BeforeInstall.php` – um script executado antes de um processo de instalação;
-* `AfterInstall.php` – executado uma vez finalizado o processo de instalação;
-* `BeforeUninstall.php` – executado antes do processo de desinstalação;
-* `AfterUninstall.php` – executado uma vez que o processo de desinstalação está concluído.
-
-Exemplo:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Pacote
-
-No final, precisamos empacotar todos estes arquivos num arquivo .z
diff --git a/i18n/pt_BR/development/hooks.md b/i18n/pt_BR/development/hooks.md
deleted file mode 100644
index db47ebbb4..000000000
--- a/i18n/pt_BR/development/hooks.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Ganchos
-
-## Criar um Gancho
-Para criar um gancho, você precisa:
-- criar um arquivo `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- declarar ação do tipo gancho;
-- limpar o Cache na Administração.
-
-## Tipos de Gancho
-
-Os principais tipos de gancho são:
-
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove;
-- afterRelate;
-- afterUnrelate;
-- afterMassRelate.
-
-### Novo Tipo de Gancho
-Você pode usar o seu próprio tipo de gancho e desencadeá-lo com
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Ordem Gancho
-Se você tiver vários ganchos, relacionados a um Tipo de Entidade e com o mesmo tipo de gancho, e o pedido de execução é importante, você pode definir uma propriedade `publicstatic$order` em um valor inteiro.
-
-Ordem ascendente - o gancho com o número de ordem mais pequeno é executado primeiro.
-
-## Exemplo
-Este exemplo define o nome da conta para novos leads, se não estiver configurado.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-use Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Ganchos Globais
-Se você precisar de aplicar um gancho para todas as entidades, você pode usar ganchos comuns. Para fazer isto, coloca a sua sua classe de gancho no diretório Comum, por exemplo: `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/pt_BR/development/how-to-create-a-dashlet.md b/i18n/pt_BR/development/how-to-create-a-dashlet.md
deleted file mode 100644
index 509baadaf..000000000
--- a/i18n/pt_BR/development/how-to-create-a-dashlet.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Como criar um dashlet
-
-Criar um arquivo `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` com a tua configuração do dashlet.
-
-Aqui precisas definir `"visão "`, e podes configurar `"aclScope"`, `"entityType"`, e `"opções"`.
-
-Se é uma lista típica dashlet, usa `"view":"views/dashlets/abstract/record-list"`, se não, crie uma visão própria (https://github.com/espocrm/documentation/blob/master/development/custom-views.md).
-
-## Opções
-Por padrão, nas opções do dashlet podes configurar _Title_ e _Auto-refresh Interval_.
-
-Campos de opção adicionais que podes definir em `"opções"` > `"campos"`.
-
-Para definir a posição dos campos, defina o layout em`"opções"` > `"layout"` > `"linhas"`
-
-Além disso, podes definir outras opções, se a tus visão precisar de mais dados.
-
-## Exemplo
-
-`application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json`
-
-```
-{
- "view":"views/dashlets/abstract/record-list",
- "aclScope": "Case",
- "entityType": "Case",
- "options": {
- "fields": {
- "title": {
- "type": "varchar",
- "required": true
- },
- "autorefreshInterval": {
- "type": "enumFloat",
- "options": [0, 0.5, 1, 2, 5, 10]
- },
- "displayRecords": {
- "type": "enumInt",
- "options": [3,4,5,10,15]
- },
- "expandedLayout": {
- "type": "base",
- "view": "views/dashlets/fields/records/expanded-layout"
- }
- },
- "defaults": {
- "sortBy": "createdAt",
- "asc": false,
- "displayRecords": 5,
- "expandedLayout": {
- "rows": [
- [
- {
- "name": "number"
- },
- {
- "name": "name",
- "link": true
- },
- {
- "name": "type"
- }
- ],
- [
- {
- "name": "status"
- },
- {
- "name": "priority"
- }
- ]
- ]
- },
- "searchData": {
- "bool": {
- "onlyMy": true
- },
- "primary": "open"
- }
- },
- "layout": [
- {
- "rows": [
- [
- {"name": "title"}
- ],
- [
- {"name": "displayRecords"},
- {"name": "autorefreshInterval"}
- ],
- [
- {"name": "expandedLayout"},
- false
- ]
- ]
- }
- ]
- }
-}
-```
-Lá podes ver alguns exemplos `application/Espo/Modules/Crm/Resources/metadata/dashlets`.
-
-## Tradução
-
-A tradução para dashlet está no escopo `Global`, na seção `"dashlets"`.
-
-__Depois de tudo, não te esqueças de Limpar Cache na Administração.__
diff --git a/i18n/pt_BR/development/link-multiple-with-primary.md b/i18n/pt_BR/development/link-multiple-with-primary.md
deleted file mode 100644
index 913e4d14f..000000000
--- a/i18n/pt_BR/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# Vincular campo múltiplo com primário
-
-~Para EspoCRM 3.6.0 e maior.~
-
-Às vezes, você tem um relacionamento `hasMany` e precisa de ter a capacidade de selecionar o registro primário entre os relacionados. Como exemplo, campo `Contatos` da entidade Case.
-
-
-
->Você precisa criar um link de `contatos` múltiplo campo com um primário para a nossa entidade personalizada `Stock`.
->
-
-###Passo 1
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-###Passo 2
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-###Passo 3
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-###Passo 4
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-###Passo 5
-Corre o reconstruir
-
-###Passo 6
-Execute SQL query
-```sql
-ATUALIZA stock
-JUNTA contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
diff --git a/i18n/pt_BR/development/metadata.md b/i18n/pt_BR/development/metadata.md
deleted file mode 100644
index 6442f068a..000000000
--- a/i18n/pt_BR/development/metadata.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Metadata
-
-Metadados destina-se a: armazenar dados do sistema, tais como campos e relacionamentos da entidade; especificando controladores frontend, visualizações, painéis; definindo campos, dashlets; e outros dados necessários para a aplicação.
-
-## Como aceder
-
-#### Backend
-
-O objeto Metadata da classe `Espo\Core\Utils\Metadata` pode ser acedido pelo Container. O caminho para um parâmetro necessário é especificado usando os pontos `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-retornará `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-irá retornar uma matriz associativa de todos os campos.
-
-#### A parte dianteira
-
-O objeto Metadata é acessível a partir de todos os objetos de exibição por método `#getMetadata`. Funciona do mesmo modo que o backend.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## Como é armazenado
-
-Metadados são armazenados em arquivos JSON que podem ser localizados em diferentes locais:
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-Quando acedes os dados por caminho `clientDefs.Account.views.edit` o primeiro lexema `clientDefs` corresponde ao nome do diretório, o segundo `Conta` para nome de arquivo `Account.json`. Todos os lexemes seguintes correspondem ao caminho no JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-Todos os arquivos JSON destes diretórios são mesclados recursivamente numa única matriz de php e armazenados num arquivo de cache.
-
-
-## Estendendo
-
-Uma vez que os metadados são mesclados de forma recursiva, podes redefinir facilmente objetos json e arrays em _custom_ e no teu _module_. Além disso, podes anexar matrizes existentes usando `__APPEND__` (desde a versão 2.6.0) como o primeiro elemento da matriz.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/pt_BR/development/new-function-in-formula.md b/i18n/pt_BR/development/new-function-in-formula.md
deleted file mode 100644
index c072cc5a3..000000000
--- a/i18n/pt_BR/development/new-function-in-formula.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# Definindo novas funções para Fórmula
-
-EspoCRM oferece a possibilidade de criar funções personalizadas que podem ser usadas na fórmula.
-
-Se a sua função estiver relacionada com um de grupos como String, Logic, Date, crie um arquivo em __{GroupName}Grupo__ pasta, nomeado __{FunctionName}Tipo.php__ com __{FunctionName}Tipo__ declaração de classe. Precisas de definir o método __'processo'__.
-
-Por exemplo, vamos criar uma nova função de string para verificar se uma string (HAYSTACK) contém outra string (AGULHA) com um possível deslocamento (OFFSET).
-
-Cria o arquivo `application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` com o código:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-use \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Adicionar a função à lista
-
-Para adicionar a função criada à lista de funções da fórmula, crie um arquivo `custom/Espo/Custom/Resources/metadata/app/formula.json` e adiciona o código:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Limpe o cache__ e use esta função na fórmula. Pode digitar `string\contains(HAYSTACK, NEEDLE, OFFSET)` ou selecionar a partir da lista de funções, se o adicionares.
diff --git a/i18n/pt_BR/development/orm.md b/i18n/pt_BR/development/orm.md
deleted file mode 100644
index cf1193498..000000000
--- a/i18n/pt_BR/development/orm.md
+++ /dev/null
@@ -1,226 +0,0 @@
-# ORM, Como gerir entidades e executar consultas
-
-O EspoCRM possui o próprio ORM (Mapeamento objeto-relacional). É muito simples criar, atualizar, ler, excluir e pesquisar entidades. Todas estas operações disponíveis através do objeto EntityManager. EntityManager está disponível nos serviços de gravação pelo método `#getEntityManager()`.
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Cria uma nova entidade
-```php
-$account = $entityManager->getEntity('Account')
-```
-ou
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Fetch existente
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-ou
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Get value
-```php
-$fieldValue = $account->get('fieldName');
-```
-
-#### Has value
-```php
-$fieldNameIsSet = $account->has('fieldName'); // true or false
-```
-
-#### Definir valor
-```php
-$account->set('fieldName', 'Test Account');
-```
-
-```php
-$account->set(array(
- 'name' => 'Test Account',
- 'assignedUserId' => '1'
-));
-```
-
-#### Loja
-```php
-$entityManager->saveEntity($account);
-```
-ou
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Remove
-```php
-$entityManager->removeEntity($account);
-```
-ou
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Encontra
-```php
-$accountList = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer'
-])->find();
-```
-
-Ordem decrescente:
-
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', true)->find();
-```
-
-Ordem ascendente:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt')->find();
-```
-
-ou:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', 'DESC')->find();
-```
-
-#### Encontra o primeiro
-```php
-$account = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer',
-])->findOne();
-```
-
-#### Encontrar relacionados
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
-```
-
-#### Relacionar entidades
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
-```
-ou
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
-```
-
-#### Entidades não relacionadas
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
-```
-ou
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
-```
-
-### Selecionar Parâmetros de Consulta
-
-#### Cláusula onde
-
-##### Operadores de comparação
-
-Operadores de comparação suportados: `>`, `<`, `>=`, `<=`, `=`, `!=`.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'amount>=' => 100
-])->find();
-```
-
-##### IN e NOT IN operadores
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage' => ['Closed Lost', 'Closed Won']
- ])->find();
-```
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage!=' => ['Closed Lost', 'Closed Won']
-])->find();
-```
-
-##### LIKE operatodores
-
-Operadores suportados:
-* `*` - LIKE,
-* `!*` -- NOT LIKE.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'name*' => '%service%'
-])->find();
-```
-
-##### OU, E operadores
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- [
- 'OR' => [
- ['stage' => 'Closed Won'],
- ['stage' => 'Closed Lost']
- ],
- 'AND' => [
- 'amountConverted>' => 100,
- 'amountConverted<=' => 999
- ]
- ]
-])->findOne();
-```
-
-#### Distito
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->distinct()->where(...)->find();
-```
-
-#### Junta-te
-
-```
-$contactList = $entityManager->getRepository('Contact')->distinct()->join('opportunities')->where([
- 'opportunities.stage' => 'Closed Won'
-])->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()->leftJoin('opportunities')->where(...)->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()
-->join(['opportunities', 'aliasForJoinedTable'])
-->where([
- 'aliasForJoinedTable.stage' => 'Closed Won'
-])->find();
-```
-
-#### Agrupar Por
-
-```
-$selectParams = [
- 'select' => ['MONTH:closeDate', 'SUM:amountConverted']
- 'groupBy' => ['MONTH:closeDate'],
- 'whereClause' => [
- 'stage' => 'Closed Won'
- ],
- 'orderBy' => 1 // ordenar pela primeira coluna
-];
-
-// aplicando juntas à esquerda para conversão de moeda
-$this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams);
-
-$pdo = $this->getEntityManager()->getPDO();
-$sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams);
-$sth = $pdo->prepare($sql);
-$sth->execute();
-
-// resultados
-$rowList = $sth->fetchAll(\PDO::FETCH_ASSOC);
-```
diff --git a/i18n/pt_BR/development/scheduled-job.md b/i18n/pt_BR/development/scheduled-job.md
deleted file mode 100644
index 89f2e291c..000000000
--- a/i18n/pt_BR/development/scheduled-job.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Criar trabalho agendado
-
-Para definir um trabalho personalizado agendado, crie um arquivo `custom/Espo/Custom/Jobs/{JOB_NAME}.php` com o conteúdo.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //toda a lógica precisa ser definida no método executado
- }
-}
-```
-
-Além disso, podes definir uma etiqueta para o teu trabalho (`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-Para implementar as alterações, vá para o painel Administração e Limpe o Cache.
diff --git a/i18n/pt_BR/development/workflow-service-actions.md b/i18n/pt_BR/development/workflow-service-actions.md
deleted file mode 100644
index b905bd301..000000000
--- a/i18n/pt_BR/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Adicionar ação de serviço personalizado para Workflow
-
-Fluxos de trabalho permitem criar ações de serviço personalizado. Este exemplo mostrará como isto pode ser feito para uma entidade de chamada.
-
-## Passo 1. Criar classe de serviço
-
-```php
- Limpar Cache. Agora, a ação do serviço está disponível para fluxos de trabalho no formulário Execução do serviço.
diff --git a/i18n/pt_BR/user-guide/activities-and-calendar.md b/i18n/pt_BR/user-guide/activities-and-calendar.md
deleted file mode 100644
index 2d52def91..000000000
--- a/i18n/pt_BR/user-guide/activities-and-calendar.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Atividades e Calendário
-
-Existem por padrão três tipos de atividades disponíveis no EspoCRM:
-
-* Reuniões;
-* Chamadas;
-* Tarefas.
-
-O administrador pode criar uma entidade personalizada do tipo Evento. Em Administração > Configurações > Atividades, é possível definir este tipo de entidade como uma atividade e disponibilizá-la no Calendário.
-
-Existe 'As minhas atividades' dashlet que mostram os registros de atividade atuais e futuros relacionados com o usuário atual.
-
-Contas, Contatos, Leads, Oportunidades, Casos têm o painel de Atividades na visualização de detalhes. As entidades personalizadas do tipo Base Plus também possuem o painel Atividades.
-
-## Reuniões, Chamadas
-
-### Participantes
-
-Existem 3 tipos de participantes suportados: Usuários, Contatos, Leads. Para cada participante é possível especificar o status de aceitação: Aceito, Tentativa, Recusado. Existe a capacidade de enviar convites via e-mail aos participantes clicando no botão no canto superior direito. Os participantes poderão definir o seu status de aceitação clicando num link correspondente no e-mail.
-
-### Lembretes
-
-Existem dois tipos de lembretes: Popup (mensagem no aplicativo) e Email.
-
-### Duração padrão
-
-A duração padrão pode ser alterada pelo administrador em Administração > Gestor de Entidada > Reuniões / Chamadas > Campos > Duração > Padrão. Deve ser especificado em segundos.
-
-
-## Tarefas
-
-Os campos Data de Início e Data de Vencimento não são necessários. As datas podem ser especificadas com ou sem as partes de tempo.
-
-### Lembretes
-
-Os lembretes para a gravação da tarefa estarão disponíveis somente se a Date de Vencimento for especificada e tiver parte do tempo.
-
-## Calendário
-
-O Calendário mostra Reuniões, Chamadas, Tarefas. Também é possível mostrar entidades personalizadas do tipo de Evento.
-
-Visualizações suportadas:
-
-* Mês;
-* Semana;
-* Dia;
-* Linha do tempo.
-
-Os usuários podem adicionar o Calendário no painel.
-
-É possível visualizar o calendário de outro usuário ( você tem acesso determinado pelas funções). O botão Calendário está disponível na visualização detalhada do usuário.
-
-### Calendário compartilhado
-
-O calendário compartilhado está disponível somente na visualização Timeline. Permite visualizar eventos de vários usuários.
diff --git a/i18n/pt_BR/user-guide/browser-support.md b/i18n/pt_BR/user-guide/browser-support.md
deleted file mode 100644
index b553f3727..000000000
--- a/i18n/pt_BR/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Suporte de Navegador
-
-Nós recomendamos o uso da última versão do Google Chrome ou Mozilla Firefox. O EspoCRM funciona melhor nesses navegadores. Testamos regularmente todos recursos nesses navegadores.
-
-Microsoft Edge e Safari também são compativeis, mas haverá menos garantias que tudo estará à funcionar sem problemas.
-
-Nós não recomendamos o uso do Internet Explorer 11.
diff --git a/i18n/pt_BR/user-guide/case-management.md b/i18n/pt_BR/user-guide/case-management.md
deleted file mode 100644
index 7a4b2bf1a..000000000
--- a/i18n/pt_BR/user-guide/case-management.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Gestão do Caso
-
-Os casos fornecem uma capacidade de rastreamento de problemas. É um aspecto principal do serviço ao cliente no EspoCRM. O termo Ticket também pode ser usado para os casos.
-
-A entidade de caso pode ser associada a uma Conta e/ou a vários Contatos.
-
-Os novos casos devem ser criados pelos seguintes cenários:
-
-* Manualmente por usuários de CRM;
-* Manualmente por usuários do portal de clientes;
-* Através da API (por exemplo, através do formulário web);
-* Automaticamente quando um novo e-mail entrou para uma caixa de correio específica.
-* Automaticamente por uma regra do Fluxo de trabalho.
-
-A gravação do caso tem um fluxo que pode ser utilizado para uma comunicação entre o cliente e o serviço. Os utilizadores de CRM também podem fazer postagens internas que não serão visíveis num portal de clientes.
-
-Quando o novo caso é criado por um usuário do portal, ele não é atribuído a nenhum usuário. Ao usuário [Fluxos de trabalho](../administration/workflows.md) o administrador pode criar uma regra que notificará certos usuários sobre um novo caso no sistema. Os fluxos de trabalho também fornecem uma capacidade para aplicar a regra de atribuição a novos casos, ou seja, regras Round-Robin e Least-Busy. Para fluxos de negócios mais complexos é recomendável utilizar [ferramenta BPM](../administration/bpm.md).
-
-Para evitar a negligência de novos casos, os usuários podem adicionar o tipo de entidade de Caso à lista de Auto-seguimento Global em Preferências. Então, eles seguirão automaticamente cada novo caso.
-
-Nota: Se não houver nenhum usuário do portal associado a um contato vinculado, o cliente não receberá notificações por e-mail sobre as atualizações no Stream. Você precisa de usar e-mails para comunicar com o cliente.
-
-### Email-para-Caso
-
-O administrador pode configurar a conta de e-mail do grupo que criará um novo caso em cada novo e-mail de entrada. Para mais informações [veja aqui](../administration/emails.md).
-
-### Conhecimento Base
-
-Os usuários podem relacionar artigos da base de conhecimento ao registro do caso.
-
-### Portal do cliente
-
-O administrador pode criar um [portal](../administration/portal.md) onde os clientes poderão criar casos.
-
-Como os usuários do portal seguem automaticamente os seus casos, eles receberão notificações por e-mail sobre as novas mensagens no Stream.
diff --git a/i18n/pt_BR/user-guide/emails.md b/i18n/pt_BR/user-guide/emails.md
deleted file mode 100644
index 5125ef2fd..000000000
--- a/i18n/pt_BR/user-guide/emails.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Diretrizes sobre o Uso de Email
-
-O EspoCRM porporciona à capacidade de procurar email na caixa IMAP. Isto faz com que seja possivel usar o EspoCRM como cliente de email juntamente com os recursos específicos do CRM.
-
-## Contas IMAP
-
-*Nota: Voçê deve ter o [cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) configurado corretamente em seu sistema para que o email recebido funcione.*
-
-O usuário pode configurar a conta IMAP na página de contas de email pessoais (guia de email> menu superior direito> Contas de Email Pessoais).
-
-Especifique quais as pastas que são para monitorar no campo Pastas Monitoriradas. Por padrão, ele está configurado no INBOX. Se Você usa um cliente de email externo para enviar emails, Você pode adicionar a pasta Enviada para arquivar esse email.
-
-*Buscar Desde* permite que você escolha a data a partir da qual os emails devem ser arquivadas. Configure-o para uma data antes de hoje, se você precisar de arquivar emails antigos.
-
-Existe a possibilidade de você especificar a *Pasta* na Conta Pessoal de Email. Os emails recebidos serão colocados nessa pasta.
-
-## Contas SMTP
-
-Os usuários podem configurar às configurações do SMTP em Preferências, bem como nas suas Contas de Email Pessoais. O administrador também pode permitir o uso do sistema SMTP (torna-lo Compartilhado).
-
-Os usuários podem ter várias contas SMTP (a partir da versão 4.2.0). Mas os endereços de email que o usuário pode usar para enviar emails são definidos pelos endereços de email do registro *Usuário*.
-
-## Trabalhar com Email
-
-Os Emails são capturados pelo cron (em segundo plano) a cada poucos minutos (o período pode ser especificado pelo Administrador).
-Pode ver todos os seus emails na aba Emails. Existem as pastas padrão, Recebidas, Enviadas, Rascunhos no lado esquerdo.
-
-O campo *Estado*. `Enviado` significa que foi enviado a partir do CRM, `Arquivado` - retirado da conta IMAP ou arquivado manualmente, `Rascunho` - significa que o email foi criado como um rascunho.
-
-Quando um novo email chega, o sistema tenta reconhecer qual registro esse email pertence. Você pode vinculá-lo com à Conta, Potencial Cliente, Oportunidade, Caso (e Contato no modo B2C) etc. Se não for reconhecido, o usuário pode conetá-lo manualmente, preenchendo o campo *Pai*.
-
-Quando um novo email vier de um novo potencial cliente, o usuário pode **converte-lo em Potencial Cliente**. Abra à entrada de email e clique em Criar potencial cliente no menu superior direito.
-
-Também é possível **criar Tarefa ou Caso** a partir de um registro de email.
-
-Se os endereços de email (de, para, cc) num registro de email forem reconhecidas pelo sistema, será mostrado à pessoa com quem eles estão relacionados (Contato, Potencial Cliente, Usuário, etc.). Se qualquer endereço de email for novo, você pode **criar contato** diretamente de lá.
-
-Todos os emails relacionados a um registro específico é mostrado no painel Histórico desse registro. Se algum email estiver relacionado, por exemplo, com oportunidade, mas a oportunidade está relacionada à conta, ela será mostrada em oportunidade e em conta
-
-## Enviar Emails
-
-Você pode escrever um novo email de várias formas:
-* Botão de *Escrever Email* na lista de Email;
-* responder a outro email;
-* clicar num endereço de email de algum registro;
-* ação *Escrever Email* no painel de Atividades.
-
-Existe a possibilidade de você **selecionar o modelo** no teu email.
-
-Você pode configurar a **assinatura do email** em Preferências.
-
-## Pastas de Email
-
-Os usuários podem criar as suas próprias pastas de email de acordo com a conviniência para colocar alguns dos emails. A lista de pastas disponíveis está disponível na página de Email no lado esquerdo. Para criar ou editar pastas, siga Email> menu suspenso no canto superior direito> Pastas.`Ignorar Notificação` significa que você não será notificado sobre os emails recebidos que pertençam à pasta especificada. Ao usar os Filtros de Emails, é possível você colocar os emails nas pastas automaticamente de acordo com os critérios específicos.
-
-## Filtros de Emails
-
-O administrador pode criar filtros de email globais para ignorar o email indesejado. Estão disponíveis em Administração> Filtros de Email.
-
-O usuário regular pode criar filtros de email para as suas contas de email pessoais ou para toda a sua caixa de entrada completa. Estão disponíveis em Email > menu suspenso no canto superior direito> Filtros.
-
-Existem dois tipos de filtros:
-* Ignorar - o email será colocado no *Lixo* ou não será importado se o filtro estiver relacionado à Conta Pessoal de Email;
-* Colocar pasta – os emails importados serão automaticamente colocados na pasta de usuário especificada.
-
-## Modelos de Email
-
-Os modelos de email estão disponíveis em Email > menu suspenso no canto superior direito> Modelos de email. Podem ser usados para emails em massa e email regular. A caixa de verificação `One-off` significa que o modelo de email será usado apenas uma vez, que é usual para o marketing por email.
-
-É possível usar os espaços reservados da pasta no corpo do modelo de email e o assunto, por exemplo. {Account.name}, {Person.emailAddress}. Serão substituídos por valores de registros relacionados.
-
- Você pode usar marcadores de espaço de pasta reservados adicionais no corpo do modelo: {optOutUrl} e {optOutLink}.
-```
-
-Cancelar a inscrição
-```
-
-Esse é uma ligação para cancelar a inscrição de email em massa.
diff --git a/i18n/pt_BR/user-guide/markdown.md b/i18n/pt_BR/user-guide/markdown.md
deleted file mode 100644
index a4ddd46d7..000000000
--- a/i18n/pt_BR/user-guide/markdown.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# Sintaxe de Markdown
-
-Os campos de texto admitem a sintaxe do markdown.
-
-## Código
-```
-`algum texto`
-```
-
-`algum texto`
-
-## Código Multilineal
-
-```
-``` algum texto ```
-```
-
-```
-algum texto
-```
-
-## Texto Forte
-
-```
-**algum texto**
-```
-
-**algum texto**
-
-## Texto Enfatizado
-
-```
-*algum texto*
-```
-
-*algum texto*
-
-## Texto Apagado
-
-```
-~~algum texto~~
-```
-
-~~algum texto~~
-
-## Bloco de Citação
-
-```
-> algum
-> texto
-```
-
-> algum
-> texto
-
-## Link
-
-```
-[texto de link](https://www.espocrm.com)
-```
-[texto de link](https://www.espocrm.com)
-
-## Lista Numerada
-
-```
-1. Algum item
-2. Outro item
-```
-
-1. Algum item
-2. Outro item
-
-## Lista Não Numerada
-
-```
-* Algum item
-* Outro item
-```
-
-* Algum item
-* Outro item
-
-## Linha Horizontal
-
-```
-___
-```
diff --git a/i18n/pt_BR/user-guide/mass-email.md b/i18n/pt_BR/user-guide/mass-email.md
deleted file mode 100644
index 8d552991d..000000000
--- a/i18n/pt_BR/user-guide/mass-email.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Email Massivo
-
-## Como enviar e-mails massivos
-
-Você necesita de ter pelo menos uma Lista de Destinos com registros de destinos e um Modelo de E-mail em sua crm.
-
-1. Crie uma nova campanha com um `E-mail` ou `Newsletter`. Selecione uma ou algumas listas de destinos no campo `Listas de Destino`.
-
-2. Depois de o registro da campanha estiver criado, crie um E-mail Massivo para esta campanha: Faça mais um clique no painel de E-mail Massivo. Especifique _Data de Inicio_ - de quando se devem enviar os e-mails, e selecione _Modelo de E-mailo_. certifique-se que o _Estado_ está configurado como `Pendente`.
-
-Se tudo estiver configurado corretamente, os e-mails devem ser desligados. Eles devem ser enviados a cada hora com porções (você pode alterar o tamanho da parcela em Administração> E-mails de saída). O administrador pode alterá-lo atualizando o campo `Agendamento` da tarefa agendada 'Verifique as Contas de E-mail do Grupo'.
-
-Você pode verificar se os e-mails são enviados em painel de registro.
-
-## Teste o que vai ser enviado aos destinatários
-
-Clique no menu suspenso direito na linha de e-mail massivo no painel _E-mail Massivo_ e em seguida, clique em _Enviar teste_.
-
-## Iniciar Sessão
-
-No registro você pode ver:
-* E-mail enviado;
-* E-mails abertos pelo destinatário;
-* Links clicados pelo destinatário;
-* Destinatários que optaram por sair;
-* Mensagens de E-mails devolvidos (não foram entregues ao destinatário).
-
-## Link de exclusão
-
-De uma maneira predefinida, o sistema agregará a opção de exclusão voluntária a todos os e-mails enviados. Mas você pode usar um personalizado no seu Modelo de E-mail.
-
-Exemplo:
-```html
-Cancelar a subscrição da lista de correio.
-```
-
-O administrador pode desabilitar o link de exclusão obrigatória que está a ser adicionado pelo sistema em Administração> E-mails de Saída.
-
-## URL de Acompanhamento
-
-Se você quiser saber se o seu destinatário abriu o link do teu e-mail, você precisa de criar um URL de acompanhamento. Especifique qualquer _Nome_ e _URL_ para onde o seu link deve conduzir. Então, você precisa de colocar o código gerado no teu Modelo de E-mail.
-
-Exemplo:
- ```html
-Teste à nossa demonstração
- ```
-
-## Listas de Destinos
-
-As Listas de Destinos contem as listas de contas, Contatos, Potenciais Clientes r Registros de Usuários.
-
-Os usuários podem preencher manualmente as listas de destinos usando a ação _Selecionar_ no painel correspondente na exibição de detalhes da Lista de Destinos. Existe a capacidade de fazer filtragem e em seguida selecionar todos os resultados da pesquisa.
-
-## Preencher Listas de Destinos com Relatórios
-
-O recurso de [Relatórios](reports.md#syncing-with-target-lists) fornece a capacidade de preencher as listas de destino com registros que correspondem a critérios específicos.
-
-## Excluir Listas de Destinos
-
-Especifique a Exclusão de Listas de Destinos para evitar o envio de email massivo para determinados destinatários. Se houver um registro com o endereço de e-mail que corresponda ao endereço de e-mail de qualquer registro excluído, o primeiro registro também será excluído.
-
-## Registro de Campanha
-
-No Registro de Campanhas, você pode consultar os e-mails que foram enviados, e-mails abertos, e-mails devolvidos, os que optaram por sair e quem clicou no link do e-mail. É possível você utilizar este log criando Lista de Destinos (menu suspenso no canto superior direito no painel) com base nos registros do log. Por exemplo, você pode escolher apenas contatos que clicaram no link (URL de rastreamento).
-
-## Solução de Problemas
-
-_Para os Administradores_
-
-#### ¿Que fazer se os e-mails não são enviados?
-
-1. Verifique se funciona _Envio de Teste_. Se não funcionar, verifique se as configurações de SMTP do sistema estão corretas.
-2. Verifique se configuraste o cron para seu sistema.
-3. Verifique se você tem o Trabalho Programado de `Enviar e-mails massivos` e está `Ativo` (Administração > Trabalhos Programados > Enviar E-mails Massivos). Verifique se há alguma coisa no Log.
-
-#### ¿O que acontece se o URL de acompanhamento tiver uma URL incorreta que não leve ao seu crm?
-
-Verifique o parâmetro 'siteUrl' no arquivo `data/config.php`. Deve ser configurado como URL do seu EspoCRM acessível a partir do mundo externo.
-
-#### Os e-mails devolvidos não se encontram a ser registrados
-
-Os e-mails devolvidos podem ser manuseados apenas pela conta de e-mail de grupo. Certifique-se de que você tem uma conta de e-mail de grupo que monitorize quais os e-mails enviados para a caixa de correio são enviados.
-
-Além disso, alguns provedores do servidor do correio podem desviar-se dos padrões, por isso os e-mails devolvidos não podem ser distinguidos.
diff --git a/i18n/pt_BR/user-guide/printing-to-pdf.md b/i18n/pt_BR/user-guide/printing-to-pdf.md
deleted file mode 100644
index 963f9ce85..000000000
--- a/i18n/pt_BR/user-guide/printing-to-pdf.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# Impressão em PDF
-
-Nota: Este recurso está disponível desde a versão 5.0.5. do EspoCRM.
-
-A impressão em PDF oferece a capacidade de criar documentos em PDF com dados de registro. O conteúdo do documento é definido pelo modelo.
-
-1. Você precisa de ter pelo menos um Modelo para o tipo de entidade de gravação que deseja imprimir.
-2. 'Imprimir em PDF' estará disponível na vista de detalhes no menu suspenso ao lado do botão 'Editar'.
-
-## Modelos
-
-A aba de Modelos está oculta por padrão. O administrador pode adicioná-lo na Administração > Interface de utilizador.
-
-Para uma edição mais precisa, é recomendável usar o modo de exibição de código.
-
-Podes imprimir os campos do registro, bem como os campos de registros relacionados, utilizando os espaços reservados no seu modelo.
-
-Exemplos:
-
-* `{{name}}` – Nome do registro;
-* `{{assignedUserName}}` – Utilização atribuído;
-* `{{account.name}}` – Nome da conta relacionada.
-
-É possível imprimir os campos de imagem:
-```
-
-```
-
-onde `imageId` - o nome do campo de imagem personalizado, concatenado com o sufixo `Id`.
-
-Para exibir os números de flutuação sem a parte fracionada (como número inteiro) usa a seguinte expressão:
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Formatação personalizada para valores de moeda:
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-
-O valor `10000.5` será imprimido como `10 000,50`.
-
-Para exibir os arquivos de texto (multilinha), use os aparelhos triplos:```{{{description}}}```.
diff --git a/i18n/pt_BR/user-guide/quotes.md b/i18n/pt_BR/user-guide/quotes.md
deleted file mode 100644
index 33f22e7a3..000000000
--- a/i18n/pt_BR/user-guide/quotes.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Citações
-
-O recurso Citações está disponível em [Pacote Avançado](https://www.espocrm.com/extensions/advanced-pack/).
-
-As citações são um grupo específico de produtos ou de serviços com suas quantidades e preços que você cita aos seus clientes.
-
-As citações têm um relacionamento com a Oportunidade. Você pode adicionar o painel de Citações à visualização detalhada da Oportunidade em Administração > Gerenciador de Layout > Oportunidades > Relacionamentos. Ao criar uma nova citação ligada a uma oportunidade, ela transfere os itens de oportunidade para a citação.
-
-Você pode adicionar o painel de Citações à visualização detalhada da Conta para você poder ver as cotações relacionadas. Você pode fazê-lo em Administração > Gerenciador de Layout > Contas > Relacionamentos.
-
-## Itens de Citações
-
-A citação possui uma lista de itens. Cada item pode representar um determinado produto ou um serviço com a sua descrição, quantidade, taxa de imposto, preço de tabela e campos de preço unitário. É possível ordenar os itens manualmente.
-
-Existe a capacidade de adicionar campos personalizados para a entidade Item de Citação usando para o efeito o Gestor de Entidades.
-
-## Modelos
-
-Por defeito, existem dois tipos de modelos disponíveis: Citação e Fatura. Você pode então criar novos modelos (Exibição da lista de Citações > menu suspenso superior direito > Modelos), bem como editar os existentes.
-
-Para uma edição mais precisa é recomendável usar o modo de Visualização de código.
-
-Você pode imprimir os campos do registro de Citações, bem como os campos de registros relacionados, utilizando espaços reservados par efeito em seu modelo.
-
-Exemplos:
-`{{accountName}}` – Nome da conta,
-
-`{{{billingAddressStreet}}}` – Rua,
-
-`{{account.type}}` – Tipo de Conta relacionada,
-
-`{{assignedUser.lastName}}` – ultimo nome do usuário signatário.
-
-Se o seu item de linha for um produto, você pode imprimir os campos do produto.
-
-Exemplos:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Comprimento e a cor são campos personalizaveis de Produtos de entidade que se encontram em exemplos.
-
-Repetição automática através de itens de citação:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-É possível imprimir campos de imagem:
-
-```
-
-```
-onde `imageId` – o nome do campo de imagem personalizado na entidade de Citação concatenada com o sufixo `Id`.
-
-Para o item de linha do produto:
-```
-
-```
-
-Para exibir números de flutuação (como quantidade, preço unitário etc.) sem parte fracionadas (como número inteiro) usa as seuintes expressões (desde a versão 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Formatação personalizada para valores de moeda (desde a versão 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Valor `10000.5` será impresso como `10 000,50`.
-
-Para exibir campos de texto (multilinha) usa aparelhos triplos: `{{{description}}}`.
-
-## Imprimir em PDF
-
-As citações podem ser impressas em PDF. Esta ação está disponível no menu suspenso ao lado do botão Editar na visualização detalhada da citação. Depois será solicitado para selecionar o Modelo.
-
-## Citação de Email
-
-O PDF de citação pode ser enviado via email como anexo. Abra o registro de citação, clique na lista suspensa ao lado do botão Editar e clique em Email PDF.
-
-## Numeração automática
-
-Você pode criar um campo de Número através do Gestor de Entidade por tipo de Citação de entidade. Administração > Gerenciador de Entidade > Citação > Campos > Adicionar Campo > Número. Depois você precisa colocá-lo na visualização detalhada usando o Gerenciador de Layout.
-
-O valor será incrementado por cada nova citação. Existe a capacidade de especificar o próximo número, bem como o prefixo.
-
-## Imposto Padrão
-
-Disponivel desde EspoCRM 4.8.0.
-
-Especifique o registro de Imposto padrão em Administração> Gerenciador de Entidade> Citações> campos> Impostos > Padrão.
-
-1. Especifique o registro de Imposto padrão na Administração > Gerenciador de Entidade> Citações> campos> Impostos > Padrão.
-2. Especifique taxa de imposto padrão na Administração > Gerenciador de Entidade> Citações> campos> Impostos > Padrão.
-
-## Faturas
-
-A citação pode ser tratada como uma fatura se o seu estado for `Aprovado`. Então os campos _Data da Fatura_, _Número da Fatura_ aparecem. Você pode usar um modelo diferente para a impressão das faturas.
diff --git a/i18n/pt_BR/user-guide/reports.md b/i18n/pt_BR/user-guide/reports.md
deleted file mode 100644
index 8d75ea7ba..000000000
--- a/i18n/pt_BR/user-guide/reports.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Relatórios
-
-O recurso Relatórios está disponível em [Pacote Avançado](https://www.espocrm.com/extensions/advanced-pack/).
-
-Existem dois tipos de relatórios: Lista e Grade.
-
-## Listar Relatórios
-
-Listar relatórios resulta a lista de registros que seguem critérios especificos.
-
-Para criar um novo relatório da lista, clique na aba Relatórios e clique em Criar Botão de Relatório. Escolha o Tipo de Entidade que você necessita e clique em Criar botão na seção de Relatório da Lista.
-
-No campo _Colunas_ escolha o campo que você gostaria ver exibido. Abaixo você pode especificar os parâmetros de exibição para cada uma das coluna, p.e. largura e alinhamento.
-
-Escolha a classificação necessária no campo _Ordem de Lista_ .
-
-Na seção _Filtros_ você pode especificar os critérios que determinam quais os registros que serão listados no seu relatório. Você pode usar os operadores lógicos 'OU' e 'E' aqui.
-
-Os _Filtros de Tempo de Execução_ permitem que você especifique diferentes filtros antes de executar o relatório.
-
-Você pode __exportar__ a lista de registro de resultados para o excel e em formato csv.
-
-## Registros de Grade
-
-Os relatórios de grade resultam de valores resumidos e agrupados por campos especificados. Esses relatórios podem ser exibidos como um gráfico.
-
-
-
-Para você criar um novo relatório de grade, clique na aba Relatórios e em seguida clique no botão Criar relatório. Escolha o Tipo de Entidade necessário e clique em Criar botão na seção Relatório de Grade.
-
-No campo _Grupo Por_, escolha um ou dois campos para os quais os dados do relatório devem ser agrupados. É possível agrupar por ano, mês, dia para os campos de data. Se você agrupar por dois campos, o seu relatório será considerado como tridimensional.
-
-No campo _Colunas_, selecione uma ou mais funções agregadas como COUNT, SUM (soma), MIN, MAX, AVG (média).
-
-O campo _Ordem por_ defina como os dados do relatório serão classificados.
-
-Na seção _Filtros_ podes especificar critérios que determinam quais os registros que serão usados no teu relatório. Você pode usar os operadores lógicos 'OU' e 'E' aqui.
-
-Os _Filtros de Tempo de Execução_ permitem que especifiques os diferentes filtros antes de executar o relatório.
-
-O relatório Grade permite exibir os resultados num gráfico. Existem os seguintes _tipos de gráficos_: Barra (Horizontal), Barra (Vertical), Torta, Linha.
-
-É impossivel __exportar__ os resultados em grade para o excel e em formatos csv.
-
-## Filtros
-
-### Campo de filtro
-
-Tipo de filtro simples de usar. Você também pode escolher os campos da entidade alvo, bem como as entidades relacionadas.
-
-
-
-### OU grupo
-
-OU significa que pelo menos uma condição do grupo deve ser cumprida.
-
-
-
-### E grupo
-
-E significa que todas as condições do grupo devem ser atendidas.
-
-### NÃO grupo
-
-Fornece uma capacidade de filtrar registros que não correspondem aos critérios especificados. Por exemplo. listar as contas que não têm qualquer oportunidade de status com os Ganhos Fechados ou Perdidos Fechados.
-
-
-
-### Expressão Complexa
-
-Para um uso mais avançado. Você pode aplicar a função para uma determinada coluna da base de dados e compará-la com o resultado da expressão da [formula](../administration/formula.md).
-
-Nota: Se você precisar de comparar apenas com um valor de cadeia simples, você deve colocá-lo em citações simples `'alguma cadeia'`.
-
-Nota: Funções destinadas a interagir com registro de entidade não irão funcionar aqui porque a fórmula não é aplicada no registro específico.
-
-
-
-## Exibindo no painel
-
-Você pode exibir qualquer relatório no painel. Para isso, você precisa de adicionar o Relatório dashlet e em seguida escolhe o relatório necessário nas opções do dashlet.
-
-## Envio de Email
-
-É possível você fazer o sistema enviar regularmente relatórios de resultados a determinados usuários, de acordo com o tempo especificado. Isso deve ser configurado individualmente para determinados relatórios.
-
-## Sincronização com Listas de Destino
-
-É possível ter listas de destino sincronizadas com os resultados do relatório da lista. É conveniente para o email massivo quando desejas enviar e-mails apenas para contatos que cumpram com alguns dos critérios no momento do envio. Este recurso está disponível na visualização detalhada de qualquer lista de destino no painel 'Sincronizar com Relatórios'.
diff --git a/i18n/pt_BR/user-guide/sales-management.md b/i18n/pt_BR/user-guide/sales-management.md
deleted file mode 100644
index c81ba5a50..000000000
--- a/i18n/pt_BR/user-guide/sales-management.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Gestor de Vendas
-
-## Leads
-
-A Lead representa uma pessoa ou uma organização que atualmente não é um cliente, mas que tem potencial para ser. Criar um registro principal geralmente é o primeiro passo do processo de venda. À medida que mais informações são reunidas sobre a Lead, é suposto que a liderança será convertida em Conta, Contato e Oportunidade.
-
-Novas leads devem ser criadas pelos seguintes cenários:
-
-* Manualmente por usuários de CRM;
-* Através da API (por exemplo, através do formulário web);
-* Automaticamente por uma regra do fluxo de trabalho.
-
-Ao utilizar [Fluxos de trabalho](../administration/workflows.md), o administrador pode configurar no sistema para aplicar uma regra de atribuição específica aos novos leads, ou seja, Round-Robin e Least-Busy regras. Para fluxos de negócios mais complexos é recomendável utilizar [ferramenta BPM](../administration/bpm.md).
-Para evitar a negligência de novas leads, os usuários podem adicionar o tipo de entidade principal à lista de seguimento automático global em Preferências. Então, eles seguirão automaticamente todas as novas leads.
-
-## Oportunidades
-
-A oportunidade representa um acordo potencial ou fechado. A oportunidade com o estágio 'Fechado Won' é levada em consideração para um cálculo de receita de vendas.
-
-Os estágios seguintes estão disponíveis por padrão:
-
-* Prospecção;
-* Qualificação;
-* Proposta;
-* Negociação;
-* Fechado Ganhou;
-* Fechado Perdido.
-
-O administrador pode definir estágios personalizados dependendo do fluxo de negócios da empresa. Mas não é recomendado remover o estágio 'Fechado Won', pois é usado para calcular uma receita.
-
-## Análise de vendas
-
-Os gráficos a seguir estão disponíveis no painel por padrão:
-
-* Vendas por mês;
-* Oportunidades por fonte principal;
-* Oportunidades por fase;
-* Pipeline de vendas.
-
-Ao utilizar [Ferramenta Relatórios](reports.md), é possível visualizar estatísticas de vendas com base em critérios específicos. Os gráficos de relatório podem ser exibidos no painel.
-
-### Previsão de receita
-
-1. Crie um novo relatório de grade para o tipo de entidade Oportunidade.
-2. Adicione 'MONTH: Close Date' ao Grupo de campo.
-3. Adicione o campo 'SUM: valor ponderado' para as colunas.
-4. Adicione o campo 'Fechar data' ao Filtro de tempo de execução.
-5. Selecione o tipo de gráfico 'Barra (vertical)'.
-
-Este relatório mostrará previsões de receita com base em probabilidades de oportunidades.
-
-Os usuários que tenham acesso a este relatório poderão adicioná-lo em seus painéis.
diff --git a/i18n/pt_BR/user-guide/stream.md b/i18n/pt_BR/user-guide/stream.md
deleted file mode 100644
index af9d78be3..000000000
--- a/i18n/pt_BR/user-guide/stream.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Transmissão
-
-A transmissão no EspoCRM é um feed onde você pode verificar as suas atualizações e novas adições para os registros que você acompanha. Você também pode publicar para transmitir e transmitir através de outros usuários (desde a versão 3.8.0). Existe dois tipos de transmissão no EspoCRM: sequência de registros e sequência de usuários.
-
-Por defeito, as seguintes entidades possuem uma transmissão: Contas, Contatos, Leads, Oportunidades, Casos. Os administradores podem ativar ou desativar a transmissão de uma determinada entidade em [Entity Manager](../administration/entity-manager.md).
-
-## Registo de Transmissão
-
-A gravação da transmissão é mostrada no painel Transmissão de um determinado registro na visualização de detalhes. As postagens, as atualizações e as novas adições relacionadas ao registro atual encontram-se aqui descritas.
-
-## Transmissão de Utilizador
-
-Os usuários podem visualizar a sua transmissão no Dashlet da Transmissão, bem como na aba Transmissão. Os usuários também podem visualizar a transmissão de outros usuários na visualização de detalhes do usuário, caso eles tiverem um acesso que seja controlado pelo campo das Funções da `Permissão do Usuário`.
-
-Na transmissão de usuários, você pode visualizar postagens, atualizações e novas adições relacionadas aos registros que o usuário acompanha. Você também pode visualizar as postagens dirigidas ao usuário. Estas postagens não estão relacionadas com nenhum registro.
-
-## Notificações
-
-Você irá receber notificações sobre novas adições à sua transmissão que foram causadas por outros usuários.
-
-## Postagens
-
-Você pode criar uma postagem relacionada com um determinado registro. Você também pode anexar vários arquivos e imagens à sua postagem. Se você quiser mencionar alguém em sua publicação, basta escrever o símbolo `@` e começar a escrever o nome do usuário. O usuário que mencionou você em sua publicação será notificado sobre isso.
-
-## Postagens dos Usuários
-
-_Este recurso está disponível desde a versão 3.8.0._
-
-Os usuários podem criar postagens para determinados usuários, para determinadas equipes, para todos os usuários e para si mesmos. Um acesso para esta funcionalidade é controlado pelo campo de funções `Atribuição de Permissão`.
-
-## Filtrando
-
-Você pode filtrar o que quiser mostrar em uma transmissão: `Todos`,` Postagens` ou `Atualizações`.
-
diff --git a/i18n/pt_PT/administration/apache-server-configuration.md b/i18n/pt_PT/administration/apache-server-configuration.md
deleted file mode 100644
index 6c826c4c3..000000000
--- a/i18n/pt_PT/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Configuração do servidor Apache para EspoCRM
-
-Estas instruções são suplementares às orientações [Configuração do Servidor](server-configuration.md). Por favor, nota que todas as configurações listadas aqui são feitas num servidor Ubuntu.
-
-## Requerimentos de PHP
-
-Para instalar todas as bibliotecas necessárias, executa estes comandos num terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Reparando o erro “API Error: EspoCRM API is unavailable”:
-
-Segue apenas os passos necessários. Após cada passo, verifica se o problema foi resolvido.
-
-### 1. Habilitar o suporte “mod_rewrite” em Apache
-
-Para habilitar “mod_rewrite,” executa estes comandos no terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Habilitar o suporte .htaccess
-
-Para habilitar o suporte .htaccess, adiciona/edita as Configurações do Servidor /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf ou /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Em seguida, executa este comando num terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Adicionar o caminho RewriteBase
-
-Abrir um arquivo /ESPOCRM_DIRECTORY/api/v1/.htaccess e substituir a seguinte linha:
-
-```
-# RewriteBase /
-```
-
-por
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-onde, REQUEST_URI é uma parte de uma URL, por exemplo, para “http://example.com/espocrm/”, REQUEST_URI é “espocrm”.
-
-
-## Habilitar o suporte HTTP AUTHORIZATION (somente para FastCGI).
-
-FastCGI não suporta HTTP AUTHORIZATION por padrão. Se tu usas FastCGI, tens que habilitar o teu VirtualHost ou /etc/apache2/apache2.conf (httpd.conf) adicionando o código:
-
-Para o módulo Fcgid:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Para o módulo FastCgi:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Para verificar qual módulo está ser usado, executa este comando e encontre o módulo:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/pt_PT/administration/b2c.md b/i18n/pt_PT/administration/b2c.md
deleted file mode 100644
index 430386067..000000000
--- a/i18n/pt_PT/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#Configurando EspoCRM para B2C (Business-to-Client)
-
-Por padrão, EspoCRM está configurado para ser usado como negócios B2B. Entretanto, tu podes facilmente configurá-lo para B2C.
-
-* Muda `b2cMode` para 'true' no seu arquivo de configuração `data/config.php`. Desde a versão 4.3.0, isto pode ser configurado em Administration > Seetings.
-* Remove a aba *Account* do menu de navegação (Administration > User Interface).
-* Remove os campos *Account* dos seus layouts (Administation > Layout Manager).
-* Desabilita o acesso para o escopo *Account* para todas as suas funções (Administration > Roles).
-* Remove a conta das listas de seleção para todos os campos principais (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
diff --git a/i18n/pt_PT/administration/backup-and-restore.md b/i18n/pt_PT/administration/backup-and-restore.md
deleted file mode 100644
index add47b3b5..000000000
--- a/i18n/pt_PT/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Cópia de Segurança e Restauração
-
-## Como fazer uma cópia de segurança do EspoCRM manualmente
-
-EspoCRM consiste em arquivos e informações da base de dados. Todas essas informações são necessárias para criar uma cópia de segurança completa do EspoCRM. Aqui estão as instruções de como fazer isso num servidor Ubuntu com MySQL.
-
-### Passo 1. Cópia de segurança dos arquivos
-
-Criar um arquivo com o conteúdo do diretório do EspoCRM instalado. Para Ubuntu o caminho padrão é `/var/www/html`. Podes usar este comando:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Passo 2. Cópia de segurança da base de dados
-
-Para salvar todas as suas informações, tu deves saber o nome e as credenciais de acesso da base de dados. Podes encontrar o nome da base de dados no arquivo de configuração `/ESPOCRM_DIRECTORY/data/config.php` sob a sessão `database`. Podes usar este comando para salvar o teu banco de dados:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Passo 3. Copiar a cópia de segurança
-
-Isto é tudo. Agora, tu deves copiar a cópia de segurança criada para um local seguro.
-
-
-## Como fazer uma cópia de segurança do EspoCRM com um script
-
-Podes usar um script para salvar todas as informações necessárias. Faça login através de SSH e executa os comandos (testados em servidor Ubuntu).
-
-### Descarrega um script
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Executa o script
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-onde
- * `PATH_TO_ESPOCRM` é um caminho para o diretório do EspoCRM instalado.
- * `BACKUP_PATH` é um caminho para o diretório da cópia de segurança.
-
-Para servidor Ubuntu é:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Nota: Se o teu utilizador MySQL não tem os direitos necessários para despejar a tua base de dados, será solicitado que entres com as credenciais de outro utilizador MySQL.
-
-Após a criação bem-sucedida, irás receber um caminho para a cópia de segurança criada.
-
-## Restauração do EspoCRM a partir de uma cópia de segurança
-
-Podes restaurar EspoCRM de uma cópia de segurança criada como descrito acima.
-
-### Passo 1. Extraia os arquivos da cópia de segurança
-
-Para extrair arquivos, podes usar o Archive Manager ou executar o comando abaixo. Os arquivos precisam ser colocados num diretório de servidor na web.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-onde:
- * `/var/www/html` é um diretório do servidor da web.
-
-### Passo 2. Definir permissões requeridas
-
-Os arquivos deveriam ser propriedade de um utilizador do servidor da web e ter as permissões corretas. Por favor, define as permissões necessárias através das [instruções](server-configuration.md#permissões-requeridas-para-sistemas-baseados-em-unix).
-
-### Passo 3. Importar o despejo da base de dados
-
-O despejo da base de dados deve ser importando para a mesma base de dados com a mesma credencial de utilizador, caso contrário a correção deve ser feita no arquivo de configuração `ESPOCRM_DIRECTORY/data/config.php`. Para importar a tua base de dados do despejo, executa o comando abaixo num terminal:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Passo 4. Verificar/configurar crontab
-
-Verifica se o teu crontab está configurado apropriadamente. Executa o comando abaixo e verifica se o caminho para EspoCRM está correto:
-
-```bash
-sudo crontab -l -u www-data
-```
-onde:
- * `www-data` é teu utilizador do servidor de web.
-
-Se tiveres que fazer quaisquer mudanças, usa este comando:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Mais detalhes sobre configurar crontab para EspoCRM está descrito [aqui](server-configuration.md#configure-um-crontab).
diff --git a/i18n/pt_PT/administration/bpm.md b/i18n/pt_PT/administration/bpm.md
deleted file mode 100644
index 8be85ee06..000000000
--- a/i18n/pt_PT/administration/bpm.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# Business Process Management
-
-A ferramenta Business Process Management (BPM) dá a habilidade de modelar e automatizar os processos de negócios no EspoCRM. É um motor que executa processos de negócios descrito no BPMN 2.0 padrão. A ferramenta BPM está disponível na extensão [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-
-
-### Diferença da ferramenta Workflows
-
-A ferramenta Workflows está destinada para automação de regras simples de negócios, sem fluxo sequencial de itens, quando não há necessidade de mostrar o fluxo em gráficos.
-
-A ferramenta BPM é destinada a fluxos de negócios mais complexos, onde pode haver fluxos divergindo e convergindo, atrasos na execução, interações do utilizador. Um fluxograma faz os processos do negócio mais compreensivos para um humano, um log permite ver como o processo foi mantido.
-
-## Fluxogramas dos Processos
-
-O link para os fluxogramas dos processos está disponível no painel de administração. Isso também pode ser adicionado como uma aba no painel de navegação.
-
-Fluxogramas são destinados para a modelagem de processos de negócios. Administradores podem criar e editar fluxogramas. Utilizadores comuns podem somente ver os fluxogramas.
-
-Cada fluxograma tem um tipo de entidade específica (campo Target Type). O fluxograma determina a execução de instâncias de processos futuros. Ele consiste em elementos do fluxograma e conexões entre elementos.
-
-Se os processos do fluxograma têm o campo 'Is Active' desmarcado, ele não iniciará as instâncias dos processos.
-
-Para mostrar detalhes e parâmetros de certo elemento do fluxograma, precisas de clicar nele. Em modo de edição tu és capaz de editar os parâmetros.
-
-## Processos
-
-Os processos estão disponíveis no painel de administração. O link também pode ser adicionado à aba no painel de navegação.
-
-Os processos representam instâncias de processos de negócios. Quando ele é iniciado, o seu estado para a ser 'Started'. Quando o processo é finalizado, o seu estado passa a ser 'Ended'. O processo pode também ser parado manualmente por um utilizador que tenha acesso à edição de processos. Se ele é parado manualmente, o seu estado passa a ser 'Stopped'.
-
-O processo é executado de acordo com o fluxograma. O processo de fluxograma não pode ser mudado depois que o processo é iniciado.
-
-O processo está relacionado obrigatoriamente a um único registro alvo.
-
-Os processos podem ser iniciados automaticamente (sob condições específicas ou através de agendamento) ou manualmente (onde há pelo menos um 'Iniciar Evento' no fluxograma). Para começar processos manualmente o utilizador precisa de clicar no botão 'Iniciar Processo' na lista de processos.
-
-## Elementos dos Fluxogramas
-
-### Eventos
-
-Eventos são mostrados nos fluxogramas como círculos.
-
-#### Iniciar Evento
-
-Não tem parâmetros. É um ponto de início do processo. Iniciar Evento pode ser iniciado manualmente por um utilizador que tenha acesso para criar processos. O usuário precisa clicar no botão 'Iniciar Processo' na lista de processos.
-
-#### Iniciar Evento Condicional
-
-Um ponto de início do processo. É suposto para ser acionado automaticamente quando as condições específicas são atendidas. Há dois tipos de acionamentos: 'Depois de um registro criado', 'Depois de um registro salvo'.
-
-#### Iniciar Processo Agendado
-
-Um ponto de início do processo. Isso inicia processos por agendamento. Precisas especificar a lista de reporte que retorna registros para iniciar processos e agendar na notação do crontab.
-
-#### Evento Intermediário Condicional
-
-Este evento para o fluxo até que critérios específicos sejam atendidos.
-
-#### Evento Intermediário Agendado
-
-Este evento para o fluxo e esperar o quanto for especificado pelos parâmetros dos eventos.
-
-Para agendamentos mais complexos podes utilizar [fórmula](formula.md). Scripts de fórmula devem retornar um valor Data-Tempo (em fuso horário UTC). Uma vez que esse tempo chega, o fluxo procederá para o próximo elemento.
-
-Através da utilização da função de fórmula datetime\closest, é possível definir o relógio para uma hora específica no futuro, por exemplo, o início do próximo dia de trabalho.
-
-#### Fim de Evento
-
-Finaliza o fluxo atual. Ele não finaliza fluxos sendo executados em paralelo. Quando o fluxo chega ao fim do evento e não há qualquer coisa executando em paralelo, o processo finaliza.
-
-#### Fim de Evento Conclusivo
-
-Finaliza todos os fluxos. Processo é subsequentemente finalizado.
-
-### Entradas
-
-Entradas são mostrados como diamantes.
-
-#### Entrada Exclusiva
-
-Pode divergir ou convergir fluxos.
-
-No caso de divergência, ela define um único fluxo (caminho) que será escolhido de acordo com critérios específicos. A primeira condição atendida determina o fluxo, próximas condições são omitidas. Há uma habilidade de especificar fluxo padrão. O fluxo padrão é escolhido se não existem quaisquer condições atendidas. O fluxo padrão está marcado com um sinal de barra.
-
-No caso de convergência, ela apenas direciona o fluxo para o elemento de saída. Ela não é bloqueada após o fluxo passar através, então fluxos paralelos não serão unidos em um único fluxo.
-
-
-
-
-
-#### Entrada Inclusiva
-
-Pode divergir ou convergir fluxos.
-
-No caso de divergência, ela pode direcionar um ou múltiplos fluxos paralelos (caminhos), dependendo do atendimento de critérios de cada fluxo. O fluxo padrão é escolhido se não existem quaisquer condições atendidas. O fluxo padrão está marcado com um sinal de barra.
-
-Se há necessidade de unir fluxos paralelos produzidos por uma entrada inclusiva divergente, tu precisas usar uma entrada inclusiva convergente. Ela vai esperar for todos os fluxos de entrada e então seguir para o elemento de saída.
-
-
-
-Nota: Entradas divergentes e convergentes devem ser balanceadas.
-
-Nota: Se um dos fluxos paralelos foi finalizado por algum motivo então a entrada divergente nunca será processada. O processo será bloqueado. Evita um design de fluxograma que possa trazer tal situação.
-
-#### Entrada Paralela
-
-Pode divergir ou convergir fluxos.
-
-Em caso de divergência, ela divide o fluxo em múltiplos fluxos paralelos. Não há parâmetros para esse tipo de entrada.
-
-Em caso de convergência, ela espera até todos os fluxos de entrada venham e então continua para o próximo elemento de saída.
-
-
-
-Nota: Entradas divergentes e convergentes devem ser balanceadas.
-
-Nota: Se um dos fluxos paralelos foi finalizado por algum motivo então a entrada divergente nunca será processada. O processo será bloqueado. Evita um design de fluxograma que possa trazer tal situação.
-
-#### Entrada Baseada em Evento
-
-Pode somente divergir fluxos.
-
-Ela para o fluxo até qualquer dos eventos de saída seja disparado. O evento disparado determina o único fluxo. Outros eventos de saída são rejeitados.
-
-Somente eventos intermediários podem estar na outra saído do fluxo de sequência de saída.
-
-
-
-### Atividades
-
-Atividades são mostradas como retângulos arredondados.
-
-#### Tarefas
-
-Tarefas podem executar as ações seguintes:
-
-* Criar Registro - cria um novo registro de qualquer tipo de entidade;
-* Criar Registro Relacionado - cria um novo registro relacionado ao registro alvo;
-* Atualizar Registro Alvo;
-* Atualizar Registro Relacionado - atualiza o registro ou registros relacionados ao registro alvo;
-* Atualizar Registro Criado - atualiza um campo específico de qualquer registro criado no processo atual;
-* Atualizar Processo de Registro - pode ser usado para designar o processo a um utilizador ou equipa específico;
-* Ligar a Outro Registro - liga o registro alvo com um registro específico;
-* Romper Ligação de Outro Registro - rompe a ligação do registro alvo do registro especificado;
-* Aplicar Regra de Designação - designa o registro alvo, o registro do processo ou qualquer registro criado pelo processo de acordo com a regra específica;
-* Criar Notificação - cria notificação dentro do aplicativo para usuários específicos;
-* Fazer Seguido - faz um usuário específico seguir o registro alvo, o registro do processo ou qualquer registro criado pelo processo;
-* Executar Ação de Serviço - executa ações de serviços personalizados implementados por desenvolvedores.
-
-Ações disponíveis para tarefas são quase as mesmas como na característica Fluxo de Trabalho. Veja mais detalhes sobre [ações de fluxo de trabalho](workflows.md#ações).
-
-#### Enviar Mensagem de Tarefa
-
-Envia mensagem por email para um receptor específico.
-
-#### Tarefa de Utilizador
-
-Providencia uma habilidade flexível de interação de utilizador. Ela para a execução até que o usuário (explicitamente especificado ou por regra de designação) conclua a tarefa. O registro da Tarefa do Processo do Usuário será criado no sistema. Por padrão, existem três tipos de ações: Aprovar, Rever e Concluir.
-
-* As do tipo Aprovar exige que o usuário escolha entre 'Aprovada' ou 'Recusada'.
-* As do tipo Revisar somente dão uma opção: 'Revisado'.
-* As do tipo Concluir possuem duas opções: 'Completada' e 'Falhada'.
-
-
-O usuário designado a criar o registro da Tarefa do Processo do Usuário receberá uma notificação dentro do aplicativo. O administrador pode também ativar notificações por email.
-
-Os utilizadores podem também adicionar Tarefas do Utilizador do Processo como pequenas informações em seu painel de controle para ver tarefas do utilizador do processo atual deles.
-
-É possível ler a resolução da tarefa de utilizador passada dentro de uma entrada divergente ou eventos condicionais, fazendo ramificação no fluxo do processo.
-
-#### Tarefa de Script
-
-Executa o script na linguagem [espo-fórmula](formula.md) Todas as variáveis definidas (`$variableName`) serão guardadas e estarão disponíveis dentro do processo.
-
-### Fluxos
-
-#### Sequência de Fluxos
-
-Representadas como uma flecha sólida. Indica a ordem em que os elementos do processo serão executados.
-
-## Condições
-
-Entradas de eventos condicionais, exclusivas e inclusivas divergentes, possuem condições que determinam o fluxo do processo.
-
-Através da UI há uma habilidade de verificar condições para os seguintes registros:
-
-* Registro Alvo;
-* Registros relacionados ao alvo através de relacionamentos muitos-para-um e filho-para-pai;
-* Registros criados pelos processos através de tarefas;
-* Registros de tarefas de utilizadores, que permitem a verificação da resolução.
-
-É possível também definir condições na linguagem [Espo-fórmula](formula.md).
-
-Condições na ferramenta BPM são as mesmas como na característica Fluxo de Trabalho. Veja mais detalhes sobre isso em [condições dos fluxos de trabalhos](workflows.md#condições).
-
-## Exemplos
-
-### Exemplo 1
-
-
-
-### Exemplo 2
-
-
-
-### Exemplo 3
-
-
diff --git a/i18n/pt_PT/administration/emails.md b/i18n/pt_PT/administration/emails.md
deleted file mode 100644
index 5d6b65cd6..000000000
--- a/i18n/pt_PT/administration/emails.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Emails
-
-Importante. [Cron](server-configuration.md#configure-um-crontab) deveria ser configurado no teu sistema para fazer com que as pesquisas de email funcione. Podes encontrar as informações no teu EspoCRM em Administration > Scheduled Jobs.
-
-## Panorama
-
-EspoCRM tem uma habilidade de monitorizar caixas de email IMAP. O email pode ser arquivado de dois modos: Grupo de Contas de Email e Contas de Email Pessoais. Contas de Entrada para Grupo são pretendidas para caixas de email de grupos: o caso mais comum é uma caixa para o suporte. Contas de Email Pessoal são pretendidas para as caixas de email pessoais dos utilizadores.
-
-Enquanto um email está a ser recebido, o sistema tenta ligá-lo com o registro apropriado (Contas, Condução, Oportunidade, Caso). Os utilizadores que seguem aquele registro vão receber uma notificação sobre um novo email no sistema, mesmo que ele não esteja no 'Para' ou 'CC'.
-
-## Grupo de Contas de Email
-
-Somente o administrador pode configurar Grupo de Contas de Email. Os Grupo de Contas de Email podem ser usados para emails que estão a ser recebidos ou enviados. Enviar emails de contas de grupos está disponível desde a versão 4.9.0.
-
-O campo equipas determina a quais equipas serão atribuídos os emails que estão a chegar.
-
-Se o grupo de contas de email tem SMTP e está verificado como divididos, então um acesso será controlado por Papéis através da permissão do Grupo de Contas de Email. O campo equipas será usado se o nível de permissão estiver definido como equipa.
-
-Existe uma habilidade de fazer o sistema enviar uma mensagem automática para emails recebidos.
-
-## Email-para-Caixa
-
-Há uma opção de fazer o sistema criar caixas de emails de grupo recebidos.
-Essa característica é intencionada para as equipas de suporte.
-As caixas podem ser distribuídas para utilizadores de uma equipa específico de acordo com esses caminhos: 'atribuição direta', 'um utilizador por turno' e 'menos ocupado'.
-Somente o primeiro email na sequência cria uma nova caixa.
-Cada email subsequente será ligado a um registro de caixa existente e mostrado no seu painel 'Transmissão'.
-
-Quando os utilizadores pretendem enviar uma resposta para o cliente, eles precisam de ter a certeza que a caixa está selecionada como um superior do email que está sendo enviado. Isso fará com que o cliente responda para o endereço de email do grupo em vez de para o email do utilizador.
-
-## Contas de Email Pessoal
-
-Os utilizadores podem configurar as suas próprias contas de email que necessitem de monitorização. Emails > Top Right Dropdown Menu > Personal Email Accounts. O administrador também pode gerir as contas de email dos utilizadores.
-
-## Filtros de Email
-
-Esses permitem que ocorra a filtragem dos emails recebidos de acordo com critérios específicos Por exemplo, se tu não quiseres mensagens de notificação enviadas por alguma aplicação seja importada para o EspoCRM, podes criar um filtro para fazer EspoCRM ignorá-las.
-
-O administrador pode criar filtros globais, aplicados para todas as contas de email. Os utilizadores podem criar filtros para suas próprias contas de email e para uma caixa de entrada inteira.
diff --git a/i18n/pt_PT/administration/entity-manager.md b/i18n/pt_PT/administration/entity-manager.md
deleted file mode 100644
index 278734a39..000000000
--- a/i18n/pt_PT/administration/entity-manager.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Gestor de Entidades
-
-O Gestor de Entidades está disponível através do painel 'Administração'. Ele fornece uma capacidade altamente personalizar sua instância de EspoCRM. Tu és capaz de fazer o seguinte:
-
-* Adicionar novos tipos de entidades.
-* Personalizar tipos de entidades existentes: mudas rótulos, ordem padrão visto como lista, habilitar ou desabilitar transmissão.
-* Configurar campos: adicionar novo, personalizar os existentes.
-* Configurar relacionamentos: adicionar novo, mudar rótulos dos existentes.
-
-## Criando novas entidades
-
-Clique no botão 'Criar Entidade' na página do Gestor de Entidades Especificar nome, rótolo e tipo. Se selecionares o tipo 'Pessoa', sua entidade vai ter os campos Email, Telefone, Primeiro Nome, Último Nome e Saudação. Marque 'Transmissão' se quiseres que a sua entidade tenha um painel de transmissão e os utilizadores sejam capazes de 'Seguir' entidades desse tipo.
-
-Tipos:
-
-* Básico - apenas uma entidade vazia com campos básicos como Nome, Usuário Designado, Equipas, Descrição.
-* Básico Maior - como o Básico, porém com os painéis Atividades, Histórico e Tarefas (disponível desde a versão 4.3.0).
-* Evento - campos Data de Início, Data de Fim, Duração, Superior, Estado. Disponível no painel Calendário e Atividades (desde 4.3.0, deve estar habilitada em Administração > Opções).
-* Pessoa - campos Email, Telefone, Primeiro Nome, Último Nome, Saudação, Endereço. Painéis Atividades, Histórico, Tarefas.
-* Companhia - campos Email, Telefone, Endereço de Cobrança, Endereço de Entrega. Painéis Atividades, Histórico, Tarefas.
-
-## Atualizar entidade existente
-
-Se clicares no link 'Editar' numa certa entidade, tu serás capaz de mudar alguns parâmetros daquela entidade.
-
-* Rótulos - nomes singular e plural da entidade.
-* Os registros de ordem padrão são organizados nas visualizações de listas.
-* Transmissão - se o recurso Transmissão está ativado para esta entidade.
-* Desabilitado - marca se não precisares dessa entidade no teu sistema.
-* Filtros de Campos de Texto - quais campos 'pesquisar por' para o filtro de texto principal e pesquisa global
-
-
-## Campos
-
-Ao clicar no link 'Campos' serás direcionado para uma página separada. Lá serás capaz de criar novos campos ou atualizar os existentes. Os tipos seguintes de campos estão disponíveis no Gerenciador de Entidades:
-
-* Endereço - endereço com rua, cidade, estado, código postal e país;
-* Arranjo - lista de valores, com a capacidade de selecionar valores múltiplos (não é uma boa opção se precisares de pesquisar através desse campo); os utilizadores podem adicionar os seus próprios valores se as opções não foram especificadas.
-* Anexar Múltiplo - anexar vários arquivos;
-* Auto-incremento - lê o número gerado;
-* Booleano - caixa para marcar, verdadeiro ou falso;
-* Moeda - para valores monetários;
-* Data;
-* Hora;
-* Enum - caixa de seleção, com a capacidade de selecionar somente um valor;
-* Arquivo - carregar um arquivo;
-* Decimal - número com casas decimais;
-* Externo - um campo de uma entidade relacionada;
-* Imagem - carregar um arquivo de imagem com pré-visualização;
-* Inteiro - número inteiro;
-* Número - número em uma sequência de caracteres que se auto-incrementa, com um possível prefixo e um tamanho específico;
-* Multi-enum - lista de valores, com a capacidade de selecionar valores múltiplos (não é uma boa opção se você necessita pesquisar nesse campo), similar ao Arranjo mas melhor.
-* Texto - área de texto, para longos textos de multilinhas;
-* URL - para links;
-* Varchar - texto curto;
-* Wysiwyg - parecido com o campo Texto, com a capacidade de formatar texto.
-
-Parâmetros:
-* Requeridos - se o preenchimento do campo é obrigatório.
-* Valor Padrão - Valor do campo definido através da criação de um novo registro.
-* Auditado - atualizações do campo serão registradas na Transmissão
-
-**Nota**: Após teres de adicionar um novo campo, precisas de colocar esse campo em [layouts](layout-manager.md) (Administração > Gestor de Layout).
-
-### Lógica Dinâmica
-
-Fornece uma capacidade de fazer formulários dinâmicos. É possível definis condições fazendo certos campos visíveis, obrigatórios ou somente leitura. Condições serão verificadas automaticamente quando os dados nos formulários mudarem.
-
-Para os campos Enum, Arranjo e Multi-enum, é possível definir diferentes conjuntos de opções que estarão disponíveis para o campo dependendo em qual condição foi satisfeita.
-
-
-## Relacionamentos
-
-Podes criar novos relacionamentos entre ambos fora-da-caixa ou entidades personalizadas. Existem 3 tipos de relacionamentos disponíveis:
-
-* Um-Para-Muitos: após teres criado esse relacionamento podes colocar um campo para link para os detalhes do layout da entidade da direita e adicionar um painel de relacionamento à entidade da esquerda;
-* Muitos-Para-Um: o mesmo que Um-Para-Muitos, porém ao contrário;
-* Muitos-Para-Muitos: painéis de relacionamento em ambos os lados.
-
-O parâmetro 'Ligar Vários Campos' implica que o campo do tipo 'linkMultiple' será criado junto ao relacionamento. Podes colocar tal campo no layout. É conveniente para rápida escolha de registros relacionados. Não é uma boa opção se seu relacionamento é intencionado para ter muitos registros ligados, que pode causar lentidão no carregamento de detalhes no ecrã de visualização.
-
-Se o parâmetro 'Auditado' está marcado, então as atualizações dos relacionamentos serão registradas na Transmissão.
diff --git a/i18n/pt_PT/administration/extensions.md b/i18n/pt_PT/administration/extensions.md
deleted file mode 100644
index 5a898c663..000000000
--- a/i18n/pt_PT/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Gerir Extensões
-
-## Como instalar uma extensão
-
-Para instalar extensões para EspoCRM (ex: Pacote Avançado, Integração VoIP):
-
-1. Entra como administrador.
-2. Vai em Administração > Extensões.
-3. Carrega o teu pacote da extensão (arquivo zip).
-4. Clica no botão instalar.
-
-
-## Como atualizar uma extensão
-
-Para atualizar uma extensão já instalada (ex: Pacote Avançado, integração VoIP) para uma versão mais nova:
-
-1. Descarrea a nova versão da extensão necessária.
-2. Entra como administrador.
-3. Vai em Administração > Extensões.
-4. Carrega o pacote da tua nova extensão (arquivo zip) sem desinstalar a versão já instalada.
-5. Clica no botão instalar.
-
-
-## Como desinstalar uma extensão
-
-Passos para desinstalar uma extensão instalada:
-
-1. Entra como administrador.
-2. Vai em Administração > Extensões.
-3. Encontra a extensão desejada na lista de extensões disponíveis.
-4. Clica no botão Desinstalar.
-
-
-## Como apagar uma extensão
-
-Quando uma extensão é desinstalada, ela ainda fará parte do sistema. Ela pode ser completamente removida. Passos para remover uma extensão:
-
-1. Entra como administrador.
-2. Vai em Administração > Extensões.
-3. Encontra a extensão desejada na lista de extensões disponíveis.
-4. Clica no botão Remover
diff --git a/i18n/pt_PT/administration/formula.md b/i18n/pt_PT/administration/formula.md
deleted file mode 100644
index c92617cdd..000000000
--- a/i18n/pt_PT/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Campos com Cálculos (Fórmulas)
-
-No gestor de entidades é possível definir um script (fórmula) para entidades de tipos específicos. Esse script será executado todas as vezes antes do registro ser salvo.
-Ele garante a capacidade de automaticamente definir campos específicos (atributos) com valores derivados dos cálculos.
-
-Para editar uma fórmula siga Administração > Gestor de Entidades > Menu deslizante à direita na linha da entidade desejada > Fórmula.
-
-Tu também podes precisar de definir campos, que são supostamente para serem calculados, Somente de Leitura através do Gestor de Entidades.
-
-
-## Sintaxe
-
-A fórmula em EspoCRM é escrita numa única linguagem designada especificamente para esta característica.
-
-Há operadores, atributos de funções e valores que podem ser usados nas fórmulas. Expressões separadas devem ser delimitadas por caracteres ';'.
-
-### Operadores
-
-* `=` - designação.
-* `||` - é o OU lógico,
-* `&&` - é o E lógico,
-* `!` - é o NÃO lógico,
-* `+`- soma numérica,
-* `-` - subtração numérica,
-* `*` - multiplicação numérica,
-* `/` - divisão numérica,
-* `%` - módulo numérico,
-* `==` - comparação de igualdade,
-* `!=` - comparação de diferença,
-* `>` - comparação de maior que,
-* `<` - comparação de menor que,
-* `>=` - comparação de maior que ou igual a,
-* `<=` - comparação de menor que ou igual a.
-
-Priority of operators:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Atributos
-
-Atributos representam campos de valores da entidade visada. Podes inserir atributos disponíveis ao clicar no botão mais.
-
-É possível acessar atributos de entidades relacionadas com o formato seguinte: `linkName.attributeName`.
-
-
-### Funções
-
-Formato de uso das funções: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Funções fora-da-caixa estão listadas abaixo.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` Se a CONDITION está satisfeita, então faça CONSEQUENT. Se não está -- então faz ALTERNATIVE.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` Se a CONDITION está satisfeita, então faz CONSEQUENT. Se não está -- não faças nada.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Concatena duas ou mais sequências de caracteres.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Extrai os caracteres da STRING na posição START e LENGTH.
-
-Se LENGTH for omitida, será retornada a subsequência de caracteres iniciada em START até o fim da STRING.
-
-Se LENGTH for negativo, então aquela quantidade de caracteres serão omitidos do final da STRING.
-
-#### string\\trim
-`string\trim(STRING)` Retira espaço em branco do início e do fim da STRING.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Converte as letras para minúsculas. (desde a versão 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Converte as letras para maiúsculas. (desde a versão 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Retorna a data de hoje.
-
-#### datetime\now
-`datetime\now()` Retorna a data e hora atual.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Converte a data ou data e hora VALUE em uma sequência de caracteres formatada de acordo com as configurações do aplicativo. TIMEZONE e FORMAT podem ser omitidos. Se o TIMEZONE for omitida, então o fuso horário padrão será usado. Se o FORMAT for omitido, então o formato padrão será usado.
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Retorna a data do mês (1-31). `0` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Retorna o mês (1-12). `0` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Retorna o ano. `0` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Retorna a hora (0-23). `-1` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Retorna os minutos (0-59). `-1` se VALUE estiver vazio. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (desde a versão 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Retorna o dia da semana (0-6). `-1` se VALUE estiver vazio. `0` - para domingo. Se o TIMEZONE for omitido, então o fuso horário do sistema é usado. (since version 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Retorna a diferença entre duas datas ou datas e horas. INTERVAL_TYPE pode ser 'anos', 'meses', 'dias', 'horas', 'minutos'. Retorna `nulo` se falhar. O resultado será negativo se VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Adiciona MINUTES à data e hora VALUE. MINUTES podem ser negativo.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Adiciona HOURS à data e hora VALUE. HOURS pode ser negativo.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Adiciona DAYS à data ou data e hora VALUE. DAYS pode ser negativo.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Adiciona WEEKS à data ou data e hora VALUE. WEEKS pode ser negativo.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Adiciona MONTHS à data ou data e hora VALUE. MONTHS pode ser negativo.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Adiciona YEARS à data ou data e hora VALUE. YEARS pode ser negativo.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` Retorna a data ou data e hora mais próxima do VALUE baseada nos argumentos passados. (desde a versão 5.0.0)
-
-TYPE pode ser one dos seguintes valores: 'horário', 'minuto', 'hora', 'data', 'mês', 'diaDaSemana'. TARGET é um valor inteiro ou uma sequência de caracteres. IS_PAST significa achar o mais próximo no passado. Se TIMEZONE for omitida, então o fuso horário padrão é usado.
-
-Exemplos:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Retornará o valor de data e hora mais próximo no futuro com o horário 20:00.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Retornará `2017-11-01`, o primeiro dia do mês.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Retornará a próxima segunda-feira (o início do dia).
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Converte VALUE numérico em sequência de caracteres formatada de acordo com um formato específico ou configurações do aplicativo padrão. Se DECIMALS, DECIMAL_MARK OR THOUSAND_SEPARATOR então os padrões do sistema serão usados.
-
-Exemplos:
-
-`number\format(2.666667, 2)` - resultará 2.67;
-
-`number\format(1000, 2)` - resultará 1,000.00;
-
-`number\format(10.1, 0)` - resultará 10.
-
-
-#### number\abs
-`number\abs(VALUE)` Valor absoluto. Retorna nulo se VALUE não é numérico.
-
-#### number\round
-`number\round(VALUE, PRECISION)` Retorna um valor arredondado de VALUE a uma PRECISION especificada (o número de dígitos depois do ponto decimal). PRECISION também pode ser negativo ou zero (padrão).
-
-#### number\floor
-`number\floor(VALUE)` Retorna o próximo inteiro de menor valor através do arredondamento para baixo, se necessário. (desde a versão 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` Retorna o próximo inteiro de maior valor através do arredondamento para cima, se necessário. (desde a versão 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Retorna TRUE se a entidade é nova (está sendo criada) e FALSE se não está (está sendo atualizada).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Retorna TRUE se o ATTRIBUTE da entidade mudou.
-
-Exemplo:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Retorna TRUE se o ATTRIBUTE da entidade não obteve mudanças.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Atributo que foi definido quando a entidade visada foi buscada na base de dados. Antes dela ser modificada.
-
-Exemplo:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Adiciona ID para o campo Links Múltiplos. Por exemplo, adiciona 'someTeamId' ao campo 'teams'.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Adiciona a lista de IDs. (desde a versão 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Verifica se o campo Links Múltiplos tem um ID específico.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Remove um ID específico do campo Links Múltiplos.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Verifica se a entidade visada está relacionada com outra entidade representada por LINK e ID.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Retorna o ATTRIBUTE do utilizador atual.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Retorna arranjo. (desde a versão 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Retorna verdadeiro se LIST contêm VALUE. Pode ser usado pelos campos Arranjo e Multi-enum. (desde a versão 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Adiciona um ou mais elementos no final de um arranjo e retorna o novo arranjo. (desde a versão 5.0.0)
-
-#### array\length
-`array\length(LIST)` Retorna a contagem dos elementos em LIST. (desde a versão 4.8.1)
-
-
-### Valores
-
-* Sequências de caracteres. Ex: 'uma sequência de caracteres qualquer';
-* Números inteiros. Ex: 1, 100, 40300.
-* Números decimais. Ex: 5.2.
-
-### Variáveis
-
-É possível definir variáveis padronizadas nas fórmulas.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Exemplos
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Usando fórmulas em Fluxos de Trabalho
-
-Podes utilizar fórmulas nas condições e ações dos fluxos de trabalhos. Vê [documentação dos fluxos de trabalho](workflows.md#usando-fórmula-em-ações) para mais informações.
diff --git a/i18n/pt_PT/administration/import.md b/i18n/pt_PT/administration/import.md
deleted file mode 100644
index 974d8b3b2..000000000
--- a/i18n/pt_PT/administration/import.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Importar
-
-Importar é acessível somente a utilizadores administradores. Administração > Importar. Serás capaz de importar somente arquivos CSV.
-
-## Passo 1
-
-Seleciona qual o tipo de registro que precisas importar (campo Tipo de Entidade).
-Seleciona um arquivo CSV. Um arquivo deveria estar formatado com 'UTF-8'.
-Seleciona 'O que fazer?'. Opções disponíveis: 'Somente Criar', 'Criar & Atualizar', 'Somente Atualizar'.
-
-* `Somente Criar` - seleciona se quiseres que o registro seja apenas criado.
-* `Criar & Atualizar` - os registros serão criados, mas se forem encontrados registros de campo de valores coincidentes, eles serão atualizados. Serás capaz de verificar quais os campos que coincidirem no _Passo 2_.
-* `Somente Atualizar` - apenas registros com valores de campos coincidentes serão encontrados e serão atualizados.
-
-Uma vez que selecionares um arquivo csv, serás capaz de ver como ele deveria ser analisado no painel de pré-visualização. Quando mudares as propriedades, a pré-visualização será atualizada.
-
-* `Linha do Cabeçalho' - se o arquivo CSV tem a primeira linha com nomes dos campos.
-* `Executar em segundo plano' - recomendado se tiveres uma grande quantidade de registros a serem importados. Importar será processado através de cron. O estado será definido como 'Completo' quando o processo de importação finalizar.
-* `Saltar pesquisa por duplicações` - isto vai diminuir o tempo de execução da importação.
-
-Clica no botão _Próximo_ para seguir para o _Passo 2_.
-
-
-
-## Passo 2
-
-Configura o mapeamento do campo: como os campos correspondem a colunas no arquivo CSV. Podes saltar as colunas não necessárias aqui.
-Em caso de 'Criar & Atualizar' e 'Somente Atualização' precisas de verificar os campos pelos quais os registros que devem ser atualizados serão encontrados.
-Adiciona valores padrões novos que tu desejas e atualiza os registros para defini-los. Ex: podes especificar os campos Utilizador Designado ou Equipas.
-
-Após completar a importação tu serás capaz de reverter registros criados, ver duplicatas e atualizar registros. Duplicata significa que existia um registro similar no sistema. Podes remover todas as duplicatas importadas de uma vez. Nota: Reverter não funciona com registros atualizados.
-
-Clica no botão _Executar Importação_ para seguir. Pode levar algum tempo até que o processo de importação seja finalizado. Se precisares de importar uma grande quantidade de registros (dependendo das configurações do servidor, normalmente mais que 200 registros) precisas de ter a certeza que o parâmetro php 'set_time_limit' tem tamanho suficiente.
-
-
-
-## Como importar para Listas Destino
-
-Quando importares Contatos, Conduções ou Contas, podes adicioná-las a uma lista destino. No Passo 2 precisas de adicionar o campo Lista Destino no painel 'Valores Padrões' e selecionar um registro de lista destino desejada. Podes também usar a importação 'Somente Atualizar' ou 'Criar & Atualizar' para adicionar destinos existentes a uma lista destino.
diff --git a/i18n/pt_PT/administration/installation.md b/i18n/pt_PT/administration/installation.md
deleted file mode 100644
index 88a27d66d..000000000
--- a/i18n/pt_PT/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Instalação
-
-### Requisitos
-EspoCRM é executado na maioria dos fornecedores de hospedagem. Os requisitos são os seguintes:
-
-* PHP 5.6 ou versão mais recente de PHO com pdo habilitado, json, biblioteca GD, extensões mcrypt (normalmente habilitado por padrão);
-* MySQL 5.5.3 ou mais recente.
-
-Vê o artigo [Configurações do Servidor](server-configuration.md) para mais informações.
-
-### 1. Descarrea o pacote de instalação do EspoCRM
-Para descarreares a última versão do EspoCRM, acede o link [página de download](http://www.espocrm.com/download/)
-
-### 2. Faz o upload dos arquivos do EspoCRM para o Teu Servidor.
-
-Uma vez que o download esteja concluído, faz o upload do pacote para o teu servidor de web.
-Para fazeres o upload podes usar SSH, FTP ou o painel de administração da hospedagem.
-Extrai os arquivos para o diretório do teu servidor de web público (ex: `public_html`, `www`, etc.).
-
-_Nota: Para FTP, precisarás de extrair os arquivos antes de fazer o upload para o teu servidor de web._
-
-### 3. Cria uma Base de Dados MySQL para o EspoCRM usar
-
-Vai para o painel de administração da hospedagem, ou para o SSH, e cria uma nova base de dados e um utilizador para o EspoCRM (ex: 'Base de Dados MySQL' no cPanel).
-
-### 4. Executa o processo de instalação do EspoCRM.
-
-Agora, abre o teu navegador e vai para a URL com os arquivos do EspoCRM (ex: 'http://seudominio.com/espo`).
-
-Se viaulizares este ecrã, é porque deu um erro "Permissão negada".
-Logo, precisas de executar o comando mostrado no terminal através de SSH, ou definir as permissões corretas.
-Deveria ser 755 para diretórios, 644 para arquivos, e 755 para o diretório 'dados'.
-Além disso, tens que ter a certeza que possuis o _proprietário_ e o _grupo_ corretos.
-
-
-
-Se viaulizares este ecrã seguinte, o problema com a permissão foi resolvido e podes começar a instalação do EspoCRM.
-
-
-
-Nesta página, podes ler e aceitar os Termos de Uso.
-
-
-
-Digita os detalhes para tua recém-criada base de dados MySQL.
-
-
-
-Digita o teu nome de utilizador e senha de Administrador EspoCRM.
-
-
-
-Nesta página podes definir as configurações padrões do EspoCRM, como formato de data e hora, fuso horário, moeda e outros.
-
-
-
-Digita as configurações SMTP para a saída de emails, se desejares que seja possível o envio de emails.
-Este passo pode ser saltado ao clicares no botão _Próximo_.
-Todas estas opções podem ser adicionadas/modificadas no EspoCRM após a instalação.
-
-
-
-Parabéns! A instalação foi finalizada.
-O último item é configurar as Tarefas Agendadas para serem executadas pelo seu sistema. Isto pode ser feito através da execução 'crontab -e' em linux cli e em _Agendador de Tarefas do Windows_ nos sistemas Windows.
-
-
-
-Nós esperamos que tenhas ficado satisfeito ao trabalhares com o EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/pt_PT/administration/layout-manager.md b/i18n/pt_PT/administration/layout-manager.md
deleted file mode 100644
index 8cb5ba239..000000000
--- a/i18n/pt_PT/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Gertor de Layout
-
-O Gestor de Layout está disponível no painel de administração. Ele permite personalizar a aparência de detalhes, editar, listas de visualização assim como filtros de pesquisas e campos para formulário de atualizações em massa.
-
-## Listas
-
-O layout principal para a lista de visualização. Define as colunas e seus parâmetros.
-
-
-
-Os parâmetros disponíveis para colunas estão listadas abaixo.
-
-### Largura (%)
-
-A largura da coluna em percentagem, vazio significa largura automática.
-
-### Link
-
-Se marcado, o campo será mostrado como um link para a visualização de detalhes dos registros. Normalmente usado para nomes dos campos.
-
-### Não Organizável
-
-Desabilita a capacidade de organizar as colunas.
-
-### Alinhamento
-
-Alinha a coluna à esquerda ou à direita.
-
-## Detalhes
-
-O layout principal para a visualização de detalhes e editar visualização. Formata painéis, linhas e células. Células contêm campos.
-
-As linhas podem conter duas células ou uma células que está expandida à largura máxima da linha. Para adicionar linhas com uma célula expandida, precisas de adicionar a nova linha e clicar no sinal de menos em qualquer célula.
-
-
-
-## Lista (Pequena)
-
-O layout de lista para painéis de relacionamentos. Também pode ser usado em outros locais onde é aceitável mostrar listas numa visualização estreita.
-
-## Detalhes (Pequeno)
-
-A visualização de detalhes para criar rapidamente, ver rapidamente ou editar rapidamente os fomulários.
-
-## Filtros de Pesquisa
-
-A lista de campos disponíveis na visualização de lista para serem pesquisados.
-
-## Atualização em Massa
-
-A lista de campos disponíveis no fomulário de Atualização em Massa.
-
-## Painéis de Relacionamento
-
-A lista de painéis de relacionamentos mostrada na visualização detalhada na parte inferior. Painéis podem ser reordenados. É possível definir as cores dos painéis com o parâmetro Estilo.
-
-## Painéis Laterais
-
-Painéis laterais para Detalhes, Editar, Detalhes Menor, Editar Menor. Dá a capacidade de esconde ou reordenar painéis em lista como: Atividades, Histórico, Tarefas e outros. Painéis podem ser coloridos pelo parâmetro Estilo.
-
-## Layouts Adicionais
-
-Alguns tipos de entidades contém layouts adicionais: Converter Condução, Lista para Conta.
diff --git a/i18n/pt_PT/administration/ldap-authorization-for-ad.md b/i18n/pt_PT/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index 8f65ec147..000000000
--- a/i18n/pt_PT/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Autorização LDAP para Active Directory
-
-Exemplo de configuração de autorização LDAP para o servidor do Active Directory. O guia completo de configuração de configuração LDAP está descrito [aqui](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/pt_PT/administration/ldap-authorization-for-openldap.md b/i18n/pt_PT/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 96f83e70c..000000000
--- a/i18n/pt_PT/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Autorização LDAP para OpenLDAP
-
-Exemplo de configuração de autorização LDAP para servidor OpenLDAP. O guia completo de configuração de configuração LDAP está descrito [aqui](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/pt_PT/administration/ldap-authorization.md b/i18n/pt_PT/administration/ldap-authorization.md
deleted file mode 100644
index a77e72c37..000000000
--- a/i18n/pt_PT/administration/ldap-authorization.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Autorização LDAP
-
-Neste guia, nós vamos mostrar como configurar a autorização LDAP para EspoCRM. Vamos lá.
-
-Vai para o teu servidor LDAP e cria uma base DN para os utilizadores EspoCRM como a seguinte:
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Nós temos que criar um utilizador para o sistema que vai ter acesso aos utilizadores DN (“cn=espo-users,ou=users,dc=espo,dc=local”). Sendo assim, o DN completo para este utilizador do sistema será
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Agora, nós podemos adicionar o utilizador LDAP para aceder o EspoCRM. Ex: Teste de Espo com o utilizador 'teste' dentro do “cn=espo-users,ou=users,dc=espo,dc=local” DN. Por favor, nota que: para seres capaz de usares este formato de login para o EspoCRM, deves especificar as opções para o "Atributo Nome de Utilizador" e para "Base DN".
-
-Então, vai até as configurações da Autenticação EspoCRM no painel Administrador, seleciona o método 'LDAP' e preenche os detalhes no LDAP:
-
-
-
-* Host – LDAP IP ou nome da hospedagem.
-* Port – porta de conexão.
-* Auth – credenciais de acesso para o servidor LDAP:
- * Full User DN – o utilizador DN do sistema completo que vai permitir pesquisar por outros utilizadores.
- * Password – a senha de acesso para o servidor LDAP.
-* Security – protocolo SSL ou TSL.
-* Username Attribute – o atributo para identificar o utilizador. Para o Active Directory, ele pode ser “userPrincipalName” ou “sAMAccountName”.
-* Account Canonical Form – tipo de sua conta em formulário canónico. Existem 4 opções:
- * Dn – o formulário no formato `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – o formulário 'teste'.
- * Backslash – o formulário `COMPANHIA\teste`.
- * Principal – o formulário `teste@companhia.com`.
-* Bind Requires Dn – se for necessário formatar o nome de utilizador no formulário DN.
-* Base Dn – a base DN padrão usada para pesquisas de utilizadores.
-* User Login Filter – o filtro que permite restringir utilizador que são capazes de usar o EspoCRM. Ex: `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – O domínio em que a autorização do servidor LDAP está sendo usada.
-* Account Domain Name Short – O domínio curto em que a autorização do servidor LDAP está sendo usada.
-* Try Username Split – a opção para separar um nome de utilizador com o domínio
-* Opt Referrals – se referidos devem ser seguidos até o cliente LDAP..
-* Create User in EspoCRM – essa opção permite o EspoCRM criar um utilizador do LDAP.
- * User First Name Attribute – atributo LDAP que é usado para determinar o primeiro nome do utilizador.
- * User Last Name Attribute – atributo LDAP que é usado para determinar o último nome do utilizador.
- * User Title Attribute – atributo do LDAP que é usado para determinar o título do utilizador.
- * User Email Address Attribute – atributo LDAP que é usado para determinar endereço de email do utilizador.
- * User Phone Number Attribute – atributo LDAP que é usado para determinar o número de telefone do utilizador.
-
-Agora, vai para a página de login e digite as credenciais do utilizador.
-
-
-
-O utilizador foi autenticado e automaticamente criado no EspoCRM.
-
-## Instruções de configuração baseadas no teu servidor:
-* [Servidor Active Directory](ldap-authorization-for-ad.md)
-* [Servidor OpenLDAP](ldap-authorization-for-openldap.md)
-
-Para mais informações sobre como configurar LDAP podem ser lidas na página da [biblioteca Zend\Ldap](https://zendframework.github.io/zend-ldap/intro/), visto que EspoCRM usa esta biblioteca.
-
-
-
-
diff --git a/i18n/pt_PT/administration/maps.md b/i18n/pt_PT/administration/maps.md
deleted file mode 100644
index 4176f44af..000000000
--- a/i18n/pt_PT/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Mapas
-
-## Como mostrar o mapa baseado no seu campo endereço
-
-Cada campo Endereço tem o seu campo Mapa correspondente. Tudo o que precisas de fazer é colocá-lo no layout Detalhes. Ele usa o serviço do Google Maps.
-
-`Administração > Gestor de Layout > Escolher entidade (Conta, Contato, Condução ou personalizado) > Detalhes > Arrastar & Soltar o campo Mapa.`
-
-Faz a célula larga usando o sinal de menos.
-
-Podes também configurar a altura do seu campo.
-
-`Administração > Gestor de Entidade > Escolher entidade > Campos > acha o campo mapa e clica nele > edita a altura e guarda.`
-
-## Chave de API
-
-Desde a versão 4.2.0 do EspoCRM, precisas especificar uma Chave de API para usar Google Maps (Administração > Integração > Google Maps).
-
diff --git a/i18n/pt_PT/administration/moving-to-another-server.md b/i18n/pt_PT/administration/moving-to-another-server.md
deleted file mode 100644
index 857dcf9b0..000000000
--- a/i18n/pt_PT/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Mover o EspoCRM para outro servidor
-
-Segue estes passos para mover o EspoCRM para outro servidor:
-
-### Passo 1. Cópia de segurança dos arquivos
-
-Abre um gestor de arquivos ou faz login através de SSH para arquivar todos os arquivos disponíveis do diretório EspoCRM. Para mais [detalhes](backup-and-restore.md#passo-1-c%C3%B3pia-de-seguran%C3%A7a-dos-arquivos).
-
-### Passo 2. Faz uma cópia de segurança da tua base de dados
-
-Os dados guardados na base de dados (MySQL, MariaDB) devem ser salvos numa cópia de segurança. Por favor, sige esta [recomendação](backup-and-restore.md#passo-2-c%C3%B3pia-de-seguran%C3%A7a-da-base-de-dados).
-
-### Passo 3. Copia os arquivos e cópias de segurança das bases de dados para outro servidor
-
-Copia os arquivos da cópia de segurança e da tua base de dados para um novo servidor.
-
-### Passo 4. Extrai os arquivos da cópia de segurança
-
-Para extrair os arquivos da cópia de segurança, podes usar o Gestor de Arquivos ou estas [intruções](backup-and-restore.md#passo-1-extraia-os-arquivos-da-c%C3%B3pia-de-seguran%C3%A7a).
-
-Nota: Os arquivos precisam ser colocados no diretório do servidor da web.
-
-### Passo 5. Configura um servidor
-
-Configura um novo servidor baseado nas recomendações [aqui](server-configuration.md).
-
-### Passo 6. Corrije as permissões
-
-Define as permissões requeridas e proprietários dos [arquivos](server-configuration.md#permissões-requeridas-para-sistemas-baseados-em-unix).
-
-### Passo 7. Importa a tua cópia de segurança da base de dados
-
-Primeiro, deves criar uma nova base de dados com um utilizador no MySQL. Para importar a tua base de dados da cópia de segurança, segue as [instruções](backup-and-restore.md#passo-3-importar-o-despejo-da-base-de-dados).
-
-### Passo 8. Corrije as configurações do EspoCRM
-
-Após importar com sucesso e configurar o servidor, por favor, corrije as configurações do EspoCRM no arquivo `ESPOCRM_DIRECTORY/data/config.php`:
-
- * configurações de conexão da base de dados:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'NOME_DO_BANCO_DE_DADOS',
- 'user' => 'SEU_USUÁRIO',
- 'password' => 'SENHA_DO_BANCO_DE_DADOS',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - se o nome de seu domínio (URL) mudou:
-
- ```php
- 'siteUrl' => 'https://novo-link.com',
- ```
-
- * proprietário padrão dos arquivos (somente se há diferença):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- onde `www-data` é teu utilizador do servidor da web.
-
-### Passo 9. Configura um crontab
-
-Configura um [crontab](server-configuration.md#configure-um-crontab).
-
-Nota: ele deveria ser configurado pelo utilizador do servidor da web.
-
-Isto é tudo. Agora a tua instância do EspoCRM está a ser executada num novo servidor.
diff --git a/i18n/pt_PT/administration/nginx-server-configuration.md b/i18n/pt_PT/administration/nginx-server-configuration.md
deleted file mode 100644
index 7d35e8010..000000000
--- a/i18n/pt_PT/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Configuração do servidor Nginx para EspoCRM
-
-Estas instruções são suplementares às orientações [Configuração do Servidor](server-configuration.md). Por favor, nota que todas as configurações listadas aqui são feitas no servidor Ubuntu.
-
-## Requerimentos de PHP
-
-Para instalar todas as bibliotecas necessárias, executa estes comandos num terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Reparar o erro “API Error: EspoCRM API is unavailable”:
-
-Segue apenas os passos necessários. Após cada passo, verifica se o problema foi resolvido.
-
-### 1. Habilita sobrescrever regras no servidor Nginx
-
-Adiciona este código para o arquivo de configuração do bloco do teu servidor Nginx (/etc/nginx/sites-available/SEU_SITE) dentro do bloco “server”:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Se não possuis este arquivo, deves criá-lo. Para isso, abre um terminal e executa o comando:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Adiciona o código listado acima. Para mais informações em como configurar um novo Virtual Host em Nginx, por favor, lê este [guia](nginx-virtual-host.md).
-
-Executa este comando num terminal para verificar se tudo está bem:
-
-```
-sudo nginx -t
-```
-
-Se estiver, executa o comando para reinicializar o servidor Nginx:
-
-```
-sudo service nginx restart
-```
-
-### 2. Adicionar o caminho RewriteBase
-
-Abrir um arquivo /ESPOCRM_DIRECTORY/api/v1/.htaccess e substituir a seguinte linha:
-
-```
-# RewriteBase /
-```
-por
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-onde, REQUEST_URI é uma parte de uma URL, por exemplo, para “http://exemplo.com/espocrm/”, REQUEST_URI é “espocrm”.
diff --git a/i18n/pt_PT/administration/nginx-virtual-host.md b/i18n/pt_PT/administration/nginx-virtual-host.md
deleted file mode 100644
index f8f53f4c6..000000000
--- a/i18n/pt_PT/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Configurar um Host Virtual em Nginx para EspoCRM
-
-Neste guia, nós vamos mostrar como configurar um host virtual em Nginx para EspoCRM no servidor Ubuntu.
-
-## Cria um arquivo de bloco do servidor
-
-Para criares este arquivo, abre o terminal e executa o comando:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Agora, abre este arquivo (/etc/nginx/sites-available/espocrm.conf) e modifica o código seguindo o formato mostrado abaixo (algumas configurações podem ser diferentes baseadas na configuração do teu servidor):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Substitui espocrm.local pelo nome do teu domínio
- root /var/www/html/espocrm; # Especifique a raiz do documento de seu EspoCRM
-
- index index.php index.html index.htm;
-
- # Configuração SSL
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Especificar seu PHP (php-cgi or php-fpm) baseado em suas configurações
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # Com apenas o php7.0-cgi:
- # fastcgi_pass 127.0.0.1:9000;
-
- # Com o php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Adicionar sobrescrever regras
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Habilitar o bloco deste servidor
-
-Cria uma ligação simbólica:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Executa este comando para verificar se está tudo certo:
-
-```
-sudo nginx -t
-```
-
-E reinicializa o servidor Nginx:
-
-```
-sudo service nginx restart
-```
-
-## Configura os teus hosts locais (opcional, somente para um domínio local)
-
-Se adicionaste um domínio local, deves configurá-lo no teu computador local (não no servidor). Para Ubuntu, abre o arquivo `/etc/hosts` e adiciona esta linha:
-
-```
-192.168.1.1 espocrm.local # especifica o endereço de IP do teu servidor Nginx
-```
-
-Para Windows, por favor, siga essas [instruções](http://support.microsoft.com/kb/923947).
diff --git a/i18n/pt_PT/administration/portal.md b/i18n/pt_PT/administration/portal.md
deleted file mode 100644
index d2e0972b6..000000000
--- a/i18n/pt_PT/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Portal
-
-Portal fornece uma capacidade de aceder dados de crm e funções específicas para os teus clientes e parceiros. O Administrador pode criar múltiplos portais. Cada portal pode ter as suas próprias configurações, painel de controle, lista de utilizadores, configurações de controle de acesso.
-
-Para criar um portal vai em: Administração > Portais, clica no botão Criar Portal.
-
-* `Está Ativo`. Se não for marcado, o portal não estará disponível para ninguém.
-* `É Padrão`. Significa que o portal estará disponível através de uma URL mais curta: http(s)://SUA_ESPO_URL/portal.
-* `Funções`. Especifica uma ou múltiplas funções do portal que serão aplicadas aos utilizadores ligados no portal. Mais informações sobre funções do portal estão a abaixo.
-* `Lista de Abas`. Abas que serão mostradas na barra de navegação.
-* `Layout do Painel de Controle`. Especifica dashlets que serão mostradas na página inicial do portal. Nota que os utilizadores do portal não podem configurar o painel de controle deles.
-* `URL`. Campo somente leitura que mostra o link pelo qual tu podes aceder o portal.
-
-## Utilizadores do Portal
-
-Administradores podem criar utilizadores do portal.
-
-1. Administração > Utilizadores
-2. Clica no menu suspenso à direita próximo a Criar Utilizador.
-3. Clica em Criar Utilizador do Portal.
-4. Seleciona o contato em que o utilizador do portal vai estar ligado.
-5. Preenche o formulário e clica em guardar.
-
-O utilizador do portal deve estar ligado ao registro do Portal para ser capaz de aceder aquele portal.
-
-## Funções do Portal
-
-As funções do portal são similares à funções regulares no EspoCRM, mas com algumas distinções
-
-* o nível `não-definido` nega um acesso.
-* o nível `próprio` significa que o registro é criado pelo utilizador. Ex: o utilizador do portal empacotou um caso e este caso é propriedade deste utilizador.
-* o nível `conta` significa que o registro está relacionado à conta que o utilizador do portal está relacionado.
-* o nível 'contato' significa que aquele registro está relacionado ao contato que o utilizador do portal está relacionado.
-
-Os campos Utilizador Designado e Equipas são somente de leitura para utilizadores do portal.
-
-### Exemplo
-
-`Os utilizadores do portal devem ser capazes de criar casos, ver casos relacionados à conta deles; eles devem ser capazes de ver a base de conhecimentos.`
-
-1. Abre o fomulário Criar Função do Portal (Administração > Funções do Portal > Criar Função).
-2. Habilitar acesso aos Casos, define: `criar - sim, ler - conta, editar - não, apagar - não, transmitir - conta`.
-3. Habilitar acesso à Base de Conhecimentos, define: `criar - não, ler - conta, editar - não, apagar - não`.
-4. Editar o seu registro no portal (Administração > Portais). Seleciona a função do teu portal no campo Funções e depois grave.
-
-## Acesso ao Portal
-
-Podes encontrar a URL para o teu portal no campo 'URL' no registro do portal. Também é possível usares as ferramentas de configuração do servidor (como mod_rewrite) para seres capaz de aceder através de uma URL diferente. Neste caso, precisas de preencher o campo 'URL Personalizada'.
-
-### Aceder o portal através de uma URL Personalizada para servidor Apache
-
-URL Personalizada: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Regras de sobrescrita mod
-
-Especifiqua o ID do registro do portal em vez de `{PORTAL_ID}`. O ID do registro do portal está disponível na barra de endereços do teu navegador quando abres a visualização detalhada do registro do portal. Como em: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 é um ID de registro do portal.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/pt_PT/administration/roles-management.md b/i18n/pt_PT/administration/roles-management.md
deleted file mode 100644
index 4230202fe..000000000
--- a/i18n/pt_PT/administration/roles-management.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Gerenciamento de Funções
-
-## Panorama
-
-Para restringir o acesso de alguns utilizadores, precisas de usar as Funções. O administrador pode gerir as funções no painel de administração. Cara função define um acesso a certas áreas (escopo) que é aplicada a utilizadores que possuem aquela função.
-
-Um utilizador pode ter várias funções. Essas funções podem ser selecionadas para um utilizador em específico (campo 'Funções' na entidade Utilizador) e/ou ser herdada de equipas que o utilizador faz parte.
-
-Se um utilizador tem várias funções, elas serão unidas de forma que as regras permissivas tenham maior prioridade. Isso permite ao administrador gerir o controle do nível de acesso facilmente e flexivelmente.
-
-É possível ver quais as permissões estão aplicadas a certos utilizadores ao clicar no botão 'Acesso' na vista detalhada do utilizador.
-
-
-
-## Exemplo
-
-Por exemplo, o utilizador pertence à equipa 'Vendas'. Essa equipa tem uma única função 'Vendedor'. Então todos os utilizadores dessa equipa obterão a função 'Vendedor'.
-
-A função 'Vendedor' está definida da seguinte forma:
-
-Condução:
-```
-criar - sim
-ler – equipa
-editar – próprio
-apagar – não
-transmitir - equipa
-```
-
-Oportunidade:
-```
-criar - sim
-ler – equipa
-editar – próprio
-apagar – não
-transmitir - equipa
-```
-Os utilizadores irão ser capazes de ler somente as conduções e oportunidade que pertencem à equipa 'Departamento de Vendas' (campo 'Equipas').
-O utilizador será capaz de editar somente aquelas conduções e oportunidades que eles são designados ou aqueles que eles criaram.
-Os utilizadores não serão capazes de remover quaisquer conduções ou oportunidades.
-
-Nós querendo dar mais direitos para certo utilizador que está no cargo de gerente de vendas da companhia. Este empregado deve ter uma capacidade de ler/editar/apagar todos os registros da equipa 'Vendas'. O utilizador deveria pertencer à nossa equipa 'Vendas'. Mas nós precisamos criar uma nova função 'Gerente de Vendas' e selecionar essa função para aquele utilizador no campo 'Funções'.
-
-A função 'Gerente de Vendas' está definida da seguinte forma:
-
-Condução:
-```
-criar - sim
-ler – equipa
-editar – equipa
-apagar – equipa
-transmitir - equipa
-```
-
-Oportunidade:
-```
-criar - sim
-ler – equipa
-editar – equipa
-apagar – equipa
-transmitir - equipa
-```
-
-O nosso utilizador será capaz de gerir todas as conduções e oportunidades da equipa de 'Vendas'.
-
-## Permissões Especiais
-
-### Atribuição de Permissões
-
-Defina este parâmetro para restringir a habilidade de reatribuir registros para outro utilizador e/ou equipas. Se definires 'equipa' - então será possível atribuir somente a utilizadores da própria equipa(s). Se 'não' - os utilizadores não serão capazes de reatribuir de qualquer forma.
-
-Isso também define se o utilizador é capaz de transmitir uma publicação para outros utilizadores/equipas.
-
-### Permissões de Utilizadores
-
-Permite restringir uma capacidade do utilizador de ver atividades, calendário e transmissões de outros utilizadores.
-
-### Permissão de Portal
-
-Define um acesso para a informação portal, capacidade de publicar mensagens para utilizadores do portal.
-
-### Permissão para a Conta de Email do Grupo
-
-Define um acesso para as contas de email do grupo, uma capacidade de enviar emails do SMTP do grupo.
-
-### Exportar Permissão
-
-Define se o utilizador tem uma capacidade de exportar registros. (desde a versão 4.9.0)
-
-## Permissões Padrões
-
-Por padrão (se não houver qualquer uma aplicada), os utilizadores podem ler e editar todos os registros. Mas não podem apagar nenhum deles, exceto aqueles que eles mesmos criaram e são atribuídos a eles ao mesmo tempo.
-
-Existe uma capacidade de restringir um acesso aplicado por padrão ao habilitar o 'Modo Estrito ACL' em Administração > Configurações.
-
-## Segurança ao Nível do Campo
-
-Permite controlar um acesso para campos específicos.
-
-Por padrão, o utilizador pode ler todos os campos se ele puder ler o registro. O utilizador pode editar qualquer campo se ele puder editar o registro. Podes restringir o acesso a campos específicos usando a Segurança ao Nível do Campo.
-
-Na visualização da edição de um registro de função na sessão Nível do Campo, clica no ícone 'mais' próximo ao escopo específico, então seleciona o campo desejado. Então tu serás capaz de especificar o nível de acesso para as ações 'ler' e 'editar'. Há duas opções: 'sim' e 'não'.
-
-
diff --git a/i18n/pt_PT/administration/server-configuration.md b/i18n/pt_PT/administration/server-configuration.md
deleted file mode 100644
index 23448771a..000000000
--- a/i18n/pt_PT/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Configuração de Servidor para EspoCRM
-
-EspoCRM pode ser instalado no Apache ([instruções](apache-server-configuration.md)), Nginx ([instruções](nginx-server-configuration.md)), ou servidor IIS com suporte para PHP versão 5.6 ou superior e MySQL versão 5.1 ou superior.
-
-## Recomendações de Configuração
-
-### Requisitos PHP
-
-EspoCRM requer PHP versão 5.6 ou superior, com as seguintes extensões habilitadas:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – para aceder MySQL em PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – os recursos usam este formato (metadados, layout, idiomas, e outros);
-* [GD](http://php.net/manual/en/book.image.php) – para manipular imagens;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – para garantir o maior nível de proteção;
-* [Zip](http://php.net/manual/en/book.zip.php) – para ser capaz de atualizar o EspoCRM e instalar extensões;
-* [IMAP](http://php.net/manual/en/book.imap.php) – para monitorar caixas de correspondência no EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Também é recomendado ter a extensão pecl [mailparse](https://pecl.php.net/package/mailparse) instalada. É necessário para um trabalho fluído do recurso de busca de email
-
-configurações php.ini:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Requisitos MySQL
-
-EspoCRM suporta MySQL versão 5.1 ou superior.
-Estes não são peculiaridades especiais. Todas as configurações padrões são boas para o EspoCRM.
-
-## Permissões Requeridas para Sistemas Baseados em Unix
-
-Os arquivos e diretórios devem ter as seguintes permissões:
-
-* `/data`, `/custom`, `/client/custom` – devem poder modificar todos os arquivos, diretórios e subdiretórios (664 para arquivos, 775 para diretórios, incluindo todos os subdiretórios e arquivos);
-* `/application/Espo/Modules`, `/client/modules` – devem poder modificar o diretório atual (775 para o diretório atual, 644 para arquivos, 755 para diretórios e subdiretórios);
-* Todos os outros arquivos e diretórios devem poder serem lidos (644 para arquivos, 755 para diretórios).
-
-Para definir permissões, executa estes comandos no terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Todos os arquivos devem pertencer e grupo-pertencer ao processo do servidor de web. Ele pode ser “www-data”, “daemon”, “apache”, “www”, etc.
-Nota: No Bitnami Stack, os arquivos devem pertencer e grupo-pertencer ao usuário "daemon".
-Nota: Em hosts compartilhados, os arquivos devem pertencer e grupo-pertencer à conta do teu utilizador.
-
-Para definir o proprietário e grupo-proprietário, execute esses comandos no terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## Configure um crontab
-
-Para configurar um crontab em um sistema UNIX, siga os seguintes passos:
-
-* 1. Faz o login como administrador na tua instância EspoCRM
-* 2. Vai para a sessão Trabalhos Agendados no painel de administrador (Menu > Administração > Trabalhos Agendados) e copia a sequência de caracteres para o crontab. Ela é parecida com isto:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Abre um terminal e executa este comando:
-```
-crontab -e -u UTILIZADOR_SERVIDOR_DA_WEB
-```
-UTILIZADOR_SERVIDOR_DA_WEB pode ser um dos seguintes “www”, “www-data”, “apache”, etc (dependendo do teu servidor da web).
-* 4. Cola a sequência de caracteres copiada (do passo 2) e guarda o arquivo crontab (Ctrl+O, então Ctrl+X para o editor nano).
-
-## Instruções de configuração baseadas no teu servidor:
-
-* [Configuração em servidor Apache](apache-server-configuration.md).
-* [Configuração em servidor Nginx](nginx-server-configuration.md).
diff --git a/i18n/pt_PT/administration/troubleshooting.md b/i18n/pt_PT/administration/troubleshooting.md
deleted file mode 100644
index 00b08d0e8..000000000
--- a/i18n/pt_PT/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Resolução de Problemas
-
-## Verificar logs
-
-Para achar o problemas, deves verificar o arquivo do log de erros.
-
-#### Logs de erro do EspoCRM
-
-Os logs do EspoCRM estão localizados no `/logs/*.log` e contém algumas informações sobre erros.
-
-#### Logs de erro do Apache
-
-Para o servidor Ubuntu um log de erro apache está localizado em `/var/log/apache2/error.log` e contém todas as informações de erro. A localização dos arquivos de log podem ser diferentes em outros sistemas.
-
-## Habilitar modo de depuração
-
-Para habilitar o modo de depuração, vai para o diretório onde está instalado o EspoCRM, abra o arquivo `data/config.php` e muda o valor:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-para
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Tarefas Agendadas não estão a funcionar
-
-#### Problema #1: O Teu crontab não está configurado
-
-1. Faz login através do SSH para o teu servidor.
-
-2. Configura o teu [crontab](server-configuration.md#configure-um-crontab) seguindo os seguintes passos.
-
-Nota: Crontab deve ser configurado por um utilizador do servidor da web, ex: `crontab -e -u www-data`.
-
-3. Aguarda algum tempo e verifica os Trabalhos Agendados para ver se qualquer trabalho foi executado (veja um painel de Log).
-
-#### Problema #2. Crontab está configurado, mas os Trabalhos Agendados não estão a funcionar
-
-Para ter certeza que não existem erros quando cron está a ser executado, tenta executar o comando cron num terminal:
-
-1. Faz login através do SSH para o teu servidor.
-
-2. Vai para o diretório onde o EspoCRM está instalado. Ex: para o diretório `/var/www/html/espocrm` o comando é:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Executa o comando crontab::
-
-```bash
-php cron.php
-```
-
-Nota: Ele deve ser executado por um utilizador do servidor da web. Se estás ligado como root, o comando deve ser (ex: para Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-onde `www-data` é um utilizador do servidor da web.
-
-4. Se não há erros, verifica os Trabalhos Agendados para ver se qualquer trabalho foi executado (ver um painel de Log).
-
-## EspoCRM não está carregando após updgare
-
-Isto pode acontecer algumas vezes em algumas hospedagens compartilhadas.
-
-Verifique os arquivos de permissões:
-/index.php
-/api/v1/index.php
-
-Eles devem ser 644. Se qualquer desses arquivos tem permissão 664, precisas mudá-la para 644. Usa o teu painel de controle da hospedagem ou comando chmod.
-
-```
-chmod 644 /path/to/file
-```
-Mais informação sobre permissões de arquivos: [aqui](server-configuration.md#permissões-requeridas-para-sistemas-baseados-em-unix).
diff --git a/i18n/pt_PT/administration/upgrading.md b/i18n/pt_PT/administration/upgrading.md
deleted file mode 100644
index e694bc734..000000000
--- a/i18n/pt_PT/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Como atualizar o EspoCRM
-
-O EspoCRM pode ser atualizado para a sua última versão seguindo os seguintes passos:
-
-### Passo 1. Verifica a tua versão atual
-
-Para verificar a tua versão atual, vai para a página Administração > Atualizar.
-
-### Passo 2. Descarregue os pacotes de atualizações necessários
-
-Vai para a página de atualização https://www.espocrm.com/download/upgrades/ e, baseado na tua versão atual, descarrega os pacotes necessários.
-
-### Passo 3. Cria uma cópia de segurança (opcional)
-
-Cria uma cópia de segurança dos teus arquivos do EspoCRM e dados antes de atualizar. Segue [estas instruções](backup-and-restore.md) para concluir esse processo.
-
-### Passo 4. Processo de atualização
-
-Vai para Administração > Atualizar. Faz o upload e instala os pacotes de atualizações um por um.
-
-Podes verificar se you tem a última versão em Menu > Sobre.
-
-## Atualização através de CLI
-
-Podes também executar a atualização através da interface da linha de comando. Precisas executar os seguintes comandos do diretório raiz do EspoCRM:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/pt_PT/administration/workflows.md b/i18n/pt_PT/administration/workflows.md
deleted file mode 100644
index a39924d33..000000000
--- a/i18n/pt_PT/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Fluxos de Trabalho
-
-O recurso Fluxos de Trabalho está disponível em [Pacote Avançado](https://www.espocrm.com/extensions/advanced-pack/).
-
-Fluxos de Trabalho automatiza os teus processos de negócios de uma forma fácil. Podes encontra-la no painel de Administração. Para criar uma regra de fluxos de trabalho, precisas de definir:
-
-* Entidade Alvo - a qual tipo de entidade o fluxos de trabalho é aplicado;
-* Tipo de Acionamento - quando o fluxo de trabalho será acionado;
-* Condições - condições precisam ser satisfeitas para acionar o fluxo de trabalho;
-* Ações - o que fazer se o fluxo de trabalho é acionado.
-
-
-## Tipos de Acionamentos
-
-### Após criar um registro
-
-Acionado apenas quando um novo registro é criado. Se as condições específicas forem satisfeitas, então as ações serão executadas.
-
-### Após guardar um registro
-
-Acionado quando um novo registro é criado ou um registro existente é atualizado. Se as condições específicas forem satisfeitas, então as ações serão executadas.
-
-Para as regras de fluxos de trabalho com esse tipo de acionamento, é uma prática comum ter uma condição que verifica se algum campo 'mudou'. Ex: Se o estado de Caso mudou, então executa algumas ações.
-
-### Agendamento
-
-Acionado de acordo com a agenda definida. Podes configurá-lo para o executar todo dia, toda semana, etc. Ações serão aplicadas para registros retornados por uma lista relatório especificada. Então tu precisas também de criar uma lista relatório.
-
-Agendar está especificado numa notação crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Ano (amplitude: 1900-3000)
-| | | | +---- Dia da Semana (amplitude: 1-7, 1 significa Segunda-feira)
-| | | +------ Mês do Ano (amplitude: 1-12)
-| | +-------- Dia do Mês (amplitude: 1-31)
-| +---------- Hora (amplitude: 0-23)
-+------------ Minuto (amplitude: 0-59)
-```
-
-### Sequencial
-
-Raramente usado. Deveria ser executado por outro fluxo de trabalho. Gera uma capacidade de fazer uma lógica complexa.
-
-Nota: Para fluxos de trabalho sequenciais, é recomendado utilizar a [ferramenta BPM](bpm.md) em vez do recurso Fluxos de Trabalho.
-
-## Condições
-
-Podes especificar condições que devem ser satisfeitas para acionar o fluxo de trabalho. Existem duas maneiras como as condições podem ser especificadas: com o construtor de condições UI e com fórmula.
-
-### Construtor de condições UI
-
-Alguns tipos de condições disponíveis:
-
-* _iguais_ - o campo é igual a um valor específico ou um valor de outro campo;
-* _era_igual_ - o campo era igual a um valor específico antes do fluxo de trabalho ser acionado;
-* _nao_igual_ - o campo não é igual a um valor específico ou um valor de outro campo;
-* _nao_era_igual_ - O campo não era igual a um valor específico antes do fluxo de trabalho ser acionado;
-* _vazio_ - o valor do campo está vazio;
-* _nao vazio_ - o valor do campo não está vazio;
-* _alterado_ - o campo foi alterado;
-* _nao alterado_ - o campo não foi alterado.
-
-### Condições para Fórmulas
-
-As fórmulas dão a capacidade de definir condições de qualquer complexidade. Para ler sobre a sintaxe de fórmulas, vê [este artigo](formula.md).
-
-Nota: Não deve haver qualquer delimitador ';' usado no código da fórmula quando ela determina uma condição.
-
-## Ações
-
-### Enviar Email
-
-O sistema vai enviar um email usando um modelo de email específico. Um endereço de email do destinatário pode ser tirado do registro visado, qualquer registro relacionado, do utilizador atual, seguidores, equipa de utilizadores ou especificado. Os emails podem ser enviados imediatamente ou atrasados por um intervalo específico.
-
-### Criar Registro
-
-O sistema vai criar o novo registro de qualquer tipo de entidade. Se existe um relacionamento entre o registro alvo e o registro sendo criado, é possível relacionar os registros.
-
-Há uma capacidade para definir fórmula para calcular campos.
-
-### Criar Registro Relacionado
-
-O sistema vai criar o registro relacionado ao registro visado. É possível definir fórmula para calcular campos.
-
-### Atualizar Registro Alvo
-
-Permite alteração de um campo específico do registro visado. É possível definir fórmula para calcular campos.
-
-Se precisares de adicionar novos itens para o campo Link-Múltiplo sem perder os dados existentes (ex: Equipas), precisas utilizar a função fórmula entity\addLinkMultipleId. Exemplo: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### Atualizar Registro Relacionado
-
-Permite alteração de campos específicos do registro ou registros relacionados. É possível definir fórmula para calcular campos.
-
-### Vincular com Outro Registro
-
-Relaciona a entidade visada com outra entidade específica. Ex: adiciona uma equipa específica para o registro.
-
-### Desvincular com Outro Registro
-
-Acaba com a relação da entidade visada e outra entidade específica. Ex: remove uma equipa específica do registro.
-
-### Aplicar Regra de Atribuição
-
-Atribui o registro alvo ao utilizador pela função de distribuição. Existem duas regras disponíveis: Um-por-Turno e Menos-Ocupado.
-
-* Um-por-Turno - os utilizadores são escolhidos de uma lista (equipa) do início ao fim e então começa novamente.
-* Menos-Ocupado - o utilizador que tem menos registros de atribuições será escolhido para a atribuição.
-
-_Lista Relatório_ - Para a distribuição Menos-Ocupado, determina quais os registros serão levados em consideração para calcular o número de registros atribuídos. Ex: para os Casos nós precisamos apanhar somente registros com o estado ativo.
-
-### Criar Notificação
-
-Notificar utilizadores específicos com a mensagem. É possível usar espaços reservados nas mensagens modelo: {entidade} - registro visado, {utilizador} - utilizador atual.
-
-### Fazer Seguido
-
-Força utilizadores específicos a seguir a entidade alvo ou uma entidade relacionada.
-
-### Acionar Outro Fluxo de Trabalho
-
-Permite fazer fluxos de trabalho sequenciais. É possível remificar fluxo de trabalho por condição: Podes configurar o fluxo de trabalho para acionar dois fluxos de trabalho com diferentes condições definidas naqueles fluxos de trabalho.
-
-É possível atrasar a execução de fluxo de trabalho sequencial. Em fluxo de trabalho sequencial, podes definir a condição que verifica se os campos específicos foram alterados desde o fluxo de trabalho superior foi acionado ao usar os tipos de condição _Alterado_ e _Era Igual_.
-
-Nota: Para fluxos de trabalho sequenciais, é recomendado utilizar a [ferramenta BPM](bpm.md) em vez do recurso Fluxos de Trabalho.
-
-### Execute a Ação de Serviço
-
-Permite executar scripts de serviços específicos. Por padrão existem as seguintes ações disponíveis:
-
-* Mandar Convite - para Reuniões/Chamadas;
-* Adicionar Itens Citados - para Citações.
-
-Os desenvolvedores podem escrever suas próprias ações de serviço. Vê [mais detalhes](../development/workflow-service-actions.md).
-
-## Usando Fórmula em Ações
-
-É possível definir fórmula para calcular campos para Criar Registro, Atualizar Registro Alvo, Criar Registro Relacionado, Atualizar Registro Relacionado. Para os últimos dois, para aceder os atributos da entidade alvo, deves usar a função `targetEntity\attribute`. Para aceder atributos da entidade alvo que foi definida antes do fluxo de trabalho, `targetEntity\attributeFetched`.
-
-Exemplo:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/pt_PT/development/api.md b/i18n/pt_PT/development/api.md
deleted file mode 100644
index 672522e90..000000000
--- a/i18n/pt_PT/development/api.md
+++ /dev/null
@@ -1,220 +0,0 @@
-# REST API
-
-EspoCRM é um aplicativo de página única para que um frontend use a API REST para se conectar a um backend.
-Todas as operações que tu executas usando UI podes implementar através de chamadas de API usando seu idioma de programação.
-Podes aprender como funciona a API se tu rastreares o que está acontecendo na guia de rede no console do navegador.
-
-A maioria das funções api retorna JSON. As chamadas POST, PATCH geralmente precisam de alguns dados JSON na carga útil.
-
-O URL básico da API EspoCRM é: `api/v1/`. Você precisa compará-lo com as expressões nesta referência. Exemplo:
-
-`OBTER http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Autenticação
-
-A API do EspoCRM usa [Autenticação Básica](http://en.wikipedia.org/wiki/Basic_access_authentication). Nome de utilizador e senha/token são passados pelo cabeçalho 'Autorização' codificado em base64.
-
-`"Autorização: Básico " + base64Encode(usuário + ':' + senha)`
-
-É melhor usar o token de autenticação em vez da senha quando trabalhares com api. Neste caso, precisarás de fornecer nome de utilizador e senha/token no cabeçalho `Espo-Autorization`.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-1. Obter token de acesso pela solicitação 'OBTER App/utilizador' com nome de utulizador e senha passados no cabeçalho `Espo-Autorization`.
-2. Usa este token em vez de senha no cabeçalho `Espo-Authorization` para todas as solicitações adicionais.
-3. Se o erro do pedido retornar 403 significa que o nome de utilizador/senha é errado ou o token já não é válido.
-
-#### Token de Autenticação / Dados Específicos do Utilizador
-
-`OBTER App/utilizador`
-
-Retorna:
-
-* `token` - token de acesso para usar;
-* `acl` - informações sobre acesso de utilizadores;
-* `preferências` - preferências de utilizador;
-* `utilizador` - atributos de registro de utilizador.
-
-
-## CRUD Operações
-
-#### Entidades de Lista
-
-`OBTER {entidadeTipo}`
-
-OBTER parâmetros:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-* `onde` - (array) filtros;
-* `sortBy` - (string) campo para classificar por;
-* `asc` - (bool) direção de classificação.
-
-_Exemplo_
-`OBTER Conta?offset=0&maxSize=20``
-
-Retorna:
-```
-{
- "lista": [... variedade de registros...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Ler Entidade
-
-`OBTER {entidadeTipo}/{id}`
-
-Retorna atributos no objeto JSON.
-
-_Exemplo_
-
-`OBTER Conta/5564764442a6d024c`
-
-#### Criar Entidade
-
-`POST {entidadeTipo}`
-
-Carga útil: atributos de objeto de entidade.
-
-Retorna os atributos da entidade no objeto JSON.
-
-_Exemplo_
-
-`POST Conta`
-
-Carga útil:
-```
-{
- "nome": "Teste",
- "assignedUserId": "1"
-}
-```
-
-#### Entidade de atualização
-
-`REMENDO {entityType}/{id}`
-
-ou
-
-`COLOCAR {entidadeTipo}/{id}`
-
-Carga útil: os atributos do objeto de entidade precisam ser alterados.
-
-Retorna atributos no objeto JSON.
-
-_Exemplo_
-
-`REMENDO Conta/5564764442a6d024c`
-
-Carga útil:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Eliminar Entidade
-
-`Eliminar {entidadeTipo}/{id}`
-
-_Exemplo_
-
-`ELIMINAR Conta/5564764442a6d024c`
-
-
-## Entidades Relacionadas
-
-#### Entidades Relacionadas à Lista
-
-`OBTER {entidadeTipo}/{id}/{link}`
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-* `onde` - (array) filtros;
-* `ordenarPor` - (string) campo para classificar por;
-* `asc` - (bool) direção de classificação.
-
-_Exemplo_
-
-`OBTER Conta/5564764442a6d024c/oportunidades`
-
-Retorna:
-```
-{
- "lista": [... variedade de registros...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Link Entidade
-
-`POST {entidadeTipo}/{id}/{link}`
-
-Carga útil:
-
-1. `id` atributo.
-2. `ids` atributo de matriz.
-3. `"massRelate": verdade` e `"onde": {...}` relacionar registros múltiplos por critérios de pesquisa.
-
-_Exemplo_
-
-`POST Conta/5564764442a6d024c/oportunidades`
-
-Carga útil:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Entidade Desvinculada
-
-`EXCLUIR {entidadeTipo}/{id}/{link}`
-
-Carga útil:
-
-1. JSON with `id` attribute.
-2. JSON with `ids` array attribute.
-
-_Exemplo_
-
-`EXCLUIR Conta/5564764442a6d024c/oportunidades`
-
-Carga útil:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-## Stream
-
-#### Lista de entradas de Stream luxo para o utilizador atual
-
-`OBTER Stream`
-
-OBTER parâmetros:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-
-#### Lista de entradas de Stream relacionadas a uma gravação específica
-
-`OBTER {entidadeTipo}/{id}/stream`
-
-OBTER parâmetros:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) tamanho máximo;
-
-#### Acompanhe o registro
-
-`COLOCA {entidadeTipo}/{id}/inscrição`
-
-#### Desativar registro
-
-`ELIMINAR {entidadeTipo}/{id}/inscrição`
-
-
-
diff --git a/i18n/pt_PT/development/custom-field-type.md b/i18n/pt_PT/development/custom-field-type.md
deleted file mode 100644
index dcf5b03f9..000000000
--- a/i18n/pt_PT/development/custom-field-type.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Criar tipo de campo personalizado
-
-### Definição de campo
-
-Criar um arquivo `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` com os parâmetros necessários.
-```
-{
- "visão": "personalizado:visão/campos/{campo-tipo}"`
-}
-```
-
-Utiliza os tipos de campo fora da caixa como exemplos: `/aplicação/Espo/Recursos/metadata/campos`.
-
-### Tradução
-
-O rótulo é usado no Gestor de Entidade pode ser configurado em `personalizado/Espo/personalizado/Recursos/i18n/en_US/Admin.json` na seção `camposTipos
-Se precisares de adicionar tradução para outro idioma, usa o idioma necessário [código de idioma](https://en.wikipedia.org/wiki/ISO_639-1)_[código do país](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) ao invés de`en_US`. Na `data/config.php` Na seção `languageList` podes encontrar a lista de idiomas incluídos.
-
-### Visão
-
-Cria a vista para o campo `cliente/personalizado/src/visão/campos/{campo-tipo}.js` e define os teus modelos
-```
-Espo.define('personalizado:visão/campos/[campo-tipo]', 'visão/campos/base', função (Dep) {
-
- retorna Dep.extend({
-
- });
-});
-```
-
-Usa os exemplos de tipos de campo excluídos:
-- `/cliente/src/visão/campos` - visão;
-- `/cliente/res/modelos/campos` - modelos.
-
-Então precisas executar a reconstrução no painel de administração.
diff --git a/i18n/pt_PT/development/custom-views.md b/i18n/pt_PT/development/custom-views.md
deleted file mode 100644
index 21b8e9812..000000000
--- a/i18n/pt_PT/development/custom-views.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Visualizações personalizadas
-
-## Registro de Visualizações
-
-O framework EspoCRM oferece habilidades flexíveis para definir visualizações personalizadas para determinados tipos de entidades. Eles devem ser definidos como categoria de metadados `clientDefs`.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-A exibição de registro/detalhe contém todos os painéis com campos, relações e outros dados que você pode ver na visualização detalhada. Não contém cabeçalho e botões no canto superior direito.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Aqui está o seu modelo personalizado. Omita se não precisares disso.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Aqui está a sua visão personalizada. Omita se não precisares disso.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Aqui está a sua visão personalizada. Omita se não precisares disso.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Aqui está a sua visão personalizada. Omita se não precisares disso.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Aqui está a lógica de inicialização personalizada. Como ligar ouvindo mudanças no modelo.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Código personalizado a ser invocado logo após a renderização, quando DOM estiver disponível.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-Podes criar um modelo personalizado com o seguinte caminho:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-A exibição de detalhes contém exibição de Registro/Detalhe e cabeçalho.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-O mesmo que o detalhe, mas é usado quando o registro está sendo criado ou editado não no modo de edição inline.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-A exibição de lista contém exibição de Registro/Lista, cabeçalho e formulário de pesquisa.
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-A exibição Lista/Registro contém linhas de registros.
-
-
-Vale a pena mencionar que precisas herdar a tua classe de visualização de uma classe específica para a sua entidade se já existe.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Visualizações de Campo
-
-As visualizações personalizadas para campos específicos devem ser especificadas na seção entityDefs dos metadados.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
diff --git a/i18n/pt_PT/development/dynamic-forms.md b/i18n/pt_PT/development/dynamic-forms.md
deleted file mode 100644
index 427c54fba..000000000
--- a/i18n/pt_PT/development/dynamic-forms.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Formulários Dinâmicos
-
-Nota: desde a versão 4.3.0, é possível definir a forma dinâmica através da UI do administrador no Entity Manager.
-
-Existe a capacidade de definir um comportamento de formulário no EspoCRM.
-
-## Exemplo
-
-> Precisa mostrar o campo _nextStep_ numa visualização de detalhes da Oportunidade somente se o estágio for 'Fechado Vencido'.
->
-
-Criar ficheiro `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Isso significa que o campo _nextStep_ será escondido por padrão e mostrado se o palco igual a 'Ganho Fechado'.
-
-A lista de ações disponíveis: `show`,` hide`, `setRequired`,` setNotRequired`.
-
-Existe também a capacidade de ocultar/mostrar painéis. Especifica ps nomes do painel em `painéis', atribui o mesmo modo como `campos'.
-
diff --git a/i18n/pt_PT/development/extension-packages.md b/i18n/pt_PT/development/extension-packages.md
deleted file mode 100644
index 2114eb4ba..000000000
--- a/i18n/pt_PT/development/extension-packages.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Pacotes de extensão
-
-As extensões permitem adicionar funcionalidades adicionais ao EspoCRM. Elas podem ser instaladas pelo painel Administrador na seção `Personalização`.
-
-
-
-## Como criar o pacote de extensão
-
-Uma estrutura de Arquivo do pacote:
-
-* `/manifest.json` – um arquivo que contém propriedades de extensão;
-* `/files` – um diretório que contém os arquivos de extensão;
-* `/scripts` – contém os scripts da extensão.
-
-### Manifesto
-```json
-{
- "nome": "Nome da Extensão",
- "versão": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "autor": "Teu Nome",
- "descrição": "Descrição da sua extensão",
- "eliminar": []
-}
-```
-
-* A Sintaxe da `versão' e 'acceptableVersions` é descrita pela especificação v2.0.0 encontrada em http://semver.org.
-* `eliminar` - é a lista de arquivos principais que precisam ser excluídos. Este parâmetro não é recomendado para usar. Tu podes omiti-lo.
-
-### Arquivos
-
-Todos os arquivos de extensão devem ser colocados no diretório `arquivos`. Eles serão copiados para o diretório principal do EspoCRM.
-
-### Scripts
-
-Para diferentes fins, o EspoCRM suporta os seguintes tipos de scripts. Todos devem ser inseridos no diretório `scripts`.
-
-* `BeforeInstall.php` – um script executado antes de um processo de instalação;
-* `AfterInstall.php` – executado uma vez finalizado o processo de instalação;
-* `BeforeUninstall.php` – executado antes do processo de desinstalação;
-* `AfterUninstall.php` – executado uma vez que o processo de desinstalação está concluído.
-
-Exemplo:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Pacote
-
-No final, precisamos empacotar todos estes arquivos num arquivo .zip.
diff --git a/i18n/pt_PT/development/hooks.md b/i18n/pt_PT/development/hooks.md
deleted file mode 100644
index 2afcf86ca..000000000
--- a/i18n/pt_PT/development/hooks.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Ganchos
-
-## Criar um Gancho
-Para criar um gancho, tu precisas:
-- cria um arquivo `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- declara ação do tipo gancho;
-- limpa o Cache na Administração.
-
-## Tipos de Gancho
-
-Os principais tipos de gancho são:
-
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove;
-- afterRelate;
-- afterUnrelate;
-- afterMassRelate.
-
-### Novo Tipo de Gancho
-Podes usar o teu próprio tipo de gancho e desencadeá-lo com
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Ordem Gancho
-Se tiveres vários ganchos, relacionados a um Tipo de Entidade e com o mesmo tipo de gancho, e o pedido de execução é importante, podes definir uma propriedade `publicstatic$order` num valor inteiro.
-
-Ordem ascendente - o gancho com o número de ordem mais pequeno é executado primeiro.
-
-## Exemplo
-Este exemplo define o nome da conta para novos leads, se não estiver configurado.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-usa Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Ganchos Globais
-Se precisares de aplicar um gancho para todas as entidades, podes usar ganchos comuns. Para fazer isto, coloca a tua sua classe de gancho no diretório Comum, por exemplo: `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/pt_PT/development/link-multiple-with-primary.md b/i18n/pt_PT/development/link-multiple-with-primary.md
deleted file mode 100644
index c8c17c97c..000000000
--- a/i18n/pt_PT/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,129 +0,0 @@
-# Vincular campo múltiplo com primário
-
-Às vezes, tu tens um relacionamento `hasMany` e precisas de ter a capacidade de selecionar o registro primário entre os relacionados. Como exemplo, campo `Contatos` da entidade Case.
-
-
-
->Precisas criar um link de `contatos` múltiplo campo com um primário para a nossa entidade personalizada `Stock`.
->
-
-### Passo 1
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-### Passo 2
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-### Passo 3
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-### Passo 4
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-### Passo 5
-Corre o reconstruir
-
-### Passo 6
-Executa SQL query
-```sql
-ATUALIZA stock
-JUNTA contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
diff --git a/i18n/pt_PT/development/metadata.md b/i18n/pt_PT/development/metadata.md
deleted file mode 100644
index 6442f068a..000000000
--- a/i18n/pt_PT/development/metadata.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Metadata
-
-Metadados destina-se a: armazenar dados do sistema, tais como campos e relacionamentos da entidade; especificando controladores frontend, visualizações, painéis; definindo campos, dashlets; e outros dados necessários para a aplicação.
-
-## Como aceder
-
-#### Backend
-
-O objeto Metadata da classe `Espo\Core\Utils\Metadata` pode ser acedido pelo Container. O caminho para um parâmetro necessário é especificado usando os pontos `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-retornará `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-irá retornar uma matriz associativa de todos os campos.
-
-#### A parte dianteira
-
-O objeto Metadata é acessível a partir de todos os objetos de exibição por método `#getMetadata`. Funciona do mesmo modo que o backend.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## Como é armazenado
-
-Metadados são armazenados em arquivos JSON que podem ser localizados em diferentes locais:
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-Quando acedes os dados por caminho `clientDefs.Account.views.edit` o primeiro lexema `clientDefs` corresponde ao nome do diretório, o segundo `Conta` para nome de arquivo `Account.json`. Todos os lexemes seguintes correspondem ao caminho no JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-Todos os arquivos JSON destes diretórios são mesclados recursivamente numa única matriz de php e armazenados num arquivo de cache.
-
-
-## Estendendo
-
-Uma vez que os metadados são mesclados de forma recursiva, podes redefinir facilmente objetos json e arrays em _custom_ e no teu _module_. Além disso, podes anexar matrizes existentes usando `__APPEND__` (desde a versão 2.6.0) como o primeiro elemento da matriz.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/pt_PT/development/new-function-in-formula.md b/i18n/pt_PT/development/new-function-in-formula.md
deleted file mode 100644
index 8d974d48b..000000000
--- a/i18n/pt_PT/development/new-function-in-formula.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Definindo novas funções para Fórmula
-
-EspoCRM oferece a possibilidade de criar funções personalizadas que podem ser usadas na fórmula.
-
-Se a sua função estiver relacionada com um de grupos como String, Logic, Date, cria um arquivo em __{GroupName}Grupo__ pasta, nomeado __{FunctionName}Tipo.php__ com __{FunctionName}Tipo__ declaração de classe. Precisas de definir o método __'processo'__.
-
-Por exemplo, vamos criar uma nova função de string para verificar se uma string (HAYSTACK) contém outra string (AGULHA) com um possível deslocamento (OFFSET).
-
-Cria o arquivo `application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` com o código:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-usa \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Adicionar a função à lista
-
-Para adicionar a função criada à lista de funções da fórmula, cria um arquivo `custom/Espo/Custom/Resources/metadata/app/formula.json` e adiciona o código:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Limpa o cache__ e usa esta função na fórmula. Podes digitar `string\contains(HAYSTACK, NEEDLE, OFFSET)` ou selecionar a partir da lista de funções, se o adicionares.
-
diff --git a/i18n/pt_PT/development/orm.md b/i18n/pt_PT/development/orm.md
deleted file mode 100644
index cf1193498..000000000
--- a/i18n/pt_PT/development/orm.md
+++ /dev/null
@@ -1,226 +0,0 @@
-# ORM, Como gerir entidades e executar consultas
-
-O EspoCRM possui o próprio ORM (Mapeamento objeto-relacional). É muito simples criar, atualizar, ler, excluir e pesquisar entidades. Todas estas operações disponíveis através do objeto EntityManager. EntityManager está disponível nos serviços de gravação pelo método `#getEntityManager()`.
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Cria uma nova entidade
-```php
-$account = $entityManager->getEntity('Account')
-```
-ou
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Fetch existente
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-ou
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Get value
-```php
-$fieldValue = $account->get('fieldName');
-```
-
-#### Has value
-```php
-$fieldNameIsSet = $account->has('fieldName'); // true or false
-```
-
-#### Definir valor
-```php
-$account->set('fieldName', 'Test Account');
-```
-
-```php
-$account->set(array(
- 'name' => 'Test Account',
- 'assignedUserId' => '1'
-));
-```
-
-#### Loja
-```php
-$entityManager->saveEntity($account);
-```
-ou
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Remove
-```php
-$entityManager->removeEntity($account);
-```
-ou
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Encontra
-```php
-$accountList = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer'
-])->find();
-```
-
-Ordem decrescente:
-
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', true)->find();
-```
-
-Ordem ascendente:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt')->find();
-```
-
-ou:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', 'DESC')->find();
-```
-
-#### Encontra o primeiro
-```php
-$account = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer',
-])->findOne();
-```
-
-#### Encontrar relacionados
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
-```
-
-#### Relacionar entidades
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
-```
-ou
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
-```
-
-#### Entidades não relacionadas
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
-```
-ou
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
-```
-
-### Selecionar Parâmetros de Consulta
-
-#### Cláusula onde
-
-##### Operadores de comparação
-
-Operadores de comparação suportados: `>`, `<`, `>=`, `<=`, `=`, `!=`.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'amount>=' => 100
-])->find();
-```
-
-##### IN e NOT IN operadores
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage' => ['Closed Lost', 'Closed Won']
- ])->find();
-```
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage!=' => ['Closed Lost', 'Closed Won']
-])->find();
-```
-
-##### LIKE operatodores
-
-Operadores suportados:
-* `*` - LIKE,
-* `!*` -- NOT LIKE.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'name*' => '%service%'
-])->find();
-```
-
-##### OU, E operadores
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- [
- 'OR' => [
- ['stage' => 'Closed Won'],
- ['stage' => 'Closed Lost']
- ],
- 'AND' => [
- 'amountConverted>' => 100,
- 'amountConverted<=' => 999
- ]
- ]
-])->findOne();
-```
-
-#### Distito
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->distinct()->where(...)->find();
-```
-
-#### Junta-te
-
-```
-$contactList = $entityManager->getRepository('Contact')->distinct()->join('opportunities')->where([
- 'opportunities.stage' => 'Closed Won'
-])->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()->leftJoin('opportunities')->where(...)->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()
-->join(['opportunities', 'aliasForJoinedTable'])
-->where([
- 'aliasForJoinedTable.stage' => 'Closed Won'
-])->find();
-```
-
-#### Agrupar Por
-
-```
-$selectParams = [
- 'select' => ['MONTH:closeDate', 'SUM:amountConverted']
- 'groupBy' => ['MONTH:closeDate'],
- 'whereClause' => [
- 'stage' => 'Closed Won'
- ],
- 'orderBy' => 1 // ordenar pela primeira coluna
-];
-
-// aplicando juntas à esquerda para conversão de moeda
-$this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams);
-
-$pdo = $this->getEntityManager()->getPDO();
-$sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams);
-$sth = $pdo->prepare($sql);
-$sth->execute();
-
-// resultados
-$rowList = $sth->fetchAll(\PDO::FETCH_ASSOC);
-```
diff --git a/i18n/pt_PT/development/scheduled-job.md b/i18n/pt_PT/development/scheduled-job.md
deleted file mode 100644
index 4c68dc0e6..000000000
--- a/i18n/pt_PT/development/scheduled-job.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Criar trabalho agendado
-
-Para definir um trabalho personalizado agendado, cria um arquivo `custom/Espo/Custom/Jobs/{JOB_NAME}.php` com o conteúdo.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //toda a lógica precisa ser definida no método executado
- }
-}
-```
-
-Além disso, podes definir uma etiqueta para o teu trabalho (`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-Para implementar as alterações, vai para o painel Administração e Limpa o Cache.
diff --git a/i18n/pt_PT/development/workflow-service-actions.md b/i18n/pt_PT/development/workflow-service-actions.md
deleted file mode 100644
index a2ea32bbe..000000000
--- a/i18n/pt_PT/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Adicionar ação de serviço personalizado para Workflow
-
-Fluxos de trabalho permitem criar ações de serviço personalizado. Este exemplo mostrará como isto pode ser feito para uma entidade de chamada.
-
-## Passo 1. Criar classe de serviço
-
-```php
- Limpar Cache. Agora, a ação do serviço está disponível para fluxos de trabalho no formulário Execução do serviço.
diff --git a/i18n/pt_PT/user-guide/activities-and-calendar.md b/i18n/pt_PT/user-guide/activities-and-calendar.md
deleted file mode 100644
index b281376f1..000000000
--- a/i18n/pt_PT/user-guide/activities-and-calendar.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Atividades e Calendário
-
-Existem por padrão três tipos de atividades disponíveis no EspoCRM:
-
-* Reuniões;
-* Chamadas;
-* Tarefas.
-
-O administrador pode criar uma entidade personalizada do tipo Evento. Em Administração > Configurações > Atividades, é possível definir este tipo de entidade como uma atividade e disponibilizá-la no Calendário.
-
-Existe 'As minhas atividades' dashlet que mostram os registros de atividade atuais e futuros relacionados com o utilizador atual.
-
-Contas, Contatos, Leads, Oportunidades, Casos têm o painel de Atividades na visualização de detalhes. As entidades personalizadas do tipo Base Plus também possuem o painel Atividades.
-
-## Reuniões, Chamadas
-
-### Participantes
-
-Existem 3 tipos de participantes suportados: Utilizadores, Contatos, Leads. Para cada participante é possível especificar o status de aceitação: Aceito, Tentativa, Recusado. Existe a capacidade de enviar convites via e-mail aos participantes clicando no botão no canto superior direito. Os participantes poderão definir o seu status de aceitação clicando num link correspondente no e-mail.
-
-### Lembretes
-
-Existem dois tipos de lembretes: Popup (mensagem no aplicativo) e Email.
-
-### Duração padrão
-
-A duração padrão pode ser alterada pelo administrador em Administração > Gestor de Entidad> Reuniões / Chamadas > Campos > Duração > Padrão. Deve ser especificado em segundos.
-
-
-## Tarefas
-
-Os campos Data de Início e Data de Vencimento não são necessários. As datas podem ser especificadas com ou sem as partes de tempo.
-
-### Lembretes
-
-Os lembretes para a gravação da tarefa estarão disponíveis somente se a Date de Vencimento for especificada e tiver parte do tempo.
-
-## Calendário
-
-O Calendário mostra Reuniões, Chamadas, Tarefas. Também é possível mostrar entidades personalizadas do tipo de Evento.
-
-Visualizações suportadas:
-
-* Mês;
-* Semana;
-* Dia;
-* Linha do tempo.
-
-Os utilizadores podem adicionar o Calendário no painel.
-
-É possível visualizar o calendário de outro utilizador ( tens acesso determinado pelas funções). O botão Calendário está disponível na visualização detalhada do utilizador.
-
-### Calendário compartilhado
-
-O calendário compartilhado está disponível somente na visualização Timeline. Permite visualizar eventos de vários utilizadores.
diff --git a/i18n/pt_PT/user-guide/browser-support.md b/i18n/pt_PT/user-guide/browser-support.md
deleted file mode 100644
index d0908cf2a..000000000
--- a/i18n/pt_PT/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Suporte do Navegador
-
-Nós recomendamos o uso da ultima versão do Google Chrome ou Mozilla Firefox. O EspoCRM funciona melhor nestes navegadores. Testamos regularmente todos os recursos nestes naveadores.
-
-Microsoft Edge e Safari também são compativeis, mas há menos garantias de que tudo estárá a funcionar sem problemas.
-
-We heighly do not recommend using Internet Explorer 11.
diff --git a/i18n/pt_PT/user-guide/case-management.md b/i18n/pt_PT/user-guide/case-management.md
deleted file mode 100644
index d62344f85..000000000
--- a/i18n/pt_PT/user-guide/case-management.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Gestão do Caso
-
-Os casos fornecem uma capacidade de rastreamento de problemas. É um aspecto principal do serviço ao cliente no EspoCRM. O termo Ticket também pode ser usado para os casos.
-
-A entidade de caso pode ser associada a uma Conta e/ou a vários Contatos.
-
-Os novos casos devem ser criados pelos seguintes cenários:
-
-* Manualmente por utilizadores de CRM;
-* Manualmente por utilizadores do portal de clientes;
-* Através da API (por exemplo, através do formulário web);
-* Automaticamente quando um novo e-mail entrou para uma caixa de correio específica.
-* Automaticamente por uma regra do Fluxo de trabalho.
-
-A gravação do caso tem um fluxo que pode ser utilizado para uma comunicação entre o cliente e o serviço. Os utilizadores de CRM também podem fazer postagens internas que não serão visíveis num portal de clientes.
-
-Quando o novo caso é criado por um utilizador do portal, ele não é atribuído a nenhum utilizador. Ao utilizar [Fluxos de trabalho](../administration/workflows.md) o administrador pode criar uma regra que notificará certos utilizadores sobre um novo caso no sistema. Os fluxos de trabalho também fornecem uma capacidade para aplicar a regra de atribuição a novos casos, ou seja, regras Round-Robin e Least-Busy. Para fluxos de negócios mais complexos é recomendável utilizar [ferramenta BPM](../administration/bpm.md).
-
-Para evitar a negligência de novos casos, os utilizadores podem adicionar o tipo de entidade de Caso à lista de Auto-seguimento Global em Preferências. Então, eles seguirão automaticamente cada novo caso.
-
-Nota: Se não houver nenhum utilizador do portal associado a um contato vinculado, o cliente não receberá notificações por e-mail sobre as atualizações no Stream. Precisas de usar e-mails para comunicar com o cliente.
-
-### Email-para-Caso
-
-O administrador pode configurar a conta de e-mail do grupo que criará um novo caso em cada novo e-mail de entrada. Para mais informações [veja aqui](../administration/emails.md).
-
-### Conhecimento Base
-
-Os utilizadores podem relacionar artigos da base de conhecimento ao registro do caso.
-
-### Portal do cliente
-
-O administrador pode criar um [portal](../administration/portal.md) onde os clientes poderão criar casos.
-
-Como os utilizadores do portal seguem automaticamente os seus casos, eles receberão notificações por e-mail sobre as novas mensagens no Stream.
diff --git a/i18n/pt_PT/user-guide/emails.md b/i18n/pt_PT/user-guide/emails.md
deleted file mode 100644
index d965cda65..000000000
--- a/i18n/pt_PT/user-guide/emails.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Diretrizes sobre o Uso do Correio Eletronico
-
-O EspoCRM porporciona a capacidade de procurar correio eletrónico na caixa IMAP. Isto faz com que seja possivel usar o EspoCRM como um cliente de correio eletrónico juntamente com os recursos específicos do CRM.
-
-## Contas IMAP
-
-*Nota: Deves ter o [cron](../administration/server-configuration.md#configure-um-crontab) configurado corretamente no teu sistema para que o correio eletrónico recebido funcione.*
-
-O utilizador pode configurar a conta IMAP na página de contas de correio eletrónico pessoais (guia do correio eletrónico> menu superior direito> Contas de Correio Eletrónico Pessoais).
-
-Especifica quais as pastas que são para monitorizar no campo Pastas Monitorizadas. Por padrão, ele está configurado no INBOX. Se usas um cliente de correio eletrónico externo para enviar mensagens de correio eletrónico, Podes adicionar a pasta Enviada para arquivar este correio eletrónico.
-
-*Pesquisa Desde* permite que escolhas a data a partir da qual as mensagens de correio eletrónico devem ser arquivadas. Configura-o para uma data antes de hoje, se precisares de arquivar correio eletrónico antigo.
-
-Existe a possibilidade de especificares a *Pasta* na Conta Pessoal de Correio Eletrónico. As mensagens de correio eletrónico recebidas serão colocadas nessa pasta.
-
-## Contas SMTP
-
-Os utilizadores podem configurar as configurações do SMTP em Preferências, bem como nas suas Contas de Correio Eletrónico Pessoais. O administrador também pode permitir o uso do sistema SMTP (torna-lo Compartilhado).
-
-Os utilizadores podem ter várias contas SMTP (a partir da versão 4.2.0). Mas os endereços de correio eletrónico que o utilizador pode usar para enviar mensagens de correio eletrónico são definidos pelos endereços de correio eletrónico do registro *Utilizador*.
-
-## Trabalhar com Correio Eletrónico
-
-As mensagens de correio eletrónico são capturados pelo cron (em segundo plano) a cada poucos minutos (o período pode ser especificado pelo Administrador).
-Pode ver todos as tuas mensagens de corrreio eletrónico na aba Correio Eletrónico. Existem as pastas padrão, Recebidas, Enviadas, Rascunhos no lado esquerdo.
-
-O campo de *Estado*. `Enviado` significa que foi enviado a partir do CRM, `Arquivado` - retirado da conta IMAP ou arquivado manualmente, `Rascunho` - significa que o correio electrónico foi criado como um rascunho.
-
-Quando uma nova mensagem de correio eletrónico chega, o sistema tenta reconhecer a qual registro este correio eletrónico pertence. Podes vinculá-lo com a Conta, Potencial Cliente, Oportunidade, Caso (e Contato no modo B2C) etc. Se não for reconhecido, o utilizador pode conetá-lo manualmente, preenchendo o campo *Pai*.
-
-Quando uma nova mensagem de correio eletrónico vier de um novo potencial cliente, o utilizador pode **converte-lo em Potencial Cliente**. Abre a entrada de correio eletrónico e clica em Criar potencial cliente no menu superior direito.
-
-Também é possível **criar Tarefa ou Caso** a partir de um registro de correio eletrónico.
-
-Se os endereços de correio eletrónico (de, para, cc) num registro de correio eletrónico forem reconhecidas pelo sistema, será mostrado a pessoa com quem eles estão relacionados (Contato, Potencial Cliente, Utilizador, etc.). Se qualquer endereço de correio eletrónico for novo, podes **criar contato** diretamente de lá.
-
-Todas as mensagens de correio eletrónico relacionados a um registro específico émostrado no painel Histórico desse registro. Se algum correio eletrónico estiver relacionado, por exemplo, com oportunidade, mas a oportunidade está relacionada à conta, ela será mostrada em oportunidade e em conta
-
-## Enviar Correio Electrónico
-
-Podes escrever uma nova mensagem de correio eletrónico de várias formas:
-* Botão de *Escrever Correio Eletrónico* na lista de Correio Eletrónico;
-* responder a outro correio eletrónico;
-* clicar num endereço de correio eletrónico de algum registro;
-* ação *Escrever Correio Eletrónico* no painel de Atividades.
-
-Existe a possibilidade de **selecionares o modelo** no teu correio eletrónico.
-
-Podes configurar a **assinatura do correio eletrónico** em Preferências.
-
-## Pastas de Correio Electrónico
-
-Os utilizadores podem criar as suas próprias pastas de correio eletrónico de acordo com a conviniência para colocar algumas das mensagens de correio eletrónico. A lista de pastas disponíveis está disponível na página de Correio Eletrónico no lado esquerdo. Para criar ou editar pastas, siga o Correio Eletrónico> menu suspenso no canto superior direito> Pastas.`Ignorar Notificação` significa que não serás notificado sobre as mensagens de correio eletrónico recebidas que pertençam à pasta especificada. Ao usares os Filtros de Correio Eletrónico, é possível colocares as mensagens de correio eletrónico nas pastas automaticamente de acordo com os critérios específicos.
-
-## Filtros de Correio Eletrónico
-
-O administrador pode criar filtros de correio eletrónico globais para ignorar o correio eletrónico indesejado. Estão disponíveis em Administração> Filtros de Correio Eletrónico Email.
-
-O utilizador regular pode criar filtros de correio eletrónico para as suas contas de correio eletrónico pessoais ou para toda a sua caixa de entrada completa. Estão disponíveis em Correio Eletrónico > menu suspenso no canto superior direito> Filtros.
-
-Existem dois tipos de filtros:
-* Ignorar - o correio eletrónico será colocado no *Lixo* ou não será importado se o filtro estiver relacionado a Conta Pessoal de Correio Eletrónico;
-* Colocar pasta – as mensagens de correio eletrónico importados serão automaticamente colocados na pasta de utilizador especificada.
-
-## Modelos de Correio Eletrónico
-
-Os modelos de correio eletrónico estão disponíveis em Correio Eletrónico > menu suspenso no canto superior direito> Modelos de correio eletrónico. Podem ser usados para correio eletrónico em massa e correio eletrónico regular. A caixa de verificação `One-off` significa que o modelo de correio eletrónico será usado apenas uma vez, que é usual para o marketing por correio eletrónico.
-
-É possível usar os espaços reservados da pasta no corpo do modelo de correio eletrónico e o assunto, por exemplo. {Account.name}, {Person.emailAddress}. Serão substituídos por valores de registros relacionados.
-
- Podes usar marcadores de espaço de pasta reservados adicionais no corpo do modelo: {optOutUrl} e {optOutLink}.
-```
-
-Cancelar a inscrição
-```
-
-Este é uma ligação para cancelar a inscrição de correio eletrónico em massa.
diff --git a/i18n/pt_PT/user-guide/markdown.md b/i18n/pt_PT/user-guide/markdown.md
deleted file mode 100644
index a4ddd46d7..000000000
--- a/i18n/pt_PT/user-guide/markdown.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# Sintaxe de Markdown
-
-Os campos de texto admitem a sintaxe do markdown.
-
-## Código
-```
-`algum texto`
-```
-
-`algum texto`
-
-## Código Multilineal
-
-```
-``` algum texto ```
-```
-
-```
-algum texto
-```
-
-## Texto Forte
-
-```
-**algum texto**
-```
-
-**algum texto**
-
-## Texto Enfatizado
-
-```
-*algum texto*
-```
-
-*algum texto*
-
-## Texto Apagado
-
-```
-~~algum texto~~
-```
-
-~~algum texto~~
-
-## Bloco de Citação
-
-```
-> algum
-> texto
-```
-
-> algum
-> texto
-
-## Link
-
-```
-[texto de link](https://www.espocrm.com)
-```
-[texto de link](https://www.espocrm.com)
-
-## Lista Numerada
-
-```
-1. Algum item
-2. Outro item
-```
-
-1. Algum item
-2. Outro item
-
-## Lista Não Numerada
-
-```
-* Algum item
-* Outro item
-```
-
-* Algum item
-* Outro item
-
-## Linha Horizontal
-
-```
-___
-```
diff --git a/i18n/pt_PT/user-guide/mass-email.md b/i18n/pt_PT/user-guide/mass-email.md
deleted file mode 100644
index 77da43ec4..000000000
--- a/i18n/pt_PT/user-guide/mass-email.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Correo Electrónico Massivo
-
-## Como enviar e-mails massivos
-
-Necesitas de ter pelo menos uma Lista de Destinos com registros de destinos e um Modelo de E-mail na tua crm.
-
-1. Cria uma nova campanha com um `E-mail` ou `Newsletter`. Seleciona uma ou algumas listas de destinos no campo `Listas de Destino`.
-
-2. Depois de o registro da campanha estiver criado, cria um E-mail Massivo para esta campanha: Faz mais um clique no painel de E-mail Massivo. Especifica _Data de Inicio_ - de quando se devem enviar os e-mails, e seleciona _Modelo de E-mailo_. certifica-te que o _Estado_ está configurado como `Pendente`.
-
-Se tiver tudo configurado corretamente, os e-mails devem desligar-se. Devem ser enviados a cada hora em parcelas (podes alterar o tamanho da parcela em Administração> E-mails de Saída). O administrador pode alterá-lo atualizando o campo `Programación` de la tarea programada `Verificar Cuentas de Correo Electrónico Grupales`.
-
-Se tudo estiver configurado corretamente, os e-mails devem ser desligados. Eles devem ser enviados a cada hora com porções (você pode alterar o tamanho da parcela em Administração> E-mails de saída). O administrador pode alterá-lo atualizando o campo `Aendamento` da tarefa agendada 'Verifique as Contas de E-mail do Grupo'.
-
-Podes verificar se os e-mails são enviados no painel de registro.
-
-## Testa o que vai ser enviado aos destinatários
-
-Clica no menu suspenso direito na linha de e-mail massivo no painel _E-mail Massivo_ e em seguida, clica em _Enviar teste_.
-
-## Iniciar Sessão
-
-No registro podes ver:
-* E-mail enviado;
-* E-mails abertos pelo destinatário;
-* Links clicados pelo destinatário;
-* Destinatários que optaram por sair;
-* Mensagens de E-mails devolvidos (não foram entregues ao destinatário).
-
-## Link de exclusão
-
-De uma maneira predefinida, o sistema agregará a opção de exclusão voluntária a todos os e-mails enviados. Mas podes usar um personalizado no teu Modelo de E-mail.
-
-Exemplo:
-```html
-Cancelar a subscrição da lista de correio.
-```
-
-O administrador pode desabilitar o link de exclusão obrigatória que está a ser adicionado pelo sistema em Administração> E-mails de Saída.
-
-## URL de Acompanhamento
-
-Se tu quiseres saber se o teu destinatário abriu o link do teu e-mail, precisas de criar um URL de acompanhamento. Especifica qualquer _Nome_ e _URL_ para onde o teu link deve conduzir. Então, precisas de colocar o código gerado no teu Modelo de E-mail.
-
-Exemplo:
- ```html
-Testa a nossa demonstração
- ```
-
-## Listas de Destinos
-
-As Listas de Destinos contêm as listas de contas, Contatos, Potenciais Clientes r Registros de Utilizadores.
-
-Os utilizadores podem preencher manualmente as listas de destinos usando a ação _Selecionar_ no painel correspondente na exibição de detalhes da Lista de Destinos. Existe a capacidade de fazer filtragem e em seguida selecionar todos os resultados da pesquisa.
-
-## Preencher Listas de Destinos com Relatórios
-
-O recurso de [Relatórios](reports.md#sincronização-com-listas-de-destino) fornece a capacidade de preencher as listas de destino com registros que correspondem a critérios específicos.
-
-## Excluir Listas de Destinos
-
-Especifica a Exclusão de Listas de Destinos para evitar o envio de email massivo para determinados destinatários. Se houver um registro com o endereço de e-mail que corresponda ao endereço de e-mail de qualquer registro excluído, o primeiro registro também será excluído.
-
-## Registro de Campanha
-
-No Registro de Campanhas, podes consultar os e-mails que foram enviados, e-mails abertos, e-mails devolvidos, os que optaram por sair e quem clicou no link do e-mail. É possível utilizares este log criando Lista de Destinos (menu suspenso no canto superior direito no painel) com base nos registros do log. Por exemplo, podes escolher apenas contatos que clicaram no link (URL de rastreamento).
-
-## Solução de Problemas
-
-_Para os Administradores_
-
-#### ¿Que fazer se os e-mails não são enviados?
-
-1. Verifica se funciona _Envio de Teste_. Se não funcionar, verifica se as configurações de SMTP do sistema estão corretas.
-2. Verifica se configuraste o cron para o teu sistema.
-3. Verifica se tens o Trabalho Proramado de `Enviar e-mails massivos` e está `Ativo` (Administração > Trabalhos Programados > Enviar E-mails Massivos). Verifique se há alguma coisa no Log.
-
-#### ¿O que acontece se o URL de acompanhamento tiver uma URL incorreta que não leve ao seu crm?
-
-Verifica o parâmetro 'siteUrl' no arquivo `data/config.php`. Deve ser configurado como URL do teu EspoCRM acessível a partir do mundo externo.
-
-#### Os e-mails devolvidos não se encontram a ser registrados
-
-Os e-mails devolvidos podem ser manuseados apenas pela conta de e-mail de grupo. Certifica-te de que tens uma conta de e-mail de grupo que monitorize quais os e-mails enviados para a caixa de correio são enviados.
-
-Além disso, alguns provedores do servidor do correio podem desviar-se dos padrões, por isso os e-mails devolvidos não podem ser distinguidos.
diff --git a/i18n/pt_PT/user-guide/printing-to-pdf.md b/i18n/pt_PT/user-guide/printing-to-pdf.md
deleted file mode 100644
index ad68c59b1..000000000
--- a/i18n/pt_PT/user-guide/printing-to-pdf.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# Impressão em PDF
-
-Nota: Este recurso está disponível desde a versão 5.0.5. do EspoCRM.
-
-A impressão em PDF oferece a capacidade de criar documentos em PDF com dados de registro. O conteúdo do documento é definido pelo modelo.
-
-1. Precisas de ter pelo menos um Modelo para o tipo de entidade de gravação que desejas imprimir.
-2. 'Imprimir em PDF' estará disponível na vista de detalhes no menu suspenso ao lado do botão 'Editar'.
-
-## Modelos
-
-A aba de Modelos está oculta por padrão. O administrador pode adicioná-lo na Administração > Interface de utilizador.
-
-Para uma edição mais precisa, é recomendável usares o modo de exibição de código.
-
-Podes imprimir os campos do registro, bem como os campos de registros relacionados, utilizando os espaços reservados no teu modelo.
-
-Exemplos:
-
-* `{{name}}` – Nome do registro;
-* `{{assignedUserName}}` – Utilização atribuído;
-* `{{account.name}}` – Nome da conta relacionada.
-
-É possível imprimir os campos de imagem:
-```
-
-```
-
-onde `imageId` - o nome do campo de imagem personalizado, concatenado com o sufixo `Id`.
-
-Para exibir os números de flutuação sem a parte fracionada (como número inteiro) usa a seguinte expressão:
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Formatação personalizada para valores de moeda:
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-
-O valor `10000.5` será imprimido como `10 000,50`.
-
-Para exibir os arquivos de texto (multilinha), usa os aparelhos triplos:```{{{description}}}```.
diff --git a/i18n/pt_PT/user-guide/quotes.md b/i18n/pt_PT/user-guide/quotes.md
deleted file mode 100644
index 2a0dd4c43..000000000
--- a/i18n/pt_PT/user-guide/quotes.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Citações
-
-O recurso Citações está disponível em [Pacote Avançado](https://www.espocrm.com/extensions/advanced-pack/).
-
-As citações são um grupo específico de produtos ou de serviços com suas quantidades e preços que tu citas aos teus clientes.
-
-As citações têm um relacionamento com a Oportunidade. Podes adicionar o painel de Citações à visualização detalhada da Oportunidade em Administração > Gestor de Layout > Oportunidades > Relacionamentos. Ao criar uma nova citação ligada a uma oportunidade, ela transfere os itens de oportunidade para a citação.
-
-Podes adicionar o painel de Citações à visualização detalhada da Conta para poderes ver as cotações relacionadas. Podes fazê-lo em Administração > Gestor de Layout > Contas > Relacionamentos.
-
-## Itens de Citações
-
-A citação possui uma lista de itens. Cada item pode representar um determinado produto ou um serviço com a sua descrição, quantidade, taxa de imposto, preço de tabela e campos de preço unitário. É possível ordenar os itens manualmente.
-
-Existe a capacidade de adicionar campos personalizados para a entidade Item de Citação usando para o efeito o Gestor de Entidades.
-
-## Modelos
-
-Por defeito, existem dois tipos de modelos disponíveis: Citação e Fatura. Podes então criar novos modelos (Exibição da lista de Citações > menu suspenso superior direito > Modelos), bem como editar os existentes.
-
-Para uma edição mais precisa é recomendável usar o modo de Visualização de código.
-
-Podes imprimir os campos do registro de Citações, bem como os campos de registros relacionados, utilizando espaços reservados par efeito no teu modelo.
-
-Exemplos:
-`{{accountName}}` – Nome da conta,
-
-`{{{billingAddressStreet}}}` – Rua,
-
-`{{account.type}}` – Tipo de Conta relacionada,
-
-`{{assignedUser.lastName}}` – ultimo nome do utilizador signatário.
-
-Se o teu item de linha for um produto, podes imprimir os campos do produto.
-
-Exemplos:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Comprimento e a cor são campos personalizaveis de Produtos de entidade que se encontram em exemplos.
-
-Repetição automática através de itens de citação:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-É possível imprimir campos de imagem:
-
-```
-
-```
-onde `imageId` – o nome do campo de imagem personalizado na entidade de Citação concatenada com o sufixo `Id`.
-
-Para o item de linha do produto:
-```
-
-```
-
-Para exibir números de flutuação (como quantidade, preço unitário etc.) sem parte fracionadas (como número inteiro) usa as seuintes expressões (desde a versão 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Formatação personalizada para valores de moeda (desde a versão 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Valor `10000.5` será impresso como `10 000,50`.
-
-Para exibir campos de texto (multilinha) usa aparelhos triplos: `{{{description}}}`.
-
-## Imprimir em PDF
-
-As citações podem ser impressas em PDF. Esta ação está disponível no menu suspenso ao lado do botão Editar na visualização detalhada da citação. Depois será solicitado para selecionar o Modelo.
-
-## Citação de Email
-
-O PDF de citação pode ser enviado via email como anexo. Abre o registro de citação, clica na lista suspensa ao lado do botão Editar e clica em Email PDF.
-
-## Numeração automática
-
-Podes criar um campo de Número através do Gestor de Entidade por tipo de Citação de entidade. Administração > Gestor de Entidade > Citação > Campos > Adicionar Campo > Número. Depois precisas colocá-lo na visualização detalhada usando o Gestor de Layout.
-
-O valor será incrementado por cada nova citação. Existe a capacidade de especificar o próximo número, bem como o prefixo.
-
-## Imposto Padrão
-
-Disponivel desde EspoCRM 4.8.0.
-
-Especifique o registro de Imposto padrão em Administração> Entity Manager> Quotes> fields> Tax> Default.
-
-1. Especifique o registro de Imposto padrão na Administração > Gestor de Entidade > Citações > campos > Impostos > Padrão.
-2. Especifique taxa de imposto padrão na Administração > Gestor de Entidade > Citações > campos > Impostos > Padrão.
-
-## Faturas
-
-A citação pode ser tratada como uma fatura se o teu estado for `Aprovado`. Então os campos _Data da Fatura_, _Número da Fatura_ aparecem. Podes usar um modelo diferente para a impressão das faturas.
diff --git a/i18n/pt_PT/user-guide/reports.md b/i18n/pt_PT/user-guide/reports.md
deleted file mode 100644
index 9830343b9..000000000
--- a/i18n/pt_PT/user-guide/reports.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Relatórios
-
-O recurso Relatórios está disponível em [Pacote Avançado](https://www.espocrm.com/extensions/advanced-pack/).
-
-Existem dois tipos de relatórios: Lista e Grade.
-
-## Listar Relatórios
-
-Listar relatórios resulta a lista de registros que seguem critérios especificos.
-
-Para criar um novo relatório da lista, clica na aba Relatórios e clica em Criar Botão de Relatório. Escolhe o Tipo de Entidade que necessitas e clica em Criar botão na seção de Relatório da Lista.
-
-No campo _Colunas_ escolhe o campo que gostarias de ver exibido. Abaixo podes especificar os parâmetros de exibição para cada uma das coluna, p.e. largura e alinhamento.
-
-Escolhe a classificação necessária no campo _Ordem de Lista_ .
-
-Na seção _Filtros_ podes especificar os critérios que determinam quais os registros que serão listados no teu relatório. Podes usar os operadores lógicos 'OU' e 'E' aqui.
-
-Os _Filtros de Tempo de Execução_ permitem que especifiques diferentes filtros antes de executares o relatório.
-
-Podes __exportar__ a lista de reistro de resultados para o excel e em formato csv.
-
-## Registros de Grade
-
-Os relatórios de grade resultam de valores resumidos e agrupados por campos especificados. Estes relatórios podem ser exibidos como um gráfico.
-
-
-
-Para criares um novo relatório de grade, clica na aba Relatórios e em seguida clica no botão Criar relatório. Escolhe o Tipo de Entidade necessário e clica em Criar botão na seção Relatório de Grade.
-
-No campo _Grupo Por_, escolhe um ou dois campos para os quais os dados do relatório devem ser agrupados. É possível agrupar por ano, mês, dia para os campos de data. Se agrupares por dois campos, o teu relatório será considerado como tridimensional.
-
-No campo _Colunas_, seleciona uma ou mais funções agregadas como COUNT, SUM (soma), MIN, MAX, AVG (média).
-
-O campo _Ordem por_ define como os dados do relatório serão classificados.
-
-Na seção _Filtros_ podes especificar critérios que determinam quais os registros que serão usados no teu relatório. Podes usar os operadores lógicos 'OU' e 'E' aqui.
-
-Os _Filtros de Tempo de Execução_ permitem que especifiques os diferentes filtros antes de executar o relatório.
-
-O relatório Grade permite exibir os resultados num gráfico. Existem os seguintes _tipos de gráficos_: Barra (Horizontal), Barra (Vertical), Torta, Linha.
-
-É impossivel __exportar__ os resultados em grade para o excel e em formatos csv.
-
-## Filtros
-
-### Campo de filtro
-
-Tipo de filtro simples de usar. Tu também podes escolher os campos da entidade alvo, bem como as entidades relacionadas.
-
-
-
-### OU grupo
-
-OU significa que pelo menos uma condição do grupo deve ser cumprida.
-
-
-
-### E grupo
-
-E significa que todas as condições do grupo devem ser atendidas.
-
-### NÃO grupo
-
-Fornece uma capacidade de filtrar registros que não correspondem aos critérios especificados. Por exemplo. listar as contas que não têm qualquer oportunidade de status com os Ganhos Fechados ou Perdidos Fechados.
-
-
-
-### Expressão Complexa
-
-Para um uso mais avançado. Podes aplicar a função para uma determinada coluna da base de dados e compará-la com o resultado da expressão da [formula](../administration/formula.md).
-
-Nota: Se precisares de comparar apenas com um valor de cadeia simples, deves colocá-lo em citações simples `'alguma cadeia'`.
-
-Nota: Funções destinadas a interagir com registro de entidade não irão funcionar aqui porque a fórmula não é aplicada no registro específico.
-
-
-
-## Exibindo no painel
-
-Podes exibir qualquer relatório no painel. Para isso, precisas de adicionar o Relatório dashlet e em seguida escolhe o relatório necessário nas opções do dashlet.
-
-## Envio de Email
-
-É possível fazeres o sistema enviar reularmente relatórios de resultados a determinados utilizadores, de acordo com o tempo especificado. Isso deve ser configurado individualmente para determinados relatórios.
-
-## Sincronização com Listas de Destino
-
-É possível ter listas de destino sincronizadas com os resultados do relatório da lista. É conveniente para o email massivo quando desejas enviar e-mails apenas para contatos que cumpram com alguns dos critérios no momento do envio. Este recurso está disponível na visualização detalhada de qualquer lista de destino no painel 'Sincronizar com Relatórios'.
diff --git a/i18n/pt_PT/user-guide/sales-management.md b/i18n/pt_PT/user-guide/sales-management.md
deleted file mode 100644
index 2607e9501..000000000
--- a/i18n/pt_PT/user-guide/sales-management.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Gestor de Vendas
-
-## Leads
-
-A Lead representa uma pessoa ou uma organização que atualmente não é um cliente, mas que tem potencial para ser. Criar um registro principal geralmente é o primeiro passo do processo de venda. À medida que mais informações são reunidas sobre a Lead, é suposto que a liderança será convertida em Conta, Contato e Oportunidade.
-
-Novas leads devem ser criadas pelos seguintes cenários:
-
-* Manualmente por utilizadores de CRM;
-* Através da API (por exemplo, através do formulário web);
-* Automaticamente por uma regra do fluxo de trabalho.
-
-Ao utilizar o [Fluxos de trabalho](../administration/workflows.md), o administrador pode configurar no sistema para aplicar uma regra de atribuição específica aos novos leads, ou seja, Round-Robin e Least-Busy regras. Para fluxos de negócios mais complexos é recomendável utilizar [ferramenta BPM](../administration/bpm.md).
-
-Para evitar a negligência de novas leads, os utilizadores podem adicionar o tipo de entidade principal à lista de seguimento automático global em Preferências. Então, eles seguirão automaticamente todas as novas leads.
-
-## Oportunidades
-
-A oportunidade representa um acordo potencial ou fechado. A oportunidade com o estágio 'Fechado Won' é levada em consideração para um cálculo de receita de vendas.
-
-Os estágios seguintes estão disponíveis por padrão:
-
-* Prospecção;
-* Qualificação;
-* Proposta;
-* Negociação;
-* Fechado Ganhou;
-* Fechado Perdido.
-
-O administrador pode definir estágios personalizados dependendo do fluxo de negócios da empresa. Mas não é recomendado remover o estágio 'Fechado Won', pois é usado para calcular uma receita.
-
-## Análise de vendas
-
-Os gráficos a seguir estão disponíveis no painel por padrão:
-
-* Vendas por mês;
-* Oportunidades por fonte principal;
-* Oportunidades por fase;
-* Pipeline de vendas.
-
-Ao utilizar [Ferramenta Relatórios](reports.md), é possível visualizar estatísticas de vendas com base em critérios específicos. Os gráficos de relatório podem ser exibidos no painel.
-
-### Previsão de receita
-
-1. Cria um novo relatório de grade para o tipo de entidade Oportunidade.
-2. Adiciona 'MONTH: Close Date' ao Grupo de campo.
-3. Adiciona o campo 'SUM: valor ponderado' para as colunas.
-4. Adiciona o campo 'Fechar data' ao Filtro de tempo de execução.
-5. Seleciona o tipo de gráfico 'Barra (vertical)'.
-
-Este relatório mostrará previsões de receita com base em probabilidades de oportunidades.
-
-Os utilizadores que tenham acesso a este relatório poderão adicioná-lo em seus painéis.
diff --git a/i18n/pt_PT/user-guide/stream.md b/i18n/pt_PT/user-guide/stream.md
deleted file mode 100644
index b84033a7c..000000000
--- a/i18n/pt_PT/user-guide/stream.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Transmissão
-
-A transmissão no EspoCRM é um feed onde podes verificar as suas atualizações e novas adições para os registros que tu acompanhas. Também podes publicar para transmitir e transmitir através de outros utilizadores (desde a versão 3.8.0). Existem dois tipos de transmissão no EspoCRM: sequência de registros e sequência de utilizadores.
-
-Por defeito, as seguintes entidades possuem uma transmissão: Contas, Contatos, Leads, Oportunidades, Casos. Os administradores podem ativar ou desativar a transmissão de uma determinada entidade em [Entity Manager](../administration/entity-manager.md).
-
-## Registo de Transmissão
-
-A gravação da transmissão é mostrada no painel Transmissão de um determinado registro na visualização de detalhes. As postagens, as atualizações e as novas adições relacionadas ao registro atual encontram-se aqui descritas.
-
-## Transmissão de Utilizador
-
-Os utilizadores podem visualizar a sua transmissão no Dashlet da Transmissão, bem como na aba Transmissão. Os utilizadores também podem visualizar a transmissão de outros utilizadores na visualização de detalhes do utilizador, caso eles tiverem um acesso que seja controlado pelo campo das Funções da `Permissão do Utilizador`.
-
-Na transmissão de utilizadores, poder visualizar postagens, atualizações e novas adições relacionadas aos registros que o utilizador acompanha. Também podes visualizar as postagens dirigidas ao utilizador. Estas postagens não estão relacionadas com nenhum registro.
-
-## Notificações
-
-Irás receber notificações sobre novas adições à tua transmissão que foram causadas por outros utilizadores.
-
-## Postagens
-
-Podes criar uma postaem relacionada com um determinado registro. Também podes anexar vários arquivos e imagens à tua postagem. Se quiseres mencionar alguém na tua publicação, basta escrever o símbolo `@` e começar a escrever o nome do utilizador. O utilizador que te mencionou na tua publicação será notificado sobre isto.
-
-## Postagens dos Utilizadores
-
-_Este recurso está disponível desde a versão 3.8.0._
-
-Os utilizadores podem criar postagens para determinados utilizadores, para determinadas equipas, para todos os utilizadores e para si mesmos. Um acesso para esta funcionalidade é controlado pelo campo de funções `Atribuição de Permissão`.
-
-## Filtrando
-
-Podes filtrar o que queres mostrar numa transmissão: `Todos`,` Postaens` ou `Atualizações`.
-
diff --git a/i18n/ro_RO/administration/apache-server-configuration.md b/i18n/ro_RO/administration/apache-server-configuration.md
deleted file mode 100644
index 3fcbd2cf3..000000000
--- a/i18n/ro_RO/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Configurările server-ului Apache pentru EspoCRM
-
-Aceste instrucțiuni sunt suplimentare la ghidul [Configurare Server] (server-configuration.md). Rețineți că toate setările configurațiilor listate aici, sunt făcute pe server-ul Ubuntu.
-
-## Cerințe PHP
-
-Pentru a instala toate librăriile necesare, rulează aceste comenzi în terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Repararea problemei “API Error: EspoCRM API is unavailable”:
-
-Efectuează doar pașii necesari. După fiecare pas, verifică dacă a fost rezolvată problema.
-
-### 1. Activează suportul “mod_rewrite” în Apache
-
-Pentru a activa “mod_rewrite,” rulează aceste comenzi într-un terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Activează suportul .htaccess
-
-Pentru a activa suportul .htaccess, adaugă/editează Setările de Configurare ale Serverului /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf sau /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Apoi, rulează această comandă într-un terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Adaugă calea RewriteBase
-
-Deschide un fișier /ESPOCRM_DIRECTORY/api/v1/.htaccess și înlocuiește următoarea linie:
-
-```
-# RewriteBase /
-```
-
-cu
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-unde REQUEST_URI face parte din URL, ex. pentru “http://example.com/espocrm/”, REQUEST_URI este “espocrm”.
-
-
-## Activează suport pentru Autorizația HTTP (numai pentru FastCGI).
-
-FastCGI nu acceptă Autorizația HTTP implicit. Dacă folosești FastCGI, trebuie să activezi în VirtualHost sau /etc/apache2/apache2.conf (httpd.conf) prin adăugarea următorului cod:
-
-Pentru modul Fcgid:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Pentru modul FastCgi:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Pentru a verifica care modul este folosit în momentul actual, rulează această comandă pentru a găsi modulul:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/ro_RO/administration/b2c.md b/i18n/ro_RO/administration/b2c.md
deleted file mode 100644
index 2094d4385..000000000
--- a/i18n/ro_RO/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#Configurare EspoCRM pentru B2C (Business-to-Client)
-
-În mod implicit EspoCRM este configurat pentru a folosi B2B. Însă îl poți seta cu ușurință pentru B2C.
-
-* Schimbă `b2cMode` în true în fișierul tău de configurare `data/config.php`. Începând cu versiunea 4.3.0 poate fi configurat în Administration > Seetings.
-* Înlătură fila *Account* din meniul de navigare (Administration > User Interface).
-* Înlătură câmpurile *Account* din aspectul tău (Administation > Layout Manager).
-* Dezactivează accesul la *Account* pentru toate rolurile (Administration > Roles).
-* Înlătură Contul din listele de selectare cu toate câmpurile părinte (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
\ No newline at end of file
diff --git a/i18n/ro_RO/administration/backup-and-restore.md b/i18n/ro_RO/administration/backup-and-restore.md
deleted file mode 100644
index 2fd4aecc8..000000000
--- a/i18n/ro_RO/administration/backup-and-restore.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# Restabilire și Copie de rezervă
-
-## Cum să faci manual o copie de rezervă a EspoCRM
-
-EspoCRM conține fișiere și date din baze de date. Toate aceste date sunt necesare pentru a se creea o copie de rezervă completă a EspoCRM. Mai jos sunt instrucțiunile pentru un server Ubuntu cu MySQL.
-
-### Pasul 1. Copie de rezervă a fișierelor
-
-Creează o arhivă a conținutului directorului instalat EspoCRM. Pentru Ubuntu calea implicită este `/var/www/html`. Poți folosi următoarea comandă:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Pasul 2. Copie de rezervă a bazei de date
-
-Pentru a face o copie de rezervă a tuturor datelor, trebuie să știi numele bazei de date și să accesezi acreditările. Poți găsi numele bazei de date în fișierul de configurare `/ESPOCRM_DIRECTORY/data/config.php` în secțiunea `database` Poți folosi această comandă pentru a face o copie de rezervă a bazei tale de date:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Pasul 3. Copiază copia de rezervă
-
-Asta este tot. Acum trebuie să copiezi copia de rezervă într-un loc sigur.
-
-
-## Cum să faci o copie de rezervă EspoCRM cu un script
-
-Poți folosi un script pentru a face o copie de rezervă a tuturor datelor necesare. Autentificare prin SSH și rularea comenzilor (testate pe serverul Ubuntu).
-
-### Descarcă un script
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Rulează scriptul
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-uned
- * `PATH_TO_ESPOCRM` is a path to installed EspoCRM directory.
- * `BACKUP_PATH` is a path to backup directory.
-
-Pentru serverul Ubuntu este:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-Rețineți: Dacă utilizatorul MySQL nu are drepturile să sa acceseze baza de date dump, va trebui să introduci acreditările unui alt utilizator MySQL.
-
-După creeara cu succes, vei primi o cale către copia de rezervă creată.
-
-## Restabiliește EspoCRM dintr-o copie de rezervă.
-
-Poți să îți restabilești EspoCRM din copia de rezervă, așa cum este descris mai sus.
-
-### Pasul 1. Dezarhivează fișierle cu copiile de rezervă.
-
-Pentru a dezarhiva fișierele, poți folosi Archive Manager sau să rulezi comanda de mai jos. Fișierele trebuie să fie plasate în directorul web-server.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-unde:
- * `/var/www/html` is a web-server directory.
-
-### Pasul 2. Setează permisiunile necesare
-
-Fișierele are trebuie deținute de un utilizator web-server și să aibe permisiunile corecte. Vă rugăm să setați permisiunile necesare prin urmarea instrucțiunilor de mai jos: [www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### Pasul 3. Importă baza de date dump
-
-Baza de date dump ar trebuie să fie importată în aceași bază de date cu acreditările utilizatorului, altfel corecția are trebui făcută în fișierul de configurare `ESPOCRM_DIRECTORY/data/config.php`. Pantru a importa baza de date din dump, rulează comada de mai jos într-un terminal:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Pasul 4. Verifică/configurează crontab
-
-Verifică dacă crontab este configurat corect. Rulează comanda de mai jos și verifică dacă calea către EspoCRM este corectă:
-
-```bash
-sudo crontab -l -u www-data
-```
-unde:
- * `www-data` is your web-server user.
-
-Dacă trebuie să faci schimbări, folosește această comandă:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Mai multe detalii despre configurarea crontab pentru EspoCRM găsiți aici [www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
diff --git a/i18n/ro_RO/administration/bpm.md b/i18n/ro_RO/administration/bpm.md
deleted file mode 100644
index 4163bee59..000000000
--- a/i18n/ro_RO/administration/bpm.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# Managementul Proceselor de Afaceri
-
-Instrumentul Managementul Proceselor de Afaceri (BPM) oferă abilitatea de a modela și automatiza procesele de afaceri în EspoCRM. Este un motor care execută procesele de afaceri descrise în standardul BPMN 2.0. Instrumentul BPM este disponibil în extensia [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-
-
-### Diferență față de instrumentul fluxurilor de lucru
-
-Instrumentul Fluxul de lucru este destinat automatizării regulilor de afaceri simple, fără elemente secvențiale de flux, atunci când nu este necesară afișarea grafică a fluxului.
-
-Instrumentul BPM este pentru fluxuri de afaceri mai complexe, unde există fluxuri divergente și convergente, întârzieri de execuție, interacțiuni între utilizatori. O vizualizare de tip diagramă face procesul de afaceri mai ușor de înțeles pentru un om, un jurnal ne permite să vedem cum a fost organizat procesul.
-
-## Procesarea Diagramelor
-
-Link-ul pentru procesarea diagramelor este disponibil în panoul de administrare. Poate fi adăugat ca și filă, din panoul de navigație.
-
-Diagramele sunt destinate procesului de modelare al afacerilor. Administratorul poate creea și edita diagrame. Utilizatorii obișnuiți au doar posibilitatea de vizualizare.
-
-Fiecare diagramă are un anumit tip de entitate (Câmpul Tip Țintă). Diagrama determină execuția proceselor viitoare ale instanțelor. Conține elemente ale diagramei și conexiunile dintre elemente.
-
-Dacă procesarea diagramei nu are bifat câmpul'Is Active' atunci nu va iniția procesarea instanțelor.
-
-Pentru a afișa detaliile și parametrii unui anumit element de diagramă, trebuie să apeși pe el. În modul deeditare, vei putea edita parametrii.
-
-## Procese
-
-Procesele sunt disponiblie din panoul de administrare. Link-ul poate fi adăugat ca și filă, din panoul de navigație.
-
-Procesul reprezintă instanța procesului de afaceri. Când este inițiată, are statutul "Started". Când procesul este terminat, are statusul de "Ended". De asemenea, procesul poate fi oprit manual de către un utilizator care are acces la editarea procesului. Dacă se oprește manual, are statusul "Stopped".
-
-Procesul se execută urmând diagrama. Procesul diagramei nu poate fi schimbat după ce a început procesul.
-
-Procesul este obligatoriu legat de înregistrarea țintă unică.
-
-Processes can be started automatically (upon specific conditions or by scheduling) or manually (where there is at least one Start Event in the flowchart). To start process manually the user needs to click 'Start Process' button on the list view of processes.
-
-## Flowchart Elements
-
-### Evenimente
-
-Evenimentele sunt afișate pe diagramă, sub formă de cercuri.
-
-#### Evenimente de Început
-
-Nu au parametrii. Este un punct de plecare al procesului. Evenimentele de Început pot fi inițiate manual de către un utilizator care are acces la creearea proceselor. Utilizatorul trebuie să apese butonul'Start Process' din lista de vizualizare a proceselor.
-
-#### Evenimente Condiționale de Început
-
-Este un punct de plecare al procesului. Este declanșat automant atunci când anumite criterii sunt îndeplinite. Există două tipuri de: 'După ce a fost creeată o înregistrare', 'După ce a fost salvată o înregistrare'.
-
-#### Evenimente de Început Declanșate
-
-Este un punct de plecare al procesului. Procesul este inițiat de după un anumit program. Trebuie să specifici raportul de listă care returnează înregistrările pentru inițierea proceselor și programarea timpului, în notația crontab.
-
-#### Evenimente Condiționale Intermediare
-
-Acest eveniment oprește fluxul până când sunt îndeplinite criteriile specificate.
-
-#### Evenimente Intermediare Declanșate
-
-Acest eveniment oprește fluxul și așteaptă atât timp cât este specificat de parametrii evenimentului.
-
-Pentru setări mai complexe poți utiliza [formula](formula.md). Scripturile ar trebui să returneze valori de tip Dată-Timp (in UTC timezone). După trecerea timpului respectiv, fluxul va trece la următorul element.
-
-Utilizând funcția dată/timp, este posibil să setați cronometrul la un moment dat în viitor, de ex. începutul următoarei zile lucrătoare.
-
-#### Terminare Eveniment
-
-Termină fluxul actual. sfârșește fluxuri care rulează în paralel. Atunci când fluxul ajunge la capătul unui eveniment și nu mai sunt altele care rulează în paralel, procesul este terminat.
-
-#### Închiderea Terminării Evenimentului
-
-Sfârșește toate fluxurile. Procesul este încheiat.
-
-### Gateways
-
-Gateways sunt afișate ca diamante.
-
-#### Gateway Exclusive
-
-Poate diverge sau converge fluxuri.
-
-În cazul unei divergențe, acesta definește un singur flux (cale) care va fi ales în funcție de criteriile specificate. Prima condiție întâlnită determină fluxul, condițiile următoare sunt omise. Există posibilitatea de a specifica fluxul implicit. Fluxul implicit este ales dacă nu există condiții îndeplinite. Fluxul implicit este marcat cu un linie oblică.
-
-În cazul convergenței, direcționează fluxul spre elementul de ieșire. Nu se blochează după ce fluxul a venit, iar fluxurile paralele nu vor fi unite în fluxul unic.
-
-
-
-
-
-#### Gateway Inclusive
-
-Poate diverge sau converge fluxurile.
-
-În caz de divergență, poate direcționa către unul sau fluxuri multiple paralele (căi), în funcție de îndeplinirea fiecărui criteriu al fluxului. Fluxul implicit este ales dacă este îndeplinită vreo condiție. Fluxul implicit este marcat cu un linie oblică.
-
-Dacă există o necesitate de îmbinare a fluxurilor paralele produse de un gateway divergent incluziv, trebuie să utilizați un gateway convergent incluziv. Aceasta va aștepta toate fluxurile de intrare și apoi va continua cu elementul de ieșire.
-
-
-
-Rețineți: Gateway divergente sau convergente trebuie să fie balansate.
-
-Rețineți: Dacă unul dintre fluxurile paralele a fost terminat, atunci gateway divergent nu va fi procesat. Acest proces va fi blocat. Evitați diagramele care pot provoca astfel de situații.
-
-#### Gateway Paralel
-
-Poate diverge sau converge fluxurile.
-
-În caz de divergență, se împarte fluxul în mai multe fluxuri paralele. Nu există parametri pentru acest tip de gateway.
-
-In case of converging it waits until all incoming flows come and then continues to the next outgoing element.
-
-
-
-Note: Gateway divergente sau convergente trebuie să fie balansate.
-
-Note: Dacă unul dintre fluxurile paralele a fost terminat, atunci gateway divergent nu va fi procesat. Acest proces va fi blocat. Evitați diagramele care pot provoca astfel de situații.
-
-#### Gateway Bazate pe Evenimente
-
-Poate doar diverge fluxuri.
-
-Acesta oprește fluxul până la declanșarea oricărui eveniment de ieșire. Evenimentul declanșat determină fluxul unic. Alte evenimente de ieșire sunt respinse.
-
-Doar evenimentele intermediare pot fi la finalul secvenței de ieșire al fluxului.
-
-
-
-### Activități
-
-Activitățile sunt afișate ca și dreptunghiuri cu colțuri rotunjite.
-
-#### Sarcină
-
-Sarcinile pot executa următoarele acțiuni:
-
-* Creeare Înregistrare - creează o nouă înregistrare pentru fiecare tip de entitate;
-* Creeare Înregistrare Legată - creează o nouă înregistrare legată de înregistrarea țintă;
-* Actualizare Înregistrarea Țintă;
-* Actualizare Înregistrare Legată - acualizează înregistrările sau înregistrările legate de înregistrarea țintă;
-* Actualizare Înregistrare Creeată - actualizează câmpul specific al oricărei înregistrări create în procesul actual;
-* Actualizare Proces Înregistrare - pot fi utilizate pentru a atribui procesul unui anumit utilizator sau echipei;
-* Legarea către o altă Înregistrare - leagă înregistrarea țintă de o înregistrare specifică;
-* Anulează legarea de la o altă Înregistrare - anulează legarea înregistrării ținte de la o înregistrare specificată;
-* Aplică Regula de atribuire - atribuie înregistrarea țintă, înregistrarea procesului sau orice înregistrare creată de proces conform cu regula specifică;
-* Creeare Notificare - creează notificări în aplicație pentru utilizatori specifici;
-* Urmărire - face utilizatori specifici să urmărească înregistrări specifice, înregistrarea procesului sau altă înregistrare creeată de un proces.
-* Rulează Acțiunea de Serviciu - rulează acțiuni de serviciu personalizate implementate de programatori.
-
-Acțiunile disponibile pentru sarcină sunt aproape la fel ca în funcția Fluxului de Lucru. Mai multe detalii găsiți aici [workflow's actions](workflows.md#actions).
-
-#### Sarcina Trimite Mesaj
-
-Trimite un mesaj către un destinatar specific.
-
-#### Sarcina Utilizator
-
-Oferă o capacitate flexibilă de interacțiune a utilizatorului. Oprește execuția până se (specificată explicit sau prin regula de atribuire) rezolvă sarcina. Înregistrările Sarcină Utilizator o să fie creeate în sistem. În mod implicit există trei tipuri de acțiuni: Aprobare, Revizuire, Îndeplinit.
-
-* Tipul de aprobare necesită utilizatorul să aleagă între 'Aprobat' and 'Respins'.
-* Tipul Revizuire îi oferă utilizatorului o opțiune: 'Revizuire'.
-* Tipul Îndeplinit oferă două opțiuni: 'Terminat' and 'Nereușit'.
-
-
-Utilizatorul atribuit înregistrării Sarcină Utilizator create va primi notificări în aplicație. De asemenea, administratorul poate activa notificările prin e-mail.
-
-Utilizatorii pot adăuga Sarcini de Proces ale Utilizatorului pe panoul lor pentru a putea vedea sarcinile de proces ale utilizatorului.
-
-Este posibilă citirea rezoluției unei sarcini trecute a unui utilizator în cadrul gateway divergente sau evenimentelor condiționale, făcând ramificația în fluxul procesului.
-
-#### Sarcină Script
-
-Execută scriptul în limba [espo-formula](formula.md). Toate variabilele (`$variableName`) o să fie stocate și diponibile în cadrul procesului.
-
-### Fluxuri
-
-#### Secvență Flux
-
-Reprezentată ca o săgeată solidă. Indică ordinea în care elementele procesului o să fie executate.
-
-## Condiții
-
-Evenimentele condiționate, gateway divergente exclusive și inclusive au condiții care determină fluxul procesului.
-
-Prin intermediul UI există posibilitatea de verificare a condițiilor după următoarele înregistrări:
-
-* Înregistrare Țintă;
-* Înregistrări Legate de Țintă prin relații de tip multe-către-una și copil-către-părinte;
-* Înregistrările creeate de procese prin sarcini;
-* Înregistrări Sarcina Utilizator, permite verificarea rezoluției.
-
-Este posibil să se definească în limba [Espo-formula](formula.md).
-
-Condițiile în instrumentul BPM sunt aceleași ca în caracteristica Fluxului de Lucru. Mai multe detalii găsiți aici [workflow's conditions](workflows.md#conditions).
-
-## Exemple
-
-### Exemplul 1
-
-
-
-### Exemplul 2
-
-
-
-### Exemplul 3
-
-
diff --git a/i18n/ro_RO/administration/email-fetching.md b/i18n/ro_RO/administration/email-fetching.md
deleted file mode 100644
index d191961c0..000000000
--- a/i18n/ro_RO/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Email-uri
-
-Acest document a fost mutat aici [here](emails.md).
diff --git a/i18n/ro_RO/administration/emails.md b/i18n/ro_RO/administration/emails.md
deleted file mode 100644
index e8275256d..000000000
--- a/i18n/ro_RO/administration/emails.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Email-uri
-
-> Important. [Cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) ar trebui să fie configurat în sistem pentru ca email fetching să meargă. Poți găsi informațiile necesare în EspoCRM în Administration > Scheduled Jobs.
-
-## Prezentare generală
-
-EspoCRM are abilitatea să monitorizeze căsuțele poștale IMAP. Email-urile pot fi arhivate în două moduri: Grouparea a Conturilor Email și a Conturilor Personale Email. Grupul Conturilor de Intrare are menirea să grupeze căsuțele poștale: cazul cel mai comun fiind o căsuță de suport. Conturile Personale de Email au menirea să fie folosite pentru căsuțele poșatale personale ale utilizatorului.
-
-Așa cum un email care ajunge în sistem încearcă să îl lege cu înregistrarea potrivită (Conturi, Conducere, Oportunitate, Caz). Utilizatorii care urmăresc acea înregistrare, o să primească o notificare despre un nou email aflat în sistem, chiar dacă nu se află în To sau CC.
-
-## Grupul Conturilor de Email
-
-Doar administartorul poate seta Grupul Conturilor de Email. Grupul Conturilor de Email poate fi folosit atât pentru a primi, cât și pentru a trimite email-uri. Trimiterea de email-uri din grupul de conturi a fost disonibilă începând cu versiunea 4.9.0.
-
-Câmpul echipelor determină cărei echipe o să fie desemnate email-urile de intrare.
-
-Dacă grupul conturiloe de email are SMTP și a fost setat ca și distribuit, accesul va fi controlat de Roluri prin permisia Grupului Conturilor de Email. Câmpul echipei va fi folosit dacă nivelul permisiunii este setat la 'echipă'.
-
-Există posibilitatea de a face sistemul să trimită un răspuns automat către email-urile primite.
-
-## Email-către-Caz
-
-Există o opțiuni de a face sistemul să creeze cazuri pentru grupurile de email-urile primite.
-Această caracteristică este destinată echipelor de la suportul tehinic.
-Cazurile pot fi distribuite către utilizatori dintr-o echipă specificată, conform următoarelor:
-`direct assignment`, `round-robin` și `less-busy`.
-Doar primul email din topic creează un nou caz.
-Fiecare caz ulterior va fi legat de înregistrarea cazului existent și afișat în panoul său Stream.
-
-Atunci când utilizatorii doresc să trimită un răsouns către client, trebuie să se asigure că cazul este selectat ca și părinte al email-ul care va fi trimis. Acest lucru va determina clientul să răspundă la adresa de email al grupului și nu la adresa utilizatorului.
-
-## Conturi Personale de Email
-
-Utilizatorii pot seta conturile personale email care trebuie să fie monitorizate. Emails > Top Right Dropdown Menu > Personal Email Accounts. Administratorii pot, de asemenea, să gestioneze conturile de email ale utilizatorilor.
-
-## Filtre Email
-
-Acestea permit filtrarea email-urilor primite, după anumite criterii. Ex. dacă nu vrei ca notificările să fie trimise de unele aplicații, să fie importate în EspoCRM, poți creea un filtru care îl facă pe EspoCRM să le sară.
-
-Adminul poate creea filtre globale, aplicate tuturor conturilor de email. Utilizatorii pot creea filtre pentru propriul cont personal de email și pentru întreaga căsuță poștală.
\ No newline at end of file
diff --git a/i18n/ro_RO/administration/entity-manager.md b/i18n/ro_RO/administration/entity-manager.md
deleted file mode 100644
index 8fac2aa1f..000000000
--- a/i18n/ro_RO/administration/entity-manager.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Manger de Entități
-
-Entity Manager este disponibil în panoul de Administrare. Oferă posibilitatea de a personaliza instanța ta de EspoCRM. Poți face asta în următoarele moduri:
-
-* Adaugă noi tipuri de entități.
-* Personalizează tipuri existente de enități: schimbă etichete, ordinea implicită în vizualizarea listei default, activează sau dezactivează stream.
-* Personalizează câmpuri: adaugă, personalizează-le pe cele existente.
-* Configurează relații: adaugă, schimbă etichetele la cele existente.
-
-## Creearea unei noi entități
-
-Apasă butonul `Creează Entitate` din pagina Managerului de Entități. Specifică numele, eticheta și tipul. Dacă ai select tipul `Persoană`, entitatea ta va avea Email, Telefon, Prenume, Nume și câmpuri de Salutare. Bifează `Stream` dacă vrei ca entitatea ta să aibe panou stream, iar utilizatorii să poată urmării asftel de entități.
-
-Tipuri:
-
-* Bază - entitate goală cu câmpuri de bază ca Nume, Utilizatori Atribuiți, Echipe, Descriere.
-* Bază Plus - ca Bază dar cu Activități, Istoric, Panouri cu sarcini (disponibil începând cu 4.3.0).
-* Eveniment - Câmpuri de Data începerii, Data sfârșirii, Durata, Părine, status. Disponibil în Calendar și panoul de Activități (începând cu 4.3.0, trebuie activată Administration > Settings).
-* Persoană - Câmpuri de Email, Telefon, Prenume, Nume, Salutare, Adresă. Activități, Istoric, Panouri cu sarcini.
-* Companie - Câmpuri de Email, Telefon, Adresa de facturare, Adresa de livrare. Activități, Istoric, Panouri cu sarcini.
-
-## Actualizează o entitate existentă
-
-Dacă apeși pe link-ul `Edit` de pe o anumită enitate, vei putea schimba o parte din parametrii acelei enități.
-
-* Etichete - numele singular sau plural al enității.
-* Ordinea implicită a înregistrărilor este sortată în afișazul listei.
-* Stream - dacă caracteristica Stream este activată.
-* Deazctivat - bifează dacă nu ai nevoie de această entitate în sistemul tău.
-* Câmpuri de filtre text - în ce câmpuri să se facă căutarea pentru filterele text principale și căutările globale.
-
-
-## Câmpuri
-
-Prin apăsarea link-ului `Câmpuri` vei fi mutat în altă pagină. Acolo vei putea creea noi câmpuri sau să actualizezi unele deja exitente. Următoarele tipuri de câmpuri sunt disponibile în Mangerul de Entități:
-
-* Adresă - adresa cu strada, oraș, stat, codul poștal și țara;
-* Array - listă de valori, cu posibilitatea de a selecta valori multiple (nu este o opțiune bună dacă vrei să cauți după acest câmp); utilizatorii își pot adăuga propriile valori dacă nu sunt specificate alte opțiuni.
-* Atașament Multiplu - fișiere multiple atașate;
-* Auto-incrementare - se pot citi doar numere generate;
-* Boolean - bifează, true sau false;
-* Valută - pentru valorile valutei;
-* Dată;
-* Oră;
-* Enum - căsuță de selectare, cu posibilitatea de a alege o singură opțiune;
-* Fișier - încărcarea unui singur fișier;
-* Float - număr cu o parte zecimală;
-* Stăin - un câmp sau o entitate asemănătoare;
-* Imagine - încărcarea unei imagini cu previzualizare;
-* Integer - număr întreg;
-* Număr - auto-incrementarea unui șir de număr cu un prefix posibil și o lungime specifică;
-* Multi-enum - listă de valori, cu posibil de a selecta valori multiple(nu este o opțiune bună dacă vrei să cauți după acest câmp), similar cu Array dar mai drăguță.
-* Text - text, pentru texte cu mai multe linii;
-* Url - pentru link-uri;
-* Varchar - text scurt;
-* Wysiwyg - similar cu câmpul Text, cu posibilitatea de a formata caractere.
-
-Parameteri:
-* Necesar - completarea câmpului este necesară.
-* Valoare implictă - Valoarea câmpului este stabilită la crearea unei noi înregistrări.
-* Auditat - actualizările câmpului vor fi înregistrate în Stream.
-
-**Rețineți**: După ce ai adăugat un nou câmp trebui să adaugi acest câmp [layouts](layout-manager.md) (Administration > Layout Manager).
-
-### Logică Dinamică
-
-Oferă posibilitatea de a face formularele dinamice. Este posibil să definiți condițiile care fac anumite câmpuri vizibile, necesare sau doar pentru citire. Condițiile vor fi verificate automat când datele din formular vor fi modificate.
-
-Pentru câmpurile Enum, Array și Multi Enum este posibilă definirea unor seturi diferite de opțiuni, care vor fi disponibile în câmp, în funcție de ce condiții sunt îndeplinite.
-
-
-## Relații
-
-Puteți crea noi relații între entitățile out-of-box și cele personalizate. Există 3 tipuri de relații disponibile:
-
-* Una-către-Multe: după ce ai creat această relație, poți adăuga un câmp de legătură la aspectul detaliat al entității potrivite și poți adăuga panoul de relații la entitatea din stânga;
-* Multe-către-Una: la fel ca Una-către-Multe dar vice versa;
-* Multe-către-Multe: panouri de relații pe ambele părți.
-
-Parameterul 'Link Multiple Field' implică faptul că tipul câmpului `linkMultiple` o să fie creeat împreună. Poți adăuga acest câmp în aspect. Este convenabil pentru alegerea rapidă a înregistrărilor aferente. Nu este o opțiune bună dacă relația ta are intenția de a avea o mulțime de înregistrări legate care pot încetini încărcarea ecranului detaliat de vizualizare.
-
-Dacă parametrul 'Audited' este bifat, actualizările relațiilor vor fi autentificate în Stream.
-
diff --git a/i18n/ro_RO/administration/extensions.md b/i18n/ro_RO/administration/extensions.md
deleted file mode 100644
index e55e3fd6e..000000000
--- a/i18n/ro_RO/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Gestionare extensii
-
-## Cum să instalezi o extensie
-
-Pentru a instala o extensie EspoCRM (ex. Pachet Avansat, Integrare VoIP):
-
-1. Autentifică-te ca administrator.
-2. Mergi la Administration > Extensions.
-3. Încarcă pachetul tău de extensii (fișier zip).
-4. Apasă pe butonul de instalre.
-
-
-## Cum să actualizezi o extensie
-
-Pentru a actualiza o extensie deja instalată (ex. Pachet Avansat, Integrare VoIP) la o versiune mai nouă:
-
-1. Descarcă veriune nouă a extensie de care ai nevoie.
-2. Autentifică-te ca administrator..
-3. Mergi la Administration > Extensions.
-4. Încarcă pachetul tău de extensii (fișier zip) fără a dezinstala versiunea existentă.
-5. Apasă pe butonul de instalre.
-
-
-## Cum să dezinstalezi o extensie
-
-Pași necesari pentru a dezinstala o extenie instalată:
-
-1. Autentifică-te ca administrator.
-2. Mergi la Administration > Extensions.
-3. Găsește extensia din lista disponibilă de extensii.
-4. Apasă pe butonul de dezinstalre.
-
-
-## Cum să ștergi o extensie
-
-Atunci când o extensie este dezinstalată, este încă diponibilă în sistem. Poate fi ștearsă complet. Pași necesari pentru a șterge o extenie:
-
-1. Autentifică-te ca administrator.
-2. Mergi la Administration > Extensions.
-3. Găsește extensia din lista disponibilă de extensii.
-4. Apasă pe butonul de înlăturare.
diff --git a/i18n/ro_RO/administration/formula.md b/i18n/ro_RO/administration/formula.md
deleted file mode 100644
index af73731ae..000000000
--- a/i18n/ro_RO/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Câmpuri calculate (Formulă)
-
-În managerul de entități este posibil să definești scriptul (formula) pentru un tip specific de entitate. Acest script va fi executat de fiecare dată înaintea ce înregistrarea este salvată.
-Oferă posibilitatea de a seta automat câmpuri specifice (atribute) cu valori derivate din calcule.
-
-Pentru a edit formula urmărește Administrare > Manager Entități > meniu jos la dreapta pe rândul necesar entitate > Formulă.
-
-Va trebui să setezi câmpuri, care trebuie calculate, Doar-Citire prin Manager Entități.
-
-
-## Sintaxă
-
-Formula EspoCRM este scrisă în limbajul simplu conceput special pentru această caracteristică.
-
-Există operatori, atribute de funcții și valori care pot fi utilizate în formulă. Expresiile separate trebuie să fie delimitate de caracter `;`.
-
-### Operatori
-
-* `=` - atribuire.
-* `||` - logic OR,
-* `&&` - logic AND,
-* `!` - logic NOT,
-* `+`- sumă numerică,
-* `-` - scădere numerică,
-* `*` - înmulțire numerică,
-* `/` - împărțire numerică,
-* `%` - numeric modulo,
-* `==` - egal comparative,
-* `!=` - nu sunt egale,
-* `>` - comparație mai mare ca,
-* `<` - comparație mai mică ca,
-* `>=` - omparație mai mare sau egală ca,
-* `<=` - omparație mai mic sau egal ca.
-
-Prioritatea operatorilor:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Atribute
-
-Atributele reprezintă valorile câmpului entității țintă. Puteți insera atributele disponibile apăsând pe butonul plus.
-
-Este posibil să accesați atribute ale entităților legate cu formatul următor `linkName.attributeName`.
-
-
-### Funcții
-
-Formatul funcției folosește: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Funcții Out-of-the-box sunt listate mai jos.
-
-#### ifThenElse
-`ifThenElse(CONDIȚIA, CONSECVENT, ALTERNATIV)` Dacă CONDIȚIA este îndeplinită efectuează CONSECVENT. Dacă nu -- atunci ALTERNATIV.
-
-#### ifThen
-`ifThen(CONDIȚIA, CONSECVENT)` Dacă CONDIȚIA este îndeplinită efectuează CONSECVENT. Dacă nu -- atunci nu efectua nimic.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Concatecnare două sau mai multe șiruri.
-
-#### string\substring
-`string\substring(ȘIR, START, LUNGIME)` Extrage caracterele din ȘIR începând cu poziția START și LUNGIME.
-
-Dacă LUNGIME este omisă, sub-șirul care începe de la START până la sfârșitul ȘIR va fi returnat.
-
-Dacă LUNGIME este negativă, atunci atât de mulre caractere vor fi omise de la sfârșitul ȘIR.
-
-#### string\\trim
-`string\trim(Șir)` înlătură spațiul de la începutul sfârșitului ȘIR
-
-#### string\\lowerCase
-`string\lowerCase(ȘIR)` Convertește literele în litere mici. (începând cu versiunea 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(ȘIR)` Convertește literele în majuscule. (începând cu versiunea 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Returnează data de astăzi.
-
-#### datetime\now
-`datetime\now()` Returnează fusul orar actual.
-
-#### datetime\format
-`datetime\format(VALOARE, [TIMP DATĂ], [FORMAT])` Convertește data sau fusul orar VALOARE Într-un șir formatat în concordanță cu setările aplicației. TIMP DATĂ și FORMAT pot fi omise. Dacă TIMP DATĂ este omis, atunci va fi setată data implicită . DAcă FORMAT este omis atunci formatul implicit o să fie folosit.
-
-#### datetime\date
-`datetime\date(VALOARE, [TIMP DATĂ])` Returnează ziua din lună (1-31). `0` dacă VALOARE este necompletată. Dacă TIMP DATĂ este omis atunci TIMP DATĂ al sistemului este folosit. (începând cu versiunea 4.7.0)
-
-#### datetime\month
-`datetime\month(VALOARE, [TIMP DATĂ])` Returnează luna (1-12). `0` dacă VALOARE este necompletată. Dacă TIMP DATĂ este omis atunci TIMP DATĂ al sistemului este folosit. (începând cu versiunea 4.7.0)
-
-#### datetime\year
-`datetime\year(VALOARE, [TIMP DATĂ])` Returnează anul. `0` dacă VALOARE este necompletată. Dacă TIMP DATĂ este omis atunci TIMP DATĂ al sistemului este folosit. (începând cu versiunea 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALOARE, [TIMP DATĂ])` Returnează ora (0-23). `-1` dacă VALOARE este necompletată. Dacă TIMP DATĂ este omis atunci TIMP DATĂ al sistemului este folosit. (începând cu versiunea 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALOARE, [TIMP DATĂ])` Returnează minutul (0-59). `-1` dacă VALOARE este necompletată. Dacă TIMP DATĂ este omis atunci TIMP DATĂ al sistemului este folosit. (începând cu versiunea 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALOARE, [TIMP DATĂ])` Returnează ziua săptămânii (0-6). `-1` dacă VALOARE este necompletată. `0` - pentru duminică. Dacă TIMP DATĂ este omis atunci TIMP DATĂ al sistemului este folosit.(începând cu versiunea 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALOARE_1, VALOARE_2, INTERVAL_TIP)` Returnează diferența între două date sau două fuse orare. INTERVAL_TIP poate fi 'ani', 'luni', 'zile', 'ore', 'minute'. Returns `null` if failure. Result will be negative if VALOARE_1 < VALOARE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALOARE, MINUTE)` Adaugă MINUTE la timp dată VALOARE. MINUTE pot fi negative.
-
-#### datetime\addHours
-`datetime\addHours(VALOARE, ORE)` Adaugă ORE la timp dată VALOARE. ORE pot fi negative.
-
-#### datetime\addDays
-`datetime\addDays(VALOARE, ZILE)` Adaugă ZILE la data sau timp dată VALOARE. ZILE pot fi negative.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALOARE, SĂPTĂMÂNI)` Adaugă SĂPTĂMÂNI la data sau timp dată VALOARE. SĂPTĂMÂNI pot fi negative.
-
-#### datetime\addMonths
-`datetime\addMonths(VALOARE, LUNI)` Adaugă LUNI la data sau timp dată VALOARE. LUNI pot fi negative.
-
-#### datetime\addYears
-`datetime\addYears(VALOARE, ANI)` Adaugă ANI la dată sau TIMP DATĂ VALOARE. ANI pot fi negativi.
-
-#### datetime\closest
-`datetime\closest(VALOARE, TIP, ȚINTĂ, [A_TRECUT], [TIMP DATĂ])` Returează cea mai apropiată VALOARE în funcție de argumente. (începând cu versiunea 5.0.0)
-
-TIP poate fi una dintre următoarele VALOAREi: 'timp', 'minut', 'oră', 'dată', 'lună', 'ziASăptămânii'. ȚINTA este integer VALOARE sau un șir VALOARE. A_TRECUT înseamnă să găsească cea mai aproape din trecut. Dacă TIMP DATĂ este omisă atunci TIMP DATĂ implcită este folosită.
-
-Exemple:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` O să returneze cea mai apropiată VALOARE din viitor cu ora 20:00.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` O să returneze `2017-11-01`, prima zi a lunii.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` O să returneze următoarea zi de Luni (începutul zilei).
-
-#### number\format
-`number\format(VALOARE, [ZECIMALE], [ZECIMALE_MARCĂ], [MII_SEPARATOR])` Convertește VALOARE numerică în șir în funcție de formatul specific sau setările implicite ale aplicației. Dacă ZECIMALE, ZECIMALE_MARCĂ_MARK sau MII_SEPARATOR atunci setările sistemului o să fie folosite.
-
-Exemple:
-
-`number\format(2.666667, 2)` - rezultă 2.67;
-
-`number\format(1000, 2)` - rezultă 1,000.00;
-
-`number\format(10.1, 0)` - rezultă 10.
-
-
-#### number\abs
-`number\abs(VALOARE)` VALOARE Absolută. Returnează nul dacă VALOARE nu este numerică.
-
-#### number\round
-`number\round(VALOARE, PRECIZIA)` Returnează VALOARE rotunjită a VALOARE pentru PRECIZIA specificată (număr de zecimale după punctul zecimal). PRECIZIA poate fi negativă sau zero (implicit).
-
-#### number\floor
-`number\floor(VALOARE)` Returnează cea mai mică următoare VALOARE integer rotunjind în jos VALOARE dacă este necesar. (începând cu versiunea 4.9.0)
-
-#### number\ceil
-`number\ceil(VALOARE)` Returnează cea mai mare următoare VALOARE integer rotunjind în jos VALOARE dacă este necesar. (începând cu versiunea 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Returnează ADEVĂRAT dacă entitatea este nouă (fiind creeată) și FALS dacă nu (fiind creeată).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATRIBUT)` Returnează ADEVĂRAT dacă ATRIBUT entității a fost schimbat.
-
-Exemple:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATRIBUT)` Returnează ADEVĂRAT dacă ATRIBUT entității nu a fost schimbat.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATRIBUT)` Atributul stabilit atunci când entitatea țintă a fost extrasă din baza de date. Înainte de a fi modificat.
-
-Exemple:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Adaugă ID la câmpul Link Multipu. De exemplu, adaugă 'someTeamId' la câmpul 'teams'.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Adaugă lisa id-urilor. (începând cu versiunea 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Verifică dacă câmpul Link Multipu are ID specific.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Înlătură ID-ul specific din câmpul Link Multipu.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Verifică dacă entitatea țintă este legată de o altă entitate reprezentată prin LINK și ID
-
-#### env\userAttribute
-`env\userAttribute(ATRIBUT)` Returnează ATRIBUT al utilizatorului actual.
-
-#### list
-`list(VALOARE-1, ... VALOARE-N)` Returnează array. (începând cu versiunea 4.7.0)
-
-#### array\includes
-`array\includes(LISTĂ, VALOARE)` Returnează adevărat dacă LISTA conține VALOARE. Poate fi folosită pentru câmpurile Array și Multi-Enum. (începând cu versiunea 4.7.0)
-
-#### array\push
-`array\push(LISTĂ, VALOARE1 [, VALOARE2 ...])` Adaugă unul sau mai multe elemente la sfârșitul unui array și returnează noul array. (începând cu versiunea 5.0.0)
-
-#### array\length
-`array\length(LISTĂ)` Returnează numărul elementelor din LISTA. (începând cu versiunea 4.8.1)
-
-
-### Valori
-
-* Șiruri. Ex. 'some string';
-* Numere Integer. Ex. 1, 100, 40300.
-* Numere Float. E.g. 5.2.
-
-### Variabile
-
-Este posibil să definești variabile personalizate în formulă.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Exemple
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Folosind formula în Fluxul de Lucru
-
-Poți folosi formula în condițile și acțiunile din Fluxul de lucru. Vezi [documentele fluxului de lucru](workflows.md) pentru mai multe informații.
diff --git a/i18n/ro_RO/administration/import.md b/i18n/ro_RO/administration/import.md
deleted file mode 100644
index 708d219f9..000000000
--- a/i18n/ro_RO/administration/import.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Importare
-
-Importarea este disponibilă doar utiliaztorilor admin. Administration > Import. Ai posibilitatea de a importa doar fișiere CSV.
-
-## Pasul 1
-
-Selectează ce tipuri de înregistrări trebuie să imporți (Câmp Tip Entitate).
-Selectează un fișier CSV. Un fișier ar trebui formatat cu `UTF-8`.
-Selectează `What to do?`. Opțiuni disponibile: 'Create Only', 'Create & Update', 'Update Only'.
-
-* `Create Only` - selectează dacă vrei ca înregistarea ta să fie doar creată.
-* `Create & Update` - înregistrările o să fie creeate, iar dacă vor fi găsite înregistrări cu aceleași câmpuri, vor fi actualizate. Vei putea alege ce câmpuri să se potrivească la pasul _Step 2_.
-* `Update only` - doar înregistrările cu aceleași valori ale câmpurior o să fie actualizate.
-
-După ce ai selectat un fișier csv, vei putea să vezi cum ar trebuie să fie analizat în panoul de Previzualizare. Când schimbi propritățiile, previzualizarea va fi actualizată.
-
-* `Header Row` - dacă fișierul CSV conține pe primul rând câmpul de nume.
-* `Execute in idle` - este recomandat în cazul în care ai o cantitate mare de înregistrări care să fie importate. Importarea se va face prin cron. Statusul o să fie schimbat în 'Complet' când s-a terminat importarea.
-* `Skip searching for duplicates` - o să scadă timpul de importare.
-
-Apasă _Next_ pentru a trece _Step 2_.
-
-
-
-## Pasul 2
-
-Setează câmpul de mapare: corespunderea fișierelor la coloanele care conțin fișierul csv. Poți să sari peste coloanele care nu sunt necesare.
-În caz de'Create & Update' și 'Update only' trebuie să bifezi câmpurile ale căror înregistrări să fie actualizate.
-Adaugă valori implicite pentru noile înregistrări și cele actualizate să fie setate. Ex. Poți să specifici Utilizatorii Atribuiți sau câmpurior echipelor.
-După ce importarea s-a terminat, vei putea inversa creearea înregistrărilor, să vezi înregistrările duplicate și actualizate. Duplicat înseamnă că a fost o înregistrare similară în sistem. Poți să elimini toate duplicatele în același timp. Rețineți: Inversarea nu funcționează cu înregistrările actualizate.
-Apasă butonul _Run Import_ pentru a merge mai departe. Ar putea să dureze un timp până ce procesul de importare să se termine. Dacă vrei să imporți o cantitate mare de înregistrări(depinde de configurările serverului, de obicei mai mult de 200 înregistrări) trebuie să te asiguri că parametrul php `set_time_limit` este suficient de mare.
-
-
-
-## Cum să imporți în Liste Ținte
-
-Când imporți Contacte, Oportunități sau Contrui poți să le adaugi într-o listă țintă. La pasul 2 trebuie să adaugi Lista Țintă în câmpul panoului `Default Values` și să selectezi înregistrarea listei țintă de care ai nevoie. Poți de asemenea să folosești `Update only` sau `Create & Update` pentru a importa sau adăuga ținte la o listă de ținte.
\ No newline at end of file
diff --git a/i18n/ro_RO/administration/installation.md b/i18n/ro_RO/administration/installation.md
deleted file mode 100644
index 2e899098a..000000000
--- a/i18n/ro_RO/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Instalare
-
-### Cerințe
-EspoCRM rulează pe cele mai mulți furnizori de găzduire. Cerințe:
-
-* PHP 5.6 versiunea cea mai nouă PHP cu extensii activate pdo, json, GD library, mcrypt (de obicei este activată în mod implicit);
-* MySQL 5.5.3 sau mai nouă.
-
-Pentru mai multe informații, vezi articole pe [Server Configuration](server-configuration.md).
-
-### 1. Descarcă pachetul de instalare EspoCRM
-Pentru a descărca ultima versiune, urmează următorul link [download page](http://www.espocrm.com/download/).
-
-### 2. Încarcă fișierele EspoCRM în serverul tău
-
-După ce descărcarea a fost terminată, încarcă pachetul în serverul tău.
-Pentru a îl încărca foloseșre SSH, FTP sau panoul de administare din găzduire.
-Extrage arhiva în directorul public al serverului (ex., `public_html`, `www`, etc.).
-
-_Note: Pentru FTP, trebuie să extragi arhiva înainte de încărcarea ei pe server._
-
-### 3. Creează o bază de date MySQL pe care să o folosească EspoCRM
-
-Du-te la panoul de administare din găzduire, sau la SSH, și creează o nouă bază de date pentru utilizator, pentru EspoCRM (ex., `MySQL Databases` in cPanel).
-
-### 4. Rulează procesul de instalare EspoCRM
-
-Deschide browserul web, și mergi la URL-ul cu fișierele EspoCRM (ex., `http://yourdomain.com/espo`).
-
-Dacă vezi acest ecran "Permission denied" a apărut o eroare.
-Va trebui să execuți comanda pe terminal prin via SSH, sau să setezi permisiune corectă.
-Ar trebui să fie 755 pentru directoare, 644 pentru fișiere, și 775 pentru directorul `data`.
-Asigură-te că ai _owner_ and _group_ corect.
-
-
-
-Dacă vezi următorul ecran, permisiunea este corectă și poți să începi instalarea EspoCRM.
-
-
-
-Pe această pagină, poți să citești și să accepși termeni si codițiile.
-
-
-
-Introdu detaliile pentru noua bază de date MySQL creeată.
-
-
-
-Introdu numele și parola pentru administor EspoCRM.
-
-
-
-Pe această pagină poți să vezi setările implicite EspoCRM, cum ar fi formatul datei și al oeri, fusul orar, valuta și altele.
-
-
-
-Introdu setările SMTP pentru email-urile de ieșire, dacă vrei să ai posibilitatea să trimiți email-uri.
-Acest pas poate fi sărit prin apăsarea butonului _Next_.
-Toate aceste opțiuni pot fi adăugate/schimbate după instalarea EspoCRM.
-
-
-
-Felicitări! Instalarea este completă!
-Ultimul lucru pentru a seta Sarcini Programate care să fie rulate în sistem. Poate fi făcut prin rularea `crontab -e` în linux cli și în _Windows Tasks Scheduler_ în Windows.
-
-
-
-Speră ca vă va face plăcere să lucrați cu EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/ro_RO/administration/layout-manager.md b/i18n/ro_RO/administration/layout-manager.md
deleted file mode 100644
index 5a2ee4ef9..000000000
--- a/i18n/ro_RO/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Manager de Aspect
-
-Managerul de Aspect este diponibil în panoul de administrație. Oferă posibilitatea de a personaliza aspectul detalilor, editarea, vizulaizarea lisei și filtrele de căutare și câmpurile pentru formulare majore de actualizare.
-
-## Listă
-
-Principalul aspect pentru vizulaizarea lisei. Definește coloane și parametrii lor.
-
-
-
-Parametrii disponibili sunt listați mai jos.
-
-### Lățime (%)
-
-Lățimea coloanei în procente, gol înseamnă lățimea automată.
-
-### Link
-
-Dacă este bifat, câmpul o să fie vizualizat ca un link pentru versiunea detaliată a înregistrării. Se folosește, de obicei, pentru câmpuri de nume..
-
-### Nu se poate sorta
-
-Dizactivează posibiitatea de a sorta coloana.
-
-### Alinierea
-
-Alierea coloanei de la stânga la dreapta.
-
-## Detaliu
-
-Aspectul principal pentru vizualizarea detaliilor și vizualizarea editării. Definește panouri, rânduri și celule. Celulele conțin câmpuri.
-
-Rândul poate conține două celule sau o celulă care este extinsă să ocupe lățimea completă a rândului. Pentru a adăuga un rând cu o celulă extinsă, trebuie să adaugi un rând nou și să apeși pe semnul minus de pe oricare celulă.
-
-
-
-## Listă (Mică)
-
-Aspectul listei pentru relațiile din panou. Poate fi folosită în alte locuri, unde se pot afișa liste în vizualizarea îngustă.
-
-## Detaliu (Mic)
-
-Vizualizarea detaliată pentru creearea rapidă, vizualizarea rapidă și editarea rapidă a formularelor.
-
-## Filtre de Căutare
-
-Lista câmpurilor disponibile în vizualizarea listei de căutare.
-
-## Actualizare în Masă
-
-Lista câmpurilor disponibile în formularul de actualizare în masă.
-
-## Panouri de Relații
-
-Lista panourilor de relații disponibile în vizualizarea detaliată. Panourile pot fi re-ordonate. Culoarea panoului se poate defini cu paramaterul Stylele.
-
-## Panouri Laterale
-
-Panourile Laterale pentru Detali, Editare, formulare pentru Detalii Mici și Editare Mică. Oferă o posibiliatate de a ascunde sau re-ordona lista de panouri Activități, Istoric, Sarcini și altele. Culoarea panoului se poate defini cu paramaterul Stylele.
-
-## Aspecte Adiționale
-
-Unele tipuri de entități conțin aspecte adiționale: Convertire Principal, Listă pentru Cont.
diff --git a/i18n/ro_RO/administration/ldap-authorization-for-ad.md b/i18n/ro_RO/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index 2b2aa0c4a..000000000
--- a/i18n/ro_RO/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Autorizația LDAP authorization pentru Director Activ
-
-Exemple de configurare a autorizației LDAP pentru serverul Director Activ. Ghidul complet al configurării autorizației LDAP este descris [aici](ldap-authorization.md).
-
-```
-Gazdă: espo.local
-Port: 389
-Utilizator complet DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Parolă: ******
-Atribut Nume Utilizator: sAMAccountName
-Utilizator ObiectectClasă: person
-Formă Canonică Cont: Principal
-Cerințe Legate DN: no
-Bază DN: cn=espo-users,ou=users,dc=espo,dc=local
-Nume Cont Domeniu: espo.local
-Nume Cont Domeniu Scurt: ESPO
-Creează Utilizator în EspoCRM: yes
-Atribut Prenume Utilizator: givenName
-Atribut Nume Utilizator: sn
-Atribut Titlu Utilizator: title
-Atribut Adresă de Email Utilizator: mail
-Atribut Număr de Telefon Utilizator: telephoneNumber
-```
-
-
diff --git a/i18n/ro_RO/administration/ldap-authorization-for-openldap.md b/i18n/ro_RO/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index a93a269b4..000000000
--- a/i18n/ro_RO/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Autorizația LDAP pentru OpenLDAP
-
-Exemple de configurare a autorizației LDAP pentru severul OpenLDAP. Ghidul complet al configurării autorizației LDAP este descris [aici](ldap-authorization.md).
-
-```
-Gazdă: espo.local
-Port: 389
-Utilizator complet DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Parolă: ******
-Atribut Nume Utilizator: uid
-Utilizator ObiectectClasă: inetOrgPerson
-Formă Canonică Cont: Dn
-Cerințe Legate DN: yes
-Bază DN: cn=espo-users,ou=users,dc=espo,dc=local
-Creează Utilizator în EspoCRM: yes
-Atribut Prenume Utilizator: givenName
-Atribut Nume Utilizator: sn
-Atribut Titlu Utilizator: title
-Atribut Adresă de Email Utilizator: mail
-Atribut Număr de Telefon Utilizator: telephoneNumber
-```
-
-
diff --git a/i18n/ro_RO/administration/ldap-authorization.md b/i18n/ro_RO/administration/ldap-authorization.md
deleted file mode 100644
index 228c73d14..000000000
--- a/i18n/ro_RO/administration/ldap-authorization.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Autorizație LDAP
-
-În acest ghid, vei putea să înveți cum se face Autorizațiea LDAP pentru EspoCRM.
-
-Du-te în serverul tău LDAP și creează o bază DN pentru utilizatori EspoCRM
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Trebuie să creăm un utilizator de sistem care să aibă acces la utilizatori DN (“cn=espo-users,ou=users,dc=espo,dc=local”). Astfel, DN complet pentru acest utilizator de sistem o să fie
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Acum, poți adăuga un utilizator LDAP pentru a accesa EspoCRM. Ex. Espo Tester cu același nume de utilizator “tester” în interiorul “cn=espo-users,ou=users,dc=espo,dc=local” DN. Vă rugăm, rețineți: pentru a putea folosi acest format de autentificare pentru EspoCRM, trebuie să specifici opțiunile “Atribut Nume Utilizator” și “Bază DN”.
-
-Apoi, mergi la setările de Autentificare EspoCRM din panoul de administrare, selectează metoda `LDAP` și completează detaliile LDAP:
-
-
-
-* Gazdă – LDAP IP sau numele gazdei.
-* Port – portul de conexiune.
-* Auth – acreditările de acces pentru serverul LDAP:
- * Utilizator Complet DN – Utilizatorul complet de sistem DN care permite căutarea altor utilizatori.
- * Parolă – parola pentru accesarea serverului LDAP.
-* Securitate – protocolul SSL sau TSL.
-* Atribut Nume Utilizator – atributul pentru a identifica utilizatorul. Pentru Director activ poate fi “userPrincipalName” sau “sAMAccountName”.
-* Forma Canonică a Contului – Tipul canonic a formei contului. Există 4 opțiuni:
- * Dn – forma în format `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Nume Utilizator – în forma `tester`.
- * Backslash – în forma `COMPANY\tester`.
- * Principal – îm forma `tester@company.com`.
-* Legarea necesită Dn – dacă este necesar să se formateze numele utilizatorului în formularul DN.
-* Bază Dn – baza DN implicită care este folosită pentru căutarea utilizatorilor.
-* Filtru Autentificare Utilizator – filtru carepermite restricționarea utilizatorilor care au posibilitatea de a folosi EspoCRM. Ex. `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Numele Domeniului Contului – Domeniul care este folosit pentru a autoriza serverul LDAP.
-* Numele Scurt al Domeniului Contului – Domeniul Scurt care este folosit pentru a autoriza serverul LDAP.
-* Încercă Tăierea Numelui Utilizatorului – opțiunea de tăiere a numelui utilizatorului cu domeniul.
-* Referali – dacă referali ar trebui să fie urmați către clientul LDAP.
-* Creează Utilizator în EspoCRM – această opțiune permite EspoCRM să creeze un utilizator din LDAP.
- * Atributul Prenumelui Utilizatorului – atribut LDAP care este folosit pentru a determina prenumele utilizatorului.
- * Atributul Numelui Utilizatorului – atribut LDAP care este folosit pentru a determina numele utilizatorului.
- * Atributul Titlului Utilizatorului – atribut LDAP care este folosit pentru a determina titlul utilizatorului.
- * Atributul Adresei de Email al Utilizatorului – atribut LDAP care este folosit pentru a determina adresa de email utilizatorului.
- * Atributul Numelui de Telefon al Utilizator – atribut LDAP care este folosit pentru a determina numărul de telefon al utilizatorului.
-
-Acum, mergi la pagina de autentificare și introdu acreditările.
-
-
-
-Utilizatorul a fost autentificat și creeat automat în EspoCRM.
-
-## Instrucțiunile de configurare bazate pe serverul tău:
-* [Active Directory server](ldap-authorization-for-ad.md)
-* [OpenLDAP server](ldap-authorization-for-openldap.md)
-
-Mai multe informații despre configurarea LDAP, găsești aici [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/), deoarece EspoCRM folosește această librărie.
-
-
-
-
diff --git a/i18n/ro_RO/administration/maps.md b/i18n/ro_RO/administration/maps.md
deleted file mode 100644
index f67132701..000000000
--- a/i18n/ro_RO/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Hărți
-
-## Cum să arăți hărți bazate pe câmpul de adresă
-
-Fiecare câmp de adresă are câmpul de hartă corespunzător. Tot ce trebuie să faci este să îl adaugi în Aspectul Detaliat. Folosește serviciile Google Maps.
-
-`Administare > Aspect Manager > Alege Entitate (Cont, Contact, Principal sau personalizat) > Detaliu > câmp Hartă Drag & Drop.`
-
-Pentru a face celula mai lată, folosește semnul minus.
-
-Poți, de asemnea, să configurezi înălțimea câmpului.
-
-`Administare > Aspect Manager > Alege Entitate > Câmpuri > găsește câmpul hărții și apasă pe el > editează înălțimea și salvează.`
-
-## Cheie Api
-
-Începând cu versiunea EspoCRM 4.2.0, trebuie să specifici cheia Api folosind Google Maps (Administrare > Integrare > Google Maps).
-
diff --git a/i18n/ro_RO/administration/moving-to-another-server.md b/i18n/ro_RO/administration/moving-to-another-server.md
deleted file mode 100644
index 5c90f5cc7..000000000
--- a/i18n/ro_RO/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Mutarea EspoCRM în alt server
-
-Pentru a muta EspoCRM în alt server, urmează următorii pași:
-
-### Pasul 1. Salvează o copie de rezervă a fișierelor
-
-Deschide un manager de fișiere sau autentifică-te prin SSH pentru a arhiva toate fișierelor disponibile din directorul EspoCRM. Mai multe detalii: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### Pasul 2. Salvează o copie de rezervă a bazei de date
-
-Pentru datele stocate în baza de date,(MySQL, MariaDB) ar trebui făcută o copie de rezervă. Vă rugăm, urmați această recomandare: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### Pasul 3. Copiază copile de rezervă ale fișierele și a bazei de date, în alt server
-
-Copiază copile de rezervă ale fișierele și a bazei de date, în alt server nou.
-
-### Pasul 4. Dezarhivează fișierele copiilor de rezervă
-
-Pentru a dezarhiva fișierele copiilor de rezervă, poți folosi Managerul de Archivare sau aceste instrucțiuni: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-Rețineți: Fișierele trebuie plasate în dierectorul web-server.
-
-### Pasul 5. Configurează un server
-
-Configurează un server nou bazat pe recomandările de aici: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### Pasul 6. Permisiuni corecte
-
-Setează permisiunile necesare și fișerele proprietarului, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### Pasul 7. Importă copia de rezervă a bazei tale de date
-
-Va trebui să creezi o bază de date cu utilizator în MySQL. Pentru a importa baza de date din copia de rezervă, urmează intrucțiunile: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### Pasul 8. Configurări EspoCRM Corecte
-
-După importarea și configurarea cu succes a severului, vă rugăm corectați configurările EspoCRM din fișierul `ESPOCRM_DIRECTORY/data/config.php`:
-
- * setări conexiune bază de date:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - dacă numele domeniului tău a fost schimbat (URL):
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * fișiere implicite proprietar (doar dacă sunt diferite):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- unde `www-data` este utilizator web-server.
-
-### Pasul 9. Setează un crontab
-
-Setează un crontab, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-Rețineți: ar trebui să fie configurat în utilizatorul web-server.
-
-Asta este tot. Acum instanța EspoCRM rulează pe un server nou.
diff --git a/i18n/ro_RO/administration/nginx-server-configuration.md b/i18n/ro_RO/administration/nginx-server-configuration.md
deleted file mode 100644
index 4493a4083..000000000
--- a/i18n/ro_RO/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Configurări server Nginx pentru EspoCRM
-
-Aceste instrucțiuni sunt suplimentare la ghidul de [Configurare Server](server-configuration.md). Reținețică toate setările de configurare listate aici sunt făcute pe server Ubuntu.
-
-## Cerințe PHP
-
-Pentru a instala librăriile necesare, rulează aceste comenzi într-un terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Repararea problemei “API Error: EspoCRM API is unavailable”:
-
-Urmează doar pașii necesari. După fiecare pas, verifică dacă a fost rezolvată problema.
-
-### 1. Activează regulile de rescriere din serverul Nginx
-
-Adaugă acest cod în fișierul block de configurarea al serverului Nginx (/etc/nginx/sites-available/YOUR_SITE) în interiorul block “server”:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Dacă nu ai acest fișier, trebui să îl creezi. Pentru a face asta, deschide un terminal și rulează comanda:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Adaugă codul de mai sus. Pentru mai multe informații despre configurarea unei boi Gazde Virtuale pe Nginx, vă rugăm citiți [ guideline](nginx-virtual-host.md).
-
-Rulează această comandă într-un terminal pentru a verifica dacă totul este în regulă:
-
-```
-sudo nginx -t
-```
-
-Dacă totul este în regulă, ruleză această comandă pentru a restarta serverul nginx:
-
-```
-sudo service nginx restart
-```
-
-### 2. Adaugă calea RewriteBase
-
-Deschide un fișier /ESPOCRM_DIRECTORY/api/v1/.htaccess și înlocuiește următoarea linie:
-
-```
-# RewriteBase /
-```
-cu
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-unde REQUEST_URI face parte din URL, ex. pentru “http://example.com/espocrm/”, REQUEST_URI este “espocrm”.
diff --git a/i18n/ro_RO/administration/nginx-virtual-host.md b/i18n/ro_RO/administration/nginx-virtual-host.md
deleted file mode 100644
index 7e62c402c..000000000
--- a/i18n/ro_RO/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Configurarea unei Gazde Virtuale pe Nginx pentru EspoCRM
-
-În acest ghid vei putea să vezi cum se configurează gazda vitruală pe Nginx în EspoCRM pe server Ubuntu.
-
-## Creează un fișier block
-
-Pentru a creea acest fișier, deschide un terminal și rulează această comandă:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Acum, deschide acest fișier (/etc/nginx/sites-available/espocrm.conf) și modifică codul, urmând formatul de mai jos (unele setări ar putea fi diferite, în funcție de configurările tale):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Activează acest block server
-
-Creează un link simbolic:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Rulează această comandă pentru a vedea dacă totul este în regulă:
-
-```
-sudo nginx -t
-```
-
-Restartează serverul Nginx:
-
-```
-sudo service nginx restart
-```
-
-## Configurează gazda locală (opțional, doar pentru un domeniu local)
-
-Dacă ai adăugat un domeniu local, trebuie să îl configurezi pe computerul local (nu pe server). Pentru Ubuntu, deschide acest fișier `/etc/hosts` și adaugă această linie:
-
-```
-192.168.1.1 espocrm.local # specifică adresa IP a serverului Nginx al tau
-```
-
-Pantru Windows, urmați aceste [instrucțiuni](http://support.microsoft.com/kb/923947).
diff --git a/i18n/ro_RO/administration/portal.md b/i18n/ro_RO/administration/portal.md
deleted file mode 100644
index 846f35cdb..000000000
--- a/i18n/ro_RO/administration/portal.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Portal
-
-Portal oferă posibilitatea de a accesa date și funcții specifice pentru clienții și partenerii dumneavoastră. Administratorul poate crea mai multe portaluri. Fiecare portal are propriile setări, dashlboard, listă utilizator, setări acces control.
-
-Pentru a creea un portal mergi la Administrare > Portaluri, apasă pe butonul Creează Portal.
-
-* `Is Active`. Dacă nu este bifat, portalul nu o să fie disponibil pentru nimeni.
-* `Is Default`. Înseamnă că portalul o să fie dispnibil pe url-ul scurt: http(s)://YOUR_ESPO_URL/portal.
-* `Roles`. Specificați unul sau mai multe roluri portal care vor fi aplicate utilizatorilor autentificați în portal. Mai multe informații despre rolurile portalului sunt mai jos.
-* `Tab List`. Filele care vor fi afișate în bara de navigare.
-* `Dashboard Layout`. Specificați dashlet-urile care vor fi afișate pe pagina de pornire a portalului. Rețineți că utilizatorii portalului nu își pot configura tabloul de bord.
-* `URL`. Citește numai câmpul care afișează link-ul cu care poți accesa portalul.
-
-## Utilizatori Portal
-
-Administratorii pot crea utilizatori portal.
-
-1. Administrare > Utilizatori.
-2. Apasă dreapta pe dropdown next pentru a creea Utilizator.
-3. Apasă Creează Utilizator Portal.
-4. Selectează Contactați utilizatorul portalului cu care va fi conectat.
-5. Completați formularul și apasă pe Salvează.
-
-Utilizatorul portalului ar trebui să fie legat de înregistrarea portalului pentru a putea accesa acel portal.
-
-## Roluri Portal
-
-Roluri Portal sunt similare cu rolurile obișnuite în EspoCRM cu câteva deosebiri.
-
-* `not-set` nivel refuză un acces.
-* `own` nivel înseamnă că înregistrarea a fost creată de utilizator. Ex. utilizatorulul portalului are un caz, iar acest caz este deținut de utilizator.
-* `account` nivel înseamnă că înregistrarea este asemănătoare cu contul pe care utilizatorul portalului este asemănător.
-* `contact` nivel înseamnă că înregistrarea este legată de utilizatorul portalului asemănătoare cu acesta.
-
-Campurile alocate utilizatorilor și echipelor sunt citite numai pentru utilizatorii portalului.
-
-### Exemplu
-
-`Utilizatorii de portal ar trebui să poată crea cazuri, să vizualizeze cazuri legate de contul lor; ar trebui să poată vedea baza de cunoștințe.`
-
-1. Deschide Rol Creează Portal din (Administrare > Roluri Portal > Creează Rol).
-2. Activează accesul la Cazuri, setează: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. Activează accesul la Baza de cunoștințe, set `create - no, read - account, edit - no, delete - no`.
-4. Editare înregistrare portal (Administrare > Portaluri). Selectează rolul portalului în fișierul Roluri și apoi salvează.
-
-## Acces la Portal
-
-Poți găsi url pentru portalul tău în cțmpul 'URL' al înregistrării portalului. De asemenea, este posibil să utilizați instrumentele de configurare a serverului (cum ar fi mod_rewrite) pentru a putea accesa url diferite. Pentru acest caz trebuie să completezi câmpul 'URL Personalizat'.
-
-### Acces portal de URL Personalizat pentru server Apache
-
-URL Personalizat: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Mod rescrie reguli
-
-Specifică ID-ul înregistrării portalului, în loc de `{PORTAL_ID}`. ID-ul înregistrării portalului este disponibil în bara de adrese atunci când deschizi vizualizarea detaliată a înregitrării portalului. Cum ar fi: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 este un id al înregistrării portalului.
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/ro_RO/administration/roles-management.md b/i18n/ro_RO/administration/roles-management.md
deleted file mode 100644
index 421bab6a2..000000000
--- a/i18n/ro_RO/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Roluri Management
-
-## Prezentare generală
-
-Pentru a restricționa accesul pentru anumiți utilizatori, trebuie să utilizați rolurile. Administratorul poate gestiona roluri în panoul de Administrare. Fiecare rol definește accesul la anumite zone (domenii) care se aplică utilizatorilor care dețin acest rol.
-
-Un utilizator poate avea mai multe roluri. Acele roluri trebuie să fie selectate (câmpul ‘Roluri’ în intrarea Utilizator) și/sau să fie moștenit de la echipele care aparțin utilizatorului.
-
-Dacă un utilizator are mai multe roluri, acestea vor fi îmbinate astfel încât regula permisivă să aibă o prioritate mai mare. Acest lucru îi permite administratorului să gestioneze ușor și flexibil, controlul accesului la nivel.
-
-Este posibil să vezi ce permisiuni au fost aplicate pentru un anumit utilizator, prin apăsarea butonului 'Access', de pe vizualizarea detaliată a utilizatorului.
-
-
-
-## Example
-
-De exemplu un utilizator aparține echipei ‘Vânzări’. Aceea echipă are un singur rol ‘Vânzător’. Astfel, toți membrii echipei o să obțină rolul de ‘Vânzător’.
-
-Rolul ‘Vânzător’ este definit în modul următor:
-
-Lead:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Utilizatorii vor putea să citească doar acei potențiali clienți și acele oportunități care aparțin echipei ‘Departamentul vânzări’ (domeniul ‘Echipa’).
-Utilizatorul va putea să editeze doar acei potențiali clienți și acele oportunități la care sunt alocați sau pe cei pe care i-au creat.
-Utilizatorii nu vor putea elimina potențialii clienții sau oportunități.
-
-Dorim să acordăm mai multe drepturi unui anumit utilizator care deține funcția de manager de vânzări în cadrul companiei. Acest angajat trebuie să poată citi/edita/șterge toate înregistrările echipei ‘Vânzări’. Acest utilizator ar trebui să aparțină echipei ‘Vânzări’. Dar va trebui să creăm un nou rol ‘Manager Vânzări’ și să selectăm acest rol din câmpul ‘Roluri’.
-
-Rolul ‘Manager Vânzări’ este definit în modul următor:
-
-Lead:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Utilizatorul nostru va putea să gestioneze toate oportunitățile și potențialii clienți din echipa ‘Vânzări’.
-
-## Permisiuni Speciale
-
-### Permisiuni de Atribuire
-
-Setați acest parametru pentru a restricționa capacitatea de a re-aloca înregistrări unui alt utilizator și/sau echipelor. Dacă setezi `echipa` - atunci va fi posibilă doar atribuirea către membrii echipei. Dacă `nu` - utilizatorii nu o să poată re-aloca.
-
-De asemenea, definește dacă utilizatorul poate publica în fluxul altui utilizator/echipe.
-
-### Permisiuni Utilizator
-
-Permite posibilitatea de restricționare a utilizatorilor să vadă activitățiile, calendarul și fluxul altor utilizatori.
-
-### Permisiuni Portal
-
-Definește accesul la informațiile portalului, posibilitatea de a publica mesaje în utilizatorii portalului.
-
-### Permisiuni Grup Conturi Email
-
-Definește accesul la grupul conurilor email, abilitatea de a trimite email-uri din grupul SMTP.
-
-### Permisiuni Export
-
-Definește dacă utilizatorul are capacitatea de a exporta înregistrări. (începând cu versiunea 4.9.0)
-
-## Permisiuni Implicite
-
-În mod implicit (dacă nu sunt aplicate) utilizatorii pot citi și edita înregistrări. Însă nu poate șterge, cu excepția celor care au fost creeate de ei și atribuite, în același timp. except those they have created and they are assigned to at the same time.
-
-Există posibilitatea de a restricționa accesul aplicat implicit prin activarea 'ACL Mod Strict ' de la Administrare > Setări.
-
-## Securitate Nivel Câmp
-
-Permite controlul accesului pentru un câmp specific.
-
-Dacă se poate citi înregistrarea, în mod implicit, utilizatorul poate citi toate câmpurile. Dacă se poate citi înregistrarea, utilizatorul poate edita orice câmp. Poți restricționa accesul la câmpuri specifice folosind Securitatea Nivel Câmp.
-
-În vizualizarea de editare a unei înregistrări de rol în secțiunea Nivel Câmp, apasă pe pictograma plus de lângă domeniul de aplicare specific, apoi selectează câmpul necesar. Acolo vei putea specifica accesul nivelui pentru acțiunile `citire` și `editare`. Există două opțiuni: `da` și `nu`.
-
-
diff --git a/i18n/ro_RO/administration/server-configuration.md b/i18n/ro_RO/administration/server-configuration.md
deleted file mode 100644
index 5811d3ef2..000000000
--- a/i18n/ro_RO/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Configurarea Server pentru EspoCRM
-
-EspoCRM poate fi instalat pe Apache ([instrucțiuni](apache-server-configuration.md)), Nginx ([instrucțiuni](nginx-server-configuration.md)), sau server IIS cu suport PHP versiunea 5.6 sau mai nouă și MySQL versiunea 5.1 sau mai nouă.
-
-## Recomandări Configurare
-
-### Cerințe PHP
-
-EspoCRM necesită PHP 5.6 sau mai nouă, cu următoarele extensii activate:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – pentru a accesa MySQL în PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – resursele folosesc următoarele formate (metadata, aspect, limbi, și altele);
-* [GD](http://php.net/manual/en/book.image.php) – să manipuleze imagini;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – pentru a asigura protecția cea mai înaltă;
-* [Zip](http://php.net/manual/en/book.zip.php) – pentru a actualiza EspoCRM și a instala extensii;
-* [IMAP](http://php.net/manual/en/book.imap.php) – să monitorizeze căsuțele poștale în EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Este de asemenea recomandat [mailparse](https://pecl.php.net/package/mailparse) pecl extensia instalată. Este necesară pentru email fetching și o muncă ușoară.
-
-php.ini setări:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Cerințe MySQL
-
-EspoCRM suportă MySQL versiunea 5.1 sau mai nouă.
-Nu există particularități speciale. Toate setările implicite sunt bune pentru EspoCRM.
-
-## Permisiuni necesare pentru Sisteme Unix-bazate
-
-Fișierele și directoarele ar trebui să aibă următoarele permisiuni:
-
-* `/data`, `/custom`, `/client/custom` – ar trebui să fie scrise fișiere, directoare și subdirectoare(664 pentru fișiere, 775 pentru directoare, inclusiv pentru subdirectoare și fișiere);
-* `/application/Espo/Modules`, `/client/modules` – trebuie să scrieți directorul actual (775 pentru directorul actual, 644 pentru fișiere, 755 pentru directoare și subdirectoare);
-* Toate celelalte fișiere și directoare trebuie să poată fi citite (644 pentru fișiere, 755 pentru directoare).
-
-Pentru a seta permisiunile, execută următoarele comenzi în terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Toate fișierele ar trebui să fie deținute și deținute de grup prin procesul de webserver. Poate fi “www-data”, “daemon”, “apache”, “www”, etc.
-Rețineți: Pe Bitnami Stack, fișierele trebuie deținute și deținute de către grup de utilizator “daemon”.
-Rețineți: On gazdele distribuite, fișierele trebuie deținute de proprietar și de grup de contul tău de utilizator.
-
-Pentru a seta proprietarul și proprietarul grupului , execută aceste comenzi în terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## Setează crontab
-
-Pentru a seta crontab pe sistemul UNIX, urmează pașii:
-
-* 1. Autentifică-te ca administrator pe instanța EspoCRM.
-* 2. Du-te la secțiunea de Activității Planificate section din panoul de administrare (Meniu > Administrare > Activități Planificate) și copiază șirul în crontab. Arată în felul următor:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Deschide un terminal și rulează această comandă:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER poate fi “www”, “www-data”, “apache”, etc (depinde de webserver).
-* 4. Lipește șirul copiat (de la pasul 2) și salvează filierul crontab (Ctrl+O, then Ctrl+X pentru nano editor).
-
-## Instrucțiuni de configurare în funcție de serverul tău:
-
-* [Configurări server Apache](apache-server-configuration.md).
-* [Configurări server Nginx](nginx-server-configuration.md).
diff --git a/i18n/ro_RO/administration/troubleshooting.md b/i18n/ro_RO/administration/troubleshooting.md
deleted file mode 100644
index 9ececd9f6..000000000
--- a/i18n/ro_RO/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Troubleshooting
-
-## Verifică jurnal
-
-Pentru a găsi problema, trebuie să verifici fișierele de eroare.
-
-#### Jurnal Erori EspoCRM
-
-Jurnalul se găsește în EspoCRM `/logs/*.log` și conține mai multe informații.
-
-#### Jurnal Erori Apache
-
-Pentru server Ubuntu, o eroare apache din jurnal se găsește `/var/log/apache2/error.log` și conține toate informațiile despre eroare. Locația fișierelor din jurnal poate fi diferită pe alte sisteme.
-
-## Activează modul reparare
-
-Pentru a activa modul de reparare, mergi la directorul instalat EspoCRM, deschide fișierul `data/config.php` și schimbă valoarea:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-to
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Activitățiile planificate nu funcționează
-
-#### Problema #1: crontab nu este configurat
-
-1. Autentifică-te prin SSH pe serverul tău.
-
-2. Configurează crontab urmând pașii: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-Rețineți: Crontab ar trebui configurat pe utilizator web-server, ex. `crontab -e -u www-data`.
-
-3. Așteaptă pentru un timp și verifică Activitățiile Planificate pentru a vedea dacă vreo problema a fost executată(vezi panoul Jurnal).
-
-#### Problema #2. Crontab este configurat, dar Activitățiile Planificate nu funcționează
-
-Pentru a te asigura ca nu există erori atunci când cron rulează, încearcă să rulezi comanda cron într-un terminal:
-
-1. Autentifică-te prin SSH pe serverul tău.
-
-2. Du-te în directorul unde EspoCRM este instalat. Ex. pentru directorul `/var/www/html/espocrm` comanda este:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Rulează comanda crontab:
-
-```bash
-php cron.php
-```
-
-Rețineți: Ar trebui executat pe utilizator web-server. Dacă ești autentificat ca și root, comanda ar trebui să fie (ex. pentru Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-unde `www-data` este utilizator web-server.
-
-4. Dacă nu sunt erori, verifică Activitățiile Planificate pentru a vedea dacă activitatea a fost executată (vezi panoul Jurnal).
-
-## EspoCRM nu se încarcă după actualizare
-
-Acest lucru se poate întâmpla uneori pe unele gazde comune.
-
-Verificați permisiunile fișierelor:
-/index.php
-/api/v1/index.php
-
-Trebuie să fie 644. Dacă vreunul dintre aceste fișiere are permisiunea 664, trebuie să îl schimbați la 644. Utilizați panoul de control al gazdei sau comanda chmod.
-
-```
-chmod 644 /path/to/file
-```
-Mai multe informații găsești: [aici](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/ro_RO/administration/upgrading.md b/i18n/ro_RO/administration/upgrading.md
deleted file mode 100644
index f15970853..000000000
--- a/i18n/ro_RO/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Cum se actualizează EspoCRM
-
-EspoCRM poate fi actualizat la ultima versiune, urmând pașii de mai jos:
-
-### Pasul 1. Verifică versiune actuală
-
-Pentru a verifica versiunea acutală dmergi la Administrare > Actualizare pagină.
-
-### Pasul 2. Descarcă pachetele de actualizare necesare
-
-Mergi la pagina de actualizare https://www.espocrm.com/download/upgrades/ și în funcție de veriunea actlaă, decarcă pachetele necesare.
-
-### Pasul 3. Creează o copie de rezervă (opțional)
-
-Înainte de actualizare, creează o copie de rezervă a datelor și fișierelor EspoCRM. Urmează [aceste instrucțiuni](https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md).
-
-### Pasul 4. Procesul de actualizare
-
-Mergi la Administrare > Actualizare. Încarcă și instalează pachetele de actualizare, unul câte unul.
-
-Poți verifica dacă ai ultima versiune la Meniu > Despre.
-
-## Actualizare prin CLI
-
-Poți să rulezi actualizare prin interfața command line. Trebuie să execuți următoarea comandă din directorul root EspoCRM.
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/ro_RO/administration/workflows.md b/i18n/ro_RO/administration/workflows.md
deleted file mode 100644
index 981304590..000000000
--- a/i18n/ro_RO/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Fluxuri de lucru
-
-Caracteristica Fluxuri de lucru este disponibilă în [Pachet Avansat](https://www.espocrm.com/extensions/advanced-pack/).
-
-Fluxurile de lucru automatizează, într-un mod simplu, procesul de afaceri. Îl puteți găsi în panoul Administrare. Pentru a crea o regulă a fluxului de lucru, trebuie să definiți:
-
-* Entitate Țintă - la ce tip de entitate este aplicat fluxul de lucru;
-* Tip declanșator - când fluxul de lucru o să fie delanșat;
-* Condiții- condițiile trebuie satisfăcute pentru a declanșa fluxul de lucru;
-* Acțiuni - ce se întâmplă dacă fluxul de lucuru este delanșat.
-
-
-## Tipuri declanșator
-
-### După ce înregsitrarea a fost creată
-
-Se declanșează numai atunci când se creează o nouă înregistrare. Dacă condițiile specificate sunt satisfăcute, atunci acțiunile vor fi executate.
-
-### După ce înregsitrarea a fost salvată
-
-Se declanșează când se creează o nouă înregistrare sau se actualizează o înregistrare existentă. Dacă condițiile specificate sunt satisfăcute, atunci acțiunile vor fi executate.
-
-Pentru regulile fluxului de lucru cu acest tip de declanșator, este recomandat să aveți o condiție care verifică a fost 'modificat' un câmp. Ex. Dacă statusul cazului a fost schimbat atunci execută unele acțiuni.
-
-### Planificat
-
-Se declanșează în funcție de planificarea definită. Puteți să îl setați să ruleze în fiecare zi, în fiecare săptămână etc. Acțiunile vor fi aplicate pentru înregistrări. Deci, trebuie să creați o listă raport.
-
-Planificarea este specificată într-o notație crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### Secvențial
-
-Folosit rar. Se presupune că este rulat de un alt flux de lucru. Oferă posibilitatea de a face o logică complexă.
-
-Rețineți: Pentru fluxuri de lucur secvențiale, este recomandat să utilizeze [intrumentul BPM](bpm.md) în loc de o caracteristica fluxurilor de lucru.
-
-## Condiții
-
-Puteți specifica condițiile care trebuie setate pentru a declanșa fluxul de lucru. Există două moduri în care condițiile pot fi specificate: cu constructorul condiție UI și cu o formulă.
-
-### Constructorul condiție UI
-
-Unele tipuri de condiții disponibile:
-
-* _egale_ - câmpul este egal cu o valoare specifică sau cu o valoare a altui câmp;
-* _a fost egal_ - câmpul a fost egal cu o valoare specifică înainte de declanșarea fluxului de lucru;
-* _nu sunt egale_ - câmpul nu este egal cu o valoare specifică sau cu o valoare a altui câmp;
-* _nu a fost egal_ - câmpul nu a fost egal cu valoarea specifică înainte ca fluxul de lucru să fie declanșat;
-* _egal_ - câmpul este gol;
-* _nu este gol_ - câmpul nu este gol;
-* _schimbat_ - câmpul a fost schimbat;
-* _nu a fost schimbat_ - câmpul nu a fost schimbat.
-
-### Condiții Formulă
-
-Formula oferă o posibilitate de a defini condițiile de orice complexitate. Pentru a citi despre sintaxa formulei mergi la [acest articol](formula.md).
-
-Rețineți: Nu ar trebui să fie nici un delimitator `;` folosit în formulă când determină o condiție.
-
-## Acțiuni
-
-### Trimite Email
-
-Sistemul o să trimită un email folosind un șablon de email specificat. Adresa de e-mail a destinatarului poate fi preluată din înregistrarea țintă, din orice înregistrare asemănătoare, utilizatorul actual, urmăritorii, utilizatorii echipei sau specificați. Emailul poate fi trimis imediat sau întârziat pentru un anumit interval.
-
-### Creați Înregistrare
-
-Sistemul o să creeze o nouă o nouă înregistrare cu o entitate de orice tip. Dacă există o relație între înregistrarea țintă și creearea înregistrării este posibil că înregistrările să se asemene.
-
-Există posibilitatea de a defini formula pentru a calcula câmpurile.
-
-### Creați înregistrare asemănătoare
-
-Sistemul o să creeze o înregistrare asemănătoare cu înregistrarea țintă. Există posibilitatea de a defini formula pentru a calcula câmpurile.
-
-### Actualizare Înregistrarea Țintă
-
-Permite schimbarea câmpurilor specifice sau a înregistrării țintă. Există posibilitatea de a defini formula pentru a calcula câmpurile.
-
-Dacă ai nevoie de a adăuga noi elemente în câmpul Link-Multiple fără să pierdeși date existente (ex. Echipe) va trebui să utilizezi formula funcției entity\addLinkMultipleId. Exemplu: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### Actualizare Înregistrări Asemănătoare
-
-Permite schimbarea câmpurilor specifice a înregistrării asemănătoare sau a înregistrării țintă. Există posibilitatea de a defini formula pentru a calcula câmpurile.
-
-### Leagă cu o altă Înregistrare
-
-Relaționează entitatea țintă cu o altă entitate specifică. Ex. adaugă o echipă specifică la înregistrare.
-
-### Dezleagă cu o altă înregistrare
-
-Opește relaționare entității țintă cu o altă entitate specifică. Ex. elimină o echipă specifică la înregistrare.
-
-### Aplicați regula de atribuire
-
-Atribuiți înregistrarea țintă către un utilizator folosind regula distribuției. Există două regului disponibile: Round-Robin și Least-Busy.
-
-* Round-Robin - utilizatorii sunt aleși de la începutul către sfârșitul listet (echipă) și apoi începând din nou.
-* Least-Busy - utilizatorul care are mai puține înregistrări atribuite, ca fi ales pentru atribuire.
-
-_Report Listă_ - Pentru distribuirea Least-Busy determină ce înregistrări o să fie luate în considerare pentru a calcula numărul de înregistrări atribuite. Ex. pentru cazurile va trebui să luam în considerare doar înregistrările utilizatorilor activi.
-
-### Creați Notificare
-
-Notifică utilizatori specifici cu mesaje. Este posibil să utilizați substituenți în șablonul mesajului: {entity} - înregistare țintă, {user} - utilizator actual.
-
-### Faceți urmărirea
-
-Forțează utilizatori specifici să urmărească enintatea țintă sau o entitate specifică asemănătoare.
-
-### Declanșează un alt flux de lucru
-
-Permite secvențarea fuxurilor de lucru. Este posibil ca fluxul de lucru să fie condiționat: puteți seta fluxul de lucru pentru a declanșa două fluxuri de lucru cu condiții diferite definite în acele fluxuri de lucru.
-
-Este posibilă întârzierea executării a fluxului de lucru secvențial. În fluxul de lucru secvențial poți să definești condițiile care verifică dacă câmpurile specificate au fost chimbate de la fluxul de lucru părinte care au fost declanșate folosind tipul de condiție _schimbat_ and _a fost egal_.
-
-Rețineți: Pentru fluxurile de lucru secvențiale este recomandat să utilizați [instrumentul BPM](bpm.md) în loc de caracteristica Fluxurilor de lucru.
-
-### Rulează Acțiune Serviciu
-
-Permite rularea de scripturi de serviciu specifice. În mod implicit, sunt disponibile următoarele acțiuni:
-
-* Trimite Invitații - pentru Întâlniri/Apeluri;
-* Adaugă Elemente de Citat - pentru Citate.
-
-Programatorii își pot scrie proprile acțiuni de serviciu. Vezi [mai multe detalii](../development/workflow-service-actions.md).
-
-## Folosind Foormula în Acțiune
-
-Este posibil să definiți o formulă pentru a calcula câmpurile pentru Creare Înregistrare, Actualizare Înregistrare Țintă, Creare Înregistrare Asemănătoare, Actualizare Înregistrări Asemănătoare. Pentru ultimele două, pentru a accesa atributele entității țintă, trebuie să utilizați funcția `targetEntity\attribute`. Pentru a accesa atributele unui obiect țintă care a fost setat înainte ca fluxul de lucru să fie declanșat, utilizați funcția `targetEntity\attributeFetched`.
-
-Exemplu:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/ro_RO/development/api.md b/i18n/ro_RO/development/api.md
deleted file mode 100644
index 9b0e0f1a0..000000000
--- a/i18n/ro_RO/development/api.md
+++ /dev/null
@@ -1,223 +0,0 @@
-# API REST
-
-EspoCRM este o aplicație de o pagină, astfel frontend folosește API REST pentru a se conecta cu un backend.
-Toate operațiile pe care le performați folosind UI le puteți implementa prin apeluri API calls folosind limbajul de programare.
-Puteți învăța cum funcționează API dacă urmăriți ce se întâmplă în fila de rețea din conosla browser.
-
-Majoritatea funcțiilor api returnează JSON. Apeluri POST, PATCH necesită de obicei niște date JSON în payload.
-
-Baza URL a API EspoCRM este: `api/v1/`. Trebuie să o puneți în așteptare în expresii în această referință. Exemplu:
-
-`GET http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Autentificare
-
-API EspoCRM folosește [Autentificare de Bază](http://en.wikipedia.org/wiki/Basic_access_authentication). Numele utilizatorului și parola/token sunt trecute prin header-ul codificat `Autorizație` în base64.
-
-`"Authorization: Basic " + base64Encode(username + ':' + password)`
-
-
-Este mai bine să folosiți token de autentificare în loc de parolă, atunci când lucrați cu api. În acest caz, va trebui să oferiți numele de utilizator și parola/token în header-ul`Espo-Authorization`.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-
-1. Obține accesul token-ului prin`GET App/user`, cerere pentru numele de utilizator și parola/token în header-ul`Espo-Authorization`.
-2. Folosiți acest token în loc de parola în header-ul`Espo-Authorization`, pentru toate viitoarele cereri.
-3. Dacă cererea returnează eroarea 403, asta însemnă cu fie numele de utilizator/parola sunt greșite sau token-ul nu mai este valid.
-
-#### Token de Autentificare/ Date Specifice ale Utilizatorului
-
-`GET App/user`
-
-Returnează:
-
-* `token` - acces token pentru folosință;
-* `acl` - informații despre accesul utilizatorului;
-* `preferences` - preferințele utilizatorului;
-* `user` - atributul înregistrării utiliztorului.
-
-
-## Operații CRUD
-
-#### Listă Entități
-
-`GET {entityType}`
-
-GET parameters:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) mărime max;
-* `where` - (array) filtere;
-* `sortBy` - (string) câmp pentru sortare;
-* `asc` - (bool) sortare direcție.
-
-_Example_
-
-`GET Account?offset=0&maxSize=20`
-
-Returnează:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Citește Entitate
-
-`GET {entityType}/{id}`
-
-Returnează atributele în obiectul JSON.
-
-_Example_
-
-`GET Account/5564764442a6d024c`
-
-#### Creează Entitatea
-
-`POST {entityType}`
-
-Payload: Obiect al atributelor entității.
-
-Returnează atributele în obiectul JSON.
-
-_Example_
-
-`POST Account`
-
-Payload:
-```
-{
- "name": "Test",
- "assignedUserId": "1"
-}
-```
-
-#### Actualizează Entitatea
-
-`PATCH {entityType}/{id}`
-
-sau
-
-`PUT {entityType}/{id}`
-
-Payload: Obiectul sau atributele entității trebuie schimbate.
-
-Returnează atributele în obiectul JSON.
-
-_Example_
-
-`PATCH Account/5564764442a6d024c`
-
-Payload:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Șterge Entitatea
-
-`DELETE {entityType}/{id}`
-
-_Example_
-
-`DELETE Account/5564764442a6d024c`
-
-
-## Entitități asemănătoare
-
-#### Lista Entităților Asemănătoare
-
-`GET {entityType}/{id}/{link}`
-
-* `offset` - (int) offset;
-* `maxSize` - (int) mărime max;
-* `where` - (array) filtere;
-* `sortBy` - (string) câmp pentru sortare;
-* `asc` - (bool) sortare direcție.
-
-_Example_
-
-`GET Account/5564764442a6d024c/opportunities`
-
-Returnează:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Link Entitate
-
-`POST {entityType}/{id}/{link}`
-
-Payload:
-
-1. `id` atribut.
-2. `ids` array atribut.
-3. `"massRelate": true` și `"where": {...}` pentru a raporta mai multe înregistrări pe criterii de căutare.
-
-_Example_
-
-`POST Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Unlink Entitate
-
-`DELETE {entityType}/{id}/{link}`
-
-Payload:
-
-1. JSON cu atribut `id`.
-2. JSON cu atribut array `ids`.
-
-_Example_
-
-`DELETE Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-## Stream
-
-#### Listă intrări stream pentru utilizatorul actual.
-
-`GET Stream`
-
-Get parameters:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) mărime max;
-
-#### Listă intrări stream raportate la o înregistrare specifică
-
-`GET {entityType}/{id}/stream`
-
-Get parameters:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) mărime max;
-
-#### Urmărește înregistrarea
-
-`PUT {entityType}/{id}/subscription`
-
-#### Nu mai urmări înregistrarea
-
-`DELETE {entityType}/{id}/subscription`
-
-
-
diff --git a/i18n/ro_RO/development/custom-field-type.md b/i18n/ro_RO/development/custom-field-type.md
deleted file mode 100644
index bdf06e7b1..000000000
--- a/i18n/ro_RO/development/custom-field-type.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Crearea unui tip specific de câmp
-
-### Definirea Câmpului
-
-Creați un fișier `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` cu parametrii necesari.
-```
-{
- "view": "custom:views/fields/{field-type}"`
-}
-```
-
-Folosiți exemplele tipurilor de câmp out-of-the-box: `/application/Espo/Resources/metadata/fields`.
-
-### Traducere
-
-Eticheta este folosită în Managerul de Entități și poate fi setată în `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` în secțiunea `fieldTypes`.
-Dacă trebuie să adăugați traduceri în altă limbă, folosiți limba de care aveți nevoie [codul limbii](https://en.wikipedia.org/wiki/ISO_639-1)_[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) instead of `en_US`. In `data/config.php` în secțiunea `languageList` puteți găsi lista cu limbile incluse.
-
-### Vizualizare
-
-Creați vizualizare în câmpul `client/custom/src/views/fields/{field-type}.js` și definiți-le șabloanele.
-```
-Espo.define('custom:views/fields/[field-type]', 'views/fields/base', function (Dep) {
-
- return Dep.extend({
-
- });
-});
-```
-
-Folosiți ca și exemplu tipurilor de câmp out-of-the-box:
-- `/client/src/views/fields` - vizualizări;
-- `/client/res/templates/fields` - șabloane.
-
-Apoi va trebui să rulați reconstruirea din panoul de administrare.
diff --git a/i18n/ro_RO/development/custom-views.md b/i18n/ro_RO/development/custom-views.md
deleted file mode 100644
index 2409b24b5..000000000
--- a/i18n/ro_RO/development/custom-views.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Vizualizări Personalizate
-
-## Vizualizări înregistrare
-
-Cadrul de lucru EspoCRM oferă abilități flexibile de a defini vizualizări personalizate pentru anumite tipuri de entități. Trebuie să fie definite în categoria `clientDefs` a metadatelor.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-Vizulaizarea Înregistrare/Detaliu conține toate panourile cu câmpuri, relații și alte date pe care le poți vedea în vizualizarea detaliată. Nu conține header și butoane în colțul de sus din dreapta.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Here is your custom template. Omit if you don't need it.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Here is your custom view. Omit if you don't need it.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Here is your custom view. Omit if you don't need it.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Here is your custom view. Omit if you don't need it.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Custom initalization logic here. Like binding listening to model changes.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Custom code to be invoked right after rendering, when DOM is avaiable.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-Ai posibilitatea de a creea un șablon personalizat cu următoarea cale:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-Vizualizarea detaliată conține vizualizarea Înregistrare/Detaliu și Header.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-La fel ca detaliul dar este folosit atunci când o înregistrare este creată sau editată dar nu în modul de editare inline.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-Ultima vizulaizare conține vizualizarea Înregistrare/Listă, Header și Vizualizarea Formularului de Căutare.
-
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-Vizualizarea Listă/Înregistrare conține rânduri din înregistrări.
-
-
-Merită menționat faptul că trebuie să moșteniți clasa de vizualizare din clasa specifică pentru entitatea dumneavoastră, dacă aceasta există deja.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Vizualizare Câmpuri
-
-Vizualizările personalizate pentru anumite câmpuri ar trebui specificate în secțiunea entityDefs a metadatelor.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
-
diff --git a/i18n/ro_RO/development/dynamic-forms.md b/i18n/ro_RO/development/dynamic-forms.md
deleted file mode 100644
index 08ac24abd..000000000
--- a/i18n/ro_RO/development/dynamic-forms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Formulare Dinamice
-
-Rețineți: Încă de la veriunea 4.3.0 este posibilă definirea formularelor dinamice prin UI a adminului în Managerul de Entități.
-
-Există o posibilitate de a defini comportamentul unui formular în EspoCRM.
-
-## Exemplu
-
-> Trebui să arătăm show _nextStep_ field pe vizualizarea detaliată a Oportunității dacă etapa este 'Closed Won'.
->
-
-Creați fișier `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Aceasta însemnă cu _nextStep_ field o să fie ascuns în mod implicit și vizibil dacă etapa este 'Closed Won'.
-
-Lista acțiuniilor disponibile: `show`, `hide`, `setRequired`, `setNotRequired`.
-
-Există, de asemenea, abilitatea de a ascunde/afișa panouri. Specifică numele panoului în `panels`, atribuit în același fel ca `fields`.
diff --git a/i18n/ro_RO/development/extension-packages.md b/i18n/ro_RO/development/extension-packages.md
deleted file mode 100644
index 0ebed5876..000000000
--- a/i18n/ro_RO/development/extension-packages.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Pachete de Extensie
-
-Extensiile permit adăugarea extra funcționalitățiilor în EspoCRM. Pot fi instalate din panoul de Administrare sub secțiunea `Customization`.
-
-## Cum se crează pachetele de extensie
-
-Structura unui fișier din pachet:
-
-* `/manifest.json` – un fișier care conține proprietăți de extensie;
-* `/files` – un director care conține fișierele de extensie;
-* `/scripts` – conține spripturile de extensie.
-
-### Manifest
-```json
-{
- "name": "Extension Name",
- "version": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "author": "Your Name",
- "description": "Description of your extension",
- "delete": []
-}
-```
-
-* Sintaxa din `version` și `acceptableVersions` este descrisă de specificațile v2.0.0 găsite la http://semver.org.
-* `delete` - este lista fișierelor de bază care trebuie șterse. Folosirea acestui parametru nu este recomandată. Îl puteți omite.
-
-### Fișiere
-
-Toate extensile fișierelor ar trebui puse în directorul `files`. Acestea o să fie copiate în directorul de bază EspoCRM.
-
-### Scripturi
-
-Pentru diferite scopuri EspoCRM acceptă următoarele tipuri de scripturi. Toate ar trebui să fie puse în directorul `scripts`.
-
-* `BeforeInstall.php` – un script executat înainte de procesul de instalare;
-* `AfterInstall.php` – executat odată ce procesul de instalare s-a terminat;
-* `BeforeUninstall.php` – executat înainte de procesul de dezinstalare;
-* `AfterUninstall.php` – executat odată ce procesul de dezinstalare s-a terminat.
-
-Exemplu:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Pachet
-
-La sfârșit, trebuie să arhivăm toate fișierele într-un arhivă .zip.
diff --git a/i18n/ro_RO/development/hooks.md b/i18n/ro_RO/development/hooks.md
deleted file mode 100644
index 440e2da21..000000000
--- a/i18n/ro_RO/development/hooks.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Hooks
-
-## Creați un Hook
-Pentru a creea un hook, trebui să:
-- creați un fișier `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- declarați tipul acțiunii hook;
-- șterge Cache din Administrare.
-
-## Tipuri de Hook
-
-Tipurile principale de hook sunt:
-
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove;
-- afterRelate;
-- afterUnrelate;
-- afterMassRelate.
-
-### Un nou tip de Hook
-Puteți să îl folosiți propriul tip de hook și să îl declanșați
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Ordinea Hook
-Dacă aveți mai multe hook, legate de Tipul Entității și cu același tip de hook, și ordinea rulării este importantă, puteți seta o proprietate `public static $order` într-o valoare de tip integer.
-
-Ordine ascendentă - Hook-ul cu cea numărul de orinde cel mai mic, va rula primul.
-
-## Exemplu
-Acest exemplu setează Numele Contului pentru noi Leads, dacă nu a fost setat încă.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-use Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Hook Globale
-Dacă trebuie să aplicați un hook pentru toate entitățile, puteți folosi hooks obișnuite. Pentru a face acest lucru, puneți clasa hook-ului în directorul Common, ex. `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/ro_RO/development/how-to-create-a-dashlet.md b/i18n/ro_RO/development/how-to-create-a-dashlet.md
deleted file mode 100644
index 3af408ab0..000000000
--- a/i18n/ro_RO/development/how-to-create-a-dashlet.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Cum să creați un dashlet
-
-Creați un fișier `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` cu configurările dashlet.
-
-Aici va trebui să definiți `"view"`, și ai putea să setezi `"aclScope"`, `"entityType"`, și `"options"`.
-
-Dacă este o listă tipică de dashlet, use `"view":"views/dashlets/abstract/record-list"`, dacă nu, creațipropria vizualizare (https://github.com/espocrm/documentation/blob/master/development/custom-views.md).
-
-## Opțiuni
-În mod implicit în opțiunile dashlet poți seta _Title_ and _Auto-refresh Interval_.
-
-Opțiuni adiționale ale câmpurilor pot fi setate `"options"` > `"fields"`.
-
-Pentru a deini poziția câmpurilor, setați aspectul în `"options"` > `"layout"` > `"rows"`
-
-De asemenea, dacă vizulaizarea necesită mai multe date, puteți defini și alte opțiuni.
-
-## Exemplu
-
-`application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json`
-
-```
-{
- "view":"views/dashlets/abstract/record-list",
- "aclScope": "Case",
- "entityType": "Case",
- "options": {
- "fields": {
- "title": {
- "type": "varchar",
- "required": true
- },
- "autorefreshInterval": {
- "type": "enumFloat",
- "options": [0, 0.5, 1, 2, 5, 10]
- },
- "displayRecords": {
- "type": "enumInt",
- "options": [3,4,5,10,15]
- },
- "expandedLayout": {
- "type": "base",
- "view": "views/dashlets/fields/records/expanded-layout"
- }
- },
- "defaults": {
- "sortBy": "createdAt",
- "asc": false,
- "displayRecords": 5,
- "expandedLayout": {
- "rows": [
- [
- {
- "name": "number"
- },
- {
- "name": "name",
- "link": true
- },
- {
- "name": "type"
- }
- ],
- [
- {
- "name": "status"
- },
- {
- "name": "priority"
- }
- ]
- ]
- },
- "searchData": {
- "bool": {
- "onlyMy": true
- },
- "primary": "open"
- }
- },
- "layout": [
- {
- "rows": [
- [
- {"name": "title"}
- ],
- [
- {"name": "displayRecords"},
- {"name": "autorefreshInterval"}
- ],
- [
- {"name": "expandedLayout"},
- false
- ]
- ]
- }
- ]
- }
-}
-```
-Aici puteți găsi exemple `application/Espo/Modules/Crm/Resources/metadata/dashlets`.
-
-## Traduceri
-
-Traduceri la dashlet se găsesc în domeniul `Global`, în secțiunea `"dashlets"`.
-
-__Nu uitați să ștergți Cache-ul din Administrare.__
diff --git a/i18n/ro_RO/development/link-multiple-with-primary.md b/i18n/ro_RO/development/link-multiple-with-primary.md
deleted file mode 100644
index 0dd5757c2..000000000
--- a/i18n/ro_RO/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Legare Câmpuri Multiple cu Primar
-
-~Pentru EspoCRM 3.6.0 și o versiune mai nouă.~
-
-Uneori aveți relația `hasMany` și posibilitatea de a selecta o înregistrare asemănătoare dintre cele asemănătoare. Spre exemplu, `Contacts` câmpurile din entitatea Caz.
-
->Trebui să creați `contacts` Legare Câmpuri Multiple cu Primar pentru entitatea personalizată cu `Stock`.
->
-
-###Pasul 1
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-###Pasul 2
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-###Pasul 3
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-###Pasul 4
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-###Pasul 5
-Rulați Reconstruirea
-
-###Step 6
-Executați SQL query
-```sql
-UPDATE stock
-JOIN contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
-
diff --git a/i18n/ro_RO/development/metadata.md b/i18n/ro_RO/development/metadata.md
deleted file mode 100644
index 8dc760eb4..000000000
--- a/i18n/ro_RO/development/metadata.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Metadate
-
-Metadatele sunt pentru: stocarea datelor sistemului cum ar fi câmpurile entității și relațiile; specificați controalele frontend, vizualizări, panouri; definirea câmpurilor, dashlets; și alte date necesare pentru aplicație.
-
-
-## Cum se pot accesa
-
-#### Backend
-
-Obiectul metadatelor din clasa `Espo\Core\Utils\Metadata` poate fi accesat din Container. Calea către un parametru necesar este specificată folosind puncte `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-will return `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-will return an associative array of all fields.
-
-#### Frontend
-
-Obiectul metadatelor este accesibil din toate obiectele prin metoda `#getMetadata`. Merge la fel ca cel din backend.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## Cum este stocat
-
-Metadatele sunt stocate în fișierul JSON care poate fi plasat în locuri diferite:
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-Când accesați datele din calea `clientDefs.Account.views.edit` primul lexeme `clientDefs` corespunde dir name, al doilea `Account` în numele fișierului `Account.json`. Toate urmând corespondentele lexemes în calea JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-Toate fișierele JSON din aceste directoare sunt unite recusiv într-un array php și stocate în fișierul cache.
-
-
-## Extindere
-
-Deoarece metadatele sunt unite recursiv prin redefinire obiectelor json și arrays in _custom_ and in your _module_. De asemenea, poți a you can adăuga în array deja existente folosind `__APPEND__` (since version 2.6.0) ca primul element din array.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/ro_RO/development/new-function-in-formula.md b/i18n/ro_RO/development/new-function-in-formula.md
deleted file mode 100644
index bb2005ac2..000000000
--- a/i18n/ro_RO/development/new-function-in-formula.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Definirea unor noi funcții pentru Formulă
-
-EspoCRM oferă posibilitatea creării unor funcții personalizate care pot fi folosite în formulă.
-
-Dacă funcția este asemănătoare cu grupuri ca String, Logic, Date, creați un fișier in __{GroupName}Group__ folder, named __{FunctionName}Type.php__ with __{FunctionName}Type__ class declaration. Va trebui să definiți metoda __'process'__.
-
-De exemplu, putem creea o nouă funție șir dacă șirul conține (HAYSTACK) un alt șir (NEEDLE) cu un posibil offset (OFFSET).
-
-Creați un fișier `application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` cu codul:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-use \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Adăugarea funției în lista
-
-Pentru a putea adăuga funcția la lista funcțiilor formulei, creați un fișier `custom/Espo/Custom/Resources/metadata/app/formula.json` și adăugați codul:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Clear cache__ și folosiți funcția în formula. Puteți să tastți `string\contains(HAYSTACK, NEEDLE, OFFSET)` sau selectați din lista funcției, dacă ați adăugat-o.
-
diff --git a/i18n/ro_RO/development/orm.md b/i18n/ro_RO/development/orm.md
deleted file mode 100644
index c259a651a..000000000
--- a/i18n/ro_RO/development/orm.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# ORM (Cum să gestionați Entități)
-
-EspoCRM are propriul ORM (Object-relational mapping). Este ușor de creat, actualizat, citit, șters și pentru a căuta entități. Toate aceste operații sunt disponibile prin obiectul Managerului de Entități. Managerul de Entități este disponibil în înregistrările Servicilor prin metoda `#getEntityManager()`.
-
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Creați o nouă entitate
-```php
-$account = $entityManager->getEntity('Account')
-```
-sau
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Fetch cea existentî
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-sau
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Obține valoare
-```php
-$fieldValue = $account->get('fieldName');
-```
-
-#### Are valoare
-```php
-$fieldNameIsSet = $account->has('fieldName'); // true or false
-```
-
-#### Setare valoare
-```php
-$account->set('fieldName', 'Test Account');
-```
-
-```php
-$account->set(array(
- 'name' => 'Test Account',
- 'assignedUserId' => '1'
-));
-```
-
-#### Stocare
-```php
-$entityManager->saveEntity($account);
-```
-sau
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Remove
-```php
-$entityManager->removeEntity($account);
-```
-sau
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Găsește
-```php
-$accountList = $entityManager->getRepository('Account')->where(array(
- 'type' => 'Customer',
-))->find();
-```
-
-Ordine descendentă:
-
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', true)->find();
-```
-
-Ordine acendentă:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt')->find();
-```
-
-sau:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', 'DESC')->find();
-```
-
-#### Găsește primul
-```php
-$account = $entityManager->getRepository('Account')->where(array(
- 'type' => 'Customer',
-))->findOne();
-```
-
-#### Găsește asemnănător
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
-```
-
-#### Înlocuiește entitate
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
-```
-sau
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
-```
-
-#### Entități neasemănătoare
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
-```
-sau
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
-```
-
diff --git a/i18n/ro_RO/development/scheduled-job.md b/i18n/ro_RO/development/scheduled-job.md
deleted file mode 100644
index d4f18878f..000000000
--- a/i18n/ro_RO/development/scheduled-job.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Crearea unei Activități Planificate
-
-Pentru a defini o Activitate Planificată personalizată creați un fișier `custom/Espo/Custom/Jobs/{JOB_NAME}.php` cu conținut.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //all the logic needs to be defined in the method run
- }
-}
-```
-
-De asemenea, puteți seta o etichetă pentru activitate (`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-Pentru a implementa schimbările, mergi la panoul din Administrare și ștergeți Cache-ul.
diff --git a/i18n/ro_RO/development/workflow-service-actions.md b/i18n/ro_RO/development/workflow-service-actions.md
deleted file mode 100644
index 70273d0ef..000000000
--- a/i18n/ro_RO/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Adăugarea unor acțiuni de serviciu personalizate pentru Fluxul de lucru
-
-Fluxurile de lucru permit crearea unor acțiuni de serviciu personalizate. Acest exemplu o să arate cum se poate face acest lucru pentru a apela o entitate.
-
-## Pasul 1. Creați clasa de serviciu
-
-```php
- Clear Cache. Acșiunea serviciului este diponibilă pentru Fluxurile de lucru în formularul Actiunilor de Rulare a Serviciilor.
\ No newline at end of file
diff --git a/i18n/ro_RO/user-guide/browser-support.md b/i18n/ro_RO/user-guide/browser-support.md
deleted file mode 100644
index ea74021c0..000000000
--- a/i18n/ro_RO/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Browsere acceptate
-
-Vă recomandăm folosirea utlimelor versiuni Google Chrome sau Mozilla Firefox. EspoCRM funcționează cel mai bine pe aceste browsere. Testăm, în mod regulat, toate funcțiile în acest browsere.
-
-Microsoft Edge și Safari sunt de asemenea acceptate, dar sunt mai puține garanții în funcționarea fără probleme.
-
-Vă recomandăm să nu folosiți Internet Explorer 11.
diff --git a/i18n/ro_RO/user-guide/emails.md b/i18n/ro_RO/user-guide/emails.md
deleted file mode 100644
index a71bd51bd..000000000
--- a/i18n/ro_RO/user-guide/emails.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Instrucțiuni pentru Utilizarea Email-urilor
-
-EspoCRM oferă posibiliteatea fetch email-uri din IMAP box. Acest lucru face posibilă folosirea EspoCRM ca și email client împreună cu caracteristicile CRM-specifice.
-
-## Conturi IMAP
-
-*Rețineți: Pentru ca email-urle de primite să funcționeze, trebuie să aveți [cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) configurat corespunzător în sistemul dumneavoastră.*
-
-Utilizatorul poate seta contul IMAP pe pagina de Conturi Personale de Email (fila Email-uri > meniul de sus-dreapta > Conturi Personale de Email).
-
-Specifică ce dosare să fie monitorizate în câmpul Dosarelor Monitorizate. În mod implicit nu este setat în INBOX. Dacă folosiți un client extern de email-uri pentru a trimite email-uri, poți adăuga Dosarul de Trimitere pentru a arhiva acele email-uri.
-
-*Fetch începând de la* permite alegerea datei de când să înceapă arhivarea email-urilor. Dacă trebuie să arhivați email-uri vechi, setați-o la o dată anterioară datei de azi.
-
-Există posibilitatea de a seta *Dosar* în Contul Personale de Email. Email-urile primite vor fi puse în acel dosar.
-
-## Conturi SMTP
-
-Utilizatorii pot seta setările SMTP în Preferințe, precum și în Conturile Personale de Email. Administratorul poate permite folosirea sistemului SMTP (să poate fi distribuit).
-
-Utilizatorii pot avea conturi multiple SMTP (începând cu versiune 4.2.0). Însă, adresele de email pe care utilizatorul le pot folosi pentru a trimite email-uri sunt definite de către adresele de email ale înregistrării * Utilizator *
-
-## Lucrul cu Email-uri
-
-Email-urile sunt fetched de către cron (în background) la fiecare câteva minute (perioda poate fi specificată de către Administrator).
-Poți vizualiza toate email-urile în fila de Email-uri. Există dosare standard Inbox, Sent, Draft în partea stângă.
-
-Câmpul *Status*. `Sent` înseamnă că a fost trimis din CRM, `Archived` – fetched din contul de IMAP sau arhivat manual, `Draft` – înseamnă că email-ul a fost creat ca o ciornă.
-
-Atunci când un email este primit, sistemul încearcă să recunoască cărui înregistrare corespunde email-ul respectiv. Îl poate lega cu Contul, Lead, Oportunitatea, Cazul (și contact în modul B2C) etc. Dacă nu a fost recunoscut, utilizatorul îl poate lega manul, completând câmpul *Parent* .
-
-Dacă un email a venit de la un potențial nou client, utilizatorul poate să **convertește în Lead**. Deschideți intrarea Email și apasați Create Lead, în partea de sus a meniului.
-
-Este posibilă crearea **creți Sarcină sau Caz** dintr-o înregistrare email.
-
-Dacă adresele de email (from, to, cc) dintr-o înregistrare sunt cunoscute sistemului, o să afișeze persoanei respective că sunt legate de (Contact, Lead, User etc). Dacă vreo adresă de email este nouă, puteți **crați contact** din dreapta.
-
-Toate email-urile legate de o anumită înregistrare sunt afișate în panoul Istoricului din acea înregistrare. Spre exemplu, dacă un email este leagat de o oportunitate, dar oportunitatea este legată de cont, o să fie afișat atât în oportunitate cât și în cont.
-
-## Trimiterea Email-urilor
-
-Puteți crea email-uri în mai multe moduri:
-* Butonul *Compose Email* din vizualizare listei de Email-uri;
-* răspunzând la un alt email;
-* apăsând pe adresa de email a unei înregistrări;
-* Acțiunea *Compose Email* din panoul de Activități.
-
-Există posibilitatea de a **select template** pentru email-ul dumneavoastră.
-
-Puteți seta **email signature** în Preferințe.
-
-## Dosare Email
-
-În funcție de nevoi, utilizatorii își pot creea propriile dosare de email-uri. Lista cu dosare disponibile este disponibilă pe pagina Email-urilor, în partea stângă. Pentru a creea sau edita dosare urmați Email-uril > dropdown în colțul din dreapta-sus > Dosare. `Skip Notification` înseamnă că nu veți fi notificat la primirea unui mesaj, care intră în anumite dosare. Prin folosirea Filtrelor de Email-uri, este posibil să puneți email-urile în dosare, după anumite criterii.
-
-## Filtre Email
-
-Administratorul poate crea filtre globale de email-uri pentru a sări peste anumite email-uri. Acestea sunt disponibile în Administrare > Filtre Email.
-
-Utilizatrul obișnuit poate crea filtre pentru email-uri pentru Conturile Personale de Email sau pentru întreaga căsuță poștală. Acestea sunt disponibile în Email-uri > dropdown în colțul din dreapta-sus > Filtere.
-
-Există două tpuri de filtere:
-* Skip - email-ul va fi pus în *Trash*, iar dacă filtrul este legat de Contul Personal de Email, nu o să fie importat;
-* Pus în Folder - email-urile importate o să fie puse automant, în dosare specificate de către utilizator.
-
-## Șabloane Email
-
-Șabloanele Email sunt disponibile în Email-uri > dropdown în colțul din dreapta-sus > Șabloane Email. Acestea pot fi folosite atât pentru trimiterea email-urilor în masă, cât și pentru email-urile obișnuite. Căsuța `One-off` înseamnă că șablonul email-ului trebuie să fi folosit o singură dată, de obicei pentru email marketing.
-
-Este posibilă utilizarea substituențiilor în conținutul șablonului email-ului și în subiectul email-ului ex {Account.name}, {Person.emailAddress}. Aceste o să fie înlocuite cu valori ale înregistrărilor legate.
-
-Puteți alege substituenți adiționali în conținutul șablonului: {optOutUrl} și {optOutLink}.
-```
-Unsubscribe
-```
-Acesta este un link de dezabonare în masă de la email-uri.
diff --git a/i18n/ro_RO/user-guide/mass-email.md b/i18n/ro_RO/user-guide/mass-email.md
deleted file mode 100644
index c289d6196..000000000
--- a/i18n/ro_RO/user-guide/mass-email.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Email în Masă
-
-## Cum să trimiteți email-uri în masă
-
-Trebuie să ai cel puțin o Listă Țintă cu înregistrări țintă și Sabloane pentru Email, în crm.
-
-1. Crează o nouă campanie cu statusul `Email` sau `Newsletter`. În câmpul `Liste Țintă`, selectează una sau mai multe liste țintă.
-2. După ce înregistrarea Campaniei este creată, creați Email-uri în Masă pentru această campanie: apăsați plus pe panoul Email-urilor în Masă. Specificați _Data Începeri_ - când să fie trimise email-urile, și selectați _Șablon Email_. Asigurați-vă că _Status_ este setat ca `În așteptare`.
-
-If everything is setup right emails should go out. They should be sent each hour with portions (you can change portion size in Administration > Outbound Emails). Administrator can change it by updating `Scheduling` field of `Check Group Email Accounts` Scheduled Job.
-Dacă totul este setat cum trebuie, email-urile ar trebui să se trimită. Acestea ar trebui timise, la fiecare oră, cu anumite poționări (puteți să schimbați mărimea în Administrare > Email-uri trimise. Administratorul poate schimba prin actualizarea câmpului `Planificare` din `Scheduling` field of `Verifică Conturi Group Email` Activități planificate.
-Puteți verifica dacă email-urile sunt trimise în panoul jurnal.
-
-## Test care va fi trimis la destinatari
-
-Apăsați dreapta jos, pe rândul cu email-uri în masă din panoul _Email în Masă_ și apăsați _Trimite Test_.
-
-## Jurnal
-
-În jurnal puteți vedea:
-* Email-urile trimise;
-* Email-urile deschise de destinatar;
-* Link-uril care au fost deshise de destinatar;
-* Destinatarii care au renunțat;
-* Bounced email (nu a ajuns la destinatar).
-
-## Renunțare - link
-
-În mod implicit, sistemul va adăuga opțiunea de renunțare la toate e-mailurile trimise. Dar puteți utiliza unul personalizat în șablonul de email.
-
-Exemplu:
-```html
-Unsubscribe from the mailing list.
-```
-
-Administratorul poate dezactiva link-ul de renunțare, obligatoriu adăugat de sistem la Administrare > Email-uri Trimise.
-
-## Urmărire URL
-
-Dacă doriți să știți că destinatarul a deschis linkul din email, trebuie să creați Urmărire URL. Specificați orice _Nume_
- și _URL_ unde dorți să ducă link-ul dumneavoastră. Apoi va trebui să lipiți codul generat în Șablonul de Email-uri.
-
- Exemplu:
- ```html
-Try our demo
- ```
-
-## Liste Țintă
-
-Listele țintă conțin listele de conturi, contacte, leads și înregistrările utilizatorilor.
-
-Utilizatorii pot folosi manual liste de destinaatari cu ajutorul acțiunii _Selectare_ din panoul corespunzător din vizualizarea detaliată a Listei Țintă. Există posibilitatea de filtrare și apoi selectare a tuturor rezultatelor căutării.
-
-## Popularea listelor țintă cu rapoarte
-
-[Rapoarte](reports.md#syncing-with-target-lists) oferă o capacitate de a popula liste țintă cu înregistrări care corespund anumitor criterii.
-
-## Excluderea listelor țintă
-
-Specificați excluderea listelor țintă pentru a evita trimiterea de email în masă anumitor destinatari. Dacă există o înregistrare cu adresa de e-mail care se potrivește cu adresa de e-mail a oricărei înregistrări care este exclusă, va fi exclusă și prima înregistrare.
-
-## Jurnalul campaniei
-
-În jurnalul Campaniei, puteți vizualiza email-urile care au fost trimise, email-urile deschise, cele care nu au ajus la destinatar, cei care au renunțat, și cei care au deschis link-ul din email. Este posibil să utilizați acest jurnal prin crearea unei liste de destinatari (drop-down în colțul din dreapta-sus al panoului) pe baza înregistrărilor din jurnal. De exemplu, selectați numai persoanele de contact care au deschis link-ul (urmărire url).
-
-## Troubleshooting
-
-_Pentru Administratori_
-
-#### Ce trebuie să faceți dacă email-urile nu sunt trimise.
-
-1. Verificați dacă _Trimite Test_ dacă merge. Dacă nu funcționează, verificați dacă setările sistemului SMTP sunt corecte.
-2. Verificați dacă aveți setat cron pentru sistemul dumneavoastră.
-3. Verificați dacă aveți planificată activitatea `Trimite Email în Masă` și este `Activă` (Administrație > Activități Planificate > Trimite Email în Masă). Verificați dacă este ceva în Jurnal.
-
-
-#### Dacă Urmărirea URL a fost greșită și nu ajunge la crm dumneavoastră.
-
-Verificați parametrul 'siteUrl' din fișierul `data/config.php`. Trebuie să fie setat ca URL pentru accesibilitatea EspoCRM dintr-un mediu extern.
-
-#### Email-urile care nu au fost trimise nu sunt trecute în jurnal
-
-Mesajele eșuate pot fi gestionate numai prin contul de email al grupului. Asigurați-vă că aveți un cont de email de grup care monitorizează căsuțele poștale prin care s-au trimis email-urile.
-
-De asemenea, unii furnizori de servere se pot abate de la standarde, astfel încât email-urile care nu au fost trimise, nu pot fi distinse.
diff --git a/i18n/ro_RO/user-guide/quotes.md b/i18n/ro_RO/user-guide/quotes.md
deleted file mode 100644
index 6400c6857..000000000
--- a/i18n/ro_RO/user-guide/quotes.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Oferte
-
-Caracteristica de Oferte este disponibilă în [Pachetul Avansat](https://www.espocrm.com/extensions/advanced-pack/).
-
-Ofertele sunt grupuri specifice de produse sau servicii cu cantitățile și prețurile pe care le cereți clienților.
-
-Ofertele au o relație cu Oportunitatea. Puteți adăuga panoul de Oferte din vizualizarea detaliată a Oportunității din Administrare > Manager Aspect > Oportunități > Relații. Atunci când creați o nouă ofertă legată de o oportunitate, elementele oportunității sunt transeferate ofertei.
-
-Pentru a putea vedea Oferte asemănătoare, puteți adăuga panoul Oferte în vizualizarea detaliată a Contului. Puteți face asta din Oportunității din Administrare > Manager Aspect > Conturi > Relații.
-
-## Elemente Ofertă
-
-Oferta are o listă de elemente has a list of items. Fiecare element poate reprezenta un anumit produs sau un serviciu care conține descriere, cantitate, cota de impozitare, prețul listei și câmpul prețului unitar. Este posibil să sortați elementele manual.
-Există posibilitatea de a adăuga câmpuri personalizate pentru Entitatea Elementului Ofertei utilizând Managerul de Entități.
-
-## Șabloane
-
-În mod implicit, există două șabloane: Ofertă și Factură. Puteți creea noi șabloane (Vizualizare Listă Oferte > Meniu sus-dreapta dropdown > Șabloane), dar puteți edita și unele existente.
-
-Pentru o editare mai precisă, este recomandat să utilizați modul Vizualizare Cod.
-
-Puteți imprima câmpurile din înregistrarea Ofertei, precum și de asemenea înregistrărilor asemănătoare prin folosirea subsituențiilor în șablon.
-
-Exemple:
-`{{accountName}}` – Nume cont,
-
-`{{{billingAddressStreet}}}` – strada,
-
-`{{account.type}}` – tipul contului asemănător,
-
-`{{assignedUser.lastName}}` – numele utilizatorului atribuit.
-
-Dacă linia elementului este un produs pe care pot fi imprimate câmpurile produsului.
-
-Exemple:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Lungimea și culoarea sunt câmpuri personalizate ale entității Produs în exemple.
-
-Looping prin elementele ofertei:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-Este posibilă imprimarea câmpurilor imaginii:
-
-```
-
-```
-where `imageId` – the name of custom image field in Quote entity concatenated with the suffix `Id`.
-
-Pentru elementul linie al produsului:
-```
-
-```
-
-Pentru a afișa numerele float (precum cantitate, unitatePreț etc.) fără o parte fracțională (ca integer) folosiți următoarele epresii (începând cu versiunea 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Formatare personalizată pentru valorile monedelor (începând cu versiunea 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Valoarea`10000.5` o să fie imprimată ca `10 000,50`.
-
-Pentru afișarea câmpurilor text (multilinie) folosiți trei acolade: `{{{description}}}`.
-
-## Imprimați PDF
-
-Ofertele por fi imprimate în format PDF. Această acțiune este disponibilă lângă butonul de Editare din vizualizarea detaliată a ofertei. Apoi va trebui să selectezi Șablonul.
-
-## Email Ofertă
-
-Oferta în foramt PDF poate fi trimisă ca atașament. Deschideți înregistrarea ofertei, apăsați jos, lângă butonul de editare și apoi deschideți Email-ul în format PDF.
-
-## Numerotare automată
-
-Puteți creea un câmp de Număr cu ajutorul Managerului de Entități pentru tipul Ofertei entității. Administrare > Manager Entități > Oferte > Câmpuri > Adaugă Câmp > Numbăr. Apoi îl puteți plasa în vizualizarea detaliată, folosind Managerul de Aspect.
-
-Valoarea va fi incrementată de fiecare ofertă nouă. Există posibilitatea de a specifica numărul următor, precum și prefixul.
-
-## Taxă implicită
-
-Disponibilă începând cu versiunea EspoCRM 4.8.0.
-
-1. Specificați înregistrarea implicită a taxei din Administrare > Manager Entități > Oferte > câmpuri > Taxe > Implicit.
-2. Specificați cota taxei implicite din Administrare > Manager Entități > Oferte > câmpuri > Cotă Taxe > Implicit.
-
-## Factori
-
-Oferta poate fi tratată ca o factură dacă statutul său a devenit `Aprobat`. Apoi câmpurile _Data Facturării_, _Numărul Facturii_ o să apară. Pentru imprimarea facturilor, puteți folosi diferite șabloane.
diff --git a/i18n/ro_RO/user-guide/stream.md b/i18n/ro_RO/user-guide/stream.md
deleted file mode 100644
index 0294575c0..000000000
--- a/i18n/ro_RO/user-guide/stream.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Stream
-
-Stream în EspoCRM este un flux unde poți vedea actualizările și noile adiții pentru înregistrările pe care le urmărești. Poți publica pe propriul stream, sau pe al altui utilizator (începând cu versiunea 3.8.0). Există două tipuri de stream în EspoCRM: stream pentru înregistare și stream pentru utilizator.
-
-În mod implicit, următoarele entități au un stream: Conturi, Contacte, Leads, Oportunități, Cazuri. Administratorii pot activa sau dezactiva stream-ul pentru o anumită enititate în [Managerul de Entități](../administration/entity-manager.md).
-
-## Stream Înregistrare
-
-Înregistrare Stream este afișată în panoul Stream a unei anumite înregistrări, din vizualizarea detaliată. Postările, actualizările și noile adiții legate de înregistrarea actuală sunt afișate aici.
-
-## Stream Utilizator
-
-De asemenea, utilizatorii îți pot vedea propriul Stream dashlet, în fila Stream. Uilizatorii pot vedea stream-ul altui utilizator în vizualizarea detaliată a utiliatorului, dacă au acces care este controlat de către câmpul `Permisiuni Utilizator` din Roluri.
-
-În stream-ul utiliatorului poți vedea postări, actualizări și noile adiții legate de înregistrările pe care le urmărește utilizatorul. De asemenea, puteți vede postările adresate utilizatorului. Aceste postări nu sunt legate de nici o înregistrare.
-
-## Notificări
-
-Veți primi notificări despre noi aiții la stream-ul tău, care au fost cauzate de alți utilizatori.
-
-## Postări
-
-Puteți creea anumite postări legate de o înregistrare. De asemenea, puteți atașa mai multe fișiere și imagini, postării. Dacă vreți să menționanți pe cineva în postare, numele utilizatorului trebuie să preceadă simbolul`@`. Utilizatorul menționat în postare, o să fie notificat.
-
-## Postări către utilizatori to users
-
-_Această caracteristică este disponibilă începând cu versiunea 3.8.0._
-
-Utilizatorii pot creea postări către anumiți utilizatori, către anumite echipe, către toți utilizatorii sau către sine. Accesul la această posibilitatea este controlat de câmpul `Permisiune de atribuire` din Roluri.
-
-## Filtrare
-
-Puteți filtra ce să se afișeze într-un stream: `Tot`, `Postări` sau `Actualizări`.
diff --git a/i18n/ru_RU/README.md b/i18n/ru_RU/README.md
deleted file mode 100644
index 0b4c5a9ee..000000000
--- a/i18n/ru_RU/README.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Документация по EspoCRM
-
-### Администрирование
-
-* [Конфигурация сервера](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/server-configuration.md)
- * [Apache](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/apache-server-configuration.md)
- * [Nginx](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/nginx-server-configuration.md)
-* [Установка](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/installation.md)
-* [Обновление](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/upgrading.md)
-* [Исправление проблем](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/troubleshooting.md)
-* [Управление ролями (контроль доступа)](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/roles-management.md)
-* [Элекронные письма](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/emails.md)
-* Настройка
- * [Управление объектами: объекты, поля, отношения](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/entity-manager.md)
- * [Управление макетами](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/layout-manager.md)
- * [Расширения](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/extensions.md)
- * [Динамические формы](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/dynamic-logic.md)
-* [Вычисляемые поля (формула)](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/formula.md)
-* [Импорт](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/import.md)
-* [Портал](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/portal.md)
-* [LDAP Авторизация](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/ldap-authorization.md)
- * [Active Directory](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/ldap-authorization-for-ad.md)
- * [OpenLDAP](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/ldap-authorization-for-openldap.md)
-* Разное
- * [Web-to-Lead](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/web-to-lead.md)
- * [Задания](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/jobs.md)
- * [Карты](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/maps.md)
- * [Режим B2C](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/b2c.md)
- * [Резервное копирование и восстановление](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/backup-and-restore.md)
- * [Перемещение на другой сервер](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/moving-to-another-server.md)
- * [Несколько ответственных пользователей](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/multiple-assigned-users.md)
-* Advanced Pack
- * [Управление Бизнес-Процессами](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/bpm.md)
- * [Рабочие потоки](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/administration/workflows.md)
----
-
-### Руководство пользователя
-
-* [Элекронные письма](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/emails.md)
-* [Лента](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/stream.md)
-* [Управление продажами](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/sales-management.md)
-* [Управление обращениями](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/case-management.md)
-* [Действия и календарь](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/activities-and-calendar.md)
-* [Отчеты](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/reports.md)
-* [Массовая рассылка](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/mass-email.md)
-* [Слияние писем (массовая рассылка)](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/mail-merge.md)
-* [Предложения](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/quotes.md)
-* [Продукты](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/products.md)
-* [Статьи базы знаний](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/knowledge-base.md)
-* [Документы](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/documents.md)
-* [Экспорт](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/export.md)
-* [Текстовый поиск](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/text-search.md)
-* Разное
- * [Печать в PDF](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/printing-to-pdf.md)
- * [Синтаксис Markdown](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/markdown.md)
- * [Поддержка браузеров](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/browser-support.md)
- * [Конфиденциальность данных](https://github.com/espocrm/documentation/blob/master/i18n/ru_RU/user-guide/data-privacy.md)
-
----
-
-Смотрите также:
-
-[Документация на сайте](https://www.espocrm.com/documentation/)
diff --git a/i18n/ru_RU/administration/apache-server-configuration.md b/i18n/ru_RU/administration/apache-server-configuration.md
deleted file mode 100644
index 3da793e35..000000000
--- a/i18n/ru_RU/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Конфигурация сервера Apache для EspoCRM
-
-Эти инструкции являются дополнительными к руководству по [Конфигурации сервера](server-configuration.md). Обратите внимание, что все перечисленные здесь параметры конфигурации выполняются на сервере Ubuntu.
-
-## Требования PHP
-
-Чтобы установить все необходимые библиотеки, выполните следующие команды в терминале:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-zip php-imap php-mbstring php-curl
-sudo phpenmod imap mbstring
-sudo service apache2 restart
-```
-
-## Исправление проблемы «Ошибка API: API EspoCRM недоступен»:
-
-Принимайте только необходимые меры. После каждого шага проверяйте, решена ли проблема.
-
-### 1. Включите поддержку «mod_rewrite» в Apache
-
-Чтобы включить «mod_rewrite», выполните следующие команды в терминале:
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Включите поддержку .htaccess
-
-Чтобы включить поддержку .htaccess, добавьте/измените параметры конфигурации сервера /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf или /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Затем выполните эту команду в терминале:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Добавьте путь RewriteBase
-
-Откройте файл /ESPOCRM_DIRECTORY/api/v1/.htaccess и замените следующую строку:
-
-```
-# RewriteBase /
-```
-
-на
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-где REQUEST_URI является частью URL, например, для «http://example.com/espocrm/» REQUEST_URI - «espocrm».
-
-
-## Включите поддержку HTTP AUTHORIZATION (только для FastCGI).
-
-FastCGI по умолчанию не поддерживает HTTP AUTHORIZATION. Если вы используете FastCGI, вы должны включить её в VirtualHost или /etc/apache2/apache2.conf (httpd.conf), добавив следующий код:
-
-Для модуля Fcgid:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Для модуля FastCgi:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Чтобы проверить, какой модуль используется в настоящее время, выполните эту команду и найдите модуль:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/ru_RU/administration/b2c.md b/i18n/ru_RU/administration/b2c.md
deleted file mode 100644
index 7f109a289..000000000
--- a/i18n/ru_RU/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Конфигурация EspoCRM для B2C (бизнес-клиент)
-
-По умолчанию EspoCRM настроен для использования в B2B. Но вы можете легко настроить его для B2C.
-
-* Измените `b2cMode` на true в файле вашей конфигурации `data/config.php`. Начиная с версии 4.3.0 его можно настроить в Administration > Setings.
-* Удалите вкладку «Контрагенты» в меню навигации (Администрирование > Интерфейс пользователя).
-* Удалите поля «Контрагентов» из расположения (Администрирование > Управление макетами).
-* Отключите доступ к контрагентам для всех своих ролей (Администрирование > Роли).
-* Удалите учетную запись из списков всех исходных полей (Администрирование > Управление объектами > {Встреча/Вызов/Задача/Электронная почта} > Поля > Исходные).
diff --git a/i18n/ru_RU/administration/backup-and-restore.md b/i18n/ru_RU/administration/backup-and-restore.md
deleted file mode 100644
index 134a09fd2..000000000
--- a/i18n/ru_RU/administration/backup-and-restore.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# Резервное копирование и восстановление
-
-## Как создать резервную копию EspoCRM вручную
-
-EspoCRM состоит из файлов и информации базы данных. Все эти данные необходимы для создания полной резервной копии EspoCRM. Вот инструкции о том, как это сделать на сервере Ubuntu с MySQL.
-
-### Шаг 1. Резервное копирование файлов
-
-Создайте архив содержимого каталога установленного EspoCRM. Для Ubuntu путь по умолчанию - `/var/www/html`. Вы можете использовать эту команду:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Шаг 2. Резервное копирование базы данных
-
-Чтобы создать резервную копию всех ваших данных, вам необходимо узнать имя базы данных и получить доступ к учетным данным. Имя базы данных можно найти в файле конфигурации `/ESPOCRM_DIRECTORY/data/config.php` в разделе `database`. Вы можете использовать эту команду для резервного копирования вашей базы данных:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Шаг 3. Скопируйте резервную копию
-
-Это все. Теперь вам нужно скопировать созданную резервную копию в безопасное место.
-
-## Как создать резервную копию EspoCRM, используя скрипт
-
-Вы можете использовать скрипт для резервного копирования всех необходимых данных. Войдите через SSH и запустите команды (протестированные на сервере Ubuntu).
-
-### Скачайте скрипт
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Запустите скрипт
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-где
- * `PATH_TO_ESPOCRM` путь к установленному каталогу EspoCRM.
- * `BACKUP_PATH` путь к каталогу резервных копий.
-
-Для сервера Ubuntu:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Примечание. Если ваш пользователь MySQL не имеет необходимых прав для выгрузки базы данных, вам будет предложено ввести учетные данные другого пользователя MySQL.
-
-После успешного создания, вы получите путь к созданной резервной копии.
-
-## Восстановление EspoCRM из резервной копии
-
-Вы можете восстановить EspoCRM из резервной копии, созданной, как описано выше.
-
-### Шаг 1. Разархивируйте файлы резервной копии
-
-Чтобы распаковать файлы, вы можете использовать Archive Manager или выполнить команду ниже. Файлы необходимо размещать в каталоге веб-сервера.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-где:
- * `/var/www/html` это директория сервера.
-
-### Шаг 2. Установите необходимые разрешения
-
-Файлы должны принадлежать пользователю веб-сервера и иметь правильные разрешения. Установите необходимые разрешения, следуя этой [инструкции] (server-configuration.md#user-content-требуемые-разрешения-для-систем-на-основе-unix).
-
-### Шаг 3. Импортируйте дамп базы данных
-
-Дамп базы данных должен быть импортирован в ту же базу данных с теми же учетными данными пользователя, иначе исправление должно быть сделано в файле конфигурации «ESPOCRM_DIRECTORY/data/config.php». Чтобы импортировать вашу базу данных из дампа, выполните следующую команду в терминале:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### Шаг 4. Проверьте/настройте crontab
-
-Проверьте, правильно ли настроен ваш crontab. Выполните приведенную ниже команду и проверьте правильность пути к EspoCRM:
-
-```bash
-sudo crontab -l -u www-data
-```
-где:
- * `www-data` ваш пользователь сервера.
-
-Если вам нужно внести какие-либо изменения, используйте эту команду:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Более подробная информация о настройке crontab для EspoCRM описана [здесь](server-configuration.md#user-content-настройка-crontab).
diff --git a/i18n/ru_RU/administration/bpm.md b/i18n/ru_RU/administration/bpm.md
deleted file mode 100644
index b8de1f046..000000000
--- a/i18n/ru_RU/administration/bpm.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# Управление Бизнес-Процессами
-
-Инструмент управления бизнес-процессами (BPM) предоставляет возможность моделировать и автоматизировать бизнес-процессы в EspoCRM. Это определнного рода двигатель, выполняющий бизнес-процессы, описанные в стандарте BPMN 2.0. Инструмент BPM доступен в расширении [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-
-
-### Основное отличие от инструмента Workflows
-
-Инструмент Workflows предназначен для автоматизации простых бизнес-правил, без последовательных элементов потока, когда нет необходимости отображать поток графически.
-
-Инструмент BPM предназначен для более сложных бизнес-потоков, где могут быть расходящиеся и сходящиеся потоки, задержки выполнения, взаимодействие пользователей. Представление блок-схемы делает бизнес-процесс более понятным для человека, а журнал позволяет увидеть, как был проведен этот процесс.
-
-## Блок-схемы процессов (Process Flowcharts)
-
-Блок-схемы процессов доступны на панели администрирования. Они также могут быть добавлены в виде вкладки на панель навигации.
-
-Блок-схемы предназначены для моделирования бизнес-процессов. Администратор может создавать и редактировать блок-схемы. Обычные пользователи могут только просматривать блок-схемы.
-
-Каждая блок-схема имеет свой тип конкретного объекта (поле Target Type). Блок-схема определяет выполнение будущих экземпляров процессов. Она содержит элементы блок-схемы и соединения между элементами.
-
-Если в блок-схеме процесса снят флажок поля "Активно" ("Is Active"), она не будет инициировать экземпляры процессов.
-
-Чтобы показать детали и параметры определенного элемента блок-схемы, вам нужно щелкнуть по нему. В режиме редактирования вы сможете редактировать параметры.
-
-## Процессы
-
-Процессы доступны в панели администрирования. Они также могут быть добавлены в виде вкладки на панель навигации.
-
-Процесс представляет собой экземпляр бизнес-процесса. Когда он инициируется, он получает статус «Запущен». Когда процесс завершен, он получает статус «Завершен». Процесс также может быть остановлен вручную пользователем, у которого есть доступ к редактированию процесса. Если он остановлен вручную, он получает статус «Остановлен».
-
-Процесс выполняется в соответствии с блок-схемой. Блок-схема процесса не может быть изменена после запуска процесса.
-
-Процесс обязательно связан с одной целевой записью.
-
-Процессы могут запускаться автоматически (при определенных условиях или по расписанию) или вручную (где в блок-схеме есть хотя бы одно стартовое событие). Чтобы запустить процесс вручную, пользователю необходимо нажать кнопку «Начать процесс» в самом списке процессов.
-
-## Элементы блок-схемы
-
-### События
-
-События отображаются на блок-схеме в виде кругов.
-
-#### Стартовое событие
-
-Не имеет параметров. Это отправная точка процесса. Стартовое событие может быть инициировано вручную пользователем, у которого есть доступ к созданию процессов. Пользователь должен нажать кнопку «Начать процесс» в представлении списка процессов.
-
-#### Условное стартовое событие
-
-Отправная точка процесса. Она должна срабатывать автоматически при соблюдении определенных условий. Существует два типа триггера: «После создания записи», «После сохранения записи».
-
-#### Стартовое событие-таймер
-
-Отправная точка процесса. Она инициирует процессы путем планирования. Вам нужно указать отчет-список, который возвращает записи для инициирования процессов и планирования в нотации crontab.
-
-#### Промежуточное условное событие
-
-Это событие останавливает поток до тех пор, пока не будут выполнены указанные критерии.
-
-#### Промежуточное событие-таймер
-
-Это событие останавливает поток и ждет, до тех пор, пока это указано в параметрах события.
-
-Для более сложных настроек таймера вы можете использовать [formula](formula.md). Сценарии формул должны возвращать значение Date-Time (в часовой пояс UTC). По истечении этого времени поток будет переходить к следующему элементу.
-
-Используя функцию datetime\closest formula, можно установить таймер на определенное время в будущем, например: начало следующего рабочего дня.
-
-#### Конечное событие
-
-Завершает текущий поток. Это не приводит к параллельной работе потоков. Когда поток достигнет конечного события, и ничто не работает параллельно, тогда процесс заканчивается.
-
-#### Завершающие конечное событие
-
-Завершает все потоки. Процесс заканчивается.
-
-### Шлюзы
-
-Шлюзы отображаются в виде ромбов.
-
-#### Эксклюзивный шлюз
-
-Может разводить или сводить потоки.
-
-В случае расхождения определяется один поток (путь), который будет выбран в соответствии с указанными критериями. Первое условие выполнения определяет поток, а следующие условия опускаются. Существует возможность указать поток по умолчанию. Поток выбирается по умолчанию, если нет каких-либо условий. Поток по умолчанию отмечен косой чертой. Должно быть как минимум два исходящих потока, чтобы можно было указывать расходящиеся критерии.
-
-В случае слияния он просто направляет поток в исходящий элемент. Он не блокируется после потока, но параллельные потоки не будут объединены в один поток.
-
-
-
-
-
-#### Включающий шлюз
-
-Может разводить или сводить потоки.
-
-В случае расхождения он может направлять один или несколько параллельных потоков (путей) в зависимости от выполнения критериев каждого потока. Поток выбирается по умолчанию, если нет каких-либо условий. Поток по умолчанию отмечен косой чертой.Должно быть как минимум два исходящих потока, чтобы можно было указывать расходящиеся критерии.
-
-Если возникает необходимость объединить параллельные потоки, создаваемые расходящимся включающим шлюзом, вам необходимо использовать конвергентный включающий шлюз. Он будет ожидать все входящие потоки, а затем продолжит исходящий элемент.
-
-
-
-Примечание. Расходящиеся и сходящиеся шлюзы должны быть сбалансированы.
-
-Примечание. Если по какой-то причине один из параллельных потоков был закончен, то расходящийся шлюз никогда не будет обработан. Процесс будет заблокирован. Избегайте создания блок-схемы, которая может привести к такой ситуации.
-
-#### Параллельный шлюз
-
-Может разводить или сводить потоки.
-
-В случае расхождения он разбивает поток на несколько параллельных потоков. Для этого типа шлюза нет параметров.
-
-В случае слияния он ожидает, пока все входящие потоки придут, а затем перейдут к следующему исходящему элементу.
-
-
-
-Примечание. Расходящиеся и сходящиеся шлюзы должны быть сбалансированы.
-
-Примечание. Если по какой-то причине один из параллельных потоков был закончен, то расходящийся шлюз никогда не будет обработан. Процесс будет заблокирован. Избегайте создания блок-схемы, которая может привести к такой ситуации.
-
-#### Шлюз на основе события
-
-Может только разводить потоки.
-
-Он останавливает поток до тех пор, пока не произойдет срабатывание какого-либо из исходящих событий. Триггерное событие определяет единственный поток. Другие исходящие события отклоняются.
-
-На другом конце потоков исходящей последовательности могут быть только промежуточные события.
-
-
-
-### Действия
-
-Действия отображаются как закругленные прямоугольники.
-
-#### Задача
-
-Задача может выполняться после действий:
-
-* Создать запись - создает новую запись любого типа сущности;
-* Создать соответствующую запись - создает новую запись, связанную с целевой записью;
-* Обновить целевую запись;
-* Обновить соответствующую запись - обновляет запись или записи, связанные с целевой записью;
-* Обновить созданную запись - обновляет определенное поле любой записи, созданной в текущем процессе;
-* Обновить запись процесса - может использоваться для назначения процесса конкретному пользователю или команде;
-* Связать с другой записью - связывает целевую запись с указанной записью;
-* Отменить связь с другой записью - отменить целевую запись из указанной записи;
-* Применить правило назначения - назначает целевую запись, запись процесса или любую запись, созданную процессом в соответствии с конкретным правилом;
-* Создать оповещение - создает оповещение в приложении для определенных пользователей;
-* Подписать - подписывает конкретных пользователей на целевую запись, запись процесса или любую запись, созданную процессом;
-* Выполнить определенное действие службы (Run Service Action) - запускает пользовательские действия службы, реализованные разработчиками.
-
-Действия, доступные для задачи, почти такие же, как в функции Workflow. Подробнее о [функции Workflows](workflows.md/#user-content-действия).
-
-#### Задача «Отправить сообщение»
-
-Отправляет электронное сообщение конкретному получателю.
-
-#### Пользовательская задача
-
-Обеспечивает гибкую способность взаимодействия с пользователем. Она прекращает выполнение до тех пор, пока пользователь (заданный точно или по назначению) не разрешит задачу. В системе будет создана запись пользовательской задачи процесса. По умолчанию существует три типа действий: Утверждение, Просморт, Выполнение.
-
-* Тип утверждения требует, чтобы пользователь выбирал между «Approved» и «Declined».
-* Тип просмотр дает только один вариант: «Просмотренный».
-* Тип выполнения имеет два варианта: «Завершено» и «Сбой».
-
-
-Пользователь, назначенный для созданной записи пользовательской задачи процесса, получит уведомление в приложении. Администратор также может включать уведомления по электронной почте.
-
-Пользователи также могут добавить виджет Process User Tasks на свою панель виджетов, чтобы увидеть их реальные задачи пользователя процесса.
-
-Можно увидеть разрешение пройденной задачи пользователя в расходящихся шлюзах или условных событиях, что делает разветвление в потоке процесса.
-
-#### Задача-скрипт
-
-Выполняет скрипт на языке [espo-formula](formula.md). Все заданные переменные (`$variableName`) будут сохранены и доступны в процессе.
-
-### Потоки
-
-#### Поток операций
-
-Представляет собой сплошную стрелу. Указывает порядок, в котором будут выполняться элементы процесса.
-
-## Условия
-
-Условные события, эксклюзивные и включающие расходящиеся шлюзы имеют условия, которые определяют поток процесса.
-
-Через интерфейс пользователя можно проверить условия для следующих записей:
-
-* Целевая запись;
-* Записи, относящиеся к цели через отношения «один-к-одному» и «от ребенка к родителям»;
-* Записи, созданные процессом через задачи;
-* Записи пользовательских задач, которые позволяют проверять разрешение.
-
-Также можно определить условия на языке [Espo-formula](formula.md).
-
-Условия в BPM те же, что и в Workflow. Подробнее об этом в [условиях Workflows](workflows.md#user-content-условия).
-
-## Примеры
-
-### Пример 1
-
-
-
-### Пример 2
-
-
-
-### Пример 3
-
-
diff --git a/i18n/ru_RU/administration/dynamic-logic.md b/i18n/ru_RU/administration/dynamic-logic.md
deleted file mode 100644
index 606e16cb4..000000000
--- a/i18n/ru_RU/administration/dynamic-logic.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Логичность динамики (динамические формы)
-
-## Поля
-
-Динамическое поведение форм может быть достигнуто за счет использования функции Логичность динамики (Dynamic Logic). Параметры логичности динамики доступны для каждого поля. Параметры доступны в Управлении объектами при редактировании или создании поля.
-
-Логичность динамики позволяет определять условия, при которых определенные поля видны, обязательны или доступны только для чтения. Условия будут автоматически проверяться при изменении данных в форме.
-
-Для полей Список (Enum),Массив (Array) и Множественный список (Multi-Enum) можно определить различные наборы параметров, которые будут доступны для поля в зависимости от того, какое условие выполнено.
-
-Условия настраиваются с помощью пользовательского интерфейса, без необходимости кодирования.
-
-
-
-## Панели
-
-В Управлении макетами вы можете указать условия, делающие видимой конкретную панель. Доступно с версии 5.2.6.
diff --git a/i18n/ru_RU/administration/emails.md b/i18n/ru_RU/administration/emails.md
deleted file mode 100644
index 0fc98fae7..000000000
--- a/i18n/ru_RU/administration/emails.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Элекронные письма
-
-> Важно. [Cron](server-configuration.md#user-content-настройка-crontab) должен быть настроен в вашей системе, чтобы электронная почта работала. Вы можете найти информацию в EspoCRM в разделе Администрирование > Планировщик заданий.
-
-## Обзор
-
-EspoCRM предоставлеет возможность контролировать почтовые ящики IMAP. Электронная почта может быть заархивирована двумя способами: Учетные записи эл. почты групп и Учетные записи эл. почты пользователей. Учетные записи эл. почты групп предназначены для групповых почтовых ящиков: наиболее распространенным случаем является ящик для службы поддержки. Учетные записи эл. почты пользователей предназначены для личных почтовых ящиков пользователей.
-
-Когда приходит электронное письмо, система пытается связать его с соответствующей записью (Контрагент, Кандидат, Сделка, Обращение). Пользователи, которые следят за этой записью, получат уведомление о новом электронном письме в системе, даже если их данные не находятся в полях "Кому" или "CC".
-
-Обратите внимание, что записи электронной почты не дублируются для разных пользователей. Если вы удалите запись электронной почты из crm, она будет удалена для всех пользователей. Вместо этого рекомендуется использовать перемещение в корзину. Доступ к "Удалению" ограничен для обычных пользователей по умолчанию.
-
-## Учетные записи эл. почты групп
-
-Только администратор может настроить учетные записи эл. почты групп. Учетные записи эл. почты групп могут использоваться как для получения, так и для отправки электронных писем. Отправка писем из групповых аккаунтов доступна с версии 4.9.0.
-
-Поле «Группы» определяет, каким командам будут назначены входящие электронные письма.
-
-Если учетная запись эл. почты группы имеет SMTP и она отмечена как общая, то доступ будет контролироваться ролями через разрешение учетной записи эл. почты группы. Поле «Группы» будет использоваться, если уровень разрешений установлен на «группа».
-
-Существует возможность заставить систему автоматически отвечать на входящих писем.
-
-## Email-to-Case
-
-Существует возможность настроить систему для создания обращений из входящих групповых электронных писем.
-Эта функция предназначена для служб поддержки.
-Обращения могут быть распределены среди пользователей из указанной группы в соответствии с этими способами:
-`direct assignment`, `round-robin` и `less-busy`.
-Только первое письмо в теме создает новый случай.
-Каждое последующие будет связано с существующей записью обращения и отображено на панели «Лента».
-
-Когда пользователи хотят отправить ответ клиенту, они должны убедиться, что обращение выбрано в качестве родителя отправляемого электронного письма. Тогда клиент будет отвечать на электронный адрес группы, а не на собственный адрес пользователя.
-
-## Учетные записи эл. почты пользователей
-
-Пользователи могут настроить свои собственные учетные записи электронной почты, которые будут контролироваться. Электронная почта > Вверху справа выпадающее меню > Учетные записи эл. почты пользователей. Администратор также может управлять учетными записями электронной почты пользователей.
-
-## Фильтры электронной почты
-
-Они позволяют фильтровать входящие электронные письма в соответствии с указанными критериями. Например. если вы не хотите, чтобы уведомления, отправленные каким-либо приложением, импортировались в EspoCRM, вы можете создать фильтр, чтобы EspoCRM пропускал их.
-
-Администратор может создавать глобальные фильтры, применяемые ко всем учетным записям электронной почты. Пользователи могут создавать фильтры для своей учетной записи эл. почты пользователя и для всех входящих писем.
diff --git a/i18n/ru_RU/administration/entity-manager.md b/i18n/ru_RU/administration/entity-manager.md
deleted file mode 100644
index a6f0658aa..000000000
--- a/i18n/ru_RU/administration/entity-manager.md
+++ /dev/null
@@ -1,142 +0,0 @@
-# Управление объектами
-
-Управление объектами доступно в панели администрирования. Оно обеспечивает возможность детальной настройки вашего EspoCRM. Вы можете сделать следующее:
-
-* Добавить новые типы объектов.
-* Настроить существующие типы объектов: изменение меток, порядок по умолчанию в представлении списка, включение или отключение ленты.
-* Настроить поля: добавить новые, настроить существующие.
-* Настроить отношения: добавить новые, изменить метки существующих.
-
-## Создание нового объекта
-
-Нажмите кнопку `Создать объект` на странице управления объектами. Укажите имя, метки и тип. Если вы выбираете `личность`, тогда вы должны указать поля: адрес электронной почты, телефон, фамилию, имя и обращение. Установите флажок `лента`, если вы хотите, чтобы ваш объект имел панель "Лента", а пользователи могли подписываться на объекты этого типа.
-
-Типы:
-
-* База - пустой объект только с базовыми полями, такими как имя, ответственный, группы, описание.
-* База плюс - такой же как база, но с панелями "Действия", "История", "Задачи" (доступно с 4.3.0).
-* Событие - поля: дата начала, дата окончания, длительность, источник, статус. Доступно в панели "Календарь" и "Действия" (начиная с 4.3.0, должно быть включено в Администрирование > Настройки).
-* Личность - поля: адрес эл. почты, телефон, имя, фамилия, обращение, адрес. Панели: "Действия", "История", "Задачи".
-* Компания -поля: адрес эл. почты, телефон, платежный адрес, почтовый адрес. Панели: "Действия", "История", "Задачи".
-
-## Параметры типа объекта
-
-Если Вы нажмете ссылку `редактировать` на определенном объекте, вы сможете изменить некоторые параметры этого объекта.
-
-* Метки - единственное и множественное название объекта.
-* Сортировка по умолчанию - как записи сортируются в представлении список.
-* Лента - включена ли функция ленты для этого объекта.
-* Отключено - установите флажок, если вам не нужна эта сущность в вашей системе.
-* Поля текстового фильтра - в каких полях искать в основном текстовом фильтре и глобальном поиске.
-* Kanban view - доступно, только если указано Поле статуса. Включает режим просмотра Kanban. (начиная с версии EspoCRM 5.2.0)
-* Цвет - это определенный цвет для быстрого распознавания. (начиная с версии EspoCRM 5.2.0)
-* Значок - выбранный значок отображается на боковой панели навигации в вертикальной теме. (начиная с версии EspoCRM 5.2.0)
-
-## Поля
-
-Нажав ссылку `Поля`, вы перейдете на отдельную страницу. Там вы сможете создавать новые поля или обновлять существующие. В Entity Manager доступны следующие типы полей:
-
-### Адрес
-
-Адрес улицы, города, штата, почтового индекса и страны.
-
-### Массив
-
-Список значений, с возможностью выбора нескольких значений. Пользователи могут добавлять свои собственные значения, если параметры не указаны. Аналогичен полю Множественный список (Multi-Enum).
-
-### Несколько вложений
-
-Несколько файловых вложений.
-
-### Автоинкрементый
-
-Генерируемое целое число только для чтения.
-
-### Boolean
-
-Флажок, true или false.
-
-### Валюта
-
-Для валютных значений.
-
-### Дата
-
-Дата без временной части.
-
-### Дата-время
-
-Дата с временной частью.
-
-### Список
-
-Поле для выбора, с возможностью выбрать только одно значение.
-
-### Файл
-
-Загрузка одного файла.
-
-### Десятичная дробь
-
-Число с десятичной частью.
-
-### Внешний
-
-Отображает значение определенного поля связанной записи. Возможен поиск по внешним полям. Только для чтения.
-
-### Изображение
-
-Загрузка файла изображения с предварительным просмотром.
-
-### Целое число
-
-Целое число.
-
-### Номер
-
-Автоинкрементное число строкового типа с возможным префиксом и определенной длиной.
-
-### Множественный список
-
-Список значений, с возможностью выбора нескольких значений, аналогичный массиву, но лучше. Пользователи могут добавлять свои собственные значения, если параметры не указаны или установлен флажок «Разрешить пользовательские параметры».
-
-### Текст
-
-Текстовая область, для длинных многострочных текстов.
-
-### Url
-
-Для ссылок.
-
-### Строка
-
-Короткий текст.
-
-### Редактор
-
-Подобно текстовому полю, с возможностью форматирования текста.
-
-Параметры:
-* Обязательное поле - обязательно ли заполнение поля.
-* Значение по умолчанию - значение поля, установленное при создании новой записи.
-* Аудит (отслеживать изменения значений) - обновления поля будут регистрироваться в ленте.
-
-**Примечание**: После того, как вы добавили новое поле, вам нужно поместить это поле в [layouts](layout-manager.md) (Администрирование > Управление макетами).
-
-### Динамическая логика
-
-Предоставляет возможность делать формы динамическими. Можно определить условия, при которых определенные поля видимы, обязательны или доступны только для чтения. Условия будут автоматически проверяться при изменении данных в форме.
-
-Для полей Список (Enum), Массив (Array) и Множественный список (Multi-Enum) можно определить различные наборы параметров, которые будут доступны для поля в зависимости от того, какое условие выполнено. Подробнее [здесь](dynamic-logic.md).
-
-## Отношения
-
-Вы можете создавать новые отношения между как готовыми, так и пользовательскими объектами. Существует 3 доступных типа отношений:
-
-* Один-ко-многим: после того, как вы создали это отношение, вы можете поместить поле ссылки в макет детали правого объекта сущности и добавить панель отношений в левой объект;
-* Много-к-одному: то же, что и «Один-ко-многим», но наоборот;
-* Многие-ко-многим: панели отношений с обеих сторон.
-
-Параметр «Link Multiple Field» подразумевает, что поле типа linkMultiple будет создано вместе с отношением. Это поле можно разместить на макете. Это удобно для быстрого сбора связанных записей. Это не очень хороший вариант, если ваши отношения предназначены для того, чтобы иметь множество связанных записей, которые могут замедлить загрузку экрана вида детализации.
-
-Если установлен параметр «Проверено», то обновления отношения будут регистрироваться в ленте.
diff --git a/i18n/ru_RU/administration/extensions.md b/i18n/ru_RU/administration/extensions.md
deleted file mode 100644
index 84f75e99a..000000000
--- a/i18n/ru_RU/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Управление расширениями
-
-## Как установить расширение
-
-Чтобы установить расширение EspoCRM (например: Advanced Pack, VoIP Integration):
-
-1. Войдите в систему как администратор.
-2. Перейдите в раздел Администрирование > Расширения.
-3. Загрузите свой дополнительный пакет (zip-файл).
-4. Нажмите кнопку «Установить».
-
-
-## Как обновить расширение
-
-Чтобы обновить уже установленное расширение (например: Advanced Pack, VoIP-интеграция) до более новой версии:
-
-1. Загрузите новую версию необходимого расширения.
-2. Войдите в систему как администратор.
-3. Перейдите в раздел Администрирование > Расширения.
-4. Загрузите новый пакет расширения (zip-файл) без удаления ранее установленной версии.
-5. Нажмите кнопку «Установить».
-
-
-## Как удалить установленное расширение
-
-Действия по удалению ранее установленного расширения:
-
-1. Войдите в систему как администратор.
-2. Перейдите в раздел Администрирование > Расширения.
-3. Найдите необходимое расширение в списке доступных расширений.
-4. Нажмите кнопку «Удалить».
-
-
-## Как удалить расширение
-
-Когда расширение удаляется, оно все еще доступно в системе. Оно может быть полностью удалено. Шаги по полному удалению расширения:
-
-1. Войдите в систему как администратор.
-2. Перейдите в раздел Администрирование > Расширения.
-3. Найдите необходимое расширение в списке доступных расширений.
-4. Нажмите кнопку «Удалить».
diff --git a/i18n/ru_RU/administration/formula.md b/i18n/ru_RU/administration/formula.md
deleted file mode 100644
index 776f95135..000000000
--- a/i18n/ru_RU/administration/formula.md
+++ /dev/null
@@ -1,333 +0,0 @@
-# Вычисляемые поля (формула)
-
-В управлении объектами можно определить скрипт (формулу) для конкретного типа сущности. Этот скрипт будет выполняться каждый раз перед сохранением записи. Он предоставляет возможность автоматически устанавливать полученные из расчета значения для конкретных полей (атрибутов).
-
-Чтобы изменить формулу, перейдите в Администрирование > Управление объектами > выпадающее меню справа в строке нужного объекта > Формула.
-
-Вам также может понадобиться установить поля, которые должны быть вычеслены,"Только чтение" в Управлении объектами.
-
-
-## Синтаксис
-
-Формула EspoCRM написана на простом языке, разработанном специально для этой функции.
-
-Существуют операторы, атрибуты функций и значения, которые можно использовать в формуле. Разделенные выражения должны быть разделены символом `;`.
-
-### Operators
-
-* `=` - назначение.
-* `||` - логическое ИЛИ,
-* `&&` - логическое И,
-* `!` - логическое НЕ,
-* `+`- числовое суммирование,
-* `-` - числовое вычитание,
-* `*` - числовое умножение,
-* `/` - числовое деление,
-* `%` - numeric modulo,
-* `==` - сравнение равно,
-* `!=` - сравнение не равно,
-* `>` - сравнение больше чем,
-* `<` - сравнение меньше чем,
-* `>=` - сравнение больше чем или равно,
-* `<=` - Сравнение меньше чем или равно.
-
-Приоритет операторов:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Атрибуты
-
-Атрибуты представляют значения полей целевого объекта. Вы можете вставить доступные атрибуты, нажав на кнопку «плюс».
-
-Можно получить доступ к атрибутам связанных объектов в следующем формате `linkName.attributeName`.
-
-
-### Функции
-
-Формат использования функции: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Готовые функции перечислены ниже.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` Если Условие (CONDITION) выполнено, тогда выполнить Следующие (CONSEQUENT). Если нет - выполнить Альтернативное (ALTERNATIVE).
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` Если Условие (CONDITION) выполнено, тогда выполнить Следующие (CONSEQUENT). Если нет - не выполнять ничего.
-
-#### string\concatenate
-`string\concatenate(STRING_1, STRING_2)` Объединяет две или более строки.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Извлекает символы из строки (STRING) по позиции START и LENGTH.
-
-Если LENGTH опущена, будет возвращена подстрока, начинающаяся с START до конца строки (STRING).
-
-Если LENGTH отрицательна, то столько же символов будет опущено в конце строки (STRING).
-
-#### string\contains
-`string\contains(STRING, NEEDLE)` Содержит ли строка (STRING) иглу (NEEDLE). (начиная с версии 5.1.2)
-
-#### string\test
-`string\test(STRING, REGULAR_EXPRESSION)` Поиск соответствия между REGULAR_EXPRESSION и STRING. (начиная с версии 5.5.2)
-
-#### string\length
-`string\length(STRING)` Длина строки (STRING). (начиная с версии 5.1.2)
-
-#### string\trim
-`string\trim(STRING)` Удаляет пробелы с начала и конца строки (STRING).
-
-#### string\lowerCase
-`string\lowerCase(STRING)` Преобразует буквы в нижний регистр. (начиная с версии 5.0.0)
-
-#### string\upperCase
-`string\upperCase(STRING)` Преобразует буквы в верхний регистр. (начиная с версии 5.0.0)
-
-#### datetime\today
-`datetime\today()` Возвращает сегодняшнюю дату.
-
-#### datetime\now
-`datetime\now()` Возвращает текущую дату и время.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Преобразует дату или дату и время в значение (VALUE), отформатированное в соответствии с настройками приложения или заданным часовым поясом и форматом. TIMEZONE и FORMAT могут быть опущены. Если TIMEZONE не указан, будет использоваться часовой пояс по умолчанию. Если FORMAT опущен, будет использоваться формат по умолчанию.
-
-Примеры:
-
-`datetime\format(closeDate, 'America/New_York', 'MM/DD/YYYY')`
-
-`datetime\format(dateStart, 'America/New_York', 'MM/DD/YYYY hh:mma')`
-
-`datetime\format(dateStart, 'Europe/Amsterdam', 'DD/MM/YYYY HH:mm')`
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Возвращает дату месяца (1-31). `0`, если значение (VALUE) пусто. Если часовой пояс (TIMEZONE) не указан, то используется системный часовой пояс. (начиная с версии 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Возвращает месяц (1-12). `0`, если значение (VALUE) пусто. Если часовой пояс (TIMEZONE) не указан, то используется системный часовой пояс. (начиная с версии 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Возвращает год. `0`, если значение (VALUE) пусто. Если часовой пояс (TIMEZONE) не указан, то используется системный часовой пояс. (начиная с версии 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Возвращает час (0-23). `-1` если значение (VALUE) пусто. Если часовой пояс (TIMEZONE) не указан, то используется системный часовой пояс. (начиная с версии 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Возвращает минуту (0-59). `-1` если значение (VALUE) пусто. Если часовой пояс (TIMEZONE) не указан, то используется системный часовой пояс. (начиная с версии 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Возвращает день недели (0-6). `-1`, если значение (VALUE) пусто. `0` - на воскресенье. Если часовой пояс (TIMEZONE) не указан, то используется системный часовой пояс. (начиная с версии 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Возвращает разницу между двумя датами или датами и временем. INTERVAL_TYPE может быть 'years', 'months', 'days', 'hours', 'minutes'. Возвращает `null`, если ошибка. Результат будет отрицательным, если VALUE_1 ', 1000)`
-
-`record\count('Opportunity', 'open')`
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Возвращает атрибут (ATTRIBUTE) текущего пользователя.
-
-Пример:
-
-`env\userAttribute('id')` - ID текущего пользователя.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Возвращает массив. (начиная с версии 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Возвращает true, если список (LIST) содержит значение (VALUE). Может использоваться для полей Array и Multi-Enum. (начиная с версии 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Добавляет один или несколько элементов в конец массива и возвращает новый массив. (начиная с версии 5.0.0)
-
-#### array\length
-`array\length(LIST)` Возвращает количество элементов в списке (LIST). (начиная с версии 4.8.1)
-
-
-### Значения
-
-* Строки. Например, 'some string';
-* Целые числа. Например, 1, 100, 40300.
-* Числа с плавающей точкой. Например, 5.2.
-
-### Переменные
-
-Можно определить пользовательские переменные в формуле.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Примеры
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Использование формулы в рабочих потоках
-
-Вы можете использовать формулу в условиях и действиях рабочего потока. Смотрите [workflows documentation](workflows.md) для получения дополнительной информации.
diff --git a/i18n/ru_RU/administration/import.md b/i18n/ru_RU/administration/import.md
deleted file mode 100644
index 5e6c66b29..000000000
--- a/i18n/ru_RU/administration/import.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Импорт
-Предоставляет возможность импортировать записи из файлов CSV.
-
-Примечание. До версии 5.4.0 импорт был доступен только для администраторов.
-
-Администратор может получить доступ к импорту в разделе Администрирование > Импортирование. По умолчанию обычные пользователи не имеют доступа. Это может быть предоставлено с ролями ACL. Администратор также может добавить вкладку «Импорт» в разделе Администрирование > Интерфейс пользователя > Список вкладок.
-
-## Шаг 1
-
-Выберите тип записей, которые необходимо импортировать (поле Тип объекта).
-Выберите файл CSV. Файл должен быть сформирован с помощью `UTF-8`.
-Выберите `Что делать?`. Доступные опции: `Только создать`, `Создать и обновить`, `Только обновить`.
-
-* `Только создать` - выберите его, если вы хотите, чтобы запись создавалась только.
-* `Создать и обновить` - будут созданы записи, но если будут найдены записи с соответствующими значениями полей, они будут обновлены. Вы сможете выбрать, какие поля должны совпадать в _Шаге 2_.
-* `Только обновить` - будут найдены только записи с соответствующими значениями полей, которые будут обновлены.
-
-После выбора файла csv вы сможете увидеть, как его следует анализировать в панели предварительного просмотра. Когда вы меняете свойства, предварительный просмотр будет обновлен.
-
-* `Есть строка заголовков` - имеет ли CSV-файл первую строку с именами полей.
-* `Выполнять в фоновом режиме` - рекомендуется, если у вас большая группа записей для импорта. Импорт будет обрабатываться через cron. При завершении процесса импорта статус будет установлен на Завершен.
-* `Пропустить поиск дубликатов` - это уменьшит время выполнения импорта.
-
-Нажмите кнопку _Далее_, чтобы перейти к _Шагу 2_.
-
-
-
-## Шаг 2
-
-Настройте сопоставление полей: как поля соответствуют столбцам csv-файла. Здесь вы можете пропустить не нужные столбцы.
-В случаях `Создать и обновить` и `Только обновить` вам нужно будет указать поля, по которым будут обновляться записи, которые должны быть обновлены.
-
-Например. Если вы выберете параметр «Обновить по» для поля «Имя», то записи с соответствующим именем будут обновлены.
-
-Добавьте значения по умолчанию для новых и обновленных записей. Например, вы можете указать поля «Ответственный» или «Группы».
-
-После того, как импорт будет выполнен, вы сможете вернуть созданные записи, просмотреть дубликаты и обновленные записи. Дубликат означает, что в системе была аналогичная запись. Вы можете сразу удалить все импортированные дубликаты. Примечание. Возврат не работает с обновленными записями.
-
-Нажмите кнопку _Импортировать_, чтобы продолжить. Это может занять некоторое время, прежде чем процесс импорта будет завершен. Если вы хотите импортировать большую группу записей (в зависимости от конфигурации вашего сервера, обычно, если более 200 записей), вам нужно убедиться, что параметр php `set_time_limit` достаточно велик.
-
-
-
-## Шаг 3
-
-После того, как записи импортированы, и вы уверены, что с импортированными данными все в порядке, вы можете «Удалить журнал импорта» (нажав кнопку в представлении результатов импорта), чтобы предотвратить случайный возврат импорта.
-
-## Как импортировать в целевой список
-
-При импорте контактов, кандидатов или контрагетов вы можете добавить их в какой-либо целевой список. На шаге 2 вам нужно добавить поле Target List на панели `Значения по умолчанию` и выбрать нужную запись списка целей. Вы также можете использовать импорт `Только обновить` или `Создать и обновить`, чтобы добавить существующие целевые объекты в целевой список.
diff --git a/i18n/ru_RU/administration/installation.md b/i18n/ru_RU/administration/installation.md
deleted file mode 100644
index 385728e42..000000000
--- a/i18n/ru_RU/administration/installation.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Установка
-
-### Требования
-EspoCRM работает на большинстве хостинг-провайдеров. Требования включают в себя следующее:
-
-* PHP 5.6 или последняя версия PHP с включенными pdo, json, GD-библиотекой, расширениями mcrypt (обычно включаются по умолчанию);
-* MySQL 5.5.3 или выше.
-
-Дополнительную информацию см. в статье [Конфигурация сервера](server-configuration.md).
-
-### 1. Загрузите установочный пакет EspoCRM
-Чтобы получить последнюю версию EspoCRM, перейдите по ссылке [download page](http://www.espocrm.com/download/).
-
-### 2. Загрузите файлы EspoCRM на ваш сервер
-
-После завершения скачивания, загрузите пакет на свой веб-сервер. Чтобы загрузить его, вы можете использовать SSH, FTP или панель администрирования хостинга. Извлеките архив в каталог общедоступного веб-сервера (например, `public_html`,` www` и т. д.).
-
-Примечание: для FTP вам необходимо перед загрузкой извлечь архив на веб-сервер.
-
-### 3. Создайте базу данных MySQL для использования EspoCRM
-
-Перейдите на панель администрирования вашего хостинга или в SSH и создайте новую базу данных и пользователя для EspoCRM (например, `Базы данных MySQL` в cPanel).
-
-### 4. Запустите процесс установки EspoCRM
-
-Теперь откройте свой веб-браузер и перейдите к URL-адресу с файлами EspoCRM (например,`http://yourdomain.com/espo`).
-
-Если вы видите этот экран, у вас есть ошибка «Разрешение отклонено». Таким образом, вам нужно выполнить отображаемую команду в терминале через SSH или установить правильное разрешение. Он должен быть 755 для каталогов, 644 для файлов и 775 для каталога `data`. Также убедитесь, что у вас есть правильные _owner_ и _group_.
-
-
-
-Если вы видите следующую картину, значит разрешение выбрано правильное разрешение, и вы можете начать установку EspoCRM.
-
-
-
-На этой странице вы можете прочитать и принять Лицензионное соглашение.
-
-
-
-Введите данные для вашей недавно созданной базы данных MySQL.
-
-
-
-Введите имя пользователя и пароль администратора EspoCRM.
-
-
-
-На этой странице вы можете установить настройки EspoCRM по умолчанию, такие как формат даты и времени, часовой пояс, валюта и другие.
-
-
-
-Введите SMTP-настройки для исходящих писем, если вы хотите иметь возможность отправлять электронные письма. Этот шаг можно пропустить, нажав кнопку _Next_. Все эти параметры могут быть добавлены/изменены в EspoCRM после установки.
-
-
-
-Поздравляю! Установка завершена. Последнее, что нужно настроить это запланированные задачи для вашей системы. Это можно сделать, запустив `crontab -e` в linux cli и в _Windows Tasks Scheduler_ в системах Windows.
-
-
-
-Надеемся, что вам понравится работать в EspoCRM.
diff --git a/i18n/ru_RU/administration/jobs.md b/i18n/ru_RU/administration/jobs.md
deleted file mode 100644
index e3246f1cf..000000000
--- a/i18n/ru_RU/administration/jobs.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Задания
-
-Задания предназначены для выполнения задач в фоновом режиме. Они обрабатывают такие операции, как отправка уведомлений, массовая рассылка, синхронизация, очистка и т.д.
-
-## Планировщик заданий
-
-Планировщик заданий предназначен для выполнения повторяющихся заданий. Планирование для конкретного задания может быть настроено администратором с использованием записи crontab.
-
-```
-* * * * *
-| | | | |
-| | | | |
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-```
-
-Если вы хотите, чтобы работа выполнялась как можно чаще, вам нужно установить расписание на `* * * * *`.
-
-## Настройка
-
-Есть два способа обработки заданий: crontab или daemon.
-
-### Cron
-
-Cron прост в настройке. Он поддерживается большинством хостинг-провайдеров.
-
-Смотрите, как настроить cron [здесь](server-configuration.md#user-content-настройка-crontab).
-
-В системах Unix cron должен запускаться не чаще, чем раз в минуту. Это ограничение можно обойти с помощью следующего трюка.
-
-Добавьте несколько строк в crontab с задержками в секундах:
-
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-* * * * * sleep 15; /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-* * * * * sleep 30; /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-* * * * * sleep 45; /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-
-Обратите внимание, что команда, которая запускает cron, отличается в зависимости от среды сервера.
-
-### Daemon
-
-Команда для запуска daemon с помощью nohup:
-
-```
-nohup php /path/to/espocrm/daemon.php &
-```
-
-Конфигурация для использования systemd:
-
-```
-[Unit]
-Description=EspoCRM Daemon Service
-Requires=mysql.service
-After=mysql.service
-
-[Service]
-Type=simple
-Restart=always
-RestartSec=5
-StartLimitInterval=0
-User=www-data
-ExecStart=/usr/bin/php /path/to/espocrm/daemon.php
-StandardError=/path/to/espocrm/data/logs/daemon.log
-
-[Install]
-WantedBy=default.target
-```
-
-Требуются расширения pcntl и posix, php 7.1 или новее. Windows не поддерживается.
-
-Рекомендуется включить обработку заданий в параллельных процессах: Администрирование > Планировщик заданий > Задания (в правом верхнем углу) > Настройки (в верхнем правом углу) > Задания, выполняемые параллельно.
-
-## Параллельное выполнение заданий
-
-По умолчанию задания выполняются одно за другим, что может вызвать ситуации, когда одно задание блокирует выполнение следующего задания на некоторое время (обычно это не более одной минуты). Чтобы избежать этого, можно запускать параллельное виполнение заданий. Параметр доступен в разделе Администрирование > Планировщик заданий > Задания в правом верхнем углу > Настройки в верхнем правом углу.
-
-Доступно начиная с версии 5.5.0.
-
-Требуются расширения pcntl и posix, php 7.1 или новее. Некоторые конфигурации серверов могут ограничивать возможность запуска дочерних процессов.
-
-Windows не поддерживается.
-
-## Смотрите также
-
-[Creating custom scheduled job](https://github.com/espocrm/documentation/blob/master/development/scheduled-job.md)
diff --git a/i18n/ru_RU/administration/layout-manager.md b/i18n/ru_RU/administration/layout-manager.md
deleted file mode 100644
index 19f0fb6d3..000000000
--- a/i18n/ru_RU/administration/layout-manager.md
+++ /dev/null
@@ -1,69 +0,0 @@
-# Управление макетами
-
-Управление макетами (Layout Manager) доступно в панели администрирования. Предоставляет возможность настройки внешнего вида представлений детализации, редактирования, списка, а также фильтров поиска и полей для форм массового обновления.
-
-## Список
-
-Основной макет представления списка. Определяет столбцы и их параметры.
-
-
-
-Доступные параметры для столбцов перечислены ниже.
-
-### Ширина (%)
-
-Ширина столбца в процентах, пустая означает стандартный размер.
-
-### Ссылка
-
-Если флажок установлен, то поле будет отображаться как ссылка на просмотр подробностей записи. Обычно используется для полей имен.
-
-### Не сортируемый
-
-Отключает возможность сортировки столбца.
-
-### Выровнять
-
-Выровнять столбец по левому или правому краю.
-
-## Детализация
-
-Основной макет для детального вида и вида редактирования. Определяет панели, строки и ячейки. Ячейки содержат поля.
-
-Строка может содержать две ячейки или одну ячейку, которая расширяется до полной ширины строки. Для добавления строки с развернутой ячейкой необходимо добавить новую строку и нажать на знак минус на любой ячейке.
-
-
-
-Для панелей можно указать название, цвет (стиль) и условия, делающие панель видимой (начиная с версии 5.2.6).
-
-## Список (сжатый)
-
-Макет списка для панели отношений. Также может использоваться в других местах, где целесообразно отображать списки в узком представлении.
-
-## Детализация (сжатая)
-
-Представление детализации для быстрого создания, быстрого просмотра и быстрого редактирования форм.
-
-## Фильтры поиска
-
-Список доступных полей в списке для поиска.
-
-## Массовое обновление
-
-Список полей, доступных в форме массовое обновление.
-
-## Панель отношений
-
-Список панелей отношений, отображаемых в виде сведений внизу. Панели можно упорядочить. Можно определить цвет панели с параметром Стиль.
-
-## Боковые панели
-
-Боковые панели для детализации, редактирования, детализации (сжатой), редактирования (сжатое). Предоставляет возможность скрывать или переупорядочивать список панелей действий, истории, задач и др. Панели могут быть раскрашены с помощью параметра Стиль.
-
-## Kanban
-
-Доступно для типов объектов с включенным представлением Kanban. (доступно с EspoCRM 5.2.0)
-
-## Дополнительные макеты
-
-Некоторые типы сущностей содержать дополнительные макеты: конвертировать кандидата, список для контрагентов.
diff --git a/i18n/ru_RU/administration/ldap-authorization-for-ad.md b/i18n/ru_RU/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index 6c1c51af5..000000000
--- a/i18n/ru_RU/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# LDAP авторизация для Active Directory
-Пример конфигурации LDAP авторизации для сервера Active Directory. Полное руководство по настройке LDAP авторизации описано [здесь](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/ru_RU/administration/ldap-authorization-for-openldap.md b/i18n/ru_RU/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index e7d7a4951..000000000
--- a/i18n/ru_RU/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# LDAP авторизация для OpenLDAP
-
-Пример конфигурации LDAP авторизации для сервера OpenLDAP. Полное руководство по настройке LDAP авторизации описано [здесь](ldap-authorization.md).
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/ru_RU/administration/ldap-authorization.md b/i18n/ru_RU/administration/ldap-authorization.md
deleted file mode 100644
index 1008b3120..000000000
--- a/i18n/ru_RU/administration/ldap-authorization.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Ldap Авторизация
-В этом руководстве мы покажем, как настроить авторизацию LDAP для EspoCRM. Поехали!
-
-Перейдите на сервер LDAP и создайте базовый DN для пользователей EspoCRM, например:
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Мы должны создать системного пользователя, который будет иметь доступ к DN пользователей (“cn=espo-users,ou=users,dc=espo,dc=local”). Итак, полное DN для этого системного пользователя будет:
-
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Теперь мы можем добавить пользователя LDAP для доступа к EspoCRM. Например, Espo Tester с именем пользователя “tester” внутри DN “cn=espo-users,ou=users,dc=espo,dc=local”. Обратите внимание: чтобы использовать этот формат входа для EspoCRM, вы должны указать опции “Username Attribute” и “Base DN”.
-
-Затем перейдите к настройкам аутентификации EspoCRM в панели администрирования, выберите метод `LDAP` и введите данные LDAP:
-
-
-
-* Сервер – LDAP IP или имя сервера.
-* Порт – порт подключения.
-* Аутентификация – учетные данные для доступа к серверу LDAP.
- * Full User DN – полный DN пользователя системы, который позволяет искать других пользователей.
- * Пароль – пароль для доступа к серверу LDAP.
-* Безопасность – протоколы SSL или TSL.
-* Атрибут имени пользователя - атрибут для идентификации пользователя. Для Active Directory это может быть “userPrincipalName” или “sAMAccountName”.
-* Account Canonical Form – тип вашей account canonical form. Есть 4 варианта:
- * Dn – форма в формате `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – форма `tester`.
- * Backslash – форма `COMPANY\tester`.
- * Principal – форма `tester@company.com`.
-* Привязка по домену – если есть необходимость отформатировать имя пользователя в форме DN.
-* Базовый домен – базовый DN по умолчанию, который используется для поиска пользователей.
-* Фильтр логина пользователя – фильтр, который позволяет ограничивать пользователей, которые могут использовать EspoCRM. Например, `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – домен, который используется для авторизации на сервере LDAP.
-* Account Domain Name Short – короткий домен, который используется для авторизации на сервере LDAP.
-* Попробовать отделить имя пользователя – возможность разделить имя пользователя и домен.
-* Оптовые рефералы – должны ли рефералы следовать клиенту LDAP.
-* Создать пользователя в EspoCRM – этот параметр позволяет EspoCRM создавать пользователя из LDAP.
- * Атрибут имени пользователя – LDAP атрибут, который используется для определения имени пользователя.
- * Атрибут фамилии пользователя – LDAP атрибут, который используется для определения фамилии пользователя.
- * Атрибут должности пользователя – LDAP атрибут, который используется для определения названия должности пользователя.
- * Атрибут адреса эл. почты пользователя – LDAP атрибут, который используется для определения адреса эл. почты пользователя.
- * Атрибут номера телефона пользователя – LDAP, который используется для определения номера телефона пользователя.
-
-Теперь перейдите на страницу входа и введите учетные данные пользователя.
-
-
-
-Пользователь был аутентифицирован и автоматически создан в EspoCRM.
-
-## Инструкции по настройке на основе вашего сервера:
-* [Active Directory server](ldap-authorization-for-ad.md)
-* [OpenLDAP server](ldap-authorization-for-openldap.md)
-
-Вы можете прочитать больше информации о настройке LDAP на странице [Zend \ Ldap library] (https://zendframework.github.io/zend-ldap/intro/), так как EspoCRM использует эту библиотеку.
diff --git a/i18n/ru_RU/administration/maps.md b/i18n/ru_RU/administration/maps.md
deleted file mode 100644
index 3c577e34a..000000000
--- a/i18n/ru_RU/administration/maps.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Карты
-
-## Как показать карту основанную на адресных полях
-
-Каждое поле адреса имеет соответствующее поле карты. Все, что вам нужно, это вписать в него подробную информацию. Это приложение использует сервис Google карты.
-
-`Администрирование > Управление макетами > Выберете объект (контрагент, контакт, кандидат или пользовательский объект) > Детализация > Перетащите поле карты.`
-
-Сделайте ячейку шире, используя знак минус.
-
-Также можно настроить высоту поля.
-
-`Администрирование > Управление объектами > Выберете объект > Поля > Найдите поле карты и щелкните по нему > Измените высоту и сохраните.`
-
-## API ключ
-
-Начиная с EspoCRM версии 4.2.0, необходимо указать ключ Api для использования Google Maps (Администрирование > Интеграции > Google Maps).
diff --git a/i18n/ru_RU/administration/moving-to-another-server.md b/i18n/ru_RU/administration/moving-to-another-server.md
deleted file mode 100644
index 042f27e67..000000000
--- a/i18n/ru_RU/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Перемещение EspoCRM на другой сервер
-
-Выполните следующие шаги, чтобы переместить EspoCRM на другой сервер:
-
-### Шаг 1. Резервное копирование файлов
-
-Откройте файловый менеджер или войдите через SSH, чтобы архивировать все доступные файлы из каталога EspoCRM. [Подробнее](backup-and-restore.md#user-content-шаг-1-резервное-копирование-файлов)
-
-### Шаг 2. Резервное копирование базы данных
-
-Данные, хранящиеся в базе данных (MySQL, MariaDB), должны быть скопированы. Следуйте этой [рекомендации](backup-and-restore.md#user-content-шаг-2-резервное-копирование-базы-данных)
-
-### Шаг 3. Скопируйте резервные копии файлов и базы данных на другой сервер
-
-Скопируйте резервные копии файлов и вашей базы данных на новый сервер.
-
-### Шаг 4. Разархивируйте файлы резервных копий
-
-Чтобы разархивировать файлы резервных копий, вы можете использовать Archive Manager или эту [инструкцию](backup-and-restore.md#user-content-шаг-1-разархивируйте-файлы-резервной-копии)
-Примечание. Файлы необходимо поместить в каталог веб-сервера.
-
-### Шаг 5. Настройка сервера
-
-Настройте новый сервер на основе рекомендаций [здесь](server-configuration.md)
-
-### Шаг 6. Правильные разрешения
-
-Установите [необходимые разрешения и владельца файлов](server-configuration.md#user-content-требуемые-разрешения-для-систем-на-основе-unix)
-
-### Шаг 7. Импортируйте резервную копию базы данных
-
-Сначала вам нужно создать новую базу данных с пользователем в MySQL. Чтобы импортировать свою базу данных из резервной копии, следуйте [инструкциям](backup-and-restore.md#user-content-шаг-3-импортируйте-дамп-базы-данных).
-
-### Шаг 8. Исправьте конфигурации EspoCRM
-
-После успешного импорта и настройки сервера, пожалуйста, исправьте конфигурацию EspoCRM в файле `ESPOCRM_DIRECTORY/data/config.php`:
-
- * настройки подключения к базе данных:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - если ваше доменное имя (URL) изменено:
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * владелец файлов по умолчанию (только если разные):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- где `www-data` это ваш веб-сервер.
-
-### Шаг 9. Установите crontab
-
-Установите [crontab](server-configuration.md#user-content-настройка-crontab).
-Примечание: он должен быть настроен под вашим пользователем веб-сервера.
-
-Это все. Теперь ваш EspoCRM работает на новом сервере.
diff --git a/i18n/ru_RU/administration/multiple-assigned-users.md b/i18n/ru_RU/administration/multiple-assigned-users.md
deleted file mode 100644
index 5dc2c5f4c..000000000
--- a/i18n/ru_RU/administration/multiple-assigned-users.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Несколько ответственных пользователей
-Примечание. Эта функция является экспериментальной и доступна только с версии 5.2.0. Безупречная работа и совместимость с другими функциями не гарантируются.
-
-Исходная версия EspoCRM позволяет назначать только одного пользователя для определенной записи. Можно добавить возможность назначать нескольких пользователей для определенного типа сущности.
-
-Для этого вам просто нужно создать отношение «многие ко многим» между нужным типом сущности и типом сущности «Пользователь» с именем «assignedUsers». Обязательно выберете параметр Link Multiple Field.
-
-
-
-Убедитесь, что вы выбрали имена ссылок, которые еще не существуют в системе.
diff --git a/i18n/ru_RU/administration/nginx-server-configuration.md b/i18n/ru_RU/administration/nginx-server-configuration.md
deleted file mode 100644
index af20f14e8..000000000
--- a/i18n/ru_RU/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Конфигурация сервера Nginx для EspoCRM
-
-Эти инструкции являются дополнительными к руководству по [Конфигурации сервера](server-configuration.md). Обратите внимание, что все перечисленные здесь параметры конфигурации выполняются на сервере Ubuntu.
-
-## Требования PHP
-
-Чтобы установить все необходимые библиотеки, выполните следующие команды в терминале:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-zip php-imap php-mbstring php-curl
-sudo phpenmod imap mbstring
-sudo service nginx restart
-```
-
-## Исправление проблемы «Ошибка API: API EspoCRM недоступен»:
-
-
-Принимайте только необходимые меры. После каждого шага проверяйте, решена ли проблема.
-
-### 1. Включите правила перезаписи на сервере Nginx
-
-Добавьте этот код в файл конфигурации блока вашего сервера Nginx (/etc/nginx/sites-available/YOUR_SITE) внутри блока «server»:
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Если у вас нет этого файла, вы должны его создать. Для этого откройте терминал и выполните команду:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-И добавьте код, указанный выше. Для получения дополнительной информации о том, как настроить новый виртуальный хост в Nginx, пожалуйста, прочитайте это [руководство](nginx-virtual-host.md).
-
-Запустите эту команду в терминале, чтобы проверить, все ли в порядке:
-
-```
-sudo nginx -t
-```
-
-Если это так, выполните команду для перезапуска сервера nginx:
-
-```
-sudo service nginx restart
-```
-
-### 2. Добавьте путь RewriteBase
-
-Откройте файл /ESPOCRM_DIRECTORY/api/v1/.htaccess и замените следующую строку:
-
-```
-# RewriteBase /
-```
-на
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-где REQUEST_URI является частью URL, например, для «http://example.com/espocrm/» REQUEST_URI - «espocrm».
diff --git a/i18n/ru_RU/administration/nginx-virtual-host.md b/i18n/ru_RU/administration/nginx-virtual-host.md
deleted file mode 100644
index 15676c966..000000000
--- a/i18n/ru_RU/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Настройка виртуального хоста на Nginx для EspoCRM
-
-В этом руководстве мы покажем, как настроить виртуальный хост на Nginx для EspoCRM на сервере Ubuntu.
-
-## Создайте файл блока сервера
-
-Чтобы создать этот файл, откройте терминал и выполните команду:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Теперь откройте этот файл (/etc/nginx/sites-available/espocrm.conf) и измените код в соответствии с форматом, приведенным ниже (некоторые параметры могут отличаться в зависимости от вашей конфигурации):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Включите этот блок сервера
-
-Создайте символическую ссылку:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Запустите эту команду, чтобы проверить, все ли в порядке:
-
-```
-sudo nginx -t
-```
-
-И перезапустите сервер Nginx:
-
-```
-sudo service nginx restart
-```
-
-## Настройте локальные хосты (необязательно, только для локального домена)
-
-Если вы добавили локальный домен, вы должны настроить его на локальном компьютере (не на сервере). Для Ubuntu откройте файл `/etc/hosts` и добавьте строку:
-```
-192.168.1.1 espocrm.local # specify the IP address of your Nginx server
-```
-
-Для Windows, пожалуйста, следуйте этим [инструкциям](http://support.microsoft.com/kb/923947).
diff --git a/i18n/ru_RU/administration/portal.md b/i18n/ru_RU/administration/portal.md
deleted file mode 100644
index eb1ad0e9c..000000000
--- a/i18n/ru_RU/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Портал
-
-Портал предоставляет возможность доступа к конкретным данным и функциям crm для ваших клиентов и партнеров. Администратор может создавать несколько порталов. Каждый портал может иметь свои собственные настройки, панель виджетов, список пользователей, настройки контроля доступа.
-
-Чтобы создать портал, перейдите в Администрирование > Порталы, нажмите кнопку «Создать портал».
-
-* `Активный`. Если параметр не выбран, портал не будет доступен никому.
-* `Портал по умолчанию`. Означает, что портал будет доступен по более короткому URL: http(s)://YOUR_ESPO_URL/portal.
-* `Роли`. Укажите одну или несколько ролей портала, которые будут применяться к пользователям, зарегистрированным на портале. Более подробная информация о ролях портала приведена ниже.
-* `Список вкладок`. Вкладки, которые будут отображаться на панели навигации.
-* `Планировка панели виджетов`. Укажите виджеты, которые будут отображаться на главной странице портала. Обратите внимание, что пользователи портала не могут настроить свою панель.
-* `URL`. Поле только для чтения, в котором отображается ссылка, с которой вы можете получить доступ к порталу.
-
-## Пользователи портала
-
-Администраторы могут создавать пользователей портала.
-
-1. Администрирование > Пользователи.
-2. Нажмите раскрывающуеся меню справа рядом с кнопкой «Создать пользователя».
-3. Нажмите «Создать пользователя портала».
-4. Выберите «Контакт», с которым будет связан пользователь портала.
-5. Заполните форму и нажмите «Сохранить».
-
-Пользователь портала должен быть связан с записью портала, чтобы иметь возможность доступа к этому порталу.
-
-## Роли портала
-
-Роли портала похожи на обычные роли в EspoCRM, но с несколькими отличиями.
-
-* Уровень `не установлено` запрещает доступ.
-* Уровень `владелец` означает, что запись создается пользователем. Например: пользователь портала редактирует какое-то обращение, и это обращение принадлежит этому пользователю.
-* Уровень `контрагент` означает, что запись связана с контрагентом, с которым связан пользователь портала.
-* Уровень `контакт` означает, что запись связана с контактом, с которым связан пользователь портала.
-
-Поля «Ответственный» и «Группы» являются полями только для чтения для пользователей портала.
-
-### Пример
-
-`Пользователи портала должны иметь возможность создавать обращения, просматривать обращения, связанные с их учетной записью; они должны иметь возможность ознакомиться с базой знаний.`
-
-1. Откройте форму «Создать роль портала» (Администрирование > Роли порталов > Создать роль портала).
-2. Включите доступ к Обращениям, установите: `создать - да, чтение - контрагент, редактирование - нет, удаление - нет, лента - контрагент`.
-3. Включите доступ к базе знаний, установите `создать - нет, чтение - контрагент, редактирование - нет, удаление - нет`.
-4. Измените запись портала (Администрирование > Порталы). Выберите роль портала в поле «Роли», а затем сохраните.
-
-## Доступ к порталу
-
-URL-адрес портала можно найти в поле «URL» в записи портала. Также можно использовать инструменты настройки сервера (такие как mod_rewrite), чтобы иметь доступ к другому URL-адресу. Для этого случая вам нужно заполнить поле «Пользовательский URL».
-
-### Доступ к порталу с помощью пользовательского URL для сервера Apache
-
-Пользовательский URL: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Правила перезаписи Mod
-
-Укажите идентификатор записи портала вместо `{PORTAL_ID}`. Идентификатор записи портала может быть доступен в адресной строке вашего веб-браузера при открытии подробной информации о записи портала. Например: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 - это идентификатор записи портала.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/ru_RU/administration/roles-management.md b/i18n/ru_RU/administration/roles-management.md
deleted file mode 100644
index c8e6d68ac..000000000
--- a/i18n/ru_RU/administration/roles-management.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# Управление ролями
-
-## Обзор
-
-Чтобы ограничить доступ для некоторых пользователей, вам нужно использовать роли. Администратор может управлять ролями в панели администрирования. Каждая роль определяет доступ к определенным областям, который применяется к пользователям, которые владеют этой ролью.
-
-Один пользователь может иметь несколько ролей. Эти роли могут быть выбраны для определенного пользователя (поле «Роли» в записи пользователя) и/или быть унаследованы от групп, к которым принадлежит пользователь.
-
-Если у пользователя несколько ролей, они будут объединены, так что разрешающее правило будет иметь более высокий приоритет. Это позволяет администратору легко и гибко управлять уровнем доступа.
-
-Можно увидеть, какие разрешения применяются к определенному пользователю, нажав кнопку «Доступ» на подробном представлении пользователя.
-
-
-
-По умолчанию пользователи могут удалять самостоятельно назначенные записи, которые они создали в течение определенного периода времени. Существует возможность отключить эту возможность в разделе Администрирование > Настройки > Разрешить удаление созданных записей.
-
-## Разрешения по умолчанию
-
-По умолчанию (если роли не применены или у роли нет установленных разрешений) пользователи имеют полный доступ. Существует возможность ограничить доступ, применяемый по умолчанию, включив «ACL Strict Mode» в разделе Администрирование > Настройки.
-
-## Действия
-* Создать - возможность создавать записи;
-* Чтение - возможность просмотра записей (в списках и детализациях);
-* Редактирование - возможность обновления записей;
-* Удаление - возможность удалять записи;
-* Лента - возможность просматривать ленту записи.
-
-## Пример
-
-Например, пользователь принадлежит группе `Продажи`. У этой группы есть единственная роль `Продавца`. Таким образом, все пользователи из этой группы получат роль `Продавца`.
-
-Роль `продавца` определяется следующим образом:
-
-Кандидат:
-```
-создать - да
-чтение - группа
-редактирование - владелец
-удаление - нет
-лента - группа
-```
-
-Сделка:
-```
-создать - да
-чтение – группа
-рекдатирование – владелец
-удаление – нет
-поток - группа
-```
-
-Пользователи смогут читать только тех кандидатов и сделки, которые принадлежат группе `Отдел продаж` (поле «Группы»).
-Пользователь сможет редактировать только тех кандидатов и сделки, которые им назначены, или те, которые они создали.
-Пользователи не смогут удалять кандидатов и сделки.
-
-Мы хотим предоставить больше прав определенному пользователю, занимающему должность менеджера по продажам в компании. Этот сотрудник должен иметь возможность читать/редактировать/удалять все записи из группы `Продажи`. Пользователь должен принадлежать нашей группе `Продажи`. Но нам нужно создать новую роль `Менеджер продаж` и выбрать эту роль для этого пользователя в поле `Роли`.
-
-Роль `менеджера продаж` определяется следующим образом:
-
-Кандидат:
-```
-создать - да
-чтение – группа
-редактирование – группа
-удаление – группа
-лентк - группа
-```
-
-Сделки:
-```
-создать - да
-чтение – группа
-редактирование – группа
-удаление – группа
-лента - группа
-```
-
-Наш пользователь сможет управлять всеми кандидатами и сделками из группы `Продажи`.
-
-## Специальные разрешения
-
-### Разрешение для назначения
-
-Установите этот параметр, чтобы ограничить возможность переназначения записей другому пользователю и/или группе. Если вы установите `группа`, тогда можно будет назначить только пользователей из собственной группы. Если `нет` - пользователи не смогут повторно назначать.
-
-Оно также определяет, может ли пользователь отправлять сообщения другим пользователям/группам.
-
-### Разрешение видеть пользователей
-
-Позволяет ограничить возможность просмотра пользователями действий, календаря и ленты других пользователей.
-
-### Разрешение портала
-
-Определяет доступ к информации портала, возможность отправлять сообщения пользователям портала.
-
-### Разрешение для учетной записи эл. почты группы
-
-Определяет доступ к групповым учетным записям электронной почты, возможность отправлять электронные письма из SMTP группы.
-
-### Разрешение на экспорт
-
-Устанавливает, имеет ли пользователь возможность экспортировать записи. (начиная с версии 4.9.0)
-
-## Безопасность на уровне полей (Field Level Security)
-
-Позволяет контролировать доступ для определенных полей.
-
-По умолчанию пользователь может читать все поля, если он может прочитать запись. Пользователь может редактировать любое поле, если он может редактировать запись. Вы можете ограничить доступ к определенным полям с помощью безопасности на уровне полей.
-
-В режиме редактирования записи роли в разделе Уровень поля (Field Level) щелкните значок плюс рядом с определенной областью, затем выберите нужное поле. Тогда вы сможете указать уровень доступа для действий `чтение` и` редактирование`. Есть варианты: `да` и` нет`.
-
-
diff --git a/i18n/ru_RU/administration/server-configuration.md b/i18n/ru_RU/administration/server-configuration.md
deleted file mode 100644
index dd7c5769d..000000000
--- a/i18n/ru_RU/administration/server-configuration.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# Конфигурация сервера для EspoCRM
-
-EspoCRM может быть установлен на сервер Apache ([инструкция](apache-server-configuration.md)), Nginx ([инструкция](nginx-server-configuration.md)) или IIS с поддержкой PHP версии 5.6 или выше и MySQL версии 5.5.3 или выше.
-
-
-## Рекомендации по конфигурации
-
-### Требования PHP
-
-EspoCRM требует PHP 5.6 или выше со следующими включенными расширениями:
-
-* [pdo](http://php.net/manual/en/book.pdo.php) – чтобы получить доступ к MySQL в PHP;
-* [json](http://php.net/manual/en/book.json.php) – ресурсы используют этот формат (метаданные, макет, языки и другие);
-* [gd](http://php.net/manual/en/book.image.php) – для манипуляций с изображениями;
-* [openssl](http://php.net/manual/en/book.openssl.php) – для обеспечения максимальной защиты;
-* [zip](http://php.net/manual/en/book.zip.php) – чтобы иметь возможность обновлять EspoCRM и устанавливать расширения;
-* [imap](http://php.net/manual/en/book.imap.php) – чтобы контролировать почтовые ящики в EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [iconv](http://php.net/manual/en/book.iconv.php);
-* [curl](http://php.net/manual/en/book.curl.php) – для интеграций;
-* [xml](http://php.net/manual/en/book.xml.php) – для экспорта в Excel;
-* [xmlwriter](http://php.net/manual/en/book.xmlwriter.php) – для экспорта в Excel;
-* [exif](http://php.net/manual/en/book.exif.php) – для правильной ориентации загружаемых изображений.
-
-Настройки php.ini:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-### Требования к базе данных
-
-EspoCRM поддерживает MySQL версии 5.5.3 или выше. MariaDB также поддерживается. Нет специфических особенностей. Все настройки по умолчанию подходят для EspoCRM.
-
-Для лучшей работы рекомендуется использовать MySQL 5.6 или выше.
-
-### Поддержка MySQL 8
-
-MySQL 8.0.4 изменил метод аутентификации по умолчанию на caching_sha2_password, который не поддерживается PHP (на момент написания). Для MySQL 8 его следует заменить на метод mysql_native_password. Для пользователя это можно сделать с помощью запроса:
-
-```
-CREATE USER username@localhost identified with mysql_native_password by 'password';
-```
-где username - ваш пользователь MySQL, password - ваш пароль пользователя MySQL.
-
-## Требуемые разрешения для систем на основе Unix
-
-Файлы и каталоги должны иметь следующие разрешения:
-
-* `/data`, `/custom`, `/client/custom` – должны быть доступны для записи все файлы, каталоги и подкаталоги (664 для файлов, 775 для каталогов, включая все подкаталоги и файлы);
-* `/application/Espo/Modules`, `/client/modules` – должен быть доступен для записи текущий каталог (775 для текущего каталога, 644 для файлов, 755 для каталогов и подкаталогов);
-* Все остальные файлы и каталоги должны быть доступны для чтения (644 для файлов, 755 для каталогов).
-
-Чтобы установить разрешения, выполните следующие команды в терминале:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom client/custom -type d -exec chmod 775 {} + && find data custom client/custom -type f -exec chmod 664 {} +;
-chmod 775 application/Espo/Modules client/modules;
-```
-
-Все файлы должны принадлежать процессу веб-сервера и принадлежать группе процесса веб-сервера. Это могут быть «www-data», «daemon», «apache», «www» и т. д.
-
-Примечание. В Bitnami Stack файлы должны принадлежать пользователю “daemon” и принадлежать группе пользователя “daemon”.
-
-Примечание. На общих хостах файлы должны принадлежать вашей учетной записи и принадлежать группе вашей учетной записи.
-
-Чтобы установить владельца и группу-владельца, выполните следующие команды в терминале:
-
-```
-cd
-chown -R : .;
-```
-
-## Настройка crontab
-
-*Информация о заданиях в EspoCRM доступна [здесь](jobs.md).*
-
-### Unix-подобные системы
-
-Чтобы настроить crontab в Unix-подобной системе, сделайте следующее:
-
-1. Войдите как администратор в свой экземпляр EspoCRM.
-2. Перейдите в раздел «Планировщик заданий» на панели администратора («Меню» > «Администрирование» > «Планировщик заданий») и скопируйте строку для crontab. Она выглядит так:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-3. Откройте терминал и выполните эту команду:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER может быть одним из следующих «www», «www-data», «apache» и т. Д. (Зависит от вашего веб-сервера).
-
-4. Вставьте скопированную строку (из шага 2) и сохраните файл crontab (Ctrl+O, затем Ctrl+X для nano-редактора).
-
-### Windows
-
-Для серверов Windows вы можете использовать запланированные задачи.
-
-
-## Инструкции по конфигурации на основе вашего сервера
-
-* [Конфигурация сервера Apache](apache-server-configuration.md).
-* [Конфигурация сервера Nginx](nginx-server-configuration.md).
diff --git a/i18n/ru_RU/administration/troubleshooting.md b/i18n/ru_RU/administration/troubleshooting.md
deleted file mode 100644
index 0ac8a809b..000000000
--- a/i18n/ru_RU/administration/troubleshooting.md
+++ /dev/null
@@ -1,110 +0,0 @@
-# Исправление проблем
-
-## Проверка журнала
-
-Чтобы узнать о проблеме, вам необходимо проверить файлы журнала ошибок.
-
-#### Журналы ошибок EspoCRM
-
-Журналы EspoCRM расположены в ` /logs/*.log` и содержат некоторую информацию об ошибке.
-
-#### Журналы ошибок Apache
-
-Для сервера Ubuntu журнал ошибок apache находится в `/var/log/apache2/error.log` и содержит всю информацию об ошибках. Расположение файлов журналов может отличаться в других системах.
-## Проверьте системные требования (system requirements)
-
-В разделе Администрирование > Системные требования. Важно установить все необходимые расширения.
-
-## Запланированные действия не работают
-
-#### Проблема №1: ваш crontab не настроен
-
-1. Войдите в систему через SSH на свой сервер.
-
-2. Настройте свой crontab, выполнив следующие [шаги](server-configuration.md#user-content-настройка-crontab)
-
-Примечание. Crontab должен быть настроен под пользователем веб-сервера, например. `crontab -e -u www-data`.
-
-3. Подождите некоторое время и проверьте Планировщик заданий, чтобы узнать, выполнены ли какие-либо задания (см. Журнал).
-
-#### Проблема №2. Crontab настроен, но запланированные задания не работают
-
-Чтобы убедиться, что при запуске cron нет ошибок, попробуйте запустить команду cron в терминале:
-
-1. Войдите в систему через SSH на свой сервер.
-
-2. Перейдите в каталог, где установлен EspoCRM. Например. для каталога `/var/www/html/espocrm` команда:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Запустите команду crontab:
-
-```bash
-php cron.php
-```
-
-Примечание. Он должен выполняться под пользователем веб-сервера. Если вы вошли в систему под учетной записью root, команда должна быть (например, для Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-где `www-data` это сервер пользователя.
-
-4. Если ошибок нет, проверьте Планировщик заданий, чтобы узнать, выполнено ли какое-либо задание (см. Журнал).
-
-## Запуск перестройки из CLI (Running rebuild from CLI)
-
-Иногда вам нужно запустить перестройку (rebuild) из интерфейса командной строки, когда приложение не загружается.
-
-```bash
-sudo -u www-data php cron.php
-```
-
-где `www-data` это пользователь веб-сервера.
-
-## EspoCRM не загружается после обновления
-
-Иногда это может происходить на некоторых общих хостах.
-
-Проверьте разрешения файлов: /index.php /api/v1/index.php
-
-Они должны быть 644. Если какой-либо из этих файлов имеет разрешение 664, вам необходимо изменить его на 644. Используйте панель управления хостинга или команду chmod.
-
-```
-chmod 644 /path/to/file
-```
-Дополнительная информация о файловых разрешениях: [здесь](server-configuration.md#user-content-требуемые-разрешения-для-систем-на-основе-unix).
-
-## Ошибка MySQL: сервер запросил метод аутентификации, неизвестный клиенту
-
-MySQL 8.0.4 изменил метод аутентификации по умолчанию на caching_sha2_password, который не поддерживается PHP. Эта проблема может быть решена с помощью этого [решения](server-configuration.md#user-content-поддержка-mysql-8).
-
-## Электронные письма не доставляются
-
-1. Убедитесь, что [cron](server-configuration.md#user-content-настройка-crontab) работает. Вы увидите уведомление об ошибке на главной странице администрирования, если cron не запущен.
-2. Проверьте журнал EspoCRM (data/logs) и журналы сервера (server logs) на наличие ошибок.
-3. Проверьте журнал (log) в разделе Администрирование > Планировщик заданий > Проверьте Personal Email Accounts. Убедитесь, что нет записей с статусом failed.
-4. Проверьте журнал (log) в разделе Администрирование > Планировщик заданий > Проверьте Group Email Accounts. Убедитесь, что нет записей с статусом failed.
-
-## Включить режим отладки
-
-Чтобы включить режим отладки, перейдите в установленный каталог EspoCRM, откройте файл `data/config.php` и измените значение:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-to
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
diff --git a/i18n/ru_RU/administration/upgrading.md b/i18n/ru_RU/administration/upgrading.md
deleted file mode 100644
index 770a93c46..000000000
--- a/i18n/ru_RU/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Как обновить EspoCRM
-
-EspoCRM можно обновить до последней версии, выполнив следующие шаги:
-
-### Шаг 1. Проверьте текущую версию
-
-Для проверки текущей версии перейдите на страницу Администрирование > обновление.
-
-### Шаг 2. Загрузите необходимые пакеты обновления
-
-Перейти на обновление страницы https://www.espocrm.com/download/upgrades/ и на основе вашей текущей версии скачать необходимые пакеты.
-
-### Шаг 3. Создание резервной копии (необязательно)
-
-Создайте резервную копию файлов и данных EspoCRM перед обновлением. Следовать [этим инструкциям](backup-and-restore.md) чтобы сделать это.
-
-### Шаг 4. Процесс обновления
-
-Перейдите в Администрирование > обновление. Загрузите и установите один за другим пакеты обновления.
-
-Вы можете проверить наличие последней версии в Меню > О программе.
-
-## Обновление через командную строку
-
-Можно также запустить обновление через интерфейс командной строки. Необходимо выполнить следующую команду из корневого каталога EspoCRM:
-
-``
-php upgrade.php /path/to/upgrade/package.zip
-``
diff --git a/i18n/ru_RU/administration/web-to-lead.md b/i18n/ru_RU/administration/web-to-lead.md
deleted file mode 100644
index 1551346b8..000000000
--- a/i18n/ru_RU/administration/web-to-lead.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# Web-to-Lead
-## Захват кандидата
-
-Примечание: доступно с версии 5.4.0.
-
-Используя функцию "Захват кандидата", администратор может создать точку входа для захвата потенциальных клиентов через API. Для создания точки входа перейдите в Администрирование > Захват кандидата.
-
-* Subscribe to Target List - Созданный кандидат будет добавлен в указанный список целей;
-* Subscribe Contact if exists - Если контакт с таким же адресом электронной почты существует, контакт будет добавлен в список целей;
-* Target Team - Группа, которой назначат созданного кандидата;
-* Campaign - Статистика будет доступна в журнале кампании;
-* Payload Fields - Выберите, какие поля должны быть переданы.
-
-### Двойное подтверждение подписки (double opt-in/confirmed opt-in)
-
-Если включено двойное подтверджение подписки, ваши подписчики должны подтвердить свое намерение подписаться, щелкнув ссылку в электронном письме. Электронное письмо будет отправлено автоматически после получения данных через API.
-
-Создайте шаблон эл. письма, который будет использоваться для двойного подтверждения подписки. Вы можете использовать следующие заполнители в теле шаблона:
-
-* `{optInUrl}` - URL для подтверждения подписки;
-* `{optInLink}` - ссылка для подтверждения подписки.
-
-Ссылка для подтверждения подписки будет добавлена автоматически, если вы не вставили заполнитель в шаблон эл. письма.
-
-## Отправка запроса API
-
-Ваш веб-сайт должен сделать запрос POST для отправки данных формы вам CRM. Запрос не требует авторизации. Вам просто нужно использовать определенный URL с ключом API. Информация о запросе доступна на боковой панели в детальном виде Захвата кандидатов.
-
-Требуемые заголовки:
-
-* Content-Type: application/json
-* Accept: application/json
-
-
-### PHP
-
-Вы можете использовать [API client for PHP](../development/api-client-php.md).
-
-Пример:
-
-```php
- $_POST['firstName'],
- 'lastName' => $_POST['lastName'],
- 'emailAddress' => $_POST['emailAddress']
-];
-
-$client->request('POST', 'LeadCapture/' . $apiKey, $formData);
-
-```
-
-### Python
-
-[API client in Python](../development/api-client-python.md)
-
-### Непосредственно через веб-браузер
-
-Примечание: работает с версии 5.4.4.
-
-Пример:
-
-```html
-
-
-
-
-```
-
-Заголовок 'Access-Control-Allow-Origin' может быть установлен в data/config.php с помощью параметра `leadCaptureAllowOrigin`. По умолчанию используеться `*` значение.
-
-## Распределение назначения кандидатов (Lead assignment distribution)
-
-Используя [Рабочие потоки](workflows.md) или [Управление Бизнес-Процессами](bpm.md), вы можете создать правило назначения, которое будет распределять кандидатов среди пользователей группы. Доступны правила Round-Robin и Least-Busy.
-
-Чтобы применить правило только для кандидатов, появляющихся через точку входа, вы можете использовать поле Кампания (Campaign) для проверки условий.
diff --git a/i18n/ru_RU/administration/workflows.md b/i18n/ru_RU/administration/workflows.md
deleted file mode 100644
index 44616ece8..000000000
--- a/i18n/ru_RU/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Рабочие потоки (Workflows)
-
-Функция Workflows доступна в [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/)
-
-Функция Workflows автоматизирует ваш бизнес-процесс простым способом. Вы можете найти ее на панели администрирования. Чтобы создать правило рабочего потока, вам необходимо определить:
-
-* Целевую сущность - к какому типу сущности применяется рабочий поток;
-* Тип триггера - при срабатывании рабочего потока;
-* Условия - условия должны быть выполнены для запуска рабочего потока;
-* Действия - что необходимо делать, если рабочий поток запускается
-
-
-## Типы триггеров
-
-### После создания записи
-
-Выполняется только при создании новой записи. Если указанные условия выполнены, то действия будут выполнены.
-
-### После сохранения записи
-
-Запускается при создании новой записи или обновлении существующей записи. Если указанные условия выполнены, то действия будут выполнены.
-
-Для правил рабочих потоков с этим типом триггера обычно принято соблюдать условие, которое проверяет, было ли какое-то поле «изменено». Например, если статус обращения изменен, выполните некоторые действия.
-
-### Запланированый (Scheduled)
-
-Выполняется в соответствии с заданным расписанием. Вы можете настроить его для запуска каждый день, каждую неделю и т. д. Действия будут применяться для записей, возвращаемых указанным отчетом-списком. Поэтому вам также нужно создать отчет-список.
-
-Планирование указано в нотации crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Год (range: 1900-3000)
-| | | | +---- День недели (range: 1-7, 1 standing for Monday)
-| | | +------ Месяц года (range: 1-12)
-| | +-------- День месяца (range: 1-31)
-| +---------- Час (range: 0-23)
-+------------ Минута (range: 0-59)
-```
-
-### Последовательный (Sequential)
-
-Используется редко. Предполагается, что будет запущен другим рабочим потоком. Предоставляет возможность создавать сложную логику.
-
-Примечание: Для последовательных рабочих потоков рекомендуется использовать [инструмент BPM](bpm.md), а не функцию Workflow.
-
-## Условия
-
-Вы можете указать условия, которые должны выполняться для запуска рабочего потока. Существует два способа определения условий: с конструктором условий пользовательского интерфейса и с формулой.
-
-### Конструктор условий пользовательского интерфейса
-
-Некоторые доступные типы условий:
-
-* _равно_ - поле равно конкретному значению или значению другого поля;
-* _было равным_ - поле было равно определенному значению до запуска рабочего потока;
-* _не равно_ - поле не равно конкретному значению или значению другого поля;
-* _не было равным_ - поле не было равно конкретному значению до запуска рабочего потока;
-* _пустое_ - значение поля пусто;
-* _не пустое_ - значение поля не пусто;
-* _изменено_ - поле было изменено;
-* _не изменено_ - поле не было изменено.
-
-### Условия формулы
-
-Формула дает возможность определять условия любой сложности. Чтобы прочитать синтаксис формулы, следуйте [этой статье](formula.md).
-
-Примечание. В определении кода не должно быть никакого разделителя `;`, если он определяет условие.
-
-## Действия
-
-### Отправить письмо
-
-Система отправит электронное письмо с использованием указанного шаблона электронной почты. Адрес электронной почты получателя может быть взят из целевой записи, любой связанной записи, текущего пользователя, последователей, пользователей команды или который непосредственно Вами указан. Сообщение может быть отправлено незамедлительно или отложено на определенный временный интервал.
-
-### Создать сущность
-
-Система создаст новую запись любого типа сущности. Если есть связь между целевой записью и созданием записи, можно связать записи.
-
-Существует возможность определять формулу для вычисления полей.
-
-### Создать связанную сущность
-
-Система создаст запись, относящуюся к целевой записи. Можно определить формулу для вычисления полей.
-
-### Обновить целевую сущность
-
-Позволяет изменять определенные поля целевой записи. Можно определить формулу для вычисления полей.
-
-Если вам нужно добавить новые элементы в поле Link-Multiple без потери существующих данных (например, для команд), вам необходимо использовать функцию function entity\addLinkMultipleId. Пример: `entity\addLinkMultipleId ('teams', 'teamId')`.
-
-### Обновить соответствующую сущность
-
-Позволяет изменять определенные поля соответствующей записи или записей. Можно определить формулу для вычисления полей.
-
-### Связать с другой сущностью (Link with Another Record)
-
-Связывает целевой объект с другим конкретным объектом. Например: добавляет конкретную команду к записи.
-
-### Отменить связь с другой сущностью (Unlink with Another Record)
-
-Отделяет целевой объект от другого конкретного объекта. Например: удаляет определенную команду из записи.
-
-### Применить правило назначения (Apply Assignment Rule)
-
-Назначьте целевую запись пользователю по правилу распределения. Существуют два доступных правила: Round-Robin и Less-Busy.
-
-* Round-Robin - пользователи выбираются сверху вниз по списку (группе) и затем это начинается снова.
-* Less-Busy - пользователь, у которого меньше назначенных записей, будет выбран для назначения.
-
-_Отчет-список_ - для распределения по Least-Busy определяет, какие записи будут приняты во внимание для расчета количества присвоенных записей. Например: для обращений нам нужно брать только записи с активным статусом.
-
-### Создать оповещение
-
-Уведомлять определенных пользователей с сообщением. В шаблоне сообщения можно использовать заполнители: {entity} - целевая запись, {user} - текущий пользователь.
-
-### Подписать
-
-Подписывает конкретных пользователей на целевой объект или конкретный связанный объект.
-
-### Запуск другого рабочего потока (Trigger Another Workflow)
-
-Позволяет создавать последовательные рабочие потоки. Можно разделить рабочий поток по условию: вы можете настроить рабочий поток для запуска двух рабочих потоков с разными условиями, определенными в этих рабочих котоках.
-
-Можно отложить выполнение последовательного рабочего потока. В последовательном рабочем потоке вы можете определить условие, которое проверяет, были ли изменены указанные поля, поскольку родительский рабочий поток был запущен с использованием типов условий _Изменено_ и _Было равным_.
-
-Примечание. Для последовательных рабочих потоков рекомендуется использовать [BPM-инструмент](bpm.md), а не функцию Workflow.
-
-### Run Service Action
-
-Позволяет запускать определенные сервисные скрипты. По умолчанию доступны следующие действия:
-
-* Отправить приглашения - для встреч/звонков;
-* Добавить Quote Item - для предложений.
-
-Разработчики могут писать свои собственные сервисные действия. См. [Подробнее](https://github.com/espocrm/documentation/blob/master/development/workflow-service-actions.md).
-
-## Использование формул в Действиях
-
-Можно определить формулу для вычисления полей для создания записи, обновления целевой записи, создания соответствующей записи, обновления соответствующей записи. Для последних двух, чтобы получить доступ к атрибутам целевого объекта, вы должны использовать функцию `targetEntity\attribute`. Чтобы получить доступ к атрибутам целевого объекта, который был установлен до запуска рабочего потока, используйте функцию `targetEntity\attributeFetched`.
-
-Например:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/ru_RU/user-guide/activities-and-calendar.md b/i18n/ru_RU/user-guide/activities-and-calendar.md
deleted file mode 100644
index cae928fe0..000000000
--- a/i18n/ru_RU/user-guide/activities-and-calendar.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Действия и календарь
-
-В EspoCRM по умолчанию доступны три типа действий:
-
-* Встречи;
-* Звонки;
-* Задачи.
-
-Администратор может создать пользовательский объект типа событие (Event). Затем в Администрирование > Настройки > Действия можно установить этот тип сущности в качестве Действия и сделать его доступным в Календаре.
-
-Существует виджет «Мои действия», в котором отображаются текущие и предстоящие записи действий, связанных с текущим пользователем.
-
-Контрагенты, контакты, кандидаты, сделки, обращения имеют панель «Действия» в детализации. Пользовательские объекты типа Base Plus также имеют панель «Действия».
-
-## Встречи, Звонки
-
-### Участники
-
-Поддерживаются 3 типа участников: пользователи, контакты, кандидаты. Для каждого участника можно указать статус принятия: Согласен, Есть сомнения, Не согласен. Существует возможность отправлять приглашения участникам по электронной почте, нажав кнопку в правом верхнем углу. Участники смогут установить свой статус принятия, нажав на соответствующую ссылку в электронном письме.
-
-### Напоминания
-
-Существует два типа напоминаний: всплывающее окно (сообщение в приложении) и эл. письмо.
-
-### Длительность по умолчанию
-
-Длительность по умолчанию может быть изменена администратором в разделе Администрирование > Управление объектами > Встречи/Звонки > Поля > Длительность > По умолчанию. Она должна быть указана в секундах.
-
-## Задачи
-
-Дата начала и дата окончания не обязательны для заполнения. Даты могут быть указаны с или без временных частей.
-
-### Напоминания
-
-Напоминания для записи задачи будут доступны только в том случае, если указана дата окончания и она имеет временную часть.
-
-## Календарь
-
-Календарь отображает Встречи, Звонки, Задачи. Также возможно показать пользовательские объекты типа Событие (Event).
-
-Поддерживаемые виды:
-
-* Месяц;
-* Неделя;
-* День;
-* Расписание.
-
-Пользователи могут добавлять календарь на свою панель виджетов.
-
-Можно просмотреть календарь другого пользователя (если у вас есть доступ, определяемый ролями). Кнопка «Календарь» доступна в детализации пользователя.
-
-### Обновление календаря
-
-Чтобы обновить элементы календаря, вы можете нажать на заголовок диапазона дат вверху в центре.
-
-### Общий календарь
-
-Общий календарь доступен с версии 5.2.0.
-
-Пользователи могут создавать собственные общие просмотры, которые будут отображать события определенных команд.
-
-Примечание: пользователь должен иметь надлежащее «Разрешение видеть пользователей», чтобы иметь возможность использовать общие календари.
-
-Общий просмотр также доступен для расписания. Позволяет просматривать события нескольких пользователей.
diff --git a/i18n/ru_RU/user-guide/browser-support.md b/i18n/ru_RU/user-guide/browser-support.md
deleted file mode 100644
index eac873480..000000000
--- a/i18n/ru_RU/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Поддержка браузеров
-
-Мы рекомендуем использовать последние версии Google Chrome или Mozilla Firefox. EspoCRM работает лучше всего в этих браузерах. Мы регулярно проверяем все функции в этих браузерах.
-
-Microsoft Edge и Safari также поддерживаются, но здесь уже меньше гарантий, что все будет работать плавно.
-
-Мы не рекомендуем использовать Internet Explorer 11.
diff --git a/i18n/ru_RU/user-guide/case-management.md b/i18n/ru_RU/user-guide/case-management.md
deleted file mode 100644
index 6f60cf198..000000000
--- a/i18n/ru_RU/user-guide/case-management.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Управление обращениями
-
-Обращения обеспечивают возможность отслеживания проблем. Это главный аспект обслуживания клиентов в EspoCRM. Тикеты также могут быть использованы для случаев.
-
-Сущность обращения может быть связана с одной организацией и/или с несколькими контактами.
-
-Новые обращения должны быть созданы по следующим сценариям:
-
-* Вручную, пользователями CRM;
-* Вручную, пользователями клиентского портала;
-* Через API (допустим через веб-форму);
-* Автоматически, когда новое письмо пришло на определенный почтовый ящик.
-* Автоматически, с помощью правила рабочего потока.
-
-Запись обращения содержит поток, который можно использовать для связи между клиентом и тех.поддержкой. Пользователи CRM также могут создавать внутренние сообщения, которые не будут видны на клиентском портале.
-
-Когда новое обращение создается пользователем портала, оно не назначается ни одному пользователю. Используя [Workflows](../administration/workflows.md) администратор может создать правило, которое будет уведомлять определенных пользователей о новом обращении в системе. Рабочие потоки также предоставляют возможность применять правило назначения к новым обращениям, т. е. Round-Robin и Least-Busy. Для более сложных бизнес-потоков рекомендуется использовать [BPM tool](../administration/bpm.md).
-
-Чтобы предотвратить исключение новых обращений, пользователи могут добавить тип сущности обращения в список для автоматической подписки на созданные записи конкретных типов объектов в настройках. Тогда они будут автоматически подписаны за каждым новым обращением.
-
-Примечание: если нет пользователя портала, связанного с присоединенным контактом, то клиент не будет получать уведомления по электронной почте об обновлениях в потоке. Вам нужно использовать электронные письма для связи с клиентом.
-
-### Email-to-Case
-
-Администратор может настроить учетную запись электронной почты группы, которая будет создавать новое обращение на каждое новое входящее сообщение. Для получения дополнительной информации [см. здесь](../administration/emails.md).
-
-### База знаний
-
-Пользователи могут связывать статьи базы знаний с записью обращения.
-
-### Клиентский портал
-
-Администратор может создать [портал](../administration/portal.md) где клиенты смогут создавать свои обращения.
-
-Так как пользователи портала автоматически отслеживают свои обращения, они будут получать уведомления по электронной почте о новых сообщениях в потоке.
diff --git a/i18n/ru_RU/user-guide/data-privacy.md b/i18n/ru_RU/user-guide/data-privacy.md
deleted file mode 100644
index 2517bfec2..000000000
--- a/i18n/ru_RU/user-guide/data-privacy.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Конфиденциальность данных
-
-Доступно с версии 5.2.0.
-
-EspoCRM предоставляет возможность просматривать и удалять личные данные для определенных записей (контакты, кандидаты, контрагенты).
-
-В Управлении объектами администратор может отметить определенные поля как те, которые могут содержать личные данные. Эта опция доступна для таких типов объектов как контрагенты, контакты, кандидаты, а также для пользовательских объектов типа Личность (Person).
-
-По умолчанию следующие поля помечены как те, которые могут содержать личные данные.
-
-Контакты и Кандидаты:
-
-* Имя
-* Адрес эл. почты
-* Телефон
-* Адрес
-
-Контрагенты:
-
-* Адрес эл. почты
-
-В детализации записи в меню (рядом с кнопкой редактирования) есть пункт «Просмотреть личные данные». Оттуда можно стереть определенные поля (только если пользователь имеет разрешение «Редактирование»).
-
-Обычные пользователи будут иметь возможность просматривать/удалять личные данные, только если у них есть «Разрешение на обработку конфиденциальных данных» (определяется ролями).
diff --git a/i18n/ru_RU/user-guide/documents.md b/i18n/ru_RU/user-guide/documents.md
deleted file mode 100644
index 25adef0fd..000000000
--- a/i18n/ru_RU/user-guide/documents.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Документы
-
-EspoCRM предоставляет возможность хранить документы.
-
-## Отправка по электронной почте
-
-При составлении письма есть возможность добавить определенный документ в качестве вложения.
-
-## Папки
-
-Папки позволяют группировать документы. Папки с документами представлены в виде иерархической древовидной структуры. Каждая папка может содержать подпапки.
-
-Папка с документами - это отдельный тип объекта, поэтому доступ можно контролировать с помощью ACL.
-
-Чтобы иметь возможность искать документы во всех подпапках, вам нужно переключиться в расширенный режим в контекстном меню рядом с корневой папкой.
diff --git a/i18n/ru_RU/user-guide/emails.md b/i18n/ru_RU/user-guide/emails.md
deleted file mode 100644
index 636eccaeb..000000000
--- a/i18n/ru_RU/user-guide/emails.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# Руководство по использованию электронной почты
-
-EspoCRM предоставляет возможность извлекать электронные письма из почтового ящика IMAP. Это позволяет использовать EspoCRM в качестве почтового клиента вместе с функциями, специфичными для CRM.
-
-## Учетные записи IMAP
-
-*Примечание: вам нужно правильно настроить [cron](../administration/server-configuration.md#user-content-настройка-crontab) в вашей системе, чтобы входящие электронные письма работали.*
-
-Пользователь может настроить учетную запись IMAP на странице Учетные записи эл. почты пользователей (вкладка Эл. письма > меню в верхнем правом углу > Учетные записи эл. почты пользователей).
-
-Укажите, какие папки следует отслеживать в поле *Отслеживаемые папки*. По умолчанию установлено INBOX. Если вы используете какой-либо внешний почтовый клиент для отправки электронных писем, вы можете добавить папку *Отправленные* для архивирования этих электронных писем.
-
-*Получить эл. письма начиная с* позволяет выбрать дату, с которой должны быть заархивированы электронные письма. Установите дату до сегодняшнего дня, если вам нужно архивировать старые письма.
-
-Существует возможность указать *Папку* в учетной записи эл. почты пользователей. Входящие письма будут помещены в эту папку.
-
-## Учетные записи SMTP
-
-Пользователи могут настроить параметры SMTP в учетных записях эл. почты пользователей, а также в настройках. Учетные записи эл. почты пользователей доступны во вкладке Эл. письма > меню в верхнем правом углу > Учетные записи эл. почты пользователей. Администратор также может разрешить использовать системный SMTP (сделать его общим (Shared)).
-
-Пользователи могут иметь несколько учетных записей SMTP. Но адреса электронной почты, которые пользователь может использовать для отправки электронных писем, определяются адресами электронной почты в записи *Пользователь* (User).
-
-## Работа с электронной почтой
-
-Письма извекаються с помощью cron (в фоновом режиме) каждые несколько минут (период может быть указан администратором). Вы можете увидеть все ваши электронные письма во вкладке *Эл. письма*. Слева находятся стандартные папки «Входящие», «Отправленные», «Черновики».
-
-Поле *Статус*. `Отправлено` означает, что письмо было отправлено из CRM, `В архиве` - получено из учетной записи IMAP или заархивировано вручную, `Черновик` - означает, что электронное письмо было создано как черновик.
-
-Когда приходит новое письмо, система пытается распознать, к какой записи принадлежит это письмо. Она может связать его с контрагентом, кандидатом, сделкой, обращением (и контактом в режиме B2C) и т.д. Если оно не было распознано, пользователь может связать его вручную, заполнив поле *Источник*.
-
-Если письмо пришло от нового кандидата, пользователь может **конверировать его в кандадата**, открыв запись эл. письма и нажав **Создать кандидата** в правом верхнем меню.
-
-Также возможно **Создать задачу или обращение** из записи эл. письма.
-
-Если адрес электронной почты (от, до, cc) в записи эл. письма известен системе, он покажет лицо, к которому он относится (контакт, кандидат, пользователь и т.д.). Если адрес электронной почты новый, вы можете создать контакт прямо оттуда.
-
-Все электронные письма, относящиеся к конкретной записи, отображаются на панели «История» этой записи. Если какое-либо электронное письмо связано, например, с сделкой, а сделка связана с контрагентом, письмо будет отображатся как в сделке, так и в контрагенте.
-
-## Отправка электронных писем
-
-Вы можете создать новое письмо несколькими способами:
-* кнопка *Новое сообщение* в представлении списка для эл. писем;
-* отвечая на другое эл. письмо;
-* нажав на адрес электронной почты какой-либо записи;
-* опция *Написать эл. письмо* на панели «Действия».
-
-Есть возможность **выбрать шаблон** вашего письма.
-
-Вы можете настроить **подпись к эл. письмам** в настройках.
-
-Можно использовать **внешний почтовый клиент** (по умолчанию на вашем компьютере или устройстве). Для этого выберете опцию *Использовать внешний почтовый клиент* в настройках. (Эта опция доступна начиная с версии 5.1.2.)
-
-## Папки для электронной почты
-
-Пользователи могут создавать свои собственные папки электронной почты для удобства размещения некоторых писем. Список доступных папок доступен на странице электронных писем слева. Для создания или редактирования папок перейдите в Эл. письма > меню в верхнем правом углу > Папки. `Пропустить оповощения` означает, что вы не будете уведомлены о входящих электронных письмах, которые попадают в определенную папку. Используя фильтры электронной почты, можно автоматически помещать электронные письма в папки по определенным критериям.
-
-## Фильтры электронной почты
-
-Администратор может создавать глобальные фильтры электронной почты, чтобы пропустить нежелательные письма. Они доступны в разделе Администрирование > Фильтры эл. почты.
-
-Обычный пользователь может создавать фильтры электронной почты для своих учетных записей эл. почты пользователей или для всех своих входящих писем. Они доступны во вкладке Эл. письма > меню в правом верхнем углу > Фильтры.
-
-Существует два типа фильтров:
-
-* Пропускать - электронная почта будет помещена в *Корзину* или не импортирована, если фильтр связан с учетной записью эл. почты пользователей;
-* Положить в папку - импортированные письма будут автоматически помещены в указанную папку пользователя.
-
-## Шаблоны электронных писем
-
-Шаблоны электронных писем доступны в разделе Эл. письма > меню в правом верхнем углу > Шаблоны эл. писем. Их можно использовать как для массовой отправки электронной почты, так и для обычной электронной почты. Опция `Одноразовый` означает, что шаблон эл. письма будет использован только один раз, что является обычным для электронного маркетинга.
-
-Можно использовать заполнители в теле и теме электронного письма, например, {Account.name}, {Person.emailAddress}. Они будут заменены значениями связанных записей.
-
-Вы можете использовать дополнительные зарезервированные заполнители в теле шаблона: {optOutUrl} и {optOutLink}.
-```
-Unsubscribe
-```
-Это ссылка для того, чтобы отписаться от массовой рассылки электронных писем.
-
-### Заполнители
-
-* `{today}` - сегодняшняя дата (версия> = 5.5.0),
-* `{now}` - текущая дата и время (версия> = 5.5.0),
-* `{optOutUrl}` - URL-адрес для отмены подписки (только для массовой рассылки),
-* `{optOutLink}` - ссылка для отмены подписки (только для массовой рассылки),
-* `{optInUrl}` - URL-адрес для подтверждения подписки (только для подтверждения подписки для Захвата кандидатов),
-* `{optInLink}` - ссылка для подтверждения подписки (только для подтверждения подписки для Захвата кандидатов).
diff --git a/i18n/ru_RU/user-guide/export.md b/i18n/ru_RU/user-guide/export.md
deleted file mode 100644
index f1e06b53f..000000000
--- a/i18n/ru_RU/user-guide/export.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Экспорт
-
-EspoCRM предоставляет возможность экспортировать записи в форматы XLSX (Excel) и CSV.
-
-### Шаг 1
-
-Выполните поиск с необходимыми фильтрами в представлении списка и выберите все результаты.
-
-
-
-### Шаг 2
-
-Нажмите на выпадающее меню *Действия*, затем нажмите *Экспортировать*.
-
-
-
-### Шаг 3
-
-Появится модальное окно, в котором вы можете указать параметры для экспорта.
-
-
-
-Вы можете выбрать определенные поля для экспорта или установить флажок для экспорта всех доступных полей.
-
-### Шаг 4
-
-После нажатия кнопки «Экспортировать», файл экспорта будет загружен.
-
-## Контроль доступа к экспорту
-
-Администратор может отключить функцию экспорта для всех пользователей, не являющихся администраторами, в разделе Администрирование > Настройки > Отключение возможности экпортирования.
-
-Также можно контролировать доступ к функции экспорта через Роли ACL с параметром «Разрешение на экспорт».
diff --git a/i18n/ru_RU/user-guide/knowledge-base.md b/i18n/ru_RU/user-guide/knowledge-base.md
deleted file mode 100644
index 2517e116c..000000000
--- a/i18n/ru_RU/user-guide/knowledge-base.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Статьи базы знаний
-
-База знаний предоставляет возможность создавать статьи. Статьи должны содержать информацию о продуктах для клиентов или помощь пользователям CRM для повышения их производительности.
-
-Чтобы сделать статью доступной на портале, необходимо установить ее статус как «Опубликован» и выбрать портал в поле «Порталы». Убедитесь, что роль портала обеспечивает доступ к базе знаний и вкладка меню навигации добавлена на портал.
-
-Если указать дату окончания срока действия, статья будет автоматически скрыта от портала в этот день.
-
-Можно указать язык для статьи. Статья будет показана только тем пользователям портала, у которых установлен этот язык.
-
-Порядок, в котором перечислены статьи, может управляться действиями в раскрывающемся меню конкретной статьи.
-
-Статьи базы знаний могут быть связаны с записями обращений, обеспечивая быстрый доступ к информации из записи обращения.
-
-## Категории
-
-Категории позволяют группировать статьи. Одна категория может содержать несколько подкатегорий. Каждая статья может относиться к одной или нескольким категориям.
-
-Категория базы знаний - это отдельный тип объекта, следовательно, доступ может контролироваться ACL.
-
-Чтобы иметь возможность искать статьи во всех подкатегориях, вам нужно переключиться в расширенный режим из контекстного меню рядом с корневой категорией.
diff --git a/i18n/ru_RU/user-guide/mail-merge.md b/i18n/ru_RU/user-guide/mail-merge.md
deleted file mode 100644
index 549529fbf..000000000
--- a/i18n/ru_RU/user-guide/mail-merge.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Слияние писем (массовая рассылка)
-
-Эта функция доступна с версии 5.3.0.
-
-1. Вам нужно иметь список целей, заполненный получателями. Доступ к спискам целей можно получить с помощью вкладки Кампании > кнопка «Списки целей» в правом верхнем углу.
-2. Создайте шаблон для типа объекта, которому вы хотите отправлять письма. Если список целей содержит записи разных типов объектов (например, Контакты и Кандидаты), вам необходимо создать шаблоны для каждого из них. Обратите внимание, что вкладка Шаблоны по умолчанию скрыта.
-3. Создайте кампанию типа Письмо (Mail). Укажите список целей для этой кампании. Укажите шаблоны.
-4. В детализации кампании щелкните раскрывающиеся меню рядом с кнопкой «Редактировать», а затем нажмите «Сгенерировать PDF-слияние». Выберите тип объекта и нажмите кнопку «Продолжить».
-
-Это сгенерирует один документ PDF для нескольких записей, которые вы можете распечатать.
-
-Обратите внимание, что по умолчанию записи с не заполненным адресным полем, пропускаются.
diff --git a/i18n/ru_RU/user-guide/markdown.md b/i18n/ru_RU/user-guide/markdown.md
deleted file mode 100644
index fd97e4452..000000000
--- a/i18n/ru_RU/user-guide/markdown.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# Синтаксис Markdown
-
-Текстовые поля поддерживают синтаксис markdown.
-
-## Код
-```
-`некоторый текст`
-```
-
-`некоторый текст`
-
-## Многострочный код
-
-```
-``` некоторый текст ```
-```
-
-```
-некоторый текст
-```
-
-## Жирный текст
-
-```
-**некоторый текст**
-```
-
-**некоторый текст**
-
-## Курсивный текст
-
-```
-*некоторый текст*
-```
-
-*некоторый текст*
-
-## Зачеркнутый текст
-
-```
-~~некоторый текст~~
-```
-
-~~некоторый текст~~
-
-## Блок цитирования (Blockquote)
-
-```
-> некоторый
-> текст
-```
-
-> некоторый
-> текст
-
-## Ссылка
-
-```
-[текст ссылки](https://www.espocrm.com)
-```
-[текст ссылки](https://www.espocrm.com)
-
-## Нумерованный список
-
-```
-1. Некоторый пункт
-2. Другой пункт
-```
-
-1. Некоторый пункт
-2. Другой пункт
-
-## Ненумерованный список
-
-```
-* Некоторый пункт
-* Другой пункт
-```
-
-* Некоторый пункт
-* Другой пункт
-
-## Горизонтальная линия
-
-```
-___
-```
diff --git a/i18n/ru_RU/user-guide/mass-email.md b/i18n/ru_RU/user-guide/mass-email.md
deleted file mode 100644
index b64f3f3b9..000000000
--- a/i18n/ru_RU/user-guide/mass-email.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Массовая рассылка
-
-## Как создать массовую рассылку
-
-Вам необходимо иметь как минимум один целевой список с целевыми записями и шаблоном электронной почты в вашем crm.
-
-1. Создайте новую кампанию со статусом `Email` или `Newsletter`. Выберите один или несколько целевых списков в поле `Целевые списки`.
-2. После создания записи кампании, вам необходимо создать электронную почту для этой кампании: нажмите «плюс» на панели «Массовая рассылка». Укажите _Дату начала_ - при отправке писем и выберите _Шаблон эл. письма_. Убедитесь в том, что _Статус_ установлен как `В ожидании`.
-
-Если все настроено правильно, электронные письма должны отправиться. Они должны отправляться частично каждый час (вы можете изменить размер порции в Администрировании > Исходящие письма). Администратор может изменить его, обновив поле `Планирование` в `Планировщике заданий для проверки учетных записей электронной почты`.
-
-Вы можете проверить, отправлены ли электронные письма или нет в панели журнала
-
-## Тестирование функции массовой рассылки
-
-Нажмите правую раскрывающуюся папку в строке массовой рассылки в панели _Массовая рассылка эл. писем_, а затем щелкните _Отправить тестовое эл. письмо_.
-
-## Журнал
-
-В журнале вы можете увидеть:
-* Отправлено ли письмо;
-* Письма, открытые получателем;
-* Ссылки, кликнутые получателем;
-* Получатели, которые отписались;
-* Возвращенные письма (не доставленные получателю).
-
-## Отказ от массовой рассылки
-
-По умолчанию система добавит ссылку для отписки от рассылки всем отправленным письмам. Но вы можете использовать личный шаблон.
-
-Например:
-```html
-Unsubscribe from the mailing list.
-```
-
-Администратор может отключить обязательное добавление ссылку для отписки от рассылки в разделе Администрирование > Исходящие письма.
-
-## Отслеживание URL
-
-Если вы хотите знать, что ваш получатель открыл ссылку с вашего письма, вам нужно создать URL отслеживание. Укажите любые _Name_ и _URL_, к которым должна привести ваша ссылка. Затем вам нужно вставить сгенерированный код в свой шаблон электронной почты.
-
- Пример:
- ```html
-Try our demo
- ```
-
-## Целевые списки
-
-Целевые списки содержат списки учетных записей, контактов, руководств и пользователей.
-
-Пользователи могут заполнять целевые списки вручную, используя действие _Select_ на соответствующей панели, подробнее в «Списке целей». Существует возможность сделать фильтрацию, а затем выбрать все результаты поиска.
-
-## Записи в целевых списках
-
-Функция [Reports](reports.md#user-content-синхронизация-с-целевыми-списками) обеспечивает возможность заполнения целевых списков записями, соответствующими определенным критериям.
-
-## Исключение целевых списков
-
-Укажите исключенные целевые списки, чтобы избежать отправки массовой почты определенным получателям. Если есть запись с адресом электронной почты, которая соответствует адресу электронной почты любой исключающей записи, первая запись также будет исключена.
-
-## Журнал кампании
-
-В Журнале кампании вы можете видеть электронные письма, которые были отправлены, открытые электронные письма, отклоненные письма, пользователей которые отписались, и кто нажал ссылку в письме. Этот журнал можно использовать, создав целевой список (раскрывающиеся меню в правом верхнем углу панели) на основе записей из журнала. Например, вы выбираете только контакты, которые щелкали по ссылке (URL-адрес отслеживания).
-
-## Исправление проблем
-
-_Для администратора_
-
-#### Что делать, если электронные письма не отправляются.
-
-1. Проверьте, работает ли _Отправить тестовое эл. письмо_. Если не работает, проверьте правильность настроек SMTP.
-2. Проверьте, установлен ли cron для вашей системы.
-3. Проверьте, есть ли задание `Отправить массовую рассылку` и статус `Активный` (Администрирование > Планировщик заданий > Отправить массовую рассылку). Проверьте, есть ли записи в журнале.
-
-#### Что делать, если отслеживание URL имеет неправильный url-адрес, который не указывает на ваш crm.
-
-Проверьте параметр 'siteUrl' в файле `data/config.php`. Он должен быть установлен как URL вашего EspoCRM, доступного из внешнего мира.
-
-#### Отправленные письма не регистрируются
-
-Отправленные электронные письма могут обрабатываться только с помощью учетной записи группы. Убедитесь, что у вас есть учетная запись электронной почты группы, которая отслеживает отправку сообщений электронной почты, отправленных в почтовый ящик.
-
-Кроме того, некоторые провайдеры почтовых серверов могут отклоняться от стандартов, поэтому отклоненные электронные письма не могут различаться.
diff --git a/i18n/ru_RU/user-guide/printing-to-pdf.md b/i18n/ru_RU/user-guide/printing-to-pdf.md
deleted file mode 100644
index 2972c900a..000000000
--- a/i18n/ru_RU/user-guide/printing-to-pdf.md
+++ /dev/null
@@ -1,112 +0,0 @@
-# Печать в PDF
-
-Примечание: эта функция доступна начиная с версии EspoCRM 5.0.5.
-
-Печать в PDF обеспечивает возможность создания PDF-документов с записанными данными. Содержимое документа определяется шаблоном.
-
-
-Примечение. Необходимо иметь по крайней мере один шаблон для типа сущности записи, которую требуется напечатать.
-
-### Печать одной записи
-
-«Печать в PDF» доступна в подробном представлении в раскрывающемся меню рядом с кнопкой «Редактировать».
-
-### Печать нескольких записей
-Эта функция доступна с EspoCRM версии 5.3.0.
-
-«Печать в PDF» доступна в виде списка как массовое действие. Вам нужно выбрать нужные записи и нажать «Печать в PDF» в меню «Действия». Это сгенерирует один объединенный файл PDF для нескольких записей.
-
-По умолчанию максимальное количество записей ограничено 50. Ограничение определяется параметром config `massPrintPdfMaxCount`.
-
-Обратите внимание, что нумерация страниц сбрасывается для каждой записи. Вам необходимо использовать заполнитель `{pageAbsoluteNumber}` для печати абсолютного количества страниц в нижнем колонтитуле.
-
-### Ограничение доступа к печати
-
-Может быть достигнуто путем ограничения доступа к типу объекта Шаблон (Template).
-
-## Шаблоны
-
-Вкладка шаблоны скрыта по умолчанию. Администратор может добавить его в Администрирование > Интерфейс пользователя.
-
-Для более точного редактирования рекомендуется использовать режим просмотра кода.
-
-Вы можете печатать поля записи, а также поля связанных записей, используя заполнители в шаблоне.
-
-Образцы:
-
-* `{{name}}` – название записи;
-* `{{assignedUserName}}` - ответственный пользователь;
-* `{{account.name}}` – название связанного контрагента.
-
-### Изображения
-
-Можно печатать поля изображения:
-
-``
-
-``
-
-где `imageId` – название настраиваемого поля изображения, связанные с `Id`.
-
-### Форматирование чисел
-
-Для отображения чисел с плавающей запятой без дробной части (в виде целого числа) используйте следующее выражение:
-
-``
-{{numberFormat quantity_RAW decimals= 0}}
-``
-
-Пользовательское форматирование значений валют:
-
-``
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-``
-
-Значение `10000.5` будет напечатано следующим образом `10 000,50`.
-
-### Текстовые поля
-
-Для отображения текстовых файлов (многострочных) используйте тройные фигурные скобки: `{{{description}}`.
-
-### Каждый итератор (Each iterator)
-
-Используйте режим просмотра кода и поместите хелпер `each` внутри html-комментария` `.
-
-Пример:
-```
-
-
-
-
{{name}}
- {{amount}}
-
-
-
-```
-
-### Поля Link-multiple
-
-Начиная с версии 5.5.0, можно проходить по множеству ссылок.
-
-Пример, печать имен контактов и ролей сделок:
-
-```
-{{#each contacts}}
- Name: {{name}},
- Role: {{opportunityRole}},
- Contact's Account Type: {{account.type}}
-{{/each}}
-```
-
-Следующий способ доступен начиная с версии 5.3.0.
-
-Пример, печать имен контактов сделки:
-```
-{{#each contactsIds}}
- {{var this ../contactsNames}}
-{{/each}}
-```
-
-### Проблемы с кодировкой
-
-Если некоторые знаки не отображаются в сгенерированных файлах PDF, это обычно можно решить, изменив шрифт в шаблоне. Для арабского языка используйте шрифт AlArabiya. Доступно с версии 5.4.0.
diff --git a/i18n/ru_RU/user-guide/products.md b/i18n/ru_RU/user-guide/products.md
deleted file mode 100644
index 7abe0feab..000000000
--- a/i18n/ru_RU/user-guide/products.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Продукты
-
-Функция "Продукты" доступна в [Sales Pack](https://www.espocrm.com/extensions/sales-pack/).
-
-Позиции продуктов могут быть использованы в Сделках и Предложениях. Они также доступны для настройки в Управлении объектами, так что вы можете создавать новые отношения между продуктами и другими объектами.
-
-Запись "Продукт" имеет три ценовых поля: Себестоимость, Цена и Цена за единицу. Существует возможность автоматического расчета цены за единицу с использованием различных формул в соответствии с выбранным Ценовым типом.
-
-
-
-Продукты могут быть добавлены в качестве списка пунктов в запись Предложения. Поля продукта можно распечатать в формате PDF. Более подробно [здесь](quotes.md#templates).
-
-Продукты могут быть добавлены в качестве списка пунктов в запись Сделки. По умолчанию эта функция отключена. Вам необходимо добавить поле "Список пунктов" в макет детализации сделки с помощью Управления макетами. Увеличьте ширину ячейки с помощью значка минус.
-
-## Категории
-
-Каждая запись типа продукт может принадлежать к какой-либо категории продуктов. Категории продуктов представлены в виде иерархической древовидной структуры. Каждая категория может иметь подкатегории.
-
-Категория продукта - это отдельный тип объекта, поэтому доступ можно контролировать с помощью ACL.
-
-Чтобы иметь возможность искать товары во всех подкатегориях, вам нужно нажать "Развернуть" в контекстном меню рядом с корневой категорией.
diff --git a/i18n/ru_RU/user-guide/quotes.md b/i18n/ru_RU/user-guide/quotes.md
deleted file mode 100644
index 9431da50a..000000000
--- a/i18n/ru_RU/user-guide/quotes.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# Предложения
-
-Функция предложений доступна в [Sales Pack](https://www.espocrm.com/extensions/sales-pack/).
-
-Предложения представляют собой определенную группу продуктов или услуг с их количеством и ценами, которые вы указываете клиентам.
-
-Предложения связаны с сделками. Вы можете добавить «Предложения» в представление детализации «Сделки». Например вот так: Администрирование > Управление макетами > Сделки > Отношения. При создании нового предложения, связанного с сделкой, оно передает элементы сделки в предложение.
-
-Вы можете добавить «Предложения» в представление детализации «Контрагентов», чтобы иметь возможность видеть связанные предложения. Это можно сделать: Администрирование > Управление макетами > Контрагенты > Отношения.
-
-## Пункты предложений (Quote Item)
-
-Предложение имеет список пунктов. Каждый пункт может представлять определенный продукт или услугу с указанием количества, налоговой ставки, цены и цены за единицу. Можно сортировать пункты вручную.
-
-Существует возможность добавлять пользовательские поля для объекта Quote Item с помощью Управления объектами.
-
-## Макет
-
-Расположение пунктов предложения можно изменить в разделе Администрирование > Управление макетами > Пункты предложения > Список (пункт). Доступно начиная с версии Advanced Pack 1.32.0.
-
-## Скидка
-
-Можно указать скидку в процентах. Чтобы иметь эту возможность, администратор должен добавить поле «Скидка (%)» (Discount (%)) в макет «Список (пункт)».
-
-## Шаблоны
-
-По умолчанию есть два доступных шаблона: Quote и Invoice. Вы можете создавать новые шаблоны (Представление списка для Предложений > Раскривающиеся меню справа вверху > Шаблоны), а также редактировать существующие.
-
-Для более точного редактирования рекомендуется использовать режим просмотра кода.
-
-Вы можете печатать поля записи предложений, а также поля связанных записей, используя заполнители в вашем шаблоне.
-
-Примеры:
-`{{accountName}}` – Имя контрагента,
-
-`{{{billingAddressStreet}}}` – улица,
-
-`{{account.type}}` – тип учетной записи,
-
-`{{assignedUser.lastName}}` – последнее имя ответственного пользователя.
-
-Если это продукт, вы можете печатать поля продукта.
-
-Примеры:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Длина и цвет - это пользовательские поля объекта Product в примерах.
-
-Предложения по пунктам:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-Можно напечатать поля изображения:
-
-```
-
-```
-где `imageId` - имя поля настраиваемого изображения, объединенное с суффиксом `Id`.
-
-Для продукта:
-```
-
-```
-
-Для отображения чисел с плавающей точкой (количество, unitPrice и т. д.), без дробной части (как целое) используйте следующие выражения (начиная с версии 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Пользовательское форматирование значений валюты (начиная с версии 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Значение `10000.5` нужно напечатать вот так: `10 000,50`.
-
-Для отображения текстовых полей (многострочных) используйте тройные фигурные скобки: `{{{description}}}`.
-
-## Печать в PDF
-
-Предложения могут быть напечатаны в формате PDF. Это действие доступно в раскрывающемся меню рядом с кнопкой «Редактировать» в детализации предложения. Затем вам будет предложено выбрать «Шаблон».
-
-## Отправка предложения по электронной почте
-
-Предложение PDF можно отправить по электронной почте в виде вложения. Откройте запись предложение, щелкнуть выпадающий список рядом с кнопкой «Редактировать» и щелчком по электронной почте «PDF».
-
-## Автоматическая нумерация
-
-Вы можете создать поле Number через Управление объектами для типа объекта Предложение. Администрирование > Управление объектами > Предложение > Поля > Добавить > Номер. Затем вам нужно поместить его в подробное представление с помощью Управления макетами.
-
-Значение будет увеличено на каждое новое предложение. Существует возможность указать следующий номер, а также префикс.
-
-## Налог по умолчанию
-
-Доступно с EspoCRM 4.8.0.
-
-1. Укажите учетную запись по умолчанию в Администрировании > Управлении объектами > Предложения > поля > Налог > По умолчанию.
-2. Укажите ставку налога по умолчанию в Администрировании > Управлении объектами > Предложения > поля > Налог (%) > По умолчанию.
-
-## Счета
-
-Предложение может рассматриваться как счет, если ее статус стал «Подтвержден». Появляются поля _Date Invoiced_, _Invoice Number_. Вы можете использовать другой шаблон счетов для печати.
diff --git a/i18n/ru_RU/user-guide/reports.md b/i18n/ru_RU/user-guide/reports.md
deleted file mode 100644
index 9908bc101..000000000
--- a/i18n/ru_RU/user-guide/reports.md
+++ /dev/null
@@ -1,125 +0,0 @@
-# Отчеты
-
-Функция отчетов доступна в [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Существует два типа отчетов: список и сетка.
-
-## Отчет-список
-
-Отчет-список выводит те записи, которые соответствуют указанным критериям.
-
-Чтобы создать новый отчет-список, нажмите вкладку «Отчеты», а затем нажмите кнопку «Создать отчет». Выберите необходимый тип объекта, затем нажмите кнопку «Создать» в разделе «Отчет-список».
-
-В поле _Columns_ выберите поля, которые вы хотите отобразить. Ниже вы можете указать параметры отображения для каждого столбца, например: ширину и выравнивание.
-
-Выберите необходимую сортировку в поле _List Order_.
-
-В разделе _Фильтры_ вы можете указать критерии, которые определят, какие записи будут перечислены в вашем отчете. Вы можете использовать логические операторы «ИЛИ», «И».
-
-_Фильтры при воспроизведении_ позволяют вам указывать разные фильтры перед запуском отчета.
-
-Вы можете __экспортировать__ результаты отчета в формате excel и csv.
-
-## Отчет-сетка
-
-В отчете по сетке суммируются значения, сгруппированные по указанным полям. Эти отчеты могут отображаться в виде диаграммы.
-
-
-
-Чтобы создать новый отчет-сетку, нажмите вкладку «Отчеты», а затем нажмите кнопку «Создать отчет». Выберите необходимый тип объекта, затем нажмите кнопку «Создать» в разделе «Отчет-сетка».
-
-В поле _Группировать по_ выберите одно или два поля, по которым вы хотите сгруппировать ваши данные отчета. Можно группировать по месяцам, месяцам, дням поля даты. Если вы группируете по двум полям, ваш отчет будет считаться трехмерным.
-
-В поле _Колонки_ выберите одну или несколько совокупных функций, таких как КОЛИЧЕСТВО, СУММА, МАКСИМАЛЬНОЕ, МИНИМАЛЬНОЕ, СРЕДНЕЕ.
-
-Поле _Сортировать по_ определяет, как будут сортироваться данные отчета.
-
-В разделе _Фильтры_ вы можете указать критерии, определяющие, какие записи будут использоваться в вашем отчете. Вы можете использовать логические операторы «ИЛИ», «И».
-
-_Фильтры при воспроизведении_ позволяет вам указать разные фильтры перед запуском отчета.
-
-Отчет-сетка позволяет отображать результаты в форме диаграммы. Существуют следующие типы _Графиков_: Столбиковый, Ленточный, Секторный, Линейный.
-
-Результаты отчета-сетки можно __экспортировать__ в формате excel и csv.
-
-## Фильтры
-
-#### Фильтр полей
-
-Простой в использовании тип фильтров. Вы также можете выбрать поля целевого объекта, а также связанные с ним объекты.
-
-
-
-### Группа ИЛИ
-
-Или означает, что по крайней мере одно условие в группе должно быть выполнено.
-
-
-
-### Группа И
-
-И означает, что все условия в группе должны быть выполнены.
-
-### Группа NOT
-
-Обеспечивает возможность фильтрации записей, не соответствующих заданным критериям. Например: перечисление контрагентов, которые не имеют сделок с закрытым статусом «Закрыто-Успех» или «Закрыто-Провал».
-
-
-
-### Комплексное выражение
-
-Для более продвинутого использования. Вы можете применить функцию для определенного столбца базы данных и сравнить ее с результатом выражения [formula](../administration/formula.md).
-
-Примечание. Если вам нужно сравнить только с простым строковым значением, вы должны поместить его в одинарные кавычки `'некоторые строки'`.
-
-Примечание. Функции, предназначенные для взаимодействия с записью сущности, здесь не работают, потому что формальная форма не применяется к конкретной записи.
-
-
-
- ## Группа Having
-Группа Having беспечивает возможность фильтрации с использованием агрегатных функций COUNT, SUM, MAX, MIN, AVG.
-
-Некоторые варианты использования:
-
-* Список контрагентов, имеющих более одной сделки. `COUNT / opportunities.id / Greater Than / 1.`
-* Отчет-сетка отображающий контрагентов, сгруппированных по отраслям, где доход превышает 1000 человек.`SUM / opportunities.amount / Greater Than / 1000.`
-
-Примечание. Совместимо с EspoCRM версий 5.1.0 и выше.
-
-## Отображение на панели управления
-
-Вы можете отображать любой отчет на панели управления. Для этого вам нужно добавить виджет Report, а затем выбрать нужный отчет в параметрах виджета.
-
-На виджете можно отображать только общую сумму.
-
-## Отправка по электронной почте
-
-Можно настроить систему для отправки результатов отчета определенным пользователям на регулярной основе в указанное время. Это должно быть настроено для определенных отчетов индивидуально.
-
-## Синхронизация с целевыми списками
-
-Можно синхронизировать списки целей с результатами отчетов-списков. Это удобно для массовой рассылки электронной почты, когда вы хотите отправлять электронные письма только контактам, которые соответствуют определенным критериям в момент отправки. Эта функция доступна в подробном представлении любого целевого списка на панели «Синхронизировать с отчетами».
-
-## Фильтры отчетов (фильтры представления списка на основе отчетов)
-
-Совместимы с EspoCRM 5.1.0 и выше.
-
-Администратор может создавать настраиваемые фильтры представления списка на основе определенных отчетов. Доступно в Администрирование > Фильтры отчетов. Можно указать группы, которые будут иметь доступ к фильтру.
-
-Примечание. Макет, указанный в отчете, не применяется к представлению списка при выборе фильтра.
-
-## Панели отчета (панели подробного просмотра, показывающие результаты отчета)
-
-Совместим с EspoCRM 5.1.0 и выше.
-
-Администратор может создавать пользовательские боковую и нижнюю панели для подробного просмотра определенного типа объекта. Можно указать группы, которые будут иметь доступ к панели.
-
-Оба отчеты (сетка и список) могут быть использованы.
-
-На панели отчетов можно отобразить только общую сумму.
-
-Порядок боковых панелей можно настроить в Менеджере макетов > Боковые панели (Detail).
-
-Порядок нижних панелей указан в записи панели отчетов. Возможно разместить панель перед панелью Лента, перед панелями Отношений или в самом низу.
-
-Панель отчетов показывает результаты, связанные с просматриваемой записи. Первое найденное отношение используется. Если в отчете имеется соответствующий фильтр при воспроизведении, он будет использоваться для ограничения результатов. Фильтр при воспроизведении должен быть полем типа link, link-multiple или link-parent.
diff --git a/i18n/ru_RU/user-guide/sales-management.md b/i18n/ru_RU/user-guide/sales-management.md
deleted file mode 100644
index 4764f2037..000000000
--- a/i18n/ru_RU/user-guide/sales-management.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# Управление продажами
-
-## Кандидаты
-
-Кандидат - это человек или организация, которая в настоящее время не является клиентом, но потенциально может им стать. Создание записи "Кандидат" обычно является первым шагом в процессе продажи. Как только дополнительная информация о кандидате будет собрана, предполагается, что он будет преобразован в контрагента, контакт и сделку.
-
-Новые кадидаты могут создаваться по следующим сценариям:
-
-* Вручную пользователями CRM;
-* Через API (например, через веб-форму);
-* Автоматически по правилу рабочего потока (Workflow).
-
-Используя [Workflows](../administration/workflows.md), администратор может настроить систему на применение определенного правила назначения для новых кандидатов, то есть на применение правил назначения Round-Robin и Least-Busy. Для более сложных бизнес-потоков рекомендуется использовать [BPM tool](../administration/bpm.md).
-
-Чтобы предотвратить пропуск новых кандидатов, пользователи могут добавить тип объекта "Кандидат" в список для автоматической подписки на созданные записи конкретных типов объектов в настройках. Тогда они будут автоматически подписаны на каждого нового кандидата.
-
-## Сделки
-
-Сделка представляет собой потенциальный или закрытый договор. Сделка со стадией "Закрыто - Успех" учитывается при расчете выручки от продаж.
-
-По умолчанию доступны следующие стадии:
-
-* Привлечение клиента;
-* Оценка возможности;
-* Предложение;
-* Согласование;
-* Закрыто - Успех;
-* Закрыто - Провал.
-
-Администратор может определить пользовательские стадии в зависимости от бизнес-потока компании: Администрирование > Управление объектами > Сделка > Поля > Стадия (Stage). Также возможно определить пользовательские стадии вероятности для каждой стадии.
-
-## Валюта
-
-Администратор может определить доступные валюты и их курсы в разделе Администрирование > Валюта. Можно конвертировать валюту существующих сделок из вида списка: выберите нужные записи, а затем нажмите «Конвертировать валюту» в раскрывающемся меню "Действия".
-
-## Аналитика продаж
-
-Следующие графики доступны на панели виджетов по умолчанию:
-
-* Продажи по месяцам;
-* Сделки по источнику кандидатов;
-* Сделки по стадиям;
-* Источники продаж.
-
-С помощью [отчётов](reports.md) можно просматривать статистику продаж на основе определенных критериев. Графики отчетов могут отображаться на панели виджетов.
-
-### Прогноз доходов
-
-1. Создайте новый отчет-сетку для типа объекта "Сделка".
-2. Добавьте "МЕСЯЦ: Дата закрытия" в поле "Группировать по".
-3. Добавьте "СУММА: Сумма (средневзвешенная)" в поле "Колонки".
-4. Добавьте "Дата закрытия" в поле "Фильтры при воспроизведении".
-5. Выберите тип графика "Столбиковый".
-
-Этот отчет покажет прогноз доходов на основе стадий вероятностей сделок.
-
-Пользователи, имеющие доступ к этому отчету, смогут добавить его на свои панели виджетов.
diff --git a/i18n/ru_RU/user-guide/stream.md b/i18n/ru_RU/user-guide/stream.md
deleted file mode 100644
index ebebb86c8..000000000
--- a/i18n/ru_RU/user-guide/stream.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Лента
-
-Лента в EspoCRM - это определенная платформа, где вы можете увидеть обновления и новости для записей, которые вам интересны. Вы также можете публиковать сообщения в своей собственной ленте и ленте других пользователей (начиная с версии 3.8.0). В EspoCRM есть два вида лент: лента записи и пользовательская лента.
-
-По умолчанию следующие объекты имеют ленту: контрагенты, контакты, сделки, обращения. Администраторы могут включать или отключать ленту для определенного объекта в [Управлении объектами](../administration/entity-manager.md).
-
-## Лента записи
-
-Лента записи отображается на панели «Лента» в представлении детализации определенной записи. Здесь размещаются сообщения, обновления и новости, связанные с текущей записью.
-
-## Пользовательская лента
-
-Пользователи могут просматривать свою ленту в виджете "Лента", а также на вкладке Лента. Пользователи также могут видеть ленты других пользователей в представлении детализации, если у них есть доступ, который контролируется полем `Разрешение видеть пользователей`.
-
-В ленте пользователя вы можете видеть сообщения, обновления и новости, связанные с записями, которые были сделаны определенным пользователем. Вы также можете видеть сообщения, которые адресованные пользователю. Эти сообщения не связаны ни с одной записью.
-
-## Оповещения
-
-Вы будете получать уведомления о новых добавлениях, которые были вызваны другими пользователями, в вашей ленте.
-
-## Сообщения
-
-Вы можете создать сообщение, связанное с определенной записью. Вы также можете прикрепить файлы и изображения к своему сообщению. Если вы хотите упомянуть кого-то в своем посте, вам нужно просто набрать символ `@` и ввести имя пользователя. Пользователь, о котором вы упомянули в своем сообщении, будет уведомлен об этом.
-
-## Сообщения для пользователей
-
-_Эта функция доступна с версии 3.8.0._
-
-Пользователи могут создавать сообщения для определенных пользователей, для определенных команд, для всех пользователей и для себя. Доступ к этой возможности контролируется полем `Разрешение на назначение` ролей.
-
-## Фильтрация
-
-Вы можете фильтровать то, что показывать в ленте: `Все`, `Сообщения` или `Обновления`.
diff --git a/i18n/ru_RU/user-guide/text-search.md b/i18n/ru_RU/user-guide/text-search.md
deleted file mode 100644
index aaae63867..000000000
--- a/i18n/ru_RU/user-guide/text-search.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Текстовый поиск
-
-## Текстовый поиск в виде "Cписок"
-
-Текстовый поиск для записей можно выполнять в виде "Список" (list view).
-
-Список полей, который используется при фильтрации, можно настроить в разделе Администрирование > Управление объектами > Редактировать определенный тип объекта > Поля текстовых фильтров.
-
-Можно использовать специальный символ `*` (доступно начиная с версии 5.3.0, для предыдущих версий использовать `%`).
-
-
-
-По умолчанию есть возможность использовать оператор "содержит" для полей varchar. Параметр доступен в Администрирование > Настройки. Обратите внимание, что это может повлиять на производительность.
-
-## Глобальный поиск (Global Search)
-
-Глобальный поиск выполняет поиск по нескольким типам объектов одновременно.
-
-Список типов объектов, используемых в глобальном поиске, можно настроить в разделе Администрирование > Настройки > Список объектов глобального поиска.
-
-Список полей, который используется при фильтрации, можно настроить в разделе Администрирование > Управление объектами > Редактировать определенный тип объекта > Поля текстовых фильтров.
-
-
-
-## Полнотекстовый поиск
-
-Доступен с версии 5.3.0.
-
-Предоставляет возможность выполнять намного более быстрый и полный текстовый поиск.
-
-Полнотекстовый поиск можно включить для указанного типа объекта в разделе Администрирование > Управление объектами > Редактировать определенный тип объекта > Полнотекстовый поиск. Требуется также перестроить ПО.
-
-Примечание: Mysql 5.5 не поддерживает полнотекстовый поиск таблиц InnoDB. 5.6.4 и более поздние версии поддерживают.
-
-Полнотекстовый поиск всегда применяется в глобальном поиске (для типов объектов с включенным полнотекстовым поиском).
-
-Текстовый поиск для записей в виде "Список" используется только для лучшей производительности. Результаты такие же, как и без полнотекстового поиска. Тем не менее, можно использовать полнотекстовый поиск, добавив `ft:` к поисковому запросу.
-
-Для таблиц InnoDB доступны следующие операторы:
-
-* `+` Ведущий знак плюс означает, что это слово должно присутствовать.
-* `-` Ведущий знак минус означает, что это слово не должно присутствовать.
-* (без оператора) Слово является необязательным, но строки, содержащие его, имеют более высокий рейтинг.
-* `*` Оператор усечения (или подстановочный знак). Добавляется к слову, которое будет затронуто.
-* `"` Фраза, заключенная в двойные кавычки, должна содержаться дословно, как она была напечатана.
diff --git a/i18n/sl-SI/administration/apache-server-configuration.md b/i18n/sl-SI/administration/apache-server-configuration.md
deleted file mode 100644
index 8d5448b46..000000000
--- a/i18n/sl-SI/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Konfiguracija Apache strežnika za EspoCRM
-
-Ta navodila dopolnjujejo navodila [Konfiguracija strežnika](server-configuration.md). Upoštevajte, prosimo, da so vse tukaj omenjene nastavitve narejene na Ubuntu strežniku.
-
-## PHP zahteve
-
-Za namestitev vseh potrebnih knjižnic vnesite v terminalu naslednje ukaze:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Odprava napake “API Error: EspoCRM API is unavailable”:
-
-Naredite samo potrebne korake. Po vsakem koraku preverite, ali je napaka odpravljena.
-
-### 1. Omogočite “mod_rewrite” podporo v Apache
-
-Da bi omogočili “mod_rewrite”, zaženite v terminalu naslednja ukaza:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Omogočite podporo za .htaccess
-
-Da bi omogočili podporo za .htaccess, dodajte/uredite nastavitve za konfiguracijo strežnika /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf ali /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Zatem zaženite v terminalu naslednji ukaz:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Dodajte RewriteBase pot
-
-Odprite datoteko /ESPOCRM_DIRECTORY/api/v1/.htaccess in zamenjajte naslednjo vrstico:
-
-```
-# RewriteBase /
-```
-
-z
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-pri čemer je REQUEST_URI del URL-ja, na primer za “http://example.com/espocrm/” je REQUEST_URI “espocrm”.
-
-
-## Omogočite podporo za HTTP AUTHORIZATION (samo za FastCGI).
-
-FastCGI ne podpira HTTP AUTHORIZATION kot privzeto nastavitev. Če uporabljate FastCGI, jo morate omogočiti v datoteki VirtualHost ali /etc/apache2/apache2.conf (httpd.conf), tako da dodate naslednjo kodo:
-
-Za Fcgid modul:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Za FastCgi modul:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Da bi preverili, kateri modul je trenutno v uporabi, zaženite ta ukaz in poiščite ustrezni modul:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/sl-SI/administration/b2c.md b/i18n/sl-SI/administration/b2c.md
deleted file mode 100644
index 89ec0510c..000000000
--- a/i18n/sl-SI/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#Konfiguracija EspoCRM za B2C (Podjetje s stranko)
-
-EspoCRM je privzeto konfiguriran za poslovanje B2B (podjetje s podjetjem). Vendar ga lahko preprosto nastavite za poslovanje B2C (podjetje s stranko).
-
-* Spremenite `b2cMode` na "true" v svoji konfiguracijski datoteki `data/config.php`. Od verzije 4.3.0 lahko to skonfigurirate v Administracija > Nastavitve.
-* Odstranite jeziček *Račun* iz navigacijskega menija (Administracija > Uporabniški vmesnik).
-* Odstranite polja *Račun* iz svojih postavitev (Administracija > Upravljalnik postavitev).
-* Onemogočite dostop do območja *Račun* za vse svoje vloge (Administracija > Vloge).
-* Odstranite Račun iz padajočih seznamov vseh nadrejenih polj (Administracija > Upravljalnik entitet > {Sestanek/Klic/Naloga/E-pošta} > Polja > Starš).
diff --git a/i18n/sl-SI/administration/backup-and-restore.md b/i18n/sl-SI/administration/backup-and-restore.md
deleted file mode 100644
index 1eeb5a445..000000000
--- a/i18n/sl-SI/administration/backup-and-restore.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# Varnostna kopija in obnovitev
-
-## Kako ročno narediti varnostno kopijo EspoCRM
-
-EspoCRM vsebuje datoteke in podatke, shranjene v podatkovni bazi. Vsi ti podatki so potrebni za ustvaritev polne varnostne kopije EspoCRM. Sledijo navodila, kako lahko to naredite na Ubuntu strežniku z MySQL.
-
-### Korak 1. Varnostna kopija datotek
-
-Ustvarite arhiv vsebine direktorija nameščenega EspoCRM. Za Ubuntu je privzeta pot `/var/www/html`. Uporabite lahko ta ukaz:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Korak 2. Varnostna kopija podatkovne baze
-
-Da bi lahko ustvarili varnostno kopijo svojih podatkov, morate vedeti ime podatkovne baze ter uporabniško ime in geslo za dostop. Ime podatkovne baze lahko najdete v konfiguracijski datoteki `/ESPOCRM_DIREKTORIJ/data/config.php` pod razdelkom `database`. Za ustvaritev varnostne kopije svoje podatkovne baze lahko uporabite ta ukaz:
-
-```bash
-mysqldump --user=UPORABNIŠKO_IME --password=VAŠE_GESLO IME_PODATKOVNE_BAZE > "db.sql"
-```
-
-### Korak 3. Kopirajte varnostno kopijo
-
-To je vse. Zdaj morate le še skopirati ustvarjeno varnostno kopijo na varno mesto.
-
-
-## Kako ustvariti varnostno kopijo EspoCRM s skripto
-
-Za to, da bi ustvarili varnostno kopijo vseh potrebnih podatkov, lahko uporabite skripto. Prijavite se prek SSH in zaženite ukaz (testirano na Ubuntu strežniku).
-
-
-### Prenesite skripto
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Zaženite skripto
-
-```bash
-bash ./backup.sh POT_DO_ESPOCRM POT_DO_VARNOSTNE_KOPIJE
-```
-pri čemer je
- * `POT_DO_ESPOCRM` pot do direktorija, kjer je nameščen EspoCRM.
- * `POT_DO_VARNOSTNE_KOPIJE` pot do direktorija, kjer se nahaja varnostna kopija.
-
-Za Ubuntu strežnik je videti takole:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Opomba: Če trenutni uporabnik MySQL nima potrebnih pravic za izvoz vaše podatkovne baze, boste pozvani, da vpišete uporabniško ime in geslo drugega MySQL uporabnika.
-
-Po uspešno ustvarjeni varnostni kopiji boste prejeli pot do te varnostne kopije.
-
-## Obnovite EspoCRM iz varnostne kopije
-
-EspoCRM lahko obnovite iz varnostne kopije, ustvarjene po zgornjem postopku.
-
-### Korak 1. Odarhiviraje datoteke varnostne kopije
-
-Za odarhiviranje datotek lahko uporabite Archive Manager ali zaženete spodnji ukaz. Datoteke morate kopirati v direktorij, ki ga bere spletni strežnik.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-pri čemer je:
- * `/var/www/html` direktorij spletnega strežnika.
-
-### Korak 2. Nastavite zahtevane pravice
-
-Lastnik datotek bi moral biti uporabnik spletnega strežnika (web-server user) in bi moral imeti pravilne pravice. Prosimo, nastavite zahtevane pravice z upoštevanjem naslednjih navodil: [www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### Korak 3. Uvozite izvoženo podatkovno bazo
-
-Izvoženo podatkovno bazo je treba uvoziti v isto podatkovno bazo z istim uporabniškim imenom in geslom, sicer je treba spremeniti konfiguracijsko datoteko `ESPOCRM_DIREKTORIJ/data/config.php`. Za uvoz vaše podatkovne baze iz izvožene datoteke zaženite spodnji ukaz v terminalu:
-
-```bash
-mysql --user=UPORABNIK_BAZE --password=GESLO_UPORABNIKA_BAZE IME_BAZE < db.sql
-```
-
-### Korak 4. Preverite/skonfigurirajte crontab
-
-Preverite, ali je vaš crontab pravilno skonfiguriran. Zaženite spodnji ukaz in preverite, ali je pot do EspoCRM pravilna:
-
-```bash
-sudo crontab -l -u www-data
-```
-pri čemer je:
- * `www-data` uporabnik spletnega strežnika (web-server user).
-
-Če morate narediti kakšno spremembno, uporabite ta ukaz:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Več podrobnosti glede konfiguriranja crontab za EspoCRM najdete tukaj: [www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
diff --git a/i18n/sl-SI/administration/bpm.md b/i18n/sl-SI/administration/bpm.md
deleted file mode 100644
index c6c22fa9d..000000000
--- a/i18n/sl-SI/administration/bpm.md
+++ /dev/null
@@ -1,209 +0,0 @@
-# Upravljanje poslovnih procesov
-
-Orodje Upravljanje poslovnih procesov (BPM) vam omogoča, da v EspoCRM oblikujete in avtomatizirate poslovne procese. Gre za stroj, ki izvaja poslovne procese, opisane v BPMN 2.0 standardu. Orodje BPM je na voljo v razširitvi [Napredni paket](https://www.espocrm.com/extensions/advanced-pack/).
-
-
-
-### Kako se razlikuje od orodja Delovni tokovi
-
-Orodje Delovni tokovi je namenjeno avtomatizaciji preprostih poslovnih pravil, brez zaporednih elementov, ki prikazujejo potek, skratka ko ni potrebno grafično prikazati poteka dela.
-
-Orodje BPM je namenjeno kompleksnejšim poslovnim potekom, pri katerih so lahko tudi razhajajoči in stekajoči se tokovi, zamiki izvajanja, posegi uporabnika. Pogled s prikazom poteka omogoča, da je poslovni proces bolj razumljiv človeku; dnevnik omogoča, da lahko vidite, kako je proces potekal.
-
-## Diagrami s prikazom poteka procesov
-
-V administracijskem panelu je na voljo povezava do diagramov s prikazom poteka procesov. Doda se jo lahko tudi kot jeziček na navigacijskem panelu.
-
-Diagrami s prikazom poteka so namenjeni oblikovanju poslovnih procesov. Administrator lahko ustvari in ureja takšne diagrame. Redni uporabniki pa lahko diagrame zgolj vidijo.
-
-Vsak diagram ima svoj specifični tip entitete (polje Tip cilja). Diagram določa izvajanje prihodnjih ustvarjenih procesov. Na njem so zajeti elementi, ki prikazujejo potek, ter povezave med elementi.
-
-Če pri diagramu ni označeno polje 'Aktiven', potem ne bo sproženo ustvarjanje procesov.
-
-Za prikaz podrobnosti in parametrov določenega elementa na diagramu morate klikniti nanj. V urejevalnem načinu boste lahko urejali parametre.
-
-## Procesi
-
-Do Procesov lahko pridete iz administracijskega panela. Povezavo se lahko doda tudi kot jeziček na navigacijskem panelu.
-
-Proces predstavlja ustvarjen poslovni proces. Ko se zažene, prejme status 'Zagnan'. Ko se proces konča, prejme status 'Končan'. Proces lahko ročno ustavi tudi uporabnik, ki ima pravice za urejanje procesa. Če se ga ustavi ročno, prejme status 'Ustavljen'.
-
-Proces se zažene glede na diagram poteka. Ko je proces enkrat zagnan, ne morete spremeniti diagrama poteka processa.
-
-Nujno je, da je proces povezan z enim samim ciljnim zapisom.
-
-Procesi se lahko zaženejo samodejno (ko so izpolnjeni določeni pogoji oziroma glede na urnik) ali ročno (če obstaja vsaj en dogodek Začetek v diagramu poteka). Da bi uporabnik ročno zagnal proces, mora klikniti gumb 'Zaženi proces' na seznamskem pogledu procesov.
-
-## Elementi Diagrama poteka
-
-### Dogodki
-
-Dogodki so na diagramu prikazani kot krogci.
-
-#### Dogodek Začetek
-
-Nima parametrov. Gre za začetno točko procesa. Dogodek Začetek lahko ročno zažene uporabnik, ki ima pravice za ustvarjanje procesov. Uporabnik mora klikniti gumb 'Zaženi proces' na seznamskem pogledu procesov.
-
-#### Dogodek Pogojni začetek
-
-Začetna točka procesa. Zažene se samodejno, ko so izpolnjeni določeni pogoji. Obstajata dva tipa sprožilcev: 'Po ustvaritvi zapisa', 'Po shranjevanju zapisa'.
-
-#### Dogodek Časovno določen začetek
-
-Začetna točka procesa. Procese zažene ob določenem času. Določiti morate seznamsko poročilo, ki vrne zapise za ustvarjanje procesov ter časovno razvrščanje v obliki, primerni za crontab.
-
-#### Dogodek Pogojno nadaljevanje
-
-Ta dogodek ustavi potek, dokler ni izpolnjen vnaprej določeni pogoj.
-
-#### Dogodek Časovno določeno nadaljevanje
-
-Ta dogodek ustavi potek in čaka tako dolgo, kot to določajo parametri dogodka.
-
-Za kompleksnejše časovne nastavitve se lahko okorisite [formule](formula.md). Skripti s formulami bi morali vrniti vrednost Datum-Čas (v UTC časovnem pasu). Ko nastopi vnaprej določeni čas, se tok nadaljuje z naslednjim elementom.
-
-Z uporabo funkcije datetime\closest je mogoče nastaviti števec na določen čas v prihodnosti, na primer na začetek naslednjega delovnega dne.
-
-#### Dogodek Konec
-
-Konča trenutni potek. Ne ustavi drugih tokov, ki potekajo vzporedno. Ko potek pride do dogodka Konec in ni nobenih vzporednih tokov, se proces konča.
-
-#### Dogodek Takojšnji konec
-
-Konča vse tokove. Proces se zatem konča.
-
-### Prehodi
-
-Prehodi so prikazani kot diamanti.
-
-#### Ekskluzivni prehod
-
-Lahko razcepi ali združi tokove.
-
-Ko pride do razcepitve, prehod določi posamični tok (pot), ki bo izbran glede na vnaprej določene pogoje. Prvi izpolnjeni pogoj določi tok, drugi pogoji se ne upoštevajo. Možno je določiti privzeti tok. Privzeti tok je izbran, če ni izpolnjen noben pogoj. Privzeti tok je označen s poševnico.
-
-Ko se tokovi združijo, prehod zgolj usmeri tok na izhodni element. Potem ko tok preide skozi prehod, se ta ne zapre, zato se vzporedni tokovi ne bodo združili v en sam tok.
-
-
-
-
-
-#### Inkluzivni prehod
-
-Lahko razcepi ali združi tokove.
-
-Ko pride do razcepitve, prehod lahko preusmeri tok na enega ali več vzporednih tokov (poti), odvisno od izpolnjenih pogojev vsakega toka. Privzeti tok je izbran, če ni izpolnjen noben pogoj. Privzeti tok je označen s poševnico.
-
-Če je potrebno združiti vzporedne tokove, ki so nastali zaradi razcepitvenega inkluzivnega prehoda, morate uporabiti združitveni inkluzivni prehod. Ta bo počakal na vse vhodne tokove in bo šele nato usmeril tok na izhodni element.
-
-
-
-Opomba: Razcepitveni in združitveni prehodi morajo biti v ravnovesju.
-
-Opomba: Če je eden od vzporednih tokov iz določenega razloga končal svojo pot, potem razcepitveni prehod nikoli ne bo aktiviran. Proces se bo ustavil. Ogibajte se takšnih diagramov poteka, ki lahko povzročijo takšno težavo.
-
-#### Vzporedni prehod
-
-Lahko razcepi ali združi tokove.
-
-Ko pride do razcepitve, razcepi tok v več vzporednih tokov. Za ta tip prehoda ni nobenih parametrov.
-
-Ko pride do združitve, prehod počaka na vse vhodne tokove in šele nato usmeri tok na naslednji izhodni element.
-
-
-
-Opomba: Razcepitveni in združitveni prehodi morajo biti v ravnovesju.
-
-Opomba: Če je eden od vzporednih tokov iz določenega razloga končal svojo pot, potem razcepitveni prehod nikoli ne bo aktiviran. Proces se bo ustavil. Ogibajte se takšnih diagramov poteka, ki lahko povzročijo takšno težavo.
-
-#### Z dogodki sprožen prehod
-
-Lahko samo razcepi tokove.
-
-Ustavi tok, dokler ni sprožen kateri koli od izhodnih dogodkov. Sproženi dogodek določi en sam tok. Drugi izhodni dogodki so zavrnjeni.
-
-Na drugi strani izhodnih zaporednih tokov so lahko samo nadaljevalni dogodki.
-
-
-
-### Aktivnosti
-
-Aktivnosti so prikazane kot zaobljeni pravokotniki.
-
-#### Naloga
-
-Naloga lahko izvrši naslednje akcije:
-
-* Ustvari zapis - ustvari nov zapis katerega koli tipa entitete;
-* Ustvari povezani zapis - ustvari nov zapis, ki je povezan s ciljnim zapisom;
-* Posodobi ciljni zapis;
-* Posodobi povezani zapis - posodobi zapis ali zapise, ki so povezani s ciljnim zapisom;
-* Posodobi ustvarjeni zapis - posodobi določeno polje katerega koli zapisa, ki je bil ustvarjen v trenutnem procesu;
-* Posodobi zapis procesa - lahko se uporabi za dodelitev procesa določenemu uporabniku ali timu;
-* Poveži z drugim zapisom - poveže ciljni zapis z izbranim zapisom;
-* Prekini povezavo z drugim zapisom - povzroči, da ciljni zapis ni več povezan z izbranim zapisom;
-* Uporabi dodelitveno pravilo - določi ciljni zapis, zapis procesa ali kateri drug zapis, ki ga je ustvaril proces glede na določeno pravilo;
-* Ustvari obvestilo - ustvari obvestilo znotraj aplikacije za določene uporabnike;
-* Ustvari sledenje - povzroči, da določeni uporabniki sledijo ciljni zapis, zapis procesa ali kateri drug zapis, ki ga je ustvaril proces;
-* Zaženi storitveno akcijo - zažene storitvene akcije po meri, ki jih izdelajo razvijalci.
-
-Akcije, ki so na voljo za nalogo, so skoraj enake tistim pri Delovnem toku. Poglejte si več podrobnosti glede [akcij pri delovnem toku](workflows.md#actions).
-
-#### Pošlji sporočilo z nalogo
-
-Pošlje e-poštno sporočilo določenemu prejemniku.
-
-#### Uporabnikova naloga
-
-Omogoča prilagodljiv sistem uporabnikove interakcije. Ustavi izvajanje, dokler uporabnik (določen eksplicitno ali z dodelitvenim pravilom) ne opravi naloge. V sistemu bo ustvarjen zapis Proces uporabnikove naloge.
-Originalno so na voljo trije tipi akcij: Sprejmi, Preglej, Opravi.
-
-* Tip Sprejmi zahteva, da uporabnik izbere med 'Sprejeto' in 'Zavrnjeno'.
-* Tip Preglej ima samo eno možnost: 'Pregledano'.
-* Tip Opravi ima dve možnosti: 'Opravljeno' in 'Neopravljeno'.
-
-
-Uporabnik, ki je določen ustvarjenemu zapisu Proces uporabnikove naloge, bo prejemal obvestila znotraj aplikacije. Administrator lahko omogoči tudi e-poštna obvestila.
-
-Uporabniki lahko prav tako dodajo element Proces uporabnikove naloge na svojo nadzorno ploščo, da lahko spremljajo dejanski proces svojih nalog.
-
-Obstaja možnost branja rešitve opravljene uporabnikove naloge znotraj razcepitvenih prehodov ali pogojnih dogodkov, s čimer se naredi ustrezna razcepitev v poteku procesa.
-
-#### Skriptna naloga
-
-Zažene skript v [Espo-formula](formula.md) jeziku. Vse določene spremenljivke (`$imeSpremenljivke`) bodo shranjene in na voljo znotraj procesa.
-
-### Tokovi
-
-#### Zaporedni tok
-
-Predstavljen je z neprekinjeno puščico. Prikazuje zaporedje, v katerem bodo elementi procesa izvršeni.
-
-## Pogoji
-
-Pogojni dogodki - ekskluzivni in inkluzivni razcepitveni prehodi imajo pogoje, ki določajo potek procesa.
-
-V uporabniškem vmesniku se lahko označi pogoje za naslednje zapise:
-
-* Ciljni zapis;
-* Zapisi, ki so povezani s ciljem z relacijami več proti eden in otroci proti starši;
-* Zapisi, ki jih je ustvaril proces s pomočjo nalog;
-* Zapisi uporabnikovih nalog, ki omogočajo pregled rešitev naloge.
-
-Pogoje je prav tako možno določiti v [Espo-formula](formula.md) jeziku.
-
-Pogoji v orodju BPM so enaki kot pri orodju Delovni tokovi. Poglejte si več podrobnosti o [pogojih delovnega toka](workflows.md#conditions).
-
-## Primeri
-
-### Primer 1
-
-
-
-### Primer 2
-
-
-
-### Primer 3
-
-
diff --git a/i18n/sl-SI/administration/email-fetching.md b/i18n/sl-SI/administration/email-fetching.md
deleted file mode 100644
index de837c5a9..000000000
--- a/i18n/sl-SI/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# E-pošta
-
-Dokument je bil prestavljen [sem](emails.md).
diff --git a/i18n/sl-SI/administration/emails.md b/i18n/sl-SI/administration/emails.md
deleted file mode 100644
index 7d7bb5cad..000000000
--- a/i18n/sl-SI/administration/emails.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# E-pošta
-
-> Pomembno. Da bi v vašem sistemu delovalo pobiranje e-pošte, je potrebno skonfigurirati [cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab). Informacije lahko dobite v svojem EspoCRM pod Administration > Scheduled Jobs.
-
-## Pregled
-
-EspoCRM ima možnost nadzora IMAP poštnih predalov. E-pošta se lahko arhivira na dva načina: kot skupinski e-poštni računi in kot osebni e-poštni računi. Skupinski dohodni računi so namenjeni za skupinske poštne predale: najpogosteje se uporablja poštni predal za podporo. Osebni e-poštni računi so namenjeni za osebne poštne predale uporabnikov.
-
-Ko prispe e-pošta, jo sistem poskuša povezati z ustreznim zapisom (Računi, Sled, Priložnost, Primer). Uporabniki, ki sledijo ta zapis, bodo v sistemu prejeli obvestilo o novi e-pošti, tudi če niso navedeni v polju Za ali CC.
-
-## Skupinski e-poštni računi
-
-Samo administrator lahko nastavi skupinske e-poštne račune. Skupinski e-poštni računi se lahko uporabljajo tako za prejemanje kot pošiljanje pošte. Pošiljanje e-pošte iz skupinskih računov je na voljo od verzije 4.9.0.
-
-Polje Teams določa, katerim timom bo dodeljena dohodna e-pošta.
-
-Če ima skupinski e-poštni račun SMTP in je označen kot deljen, potem bodo dostop nadzorovale vloge (Roles) pod pravice za Skupinski e-poštni račun. Če je stopnja pravic nastavljena na 'team', bo uporabljeno polje Teams.
-
-Obstaja tudi možnost nastavitve, da sistem pošlje samodejni odgovor za dohodno e-pošto.
-
-## E-pošta ustvari primer
-
-Obstaja možnost, da se sistem nastavi tako, da ta ustvari primere iz dohodne skupinske e-pošte. Ta možnost je namenjena timom za podporo. Primere se lahko razdeli uporabnikom iz določenega tima na naslednje načine: `direct assignment` (neposredno dodeljevanje), `round-robin` (krožno dodeljevanje) in `less-busy` (dodeljevanje najmanj zasedenemu). Samo prvo e-poštno sporočilo v nizu povezane pošte ustvari nov primer. Vsako nadaljnje sporočilo se poveže z že obstoječim zapisom primera in se prikaže v njegovem Stream panelu.
-
-Kadar uporabniki želijo poslati odgovor stranki, se morajo prepričati, da je primer izbran kot starš e-poštnega sporočila, ki se pošilja. Ta odgovor stranki bo poslan iz skupinskega e-poštnega naslova, ne pa iz uporabnikovega.
-
-## Osebni e-poštni računi
-
-Uporabniki lahko nastavijo svoje osebne e-poštne račune, ki jih je treba nadzorovati. Emails > Padajoči meni zgoraj desno > Personal Email Accounts. Tudi administrator lahko upravlja e-poštne račune uporabnikov.
-
-## E-poštni filtri
-
-Ti omogočajo filtriranje dohodne e-pošte glede na določene kriterije. Na primer, če ne želite, da se sporočila za obveščanje, ki jih pošlje določena aplikacija, uvozijo v EspoCRM, lahko ustvarite filter, da jih EspoCRM izpusti.
-
-Administrator lahko ustvari globalne filtre, ki potem veljajo za vse e-poštne račune. Uporabniki lahko ustvarijo filtre za svoj osebni e-poštni račun in za celotni poštni predal.
diff --git a/i18n/sl-SI/administration/entity-manager.md b/i18n/sl-SI/administration/entity-manager.md
deleted file mode 100644
index fc290426e..000000000
--- a/i18n/sl-SI/administration/entity-manager.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Upravljalnik entitet
-
-Upravljalnik entitet je na voljo v panelu Administracija. Omogoča vam, da svoj EspoCRM sistem popolnoma prilagodite svojim potrebam. Omogoča vam naslednje:
-
-* Dodajanje novih tipov entitet.
-* Prilagajanje obstoječih tipov entitet: lahko spremenite oznake, privzeti vrstni red v seznamskem pogledu, omogočite ali onemogočite tok.
-* Prilagajanje polj: lahko dodate nova polja, prilagodite obstoječa.
-* Prilagajanje relacij: lahko dodate nove relacije, spremenite oznake za obstoječe.
-
-## Ustvarjanje nove entitete
-
-Kliknite gumb `Ustvari entiteto` na strani Upravljalnik entitet. Določite ime, oznako in tip. Če izberete tip `Oseba`, bo vaša entiteta vsebovala polja E-pošta, Telefon, Ime, Priimek in Pozdrav. Označite `Tok`, če želite, da bo imela vaša entiteta panel s prikazom toka ter da bodo uporabniki lahko sledili entitetam tega tipa.
-
-Tipi:
-
-* Osnovni - prazna entiteta s samo osnovnimi polji, kot so Ime, Dodeljeni uporabnik, Timi, Opis.
-* Osnovni plus - podoben tipu Osnovni, toda s paneli Aktivnosti, Zgodovina, Opravila (na voljo od verzije 4.3.0).
-* Dogodek - polja Začetni datum, Končni datum, Trajanje, Starš, Status. Na voljo v panelu Koledar in Aktivnosti (od verzije 4.3.0, potrebno omogočiti v Administracija > Nastavitve).
-* Oseba - polja E-pošta, Telefon, Ime, Priimek, Pozdrav, Naslov. Paneli Aktivnosti, Zgodovina, Opravila.
-* Podjetje - polja E-pošta, Telefon, Naslov za izstavitev računa, Naslov za dostavo. Paneli Aktivnosti, Zgodovina, Opravila.
-
-## Posodabljanje obstoječe entitete
-
-Če pri določeni entiteti kliknete povezavo `Uredi`, boste lahko spremenili nekatere parametre te entitete.
-
-* Oznake - ime entitete v ednini in množini.
-* Privzeti vrstni red, po katerem so zapisi sortirani v seznamskih pogledih.
-* Tok - ali je možnost Tok omogočena za to entiteto.
-* Onemogočena - označite, če ne potrebujete te entitete v svojem sistemu.
-* Besedilna filtrirna polja - v katerih poljih naj išče glavni besedilni filter in globalni iskalnik.
-
-
-## Polja
-
-Klik na povezavo `Polja` vas bo prestavil na ločeno stran. Na njej boste lahko ustvarili nova polja ali posodobili že obstoječa. V Upravljalniku entitet so na voljo naslednji tipi polj:
-
-* Naslov - naslov, ki je sestavljen iz ulice, mesta, zvezne države, poštne številke in države;
-* Tabela - seznam vrednosti z možnostjo izbire več vrednosti (ni dobra izbira, če morate iskati po tem polju); uporabniki lahko dodajo svoje vrednosti, če ni kako drugače določeno.
-* Večkratna priponka - več pripetih datotek;
-* Samodejno oštevilčevanje - generirana številka, ki jo je mogoče le brati;
-* Boolean - potrditveno polje, pravilno ali napačno;
-* Valuta - za vrednosti valut;
-* Datum;
-* Datum in čas;
-* Enum - izbirno poljo z možnostjo izbire le ene vrednosti;
-* Datoteka - nalaganje ene datoteke;
-* Plavajoča vejica - decimalna številka;
-* Foreign - polje povezane entitete;
-* Slika - nalaganje slikovne datoteke s predogledom;
-* Integer - celo število;
-* Številka - auto-incrementing number of string type with a possible prefix and a specific length;
-* Multi-enum - seznam vrednosti z možnostjo izbire več vrednosti (ni dobra izbira, če morate iskati po tem polju), podobno Tabeli, vendar lepše.
-* Besedilo - besedilno področje za dolga, večvrstična besedila;
-* Url - za povezave;
-* Varchar - kratko besedilo;
-* Wysiwyg - podobno besedilnemu polju, z možnostjo oblikovanja besedila.
-
-Parametri:
-* Zahtevano - ali mora polje obvezno vsebovati vrednost.
-* Privzeta vrednost - vrednost polja ob ustvaritvi novega zapisa.
-* Sledenje - spremembe polja se bodo beležile v Tok.
-
-**Opomba**: Potem ko dodate novo polje, morate to polje dodati na [postavitve](layout-manager.md) (Administracija > Upravljalnik postavitev).
-
-### Dinamična logika
-
-Omogoča možnost izdelave dinamičnih obrazcev. Možno je določiti pogoje, kdaj bodo določena polja vidna, zahtevana ali samo bralna. Pogoji se preverijo samodejno, ko se podatki na obrazcu spremenijo.
-
-Za Enum, Tabelo in Multi Enum polja je možno določiti različne skupke možnosti, ki bodo na voljo za polje, odvisno od tega, kateri pogoj je izpolnjen.
-
-
-## Relacije
-
-Ustvarite lahko nove relacije tako med privzetimi kot prilagojenimi entitetami. Obstajajo trije tipi relacij:
-
-* Eden proti več: potem ko ste ustvarili to relacijo, lahko dodate Url polje v postavitev s prikazom podrobnosti desne entitete in dodate relacijski panel levi entiteti;
-* Več proti eden: enako kot Eden proti več, vendar ravno obratno;
-* Več proti več: relacijska panela na obeh straneh.
-
-Parameter 'Poveži večkratno polje' kaže na to, da bo polje tipa `linkMultiple` ustvarjeno skupaj z relacijo. Takšno polje lahko dodate postavitvi. Je prikladno za hitro izbiro povezanih zapisov. Ni pa dobra izbira, če ima vaša relacija veliko povezanih zapisov, ki lahko upočasnijo nalaganje zaslona s prikazom podrobnosti.
-
-Če je označen parameter 'Sledenje', se bodo spremembe relacije beležile v Tok.
diff --git a/i18n/sl-SI/administration/extensions.md b/i18n/sl-SI/administration/extensions.md
deleted file mode 100644
index 0beaebb33..000000000
--- a/i18n/sl-SI/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Upravljanje razširitev
-
-## Kako namestiti razširitev
-
-Za namestitev EspoCRM razširitve (na primer Napredni paket, VoIP integracija):
-
-1. Prijavite se kot administrator.
-2. Pojdite na Administracija > Razširitve.
-3. Naložite svoj razširitveni paket (zip datoteko).
-4. Kliknite gumb Namesti.
-
-
-## Kako nadgraditi razširitev
-
-Za nadgradnjo že nameščene razširitve (na primer Napredni paket, VoIP integracija) na novejšo verzijo:
-
-1. Prenesite novo verzijo potrebne razširitve.
-2. Prijavite se kot administrator.
-3. Pojdite na Administracija > Razširitve.
-4. Naložite svoj novi razširitevni paket (zip datoteko), ne da bi prej odstranili že nameščeno verzijo.
-5. Kliknite gumb Namesti.
-
-
-## Kako odstraniti razširitev (uninstall)
-
-Koraki za odstranitev nameščene razširitve:
-
-1. Prijavite se kot administrator.
-2. Pojdite na Administracija > Razširitve.
-3. Poiščite potrebno razširitev v seznamu razpoložljivih razširitev.
-4. Kliknite gumb Odstrani.
-
-
-## Kako zbrisati razširitev
-
-Ko je razširitev odstranjena, je še vedno na voljo v sistemu. Lahko jo popolnoma zbrišete. Koraki za brisanje razširitve:
-
-1. Prijavite se kot administrator.
-2. Pojdite na Administracija > Razširitve.
-3. Poiščite potrebno razširitev v seznamu razpoložljivih razširitev.
-4. Kliknite gumb Zbriši.
diff --git a/i18n/sl-SI/administration/formula.md b/i18n/sl-SI/administration/formula.md
deleted file mode 100644
index 4654ca952..000000000
--- a/i18n/sl-SI/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Izračunana polja (Formula)
-
-V Upravljalniku entitet je možno definirati skript (formulo) za določen tip entitete. Ta skript se bo izvršil vsakič, preden bo zapis shranjen.
-To omogoča, da se določenim poljem (atributom) samodejno nastavijo vrednosti, pridobljene iz izračuna.
-
-Za urejanje formule pojdite na Administracija > Upravljalnik entitet > padajoči meni na desni pri vrstici izbrane entitete > Formula.
-
-Prav tako bi bilo dobro, da poljem, ki bodo prejela izračunane vrednosti, nastavite atribut Samo branje v Upravljalniku entitet.
-
-
-## Sintaksa
-
-EspoCRM formula se piše v preprostem jeziku, oblikovanem posebej za ta namen.
-
-V formuli lahko uporabite operatorje ter atribute in vrednosti funkcij. Ločene izraze morate ločiti z znakom `;`.
-
-### Operatorji
-
-* `=` - prireditev,
-* `||` - logični ALI,
-* `&&` - logični IN,
-* `!` - logični NE,
-* `+`- numerično seštevanje,
-* `-` - numerično odštevanje,
-* `*` - numerično množenje,
-* `/` - numerično deljenje,
-* `%` - numerični modul (preostanek po deljenju),
-* `==` - primerjava: je enako,
-* `!=` - primerjava: ni enako,
-* `>` - primerjava: večje kot,
-* `<` - primerjava: manjše kot,
-* `>=` - primerjava: večje ali enako,
-* `<=` - primerjava: manjše ali enako.
-
-Prioriteta operatorjev:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Atributi
-
-Atributi predstavljajo vrednosti polj ciljne entitete. Atribute, ki so na voljo, lahko dodate s klikom na gumb plus.
-
-Do atributov povezanih entitet lahko dostopate z zapisom v naslednji obliki: `imePovezave.imeAtributa`.
-
-
-### Funkcije
-
-Funkcije se uporablja v naslednji obliki: `imeSkupine\imeFunkcije(argument1, argument2, ..., argumentN)`.
-
-V nadaljevanju so navedene privzete funkcije.
-
-#### ifThenElse
-`ifThenElse(POGOJ, POSLEDICA, ALTERNATIVA)` Če je POGOJ izpolnjen, potem naredi POSLEDICO. Če ni, potem naredi ALTERNATIVO.
-
-#### ifThen
-`ifThen(POGOJ, POSLEDICA)` Če je POGOJ izpolnjen, potem naredi POSLEDICO. Če ni, potem ne naredi nič.
-
-#### string\concatenate
-`string\concatenate(NIZ_1, NIZ_2)` Spoji oziroma združi dva ali več nizov.
-
-#### string\substring
-`string\substring(NIZ, ZAČETEK, DOLŽINA)` Izlušči znake iz NIZA od pozicije ZAČETEK in z določeno DOLŽINO.
-
-Če je DOLŽINA izpuščena, potem bo rezultat funkcije podniz od pozicije ZAČETEK do konca NIZA.
-
-Če je DOLŽINA negativna, potem bo tolikšno število znakov izpuščenih od konca NIZA.
-
-#### string\\trim
-`string\trim(NIZ)` Odstrani prazen prostor (znake za presledek) na začetku in na koncu NIZA.
-
-#### string\\lowerCase
-`string\lowerCase(NIZ)` Vse znake niza pretvori v male črke. (od verzije 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(NIZ)` Vse znake niza pretvori v velike črke. (od verzije 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Vrne današnji datum.
-
-#### datetime\now
-`datetime\now()` Vrne trenutni datum in čas.
-
-#### datetime\format
-`datetime\format(VREDNOST, [ČASOVNI PAS], [FORMAT])` Pretvori VREDNOST datum ali datum-čas v niz, formatiran glede na nastavitve aplikacije. Argumenta ČASOVNI PAS in FORMAT se lahko izpusti. Če je ČASOVNI PAS izpuščen, potem bo uporabljen privzeti časovni pas. Če je FORMAT izpuščen, potem bo uporabljen privzeti format.
-
-#### datetime\date
-`datetime\date(VREDNOST, [ČASOVNI PAS])` Vrne datum v mesecu (1-31). Če VREDNOST ni določena, vrne `0`. Če je ČASOVNI PAS izpuščen, potem se uporabi sistemski časovni pas. (od verzije 4.7.0)
-
-#### datetime\month
-`datetime\month(VREDNOST, [ČASOVNI PAS])` Vrne mesec (1-12). Če VREDNOST ni določena, vrne `0`. Če je ČASOVNI PAS izpuščen, potem se uporabi sistemski časovni pas. (od verzije 4.7.0)
-
-#### datetime\year
-`datetime\year(VREDNOST, [ČASOVNI PAS])` Vrne leto. `0` Če VREDNOST ni določena, vrne `0`. Če je ČASOVNI PAS izpuščen, potem se uporabi sistemski časovni pas. (od verzije 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VREDNOST, [ČASOVNI PAS])` Vrne uro (0-23). Če VREDNOST ni določena, vrne `-1`. Če je ČASOVNI PAS izpuščen, potem se uporabi sistemski časovni pas. (od verzije 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VREDNOST, [ČASOVNI PAS])` Vrne minuto (0-59). Če VREDNOST ni določena, vrne `-1`. Če je ČASOVNI PAS izpuščen, potem se uporabi sistemski časovni pas. (od verzije 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VREDNOST, [ČASOVNI PAS])` Vrne dan v tednu (0-6). Če VREDNOST ni določena, vrne `-1`. Za nedeljo vrne `0`. Če je ČASOVNI PAS izpuščen, potem se uporabi sistemski časovni pas. (od verzije 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VREDNOST_1, VREDNOST_2, VRSTA INTERVALA)` Vrne razliko med dvema datumoma ali poljema datum-čas. VRSTA INTERVALA je lahko 'years', 'months', 'days', 'hours', 'minutes'. Če izračun ne uspe, vrne `null`. Če je VREDNOST_1 < VREDNOST_2, je rezultat negativen.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VREDNOST, MINUTE)` Doda MINUTE k VREDNOSTI polja datum-čas. MINUTE so lahko negativne.
-
-#### datetime\addHours
-`datetime\addHours(VREDNOST, URE)` Doda URE k VREDNOSTI polja datum-čas. URE so lahko negativne.
-
-#### datetime\addDays
-`datetime\addDays(VREDNOST, DNEVI)` Doda DNEVE k VREDNOSTI polja datum-čas. DNEVI so lahko negativni.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VREDNOST, TEDNI)` Doda TEDNE k VREDNOSTI polja datum-čas. TEDNI so lahko negativni.
-
-#### datetime\addMonths
-`datetime\addMonths(VREDNOST, MESECI)` Doda MESECE k VREDNOSTI polja datum-čas. MESECI so lahko negativni.
-
-#### datetime\addYears
-`datetime\addYears(VREDNOST, LETA)` Doda LETA k VREDNOSTI polja datum-čas. LETA so lahko negativna.
-
-#### datetime\closest
-`datetime\closest(VREDNOST, VRSTA, CILJ, [V_PRETEKLOSTI], [ČASOVNI PAS])` Vrne datum ali datum-čas, ki je najbližje VREDNOSTI upoštevajoč posredovane argumente. (od verzije 5.0.0)
-
-VRSTA je lahko ena od naslednjih vrednosti: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. CILJ je celo število ali niz. V_PRETEKLOSTI pomeni, da poišče najbližjo vrednost v preteklosti. Če je ČASOVNI PAS izpuščen, potem se uporabi privzeti časovni pas.
-
-Primeri:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Vrne najbližjo vrednost datum-čas v prihodnosti s časom 20:00.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Vrne `2017-11-01`, prvi dan v mesecu.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Vrne naslednji ponedeljek (na začetku dneva).
-
-#### number\format
-`number\format(VREDNOST, [DECIMALKE], [DECIMALNA VEJICA], [LOČEVANJE TISOČIC])` Pretvori numerično VREDNOST v niz, formatiran glede na navedeni format ali glede na privzete nastavitve aplikacije. Če je argument DECIMALKE, DECIMALNA VEJICA ali LOČEVANJE TISOČIC izpuščen, potem se uporabijo sistemske privzete nastavitve.
-
-Primeri:
-
-`number\format(2.666667, 2)` - rezultat je 2.67;
-
-`number\format(1000, 2)` - rezultat je 1,000.00;
-
-`number\format(10.1, 0)` - rezultat je 10.
-
-
-#### number\abs
-`number\abs(VREDNOST)` Absolutna vrednost. Če VREDNOST ni numerična, vrne null.
-
-#### number\round
-`number\round(VREDNOST, NATANČNOST)` Vrne zaokroženo vrednost VREDNOSTI z navedeno NATANČNOSTJO (število decimalk). NATANČNOST je lahko tudi negativna ali enaka nič (privzeto).
-
-#### number\floor
-`number\floor(VREDNOST)` Vrne naslednje najnižje celo število, tako da zaokroži vrednost navzdol, če je potrebno. (od verzije 4.9.0)
-
-#### number\ceil
-`number\ceil(VREDNOST)` Vrne naslednje najvišje celo število, tako da zaokroži vrednost navzgor, če je potrebno. (od verzije 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Vrne TRUE, če je entiteta nova (je bila ustvarjena) in FALSE, če ni (je bila posodobljena).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATRIBUT)` Vrne TRUE, če se je ATRIBUT entitete spremenil.
-
-Primer:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATRIBUT)` Vrne TRUE, če se ATRIBUT entitete ni spremenil.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATRIBUT)` Atribut, ki je bil določen, ko je bila ciljna entiteta naložena iz baze podatkov. Preden je bil spremenjen.
-
-Primer:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(POVEZAVA, ID)` Doda ID polju Poveži več. Na primer, polju 'timi' doda 'nekiTimId'.
-
-`entity\addLinkMultipleId(POVEZAVA, ID_SEZNAM)` Doda seznam id-jev. (od verzije 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(POVEZAVA, ID)` Preveri, ali ima polje Poveži več določen ID.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(POVEZAVA, ID)` Odstrani določen ID polju Poveži več.
-
-#### entity\isRelated
-`entity\isRelated(POVEZAVA, ID)` Preveri, ali je ciljna entiteta povezana z drugo entiteto, predstavljeno s POVEZAVO in ID-jem.
-
-#### env\userAttribute
-`env\userAttribute(ATRIBUT)` Vrne ATRIBUT trenutnega uporabnika.
-
-#### list
-`list(VREDNOST-1, ... VREDNOST-N)` Vrne tabel. (od verzije 4.7.0)
-
-#### array\includes
-`array\includes(SEZNAM, VREDNOST)` Vrne true, če SEZNAM vsebuje VREDNOST. Uporabi se lahko za polji Tabela in Multi-Enum. (od verzije 4.7.0)
-
-#### array\push
-`array\push(SEZNAM, VREDNOST1 [, VREDNOST2 ...])` Doda en ali več elementov na konec tabele in vrne novo tabelo. (od verzije 5.0.0)
-
-#### array\length
-`array\length(SEZNAM)` Vrne število elementov v SEZNAMU. (od verzije 4.8.1)
-
-
-### Vrednosti
-
-* Nizi. Na primer 'neki niz';
-* Cela števila. Na primer 1, 100, 40300.
-* Decimalna števila. Na primer 5.2.
-
-### Spremenljivke
-
-V formuli je možno definirati lastne spremenljivke.
-```
-$imeNekeSpremenljivke = 'Test';
-opis = $test;
-```
-
-
-## Primeri
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-znesek = produkt.navedenaCena - (produkt.navedenaCenaPretvorjena * popust / 100.0);
-valutaZneska = 'EUR';
-```
-
-```
-nekoPolje = string\concatenate(ime, " '", srednjeIme, "' ", priimek);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Uporaba formule v Delovnih tokovih
-
-Formulo lahko uporabite v pogojih in akcijah Delovnih tokov. Za več informacij si poglejte [dokumentacijo za delovne tokove](workflows.md).
diff --git a/i18n/sl-SI/administration/import.md b/i18n/sl-SI/administration/import.md
deleted file mode 100644
index f86833a09..000000000
--- a/i18n/sl-SI/administration/import.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Uvoz
-
-Uvoz je dostopen samo uporabnikom z administratorskimi pravicami. Administracija > Uvoz. Podatke lahko uvažate samo iz CSV datotek.
-
-## Korak 1
-
-Izberite, katere vrste zapisov želite uvoziti (polje Tip entitete). Izberite CSV datoteko. Datoteka bi morala biti v formatu `UTF-8`.
-Izberite `Kaj naj naredim?`. Možnosti, ki so na voljo: 'Samo ustvari', 'Ustvari in posodobi', 'Samo posodobi'.
-
-* `Samo ustvari` - izberite to možnost, če želite, da je zapis samo ustvarjen.
-* `Ustvari in posodobi` - zapisi bodo ustvarjeni, toda če se bodo našli zapisi z ujemajočimi se vrednostmi polj, bodo tudi posodobljeni. To, katera polja naj bi se ujemala, boste lahko preverili eno po eno v _Koraku 2_.
-* `Samo posodobi` - posodobljeni bodo samo zapisi z ujemajočimi se vrednostmi polj.
-
-Potem ko izberete csv datoteko, boste lahko videli, kako bo ta razčlenjena, in sicer v panelu Predogled. Ko spremenite lastnosti, se predogled posodobi.
-
-* `Vrstica glave` - ali CSV datoteka vsebuje prvo vrstico z imeni polj.
-* `Zaženi v mirovanju` - priporočeno, če morate uvoziti zelo veliko število zapisov. Uvoz bo časovno koordiniran s cron-om. Ko bo uvoz dokončan, bo status nastavljen na 'Končano'.
-* `Ne išči podvojitev` - to bo skrajšalo čas uvoza.
-
-Kliknite gumb _Naprej_ za nadaljevanje v _Korak 2_.
-
-
-
-## Korak 2
-
-Nastavite preslikavo polj: kako polja ustrezajo stolpcem v csv datoteki.
-Stolpcev, ki jih ne potrebujete, lahko izpustite tukaj. V primeru 'Ustvari in posodobi' ter 'Samo posodobi', morate preveriti polja, po katerih naj bi se posodobljeni zapisi našli. Dodajte privzete vrednosti za nove in posodobljene zapise. Na primer, lahko določite polji Dodeljeni uporabnik ali Timi.
-
-Potem ko bo uvoz podatkov končan, boste lahko razveljavili ustvarjene zapise, videli podvojitve ter posodobili zapise. Podvojitev pomeni, da je v sistemu že obstajal podoben zapis. Vse uvožene podvojitve lahko odstranite hkrati. Opomba: Razveljavitev ne deluje s posodobljenimi zapisi.
-
-Kliknite gumb _Prični z uvozom_ za nadaljevanje. Postopek uvoza lahko traja kar nekaj časa. Če želite uvoziti veliko število zapisov (odvisno od vaše konfiguracije strežnika, ponavadi če je več kot 200 zapisov), morate poskrbeti, da bo php parameter `set_time_limit` dovolj velik.
-
-
-
-## Kako uvoziti v Ciljni seznam
-
-Ko uvažate Kontakte, Sledi ali Račune, jih lahko dodate na isti ciljni seznam. Pri koraku 2 morate dodati polje Ciljni seznam na panel `Privzete vrednosti` in izbrati potrebni zapis ciljnega seznama. Za to, da dodate obstoječe cilje na ciljni seznam, lahko uporabite tudi možnost uvoza `Samo posodobi` ali `Ustvari in posodobi`.
diff --git a/i18n/sl-SI/administration/installation.md b/i18n/sl-SI/administration/installation.md
deleted file mode 100644
index 49290110e..000000000
--- a/i18n/sl-SI/administration/installation.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Namestitev
-
-### Zahteve
-EspoCRM deluje na večini domen ponudnikov gostovanja. K zahtevam spada naslednje:
-
-* PHP 5.6 ali najnovejša verzija PHP z omogočenimi pdo, json, GD library, mcrypt razširitvami (ponavadi so že privzeto omogočene);
-* MySQL 5.5.3 ali novejši.
-
-Glej članek [Konfiguracija strežnika](server-configuration.md) za več informacij.
-
-### 1. Prenesite EspoCRM namestitveni paket
-Za najnovejšo različico EspoCRM obiščite to [stran za prenos](http://www.espocrm.com/download/).
-
-### 2. Naložite EspoCRM datoteke na svoj strežnik
-
-Ko bo prenos paketa končan, ga naložite na svoj spletni strežnik.
-V na namen lahko uporabite SSH, FTP ali gostujoči administratorski panel.
-Arhiv ekstrahirajte na svoj javni direktorij spletnega strežnika (npr. `public_html`, `www` itd.).
-
-_Opomba: Če uporabljate FTP, morate arhiv ekstrahirati prej, preden ga naložite na svoj spletni strežnik._
-
-### 3. Ustvarite MySQL podatkovno bazo za EspoCRM
-
-Pojdite v svoj gostujoči administratorski panel ali uporabite SSH ter ustvarite novo podatkovno bazo in uporabnika za EspoCRM (npr. `MySQL Databases` v cPanel-u).
-
-### 4. Zaženite EspoCRM namestitveni postopek
-
-Zdaj odprite svoj brskalnik in pojdite na URL z EspoCRM datotekami (npr. `http://yourdomain.com/espo`).
-
-Če vidite ta zaslon, je prišlo do napake "Nimate pravic".
-Torej morate zagnati prikazani ukaz v terminalu prek SSH oziroma nastaviti pravilne pravice (755 za direktorije, 644 za datoteke in 775 za direktorij `data`. Prav tako poskrbite, da bosta pravilno določena lastnik (_owner_) in skupina (_group_).
-
-
-
-Če vidite naslednji zaslon, so pravice pravilne in lahko začnete z namestitvijo EspoCRM.
-
-
-
-Na tej strani lahko preberete in sprejmete Licenčno pogodbo.
-
-
-
-Vnesite podrobnosti za svojo novo ustvarjeno MySQL podatkovno bazo.
-
-
-
-Vnesite uporabniško ime in geslo administratorja EspoCRM.
-
-
-
-Na tej strani lahko določite privzete nastavitve za EspoCRM, kot so format datuma in časa, časovni pas, valuto in drugo.
-
-
-
-Vnesite SMTP nastavitve za odhodno e-pošto, če želite imeti možnost pošiljanja e-pošte.
-Ta korak lahko preskočite s klikom na gumb _Naprej_.
-Vse te možnosti lahko dodate/uredite v EspoCRM po namestitvi.
-
-
-
-Čestitamo! Namestitev je končana.
-Kot zadnji korak je potrebno nastaviti funkcijo razporejanja opravil, da bo potekala na vašem sistemu. To lahko storite tako, da zaženete `crontab -e` v linux opravilni vrstici ter v _Windows Tasks Scheduler_ v operacijskem sistemu Windows.
-
-
-
-Upamo, da boste z veseljem delali v EspoCRM.
diff --git a/i18n/sl-SI/administration/layout-manager.md b/i18n/sl-SI/administration/layout-manager.md
deleted file mode 100644
index f230ab0bb..000000000
--- a/i18n/sl-SI/administration/layout-manager.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Upravljalnik postavitev
-
-Upravljalnik postavitev je na voljo v panelu Administracija.
-Omogoča vam, da prilagodite videz podrobnostnih, urejevalnih, seznamskih pogledov kakor tudi iskalnih filtrov in polj obrazcev za masovno posodobitev.
-
-## Seznam
-
-Glavna postavitev za seznamski pogled. Določa stolpce in njihove parametre.
-
-
-
-Razpoložljivi parametri za stolpce so navedeni spodaj.
-
-### Širina (%)
-
-Širina stolpca v odstotkih, prazno pomeni samodejna nastavitev širine.
-
-### Povezava
-
-Če je ta parameter označen, potem bo polje prikazano kot povezava na podrobnostni pregled zapisa. Ponavadi se uporablja za polja z imeni.
-
-### Brez sortiranja
-
-Onemogoči možnost sortiranja stolpca.
-
-### Poravnava
-
-Možnost leve ali desne poravnave stolpca.
-
-## Podrobnosti
-
-Glavna postavitev za podrobnostni pogled in urejevalni pogled. Določa panele, vrstice in celice. Celice vsebujejo polja.
-
-Vrstica lahko vsebuje dve celici ali eno celico, ki se razteza po celotni širini vrstice. Če želite dodati vrstico z razširjeno celico, morate dodati nov stolpec in klikniti na znak minus pri kateri koli celici.
-
-
-
-## Seznam (majhen)
-
-Seznamska postavitev za relacijske panele. Lahko se uporabi tudi na drugih mestih, kjer je razumno prikazati sezname v ozkem pogledu.
-
-## Podrobnosti (majhen)
-
-Podrobnostni pogled za obrazce hitro ustvarjanje, hitri pogled in hitro urejanje.
-
-## Iskalni filtri
-
-Seznam polj po katerih se lahko išče, ki so na voljo v seznamskem pogledu.
-
-## Masovna posodobitev
-
-Seznam polj, ki so na voljo na obrazcu Masovna posodobitev.
-
-## Relacijski paneli
-
-Seznam relacijskih panelov, ki je prikazan na dnu podrobnostnega pogleda. Panele se lahko prerazporedi. Panelu lahko določite barvo s parametrom Stil.
-
-## Stranski paneli
-
-Stranski paneli za obrazce Podrobnosti, Urejanje, Podrobnosti majhen, Urejanje majhen. Omogoča vam, da skrijete ali prerazporedite seznamske panele Aktivnosti, Zgodovina, Opravila in še druge. Panelom lahko določite barvo s parametrom Stil.
-
-## Dodatne postavitve
-
-Nekateri tipi entitet vsebujejo še dodatne postavitve: Pretvarjanje sledi, Seznam za račun.
diff --git a/i18n/sl-SI/administration/ldap-authorization-for-ad.md b/i18n/sl-SI/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index ef3d87b19..000000000
--- a/i18n/sl-SI/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# LDAP avtorizacija za Active Directory
-
-Primer konfiguracije LDAP avtorizacije za Active Directory strežnik. Podrobna navodila za konfiguracijo LDAP avtorizacije najdete [tukaj](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/sl-SI/administration/ldap-authorization-for-openldap.md b/i18n/sl-SI/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index ae27a19c0..000000000
--- a/i18n/sl-SI/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# LDAP avtorizacija za OpenLDAP
-
-Primer konfiguracije LDAP avtorizacije za OpenLDAP strežnik. Podrobna navodila za konfiguracijo LDAP avtorizacije najdete [tukaj](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/sl-SI/administration/ldap-authorization.md b/i18n/sl-SI/administration/ldap-authorization.md
deleted file mode 100644
index 958ec292e..000000000
--- a/i18n/sl-SI/administration/ldap-authorization.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# LDAP avtorizacija
-
-V tem razdelku bomo pokazali, kako skonfigurirati LDAP avtorizacijo za EspoCRM. Pa pričnimo!
-
-Pojdite na vaš LDAP strežnik in ustvarite osnovni DN za uporabnike EspoCRM, na primer
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Ustvariti moramo sistemskega uporabnika, ki bo imel dostop do DN uporabnikov (“cn=espo-users,ou=users,dc=espo,dc=local”). Potemtakem bo polni DN za tega sistemskega uporabnika
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Zdaj lahko dodamo LDAP uporabnika, da bo dostopal do EspoCRM. Na primer, Espo Tester z uporabniškim imenom “tester” znotraj “cn=espo-users,ou=users,dc=espo,dc=local” DN. Prosimo, upoštevajte: da boste lahko uporabljali to obliko prijave za EspoCRM, morate izbrati možnosti “Atribut uporabniško ime“ in “Osnovni DN“.
-
-Nato pojdite na nastavitve avtentikacije (overitve) EspoCRM v administracijskem panelu, izberite način `LDAP` in izpolnite podrobnosti glede LDAP:
-
-
-
-* Gostitelj – LDAP IP ali ime gostitelja.
-* Vrata – vrata povezave.
-* Auth – dostopne pravice za LDAP strežnik:
- * Polni DN uporabnika – polni sistemski DN uporabnika, ki omogoča iskanje drugih uporabnikov.
- * Geslo – geslo za dostop do LDAP strežnika.
-* Varnost – SSL ali TSL protokol.
-* Atribut uporabniško ime – atribut, ki določa uporabnika. Za Active Directory je lahko “userPrincipalName” ali “sAMAccountName”.
-* Pristna oblika računa – tip vaše pristne oblike računa. Obstajajo 4 možnosti:
- * Dn – oblika `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Uporabniško ime – oblika `tester`.
- * Leva poševnica – oblika `COMPANY\tester`.
- * Glavno ime – oblika `tester@company.com`.
-* Povezovanje zahteva DN – če je potrebno uporabniško ime predstaviti v DN obliki.
-* Osnovni DN – privzeti osnovni DN, ki se uporablja za iskanje uporabnikov.
-* Filter prijave uporabnikov – filter, s katerim se lahko omeji uporabnike, ki lahko uporabljajo EspoCRM. Na primer, `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Domensko ime računa – Domena, ki se uporablja za avtorizacijo LDAP strežnika.
-* Kratko domensko ime računa – Kratko ime domene, ki se uporablja za avtorizacijo LDAP strežnika.
-* Poskusi razdeliti uporabniško ime – možnost razdelitve uporabniškega imena z domeno.
-* Možnost napotitve – ali so možne napotitve do LDAP odjemalca.
-* Ustvari uporabnika v EspoCRM – ta možnost omogoča ustvaritev EspoCRM uporabnika iz LDAP.
- * Atribut ime uporabnika – LDAP atribut, ki se uporablja za določitev imena uporabnika.
- * Atribut priimek uporabnika – LDAP atribut, ki se uporablja za določitev priimka uporabnika.
- * Atribute naziv uporabnika – LDAP atribut, ki se uporablja za določitev naziva uporabnika.
- * Atribut e-poštni naslov uporabnika – LDAP atribut, ki se uporablja za določitev e-poštnega naslova uporabnika.
- * Atribut telefonska številka uporabnika – LDAP atribut, ki se uporablja za določitev telefonskega številke uporabnika.
-
-Zdaj pa pojdite na prijavno stran ter vpišite uporabniško ime in geslo.
-
-
-
-Uporabnik je bil avtenticiran (overjen) in samodejno ustvarjen v EspoCRM.
-
-## Navodila za konfiguracijo glede na vaš strežnik:
-* [Active Directory strežnik](ldap-authorization-for-ad.md)
-* [OpenLDAP strežnik](ldap-authorization-for-openldap.md)
-
-Več informacij glede konfiguriranja LDAP lahko najdete na strani [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/), saj EspoCRM uporablja to knjižnico.
diff --git a/i18n/sl-SI/administration/maps.md b/i18n/sl-SI/administration/maps.md
deleted file mode 100644
index baa9e8cd2..000000000
--- a/i18n/sl-SI/administration/maps.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# Zemljevidi
-
-## Kako prikazati zemljevid glede na informacije v polju Naslov
-
-Vsako polje Naslov ima tudi ustrezno polje Zemljevid. Vse, kar morate storiti, je to, da ga namestite na postavitev Podrobnosti. Uporablja storitev Google Zemljevidi.
-
-`Administracija > Upravljalnik postavitev > Izberite entiteto (Račun, Kontakt, Sled ali po meri) > Podrobnosti > Povlecite in spustite polje Zemljevid.`
-
-Razširite polje z uporabo znaka minus.
-
-Prav tako lahko spremenite višino svojega polja.
-
-`Administracija > Upravljalnik postavitev > Izberite entiteto > Polja > poiščite polje Zemljevid in kliknite nanj > uredite višino in shranite.`
-
-## Api ključ
-
-Od EspoCRM verzije 4.2.0 dalje morate določiti Api ključ, če želite uporabljati Googlje Zemljevidi (Administracija > Integracija > Google Zemljevidi)
diff --git a/i18n/sl-SI/administration/moving-to-another-server.md b/i18n/sl-SI/administration/moving-to-another-server.md
deleted file mode 100644
index 1ba5a4387..000000000
--- a/i18n/sl-SI/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Prenos EspoCRM na drug strežnik
-
-Za prenos EspoCRM na drug strežnik naredite naslednje korake:
-
-### Korak 1. Naredite varnostno kopijo datotek
-
-Odprite upravitelja datotek ali pa se prijavite prek SSH ter arhivirajte vse razpoložljive datoteke, ki so v EspoCRM direktoriju. Več podrobnosti:
-https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### Korak 2. Naredite varnostno kopijo podatkovne baze
-
-Morali bi narediti varnostno kopijo podatkov, shranjenih v podatkovni bazi (MySQL, MariaDB). Prosimo, upoštevajte to priporočilo:
-https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### Korak 3. Varnostni kopiji datotek in podatkovnih baz kopirajte na drug strežnik
-
-Kopirajte varnostni kopiji datotek in vaše podatkovne baze na nov strežnik.
-
-### Korak 4. Odarhiviraje datoteke varnostnih kopij
-
-Za odarhiviranje datotek varnostnih kopij lahko uporabite Archive Manager ali ta navodila:
-https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-Opomba: Datoteke je treba kopirati v direktorij, ki ga bere spletni strežnik.
-
-### Korak 5. Skonfigurirajte strežnik
-
-Skonfigurirajte novi strežnik v skladu z naslednjimi priporočili: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### Korak 6. Popravite pravice
-
-Določite potrebne pravice in lastnika datotek: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### Korak 7. Uvozite varnostno kopijo podatkovne baze
-
-Najprej morate ustvariti novo podatkovno bazo z uporabnikom v MySQL. Za uvoz podatkovne baze iz varnostne kopije upoštevajte ta navodila:
-https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### Korak 8. Spremenite konfiguracijo EspoCRM
-
-Potem ko boste uspešno uvozili in skonfigurirali strežnik, prosimo, ustrezno spremenite konfiguracijo EspoCRM v datoteki `ESPOCRM_DIREKTORIJ/data/config.php`:
-
- * nastavitve za povezave podatkovne baze:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'IME_PODATKOVNE_BAZE',
- 'user' => 'UPORABNIK_BAZE',
- 'password' => 'GESLO_UPORABNIKA_BAZE',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - če se je vaše ime domene (URL) spremenilo:
-
- ```php
- 'siteUrl' => 'https://nova-povezava.com',
- ```
-
- * privzeti lastnik datotek (samo, če se je spremenil):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- kjer je `www-data` vaš uporabnik spletnega strežnika (web-server user).
-
-### Korak 9. Nastavite crontab
-
-Nastavite crontab: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-Opomba: skonfiguriran mora biti pod uporabnikom spletnega strežnika.
-
-To je vse. Od zdaj naprej je vaš EspoCRM na novem strežniku.
diff --git a/i18n/sl-SI/administration/nginx-server-configuration.md b/i18n/sl-SI/administration/nginx-server-configuration.md
deleted file mode 100644
index 1ef618f3e..000000000
--- a/i18n/sl-SI/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Konfiguracija Nginx strežnika za EspoCRM
-
-Ta navodila dopolnjujejo navodila [Konfiguracija strežnika](server-configuration.md). Upoštevajte, prosimo, da so vse tukaj omenjene nastavitve narejene na Ubuntu strežniku.
-
-## PHP zahteve
-
-Za namestitev vseh potrebnih knjižnic vnesite v terminalu naslednje ukaze:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Odprava napake “API Error: EspoCRM API is unavailable”:
-
-Naredite samo potrebne korake. Po vsakem koraku preverite, ali je napaka odpravljena.
-
-### 1. Omogočite pravila za prepisovanje (rewrite rules) na Nginx strežniku
-
-Dodajte naslednjo kodo v konfiguracijsko datoteko za Nginx strežniški blok (/etc/nginx/sites-available/YOUR_SITE) znotraj “server” bloka:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Če ta datoteka ne obstaja, jo morate ustvariti. To lahko storite tako, da v terminalu zaženete ta ukaz:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-In dodajte kodo, ki je navedena zgoraj. Za več informacij, kako skonfigurirati nov Virtual Host na Nginx strežniku, prosimo, preberite ta [ navodila](nginx-virtual-host.md).
-
-Zaženite ta ukaz v terminalu, da bi preverili, ali je vse v redu:
-
-```
-sudo nginx -t
-```
-
-Če je, z naslednjim ukazom ponovno zaženite nginx strežnik:
-
-```
-sudo service nginx restart
-```
-
-### 2. Dodajte RewriteBase pot
-
-Odprite datoteko /ESPOCRM_DIRECTORY/api/v1/.htaccess in zamenjajte naslednjo vrstico:
-
-```
-# RewriteBase /
-```
-z
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-pri čemer je REQUEST_URI del URL-ja, na primer za “http://example.com/espocrm/” je REQUEST_URI “espocrm”.
diff --git a/i18n/sl-SI/administration/nginx-virtual-host.md b/i18n/sl-SI/administration/nginx-virtual-host.md
deleted file mode 100644
index fa7106279..000000000
--- a/i18n/sl-SI/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Kako skonfigurirati Virtual Host na Nginx strežniku za EspoCRM
-
-V tem priročniku bomo pokazali, kako skonfigurirati virtual host na Nginx-u za EspoCRM na Ubuntu strežniku.
-
-## Ustvarite datoteko s strežniškim blokom
-
-Da bi ustvarili to datoteko, v terminalu zaženite naslednji ukaz:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Sedaj odprite to datoteko (/etc/nginx/sites-available/espocrm.conf) in spremenite kodo, da bo ustrezala spodnjemu formatu (nekatere nastavitve bodo morda drugačne, odvisno od vaše konfiguracije):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Omogočite ta strežniški blok
-
-Ustvarite simbolično povezavo:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Zaženite ta ukaz, da bi preverili, ali je vse v redu:
-
-```
-sudo nginx -t
-```
-
-In ponovno zaženite Nginx strežnik:
-
-```
-sudo service nginx restart
-```
-
-## Skonfigurirajte "local hosts" (kot opcija, samo v primeru lokalne domene)
-
-Če ste dodali lokalno domeno, jo morate skonfigurirati na svojem računalniku (ne na strežniku). Za Ubuntu odprite datoteko `/etc/hosts` in dodajte vrstico:
-
-```
-192.168.1.1 espocrm.local # specify the IP address of your Nginx server
-```
-
-Za Windows, prosimo, upoštevajte ta [navodila](http://support.microsoft.com/kb/923947).
diff --git a/i18n/sl-SI/administration/portal.md b/i18n/sl-SI/administration/portal.md
deleted file mode 100644
index 2162896ff..000000000
--- a/i18n/sl-SI/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Portal
-
-Portal omogoča možnost, da dostopate do določenih crm podatkov in funkcij za vaše stranke in partnerje. Administrator lahko ustvari več portalov. Vsak portal ima lahko svoje nastavitve, nadzorno ploščo, seznam uporabnikov, nastavitve nadzora dostopa.
-
-Za ustvaritev portala pojdite na Administracija > Portali, kliknite gumb Ustvari portal.
-
-* `Je aktiven`. Če ni označen, potem portal ne bo na voljo nikomur.
-* `Je privzet`. Pomeni, da bo portal na voljo po krajšem url-ju: http(s)://VAS_ESPO_URL/portal.
-* `Vloge`. Določite eno ali več vlog na portalu, ki bodo dodeljene uporabnikom, prijavljenim v portal. Več informacij glede vlog na portalu najdete spodaj.
-* `Seznam zavihkov`. Zavihki, ki bodo vidni v navigacijski vrstici.
-* `Postavitev nadzorne plošče`. Določite elemente, ki bodo prikazani na domači strani portala. Upoštevajte, da uporabniki portala ne morejo konfigurirati svoje nadzorne plošče.
-* `URL`. Samo bralno polje, ki vsebuje povezavo, s katero lahko dostopate do portala.
-
-## Uporabniki portala
-
-Administratorji lahko ustvarijo uporabnike portala.
-
-1. Administracija > Uporabniki.
-2. Kliknite desni padajoči meni poleg Ustvari uporabnika.
-3. Kliknite na Ustvari uporabnika portala.
-4. Izberite Kontakt, s katerim bo uporabnik povezan.
-5. Izpolnite obrazen in kliknite Shrani.
-
-Uporabnik portala bi moral biti povezan z zapisom portala, da bi lahko dostopal do njega.
-
-## Vloge na portalu
-
-Vloge na portalu so podobne običajnim vlogam v EspoCRM, toda z nekaj razlikami.
-
-* Stopnja `ni določen` onemogoča dostop.
-* Stopnja `lasten` pomeni, da je uporabnik tisti, ki ustvari zapis. Na primer, uporabnik portala je odprl nek primer in ta uporabnik je zdaj lastnik tega primera.
-* Stopnja `račun` pomeni, da je zapis povezan z računom, s katerim je uporabnik portala povezan.
-* Stopnja `kontakt` pomeni, da je zapis povezan z zapisom, s katerim je uporabnik portala povezan.
-
-Polji Dodeljen uporabnik in Timi lahko uporabniki portala zgolj berejo.
-
-### Primer
-
-`Uporabniki portala naj bi imeli možnost ustvarjati primere, videti primere, ki so povezani z njihovim računom; imeli naj bi tudi možnost videti bazo znanja.`
-
-1. Odprite obrazec Ustvari vlogo na portalu (Administracija > Vloge na portalu > Ustvari vlogo).
-2. Omogočite dostop do Primerov, nastavite: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. Omogočite dostop do Baze podatkov, nastavite `create - no, read - account, edit - no, delete - no`.
-4. Uredite svoj zapis portala (Administracija > Portali). Izberite svojo vlogo na portalu v polju Vloge in nato shranite.
-
-## Dostop do portala
-
-Url za vaš portal lahko najdete v polju 'URL' v zapisu portala. Prav tako je možno uporabiti orodja za konfiguracijo strežnika (kot je mod_rewrite), da bi do portala lahko dostopali z drugačnim url-jem. Za ta primer morate izpolniti polje 'URL po meri'.
-
-### Dostop do portala z URL-jem po meri za Apache strežnik
-
-URL po meri: ime-gostitelja-mojega-portala.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /pot/do/espocrm/
- ServerName ime-gostitelja-mojega-portala.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias ime-gostitelja-mojega-portala.com
-
-```
-
-#### Mod rewrite pravila
-
-Določite številko zapisa portala namesto `{PORTAL_ID}`. Številka zapisa portala je na voljo v naslovni vrstici vašega brskalnika, ko odprete podrobnostni pogled zapisa portala. Primer: https://moj-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 je številka zapisa portala.
-
-```
- RewriteCond %{HTTP_HOST} ^ime-gostitelja-postala.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^ime-gostitelja-postala.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/sl-SI/administration/roles-management.md b/i18n/sl-SI/administration/roles-management.md
deleted file mode 100644
index 7c47e1ae4..000000000
--- a/i18n/sl-SI/administration/roles-management.md
+++ /dev/null
@@ -1,103 +0,0 @@
-# Upravljanje vlog
-
-## Pregled
-
-Da bi omejili dostop za nekatere uporabnike, morate uporabiti Vloge (Roles). Administrator lahko upravlja vloge v administratorskem panelu. Vsaka vloga določa dostop do določenih področij in je dodeljen uporabnikom, ki imajo to vlogo.
-
-En uporabnik ima lahko več vlog. Te vloge so lahko izbrane za specifičnega uporabnika (polje ‘Roles’ pri postavki User) in/ali so podedovane od tima, ki mu uporabnik pripada.
-
-Če ima uporabnik več vlog, potem se te združijo, tako da ima vloga z več pravicami višjo prioriteto. To omogoča administratorju, da z lahkoto in veliko fleksibilnostjo upravlja nastavitve stopenj dostopa.
-
-To, katere pravice ima določeni uporabnik, lahko preverite tako, da kliknete na gumb 'Access' na podrobnem pogledu uporabnika.
-
-
-
-## Primer
-
-Denimo, da uporabnik pripada timu ‘Sales’. Ta tim ima samo eno vlogo, ‘Salesman’. Torej bodo vsi uporabniki iz tega tima dobili vlogo ‘Salesman’.
-
-Vloga ‘Salesman’ je določena takole:
-
-Sled:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Priložnost:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Uporabniki bodo lahko imeli vpogled samo v tiste sledi in priložnosti, ki pripadajo timu ‘Sales Department’ (polje ‘Teams’). Uporabniki bodo lahko urejali samo tiste sledi in priložnosti, ki so jim dodeljene oziroma tiste, ki so jih sami ustvarili. Uporabniki ne bodo mogli odstraniti nobene sledi ali priložnosti.
-
-Določenemu uporabniku, ki ima v podjetju položaj vodje prodaje, želimo omogočiti več pravic. Ta uslužbenec mora imeti možnost branja/urejanja/brisanja vseh zapisov tima ‘Sales’. Uporabnik bi moral pripadati našemu timu ‘Sales’. Vendar moramo ustvariti novo vlogo ‘Sales Manager’ in za tega uporabnika izbrati to vlogo v polju ‘Roles’.
-
-Vloga ‘Sales Manager’ je določena takole:
-
-Sled:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Priložnost:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Naš uporabnik bo lahko upravljal vse sledi in priložnosti tima ‘Sales’.
-
-## Posebne pravice
-
-### Pravice dodeljevanja
-
-Nastavite ta parameter, če želite omejiti možnost dodeljevanja/premeščanja zapisov drugemu uporabniku in/ali timu. Če izberete `team`, potem bo možno dodeljevati le uporabnikom znotraj lastnega tima(ov). Če pa izberete `no`, uporabniki sploh ne bodo mogli dodeljevati/premeščati zapisov.
-
-Ta pravica prav tako določa, ali uporabnik lahko objavlja na tok drugih uporabnikov/timov.
-
-### Pravice uporabnika
-
-Omogočajo, da se uporabnikom omeji možnost vpogleda v aktivnosti, koledar in tok drugih uporabnikov.
-
-### Pravice portala
-
-Določajo dostop do informacij na portalu, možnost objavljanja sporočil uporabnikom portala.
-
-### Pravice skupinskega e-poštnega računa
-
-Določajo dostop do skupinskih e-poštnih računov, možnost pošiljanja e-pošte iz skupinskega SMTP.
-
-### Pravice izvažanja
-
-Določajo, ali uporabnik lahko izvaža zapise. (od verzije 4.9.0 dalje)
-
-## Privzete nastavitve
-
-Če ni določenih nobenih pravic, potem lahko uporabniki berejo in urejajo vse zapise. Vendar pa jih ne morejo brisati, razen tistih, ki so jih sami ustvarili in so jim hkrati tudi dodeljeni.
-
-Vseeno obstaja možnost, da se omeji dostop, ki je določen na začetku, tako da se omogoči način 'ACL Strict Mode' pod Administration > Settings.
-
-## Varnost na nivoju polj
-
-Omogoča nadzor dostopa za določena polja.
-
-Privzete nastavitve so takšne, da lahko uporabnik bere vsa polja, če lahko bere zapis. Uporabnik lahko ureja vsako polje, če lahko ureja zapis. Dostop do določenih polj lahko omejite z uporabo varnosti na nivoju polj (Field Level Security).
-
-V pogledu za urejanje zapisa vloge v razdelku Field Level kliknite na ikono poleg določenega območja in nato izberite ustrezno polje. Zatem boste lahko določili stopnjo dostopa za akcijo `read` (branje) in `edit` (urejanje). Obstajata dve možnosti: `yes` in `no`.
-
-
diff --git a/i18n/sl-SI/administration/server-configuration.md b/i18n/sl-SI/administration/server-configuration.md
deleted file mode 100644
index aa983ada8..000000000
--- a/i18n/sl-SI/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Konfiguracija strežnika za EspoCRM
-
-EspoCRM lahko namestite na Apache ([navodila](apache-server-configuration.md)), Nginx ([navodila](nginx-server-configuration.md)) ali IIS strežnik, ki podpira PHP verzijo 5.6 ali višjo in MySQL verzijo 5.1 ali višjo.
-
-## Predlagane konfiguracijske nastavitve
-
-### PHP zahteve
-
-EspoCRM zahteva PHP verzijo 5.6 ali višjo z naslednjimi omogočenimi razširitvami (extensions):
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – za dostop do MySQL v PHP-ju;
-* [JSON](http://php.net/manual/en/book.json.php) – viri uporabljajo ta format (metadata, postavitev strani, jeziki in drugo);
-* [GD](http://php.net/manual/en/book.image.php) – za delo s slikami;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – za zagotovitev najvišje zaščite;
-* [Zip](http://php.net/manual/en/book.zip.php) – za možnost nadgradnje EspoCRM in namestitev razširitev;
-* [IMAP](http://php.net/manual/en/book.imap.php) – za nadzor poštnih predalov v EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Priporočljivo je tudi, da imate nameščeno [mailparse](https://pecl.php.net/package/mailparse) pecl razširitev. Potrebna je za brezhibno funkcionalnost pobiranja e-pošte.
-
-php.ini nastavitve:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### MySQL zahteve
-
-EspoCRM podpira MySQL verzijo 5.1 ali višjo.
-Tukaj ni nobenih posebnosti. Vse privzete nastavitve so ustrezne za EspoCRM.
-
-## Potrebne pravice za sisteme, temelječe na Unixu
-
-Datoteke in direktoriji bi morali imeti naslednje pravice:
-
-* `/data`, `/custom`, `/client/custom` – možnost zapisovanja morajo imeti vse datoteke, direktoriji in poddirektoriji (664 za datoteke, 775 za direktorije, vključno z vsemi poddirektoriji in datotekami);
-* `/application/Espo/Modules`, `/client/modules` – možnost zapisovanja mora imeti trenutni direktorij (775 za trenutni direktorij, 644 za datoteke, 755 za direktorije in poddirektorije);
-* Možnost branja morajo imeti vse druge datoteke in direktoriji (644 za datoteke, 755 za direktorije).
-
-Pravice lahko nastavite z naslednjimi ukazi v terminalu:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Lastnik in skupinski lastnik vseh datotek bi moral biti proces spletnega strežnika. To je lahko “www-data”, “daemon”, “apache”, “www” itd.
-Opomba: Če uporabljate Bitnami Stack, mora biti lastnik in skupinski lastnik datotek “daemon” uporabnik.
-Opomba: Če uporabljate spletno gostovanje, mora biti lastnik in skupinski lastnik datotek vaš uporabniški račun.
-
-Lastnika in skupinskega lastnika lahko nastavite s temi ukazi v terminalu:
-
-```
-cd
-chown -R : .;
-```
-
-## Nastavite crontab
-
-Da bi nastavili crontab v sistemu UNIX, naredite naslednje korake:
-
-* 1. V EspoCRM se prijavite kot administrator.
-* 2. V administratorskem panelu izberite razdelek Scheduled Jobs (Menu > Administration > Scheduled Jobs) in kopirajte niz za crontab. Videti je takole:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Odprite terminal in zaženite ta ukaz:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER je lahko eden od naslednjih: “www”, “www-data”, “apache” itd. (odvisno od vašega spletnega strežnika).
-* 4. Prilepite kopirani niz (iz koraka 2) in shranite crontab datoteko (Ctrl+O, nato Ctrl+X za nano urejevalnik).
-
-## Navodila za konfiguracijo vašega strežnika:
-
-* [Konfiguracija Apache strežnika](apache-server-configuration.md).
-* [Konfiguracija Nginx strežnika](nginx-server-configuration.md).
diff --git a/i18n/sl-SI/administration/troubleshooting.md b/i18n/sl-SI/administration/troubleshooting.md
deleted file mode 100644
index e71ce59e0..000000000
--- a/i18n/sl-SI/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Odpravljanje napak
-
-## Preverite dnevnike (logs)
-
-Da bi našli vzrok težave, morate preveriti datoteke z dnevniki napak.
-
-#### EspoCRM dnevniki napak
-
-EspoCRM dnevniki se nahajajo v `/logs/*.log` in vsebujejo nekatere informacije o napakah.
-
-#### Apache dnevniki napak
-
-Za Ubuntu strežnik se apache dnevnik napak nahaja v `/var/log/apache2/error.log` in vsebuje vse informacije o napakah. Lokacija dnevniških datotek se na drugih sistemih lahko razlikuje.
-
-## Omogočite razhroščevalni način
-
-Da bi omogočili razhroščevalni način, pojdite EspoCRM direktorij, ki je bil ustvarjen ob namestitvi, odprite datoteko `data/config.php` in spremenite vrednost:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-na
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Razporejanje opravil ne deluje
-
-#### Problem #1: Vaš crontab ni skonfiguriran
-
-1. Prijavite se na svoj strežnik prek SSH.
-
-2. Svoj crontab skonfigurirajte z upoštevanjem naslednjih korakov: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-Opomba: Crontab bi moral biti nastavljen za delo z uporabnikom za spletni strežnik (web-server user), na primer `crontab -e -u www-data`.
-
-3. Počakajte nekaj časa in preverite razdelek Razporejanje opravil, da bi videli, ali je bilo kakšno opravilo zagnano (poglejte panel Dnevnik).
-
-#### Problem #2. Crontab je skonfiguriran, vendar Razporejanje opravil ne deluje
-
-Da med delovanjem crona ne bi prihajalo do napak, poskusite zagnati ukaz cron v terminalu:
-
-1. Prijavite se na svoj strežnik prek SSH.
-
-2. Pojdite v direktorij, kjer je EspoCRM nameščen. Na primer, za direktorij `/var/www/html/espocrm` vnesite naslednji ukaz:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Zaženite ukaz crontab:
-
-```bash
-php cron.php
-```
-
-Opomba: Zagnati bi ga morali z uporabnikom za spletni strežnik. Če ste prijavljeni kot root, je ukaz naslednji (na primer za Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-kjer je `www-data` uporabnik za spletni strežnik.
-
-4. Če ni nobenih napak, preverite Razporejanje opravil, da bi videli, ali je bilo kakšno opravilo zagnano (poglejte panel Dnevnik).
-
-## EspoCRM se po nadgradnji ne naloži
-
-To se lahko včasih zgodi pri nekaterih deljenih gostovanjih.
-
-Preverite pravice datotek:
-/index.php
-/api/v1/index.php
-
-Biti morajo 644. Če ima katera od datotek pravico 664, jo morate spremeniti na 644. Uporabite nadzorno plošo gostitelja oziroma ukaz chmod.
-
-```
-chmod 644 /pot/do/datoteke
-```
-Več o pravicah datotek najdete: [tukaj](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/sl-SI/administration/upgrading.md b/i18n/sl-SI/administration/upgrading.md
deleted file mode 100644
index 37a143060..000000000
--- a/i18n/sl-SI/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Kako nadgraditi EspoCRM
-
-EspoCRM lahko nadgradite na najnovejšo verzijo z upoštevanjem naslednjih korakov:
-
-### 1. korak: Preverite trenutno verzijo
-
-Da bi preverili trenutno verzijo, obiščite stran Administration > Upgrade.
-
-### 2. korak: Prenesite potrebne pakete za nadgradnjo
-
-Obiščite stran za nadgradnjo https://www.espocrm.com/download/upgrades/ in upoštevajoč vašo trenutno verzijo prenesite potrebne pakete.
-
-### 3. korak: Ustvarite varnostno kopijo (po želji)
-
-Pred nadgradnjo ustvarite varnostno kopijo svojih EspoCRM datotek in podatkov. Pri tem upoštevajte [ta navodila](https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md).
-
-### 4. korak: Postopek nadgradnje
-
-Obiščite stran Administration > Upgrade. Drugega za drugim naložite in namestite pakete za nadgradnjo.
-
-To, ali imate najnovejšo verzijo, lahko preverite na Menu > About.
-
-## Nadgradnja prek ukazne vrstice
-
-Nadgradnjo lahko zaženete tudi z uporabo ukazne vrstice. V EspoCRM glavnem direktoriju zaženite naslednji ukaz:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/sl-SI/administration/workflows.md b/i18n/sl-SI/administration/workflows.md
deleted file mode 100644
index edb238ce1..000000000
--- a/i18n/sl-SI/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Delovni tokovi
-
-Orodje Delovni tokovi (Workflows) je na voljo v [Naprednem paketu](https://www.espocrm.com/extensions/advanced-pack/).
-
-Delovni tokovi na preprost način avtomatizirajo vaš poslovni proces. To orodje lahko najdete v administracijskem panelu. Da bi ustvarili pravilo delovnega toka, morate določiti:
-
-* Ciljno entiteto - kateremu tipu entitete je delovni tok pripisan;
-* Tip sprožilca - kdaj se bo delovni tok sprožil;
-* Pogoje - da bi se delovni tok sprožil, morajo biti izpolnjeni pogoji;
-* Akcije - kaj je treba narediti, ko se delovni tok sproži.
-
-
-## Tipi sprožilcev
-
-### Po ustvarjenem zapisu
-
-Sproži se samo, ko je ustvarjen nov zapis. Če so navedeni pogoji izpolnjeni, se izvršijo akcije.
-
-### Po shranjenem zapisu
-
-Sproži se, ko je ustvarjen nov zapis oziroma je obstoječi zapis posodobljen. Če so navedeni pogoji izpolnjeni, se izvršijo akcije.
-
-Za pravila delovnih tokov s tem tipom sprožilca je običajno, da imajo izbran pogoj, ki preverja, ali se je katero polje spremenilo. Na primer, če se je status Primera spremenil, potem se izvrši določena akcija.
-
-### Časovno določen
-
-Sproži se glede na vnaprej določen urnik. Lahko ga nastavite, da se zažene vsak dan, vsak teden itn. Akcije bodo dodeljene zapisom, ki so ustvarjeni kot rezultat določenega poročila v obliki seznama. Torej morate ustvariti tudi poročilo v obliki seznama.
-
-Čas izvajanja se določi v obliki, primerni za crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Leto (razpon: 1900-3000)
-| | | | +---- Dan v tednu (razpon: 1-7, 1 pomeni ponedeljek)
-| | | +------ Mesec v letu (razpon: 1-12)
-| | +-------- Dan v mesecu (razpon: 1-31)
-| +---------- ura (razpon: 0-23)
-+------------ Minuta (razpon: 0-59)
-```
-
-### Zaporedni
-
-Redko se uporablja. Mišljeno je, da ga zažene drug delovni tok. Omogoča vam, da ustvarite zapleteno logiko.
-
-Opomba: Za zaporedne delovne tokove je priporočljivo uporabiti [orodje Upravljanje poslovnih procesov](bpm.md) namesto orodja Delovni tokovi.
-
-## Pogoji
-
-Določite lahko pogoje, ki morajo biti izpolnjeni, da bi se sprožil neki delovni tok. Obstajata dva načina za določanje pogojev: v uporabniškem vmesniku za izdelavo pogojev in s formulo.
-
-### Uporabniški vmesnik za izdelavo pogojev
-
-Nekateri tipi pogojev, ki so na voljo:
-
-* _equals_ - polje je enako določeni vrednosti oziroma vrednosti nekega drugega polja;
-* _was equal_ - polje je bilo enako določeni vrednosti, preden je bil delovni tok sprožen;
-* _not equals_ - polje ni enako določeni vrednosti oziroma vrednosti nekega drugega polja;
-* _was not equal_ - polje ni bilo enako določeni vrednosti, preden je bil delovni tok sprožen;
-* _empty_ - vrednost polja je prazna;
-* _not empty_ - vrednost polja ni prazna;
-* _changed_ - polje je bilo spremenjeno;
-* _not changed_ - polje ni bilo spremenjeno.
-
-### Pogoji s formulo
-
-Formula vam omogoča, da določite pogoje katere koli kompleksnosti. Da bi izvedeli več o sintaksi formul, si poglejte [ta članek](formula.md).
-
-Opomba: Ko določate pogoj, ne sme biti v formuli uporabljeno ločilo `;`.
-
-## Akcije
-
-### Pošlji e-pošto
-
-Sistem bo poslal e-pošto, pri čemer bo uporabil določeno e-poštno predlogo. E-poštni naslov prejemnika je lahko vzet iz ciljnega zapisa, katerega koli povezanega zapisa, trenutnega uporabnika, sledilca, timskega uporabnika ali pa je ročno določen. E-pošta je lahko poslana takoj ali pa z določenim časovnim zamikom.
-
-### Ustvari zapis
-
-Sistem bo ustvaril nov zapis katerega koli tipa entitete. Če obstaja relacija med ciljnim zapisom in ustvarjenim zapisom, je možno narediti povezavo med zapisoma.
-
-Mogoče je tudi določiti formulo, ki bo izračunala polja.
-
-### Ustvari povezani zapis
-
-Sistem bo ustvaril zapis, ki bo povezan s ciljnim zapisom. Mogoče je določiti formulo, ki bo izračunala polja.
-
-### Posodobi ciljni zapis
-
-Dopušča možnost spreminjanja določenih polj ciljnega zapisa. Mogoče je določiti formulo, ki bo izračunala polja.
-
-Če morate dodati nove elemente polju Poveži-Več (Link-Multiple), ne da bi izgubili obstoječe podatke (na primer Timi), morate uporabiti funkcijo formule entity\addLinkMultipleId. Primer: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### Posodobi povezani zapis
-
-Omogoča spreminjanje določenih polj povezanega zapisa oziroma zapisov. Mogoče je določiti formulo, ki bo izračunala polja.
-
-### Poveži z drugim zapisom
-
-Ciljno entiteto poveže z drugo izbrano entiteto. Na primer, zapisu doda določen tim.
-
-### Prekini povezavo z drugim zapisom
-
-Prekine povezavo ciljnega zapisa z drugo izbrano entiteto. Na primer, odstrani določen tim iz zapisa.
-
-### Uporabi določitveno pravilo
-
-Uporabniku določi ciljni zapis s porazdelitvenim pravilom. Na voljo sta dve pravili: krožno dodeljevanje in najmanj zaseden.
-
-* Krožno dodeljevanje - uporabniki so izbrani od vrha proti dnu seznama (tima) in potem znova od vrha.
-* Najmanj zaseden - nalogo bo dobil uporabnik, ki mu je dodeljeno manj zapisov.
-
-_Poročilo v obliki seznama_ - Za porazdelitev Najmanj zaseden določi, kateri zapisi bodo uporabljeni za izračun števila dodeljenih zapisov. Na primer, za Primere moramo izbrati samo zapise z aktivnim statusom.
-
-### Ustvari obvestilo
-
-Izbrane uporabnike obvesti s sporočilom. V predlogi sporočila je mogoče uporabiti polja s spremenljivkami. {entity} - ciljni zapis, {user} - trenutni uporabnik.
-
-### Določi sledenje
-
-Izbranim uporabnikom določi, da sledijo ciljni entiteti oziroma izbrani povezani entiteti.
-
-### Sproži drug delovni tok
-
-Omogoča ustvaritev zaporednih delovnih tokov. Obstaja možnost razcepitve delovnega toka z uporabo pogoja: delovni tok lahko nastavite tako, da sproži dva toka z različnima pogojema, definiranima v tema delovnima tokovoma.
-
-Mogoče je tudi nastaviti zakasnitev izvajanja zaporednega delovnega toka. V zaporednem delovnem toku lahko določite pogoj, ki preverja, ali so se določena polja spremenila, odkar je bil sprožen nadrejeni delovni tok, in sicer s tipoma pogojev _Changed_ in _Was Equal_.
-
-Opomba: Za zaporedne delovne tokove je priporočljivo uporabiti [orodje Upravljanje poslovnih procesov](bpm.md) namesto orodja Delovni tokovi.
-
-### Zaženi storitveno akcijo
-
-Omogoča, da zaženete določene storitvene skripte. Originalno sta na voljo naslednji akciji:
-
-* Pošlji vabila - za Sestanke/Klice;
-* Dodaj Navedene elemente - za Navedke.
-
-Razvijalci lahko napišejo svoje storitvene akcije. Preberite si [več podrobnosti](../development/workflow-service-actions.md).
-
-## Uporaba formule pri akcijah
-
-Možno je določiti formulo, ki bo izračunala polja za Ustvari zapis, Posodobi ciljni zapis, Ustvari povezani zapis, Posodobi povezani zapis. Da bi pri zadnjih dveh lahko imeli dostop do atributov ciljne entitete, bi morali uporabiti funkcijo `targetEntity\attribute`. Da bi imeli dostop do atributov ciljne entitete, ki je bila določena, preden je bil sprožen delovni tok, uporabite funkcijo `targetEntity\attributeFetched`.
-
-Primer:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/th_TH/administration/apache-server-configuration.md b/i18n/th_TH/administration/apache-server-configuration.md
deleted file mode 100644
index f9f5a2136..000000000
--- a/i18n/th_TH/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# การตั้งค่าเซิร์ฟเวอร์ Apache สำหรับ EspoCRM
-
-คำแนะนำเหล่านี้ เป็นคำแนะนำเพิ่มเติมสำหรับ [Server Configuration] (server-configuration.md) โปรดทราบว่าการตั้งค่าทั้งหมดที่ระบุไว้ในที่นี้จะสร้างบนเซิร์ฟเวอร์ Ubuntu
-
-## ข้อกำหนดของ PHP
-
-เมื่อต้องการติดตั้งไลบรารีที่จำเป็นทั้งหมด ให้เรียกใช้คำสั่งเหล่านี้ใน terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## การแก้ไขปัญหา "API Error: EspoCRM API ที่ไม่พร้อมใช้งาน”:
-
-ใช้เฉพาะขั้นตอนที่จำเป็นเท่านั้น หลังจากแต่ละขั้นตอนตรวจสอบว่าปัญหาได้รับการแก้ไขแล้ว
-
-### 1. เปิดใช้งาน "mod_rewrite" ใน Apache
-
-เพื่อเปิดใช้งาน “mod_rewrite,” ให้เรียกใช้คำสั่งเหล่านี้ใน terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. การเปิดใช้ การสนับสนุน . htaccess
-
-เพื่อเปิดใช้งาน การสนับสนุน .htaccess, เพิ่ม/แก้ไขการตั้งค่าการกำหนดค่าเซิร์ฟเวอร์/อื่นๆ/apache2/sites-available/ESPO_VIRTUAL_HOST.conf หรือ /อื่นๆ/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-หลังจากนั้น ให้เรียกใช้คำสั่งนี้ใน terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. เพิ่มเส้นทาง RewriteBase
-
-เปิดแฟ้มข้อมูล /ESPOCRM_DIRECTORY/api/v1/.htaccess และแทนที่ด้วยบรรทัดต่อไปนี้:
-
-```
-# RewriteBase /
-```
-
-กับ
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-REQUEST_URI เป็นส่วนหนึ่งของ URL เช่น สำหรับ "http://example.com/espocrm/" REQUEST_URI คือ "espocrm"
-
-## การเปิดใช้งาน การสนับสนุน HTTP AUTHORISATION (เฉพาะ FastCGI)
-
-FastCGI ไม่ได้สนับสนุน HTTP AUTHORIZATION โดยค่าเริ่มต้น ถ้าคุณใช้ FastCGI คุณต้องเปิดใช้งาน VirtualHost หรือ /etc/apache2/apache2.conf (httpd.conf) โดยการเพิ่มโค้ดต่อไปนี้:
-
-สำหรับโมดูล Fcgid:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-สำหรับโมดูล FastCgi:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-หากต้องการตรวจสอบว่าโมดูลใด กำลังใช้งานอยู่ให้เรียกใช้คำสั่งนี้และค้นหาโมดูล:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/th_TH/administration/b2c.md b/i18n/th_TH/administration/b2c.md
deleted file mode 100644
index 602d64f96..000000000
--- a/i18n/th_TH/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#การกำหนดค่า EspoCRM สำหรับ B2C (Business-to-Client)
-
-โดยค่าเริ่มต้นของ EspoCRM มีการกำหนดค่า ให้ใช้กับธุรกิจ B2B แต่คุณสามารถติดตั้งได้ง่ายสำหรับ B2C
-
-* เปลี่ยน `b2cMode` เป็น true ในแฟ้มข้อมูล config ` data / config.php` ของคุณ ตั้งแต่เวอร์ชั่น 4.3.0 สามารถกำหนดค่าได้ที่ Administration> Seetings
-* ย้ายแท็บ * Account * ออกจากเมนูนำทาง (การดูแลระบบ > ผู้ใช้ Interface)
-* ย้าย *Account* เขตข้อมูล จากรูปแบบของคุณ (การดูแลระบบ > การจัดการเค้าโครง).
-* ปิดใช้งานการเข้าถึง *Account* ขอบเขตสำหรับทุกบทบาทของคุณ (การดูแลระบบ> บทบาท)
-* ลบ บัญชีจาก picklists ของเขตข้อมูลหลักทั้งหมด (การดูแลระบบ> การจัดการ Entity> {ประชุม / โทร / งาน / อีเมล}> เขตข้อมูล> ปกครอง)
\ No newline at end of file
diff --git a/i18n/th_TH/administration/backup-and-restore.md b/i18n/th_TH/administration/backup-and-restore.md
deleted file mode 100644
index b95521d46..000000000
--- a/i18n/th_TH/administration/backup-and-restore.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# การสำรองข้อมูล และการคืนค่า
-
-## วิธี การสำรองข้อมูล EspoCRM ด้วยตนเอง
-
-EspoCRM ประกอบด้วย แฟ้มข้อมูลและฐานข้อมูล จำเป็นต้องมีข้อมูลทั้งหมด เพื่อสร้างการสำรองข้อมูลเต็มรูปแบบของ EspoCRM นี่คือคำแนะนำเกี่ยวกับวิธีการทำบนเซิร์ฟเวอร์ Ubuntu กับ MySQL
-
-### ขั้นตอน ที่ 1. การสำรองข้อมูลไฟล์
-
-สร้างที่เก็บถาวรของเนื้อหา directory ของ EspoCRM ที่ติดตั้งไว้ สำหรับ Ubuntu เส้นทางเริ่มต้นคือ `/ var / www / html` คุณสามารถใช้คำสั่งนี้:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### ขั้นตอน ที่ 2. การสำรองข้อมูล ฐานข้อมูล
-
-เพื่อที่จะสำรองข้อมูลทั้งหมดของคุณ คูณต้องรู้ชื่อของ ฐานข้อมูล และ ข้อมูล ที่รับรองการเข้าถึง คุณสามารถค้นหาชื่อของ ฐานข้อมูลในการตั้งค่าไฟล์
-`/ESPOCRM_DIRECTORY/data/config.php` ภายใต้หัวข้อ `database`คุณสามารถใช้คำสั่งนี้ เพื่อสำรองฐานข้อมูล ของคุณ:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### ขั้นตอน ที่ 3. คัดลอกการสำรองข้อมูล
-
-นั่นคือทั้งหมด ตอนนี้ คุณต้องคัดลอก การสำรองข้อมูล เพื่อสร้างไว้ในที่ปลอดภัย
-
-## วิธีการสำรองข้อมูล EspoCRM ด้วยต้นฉบับ
-
-คุณสามารถใช้ต้นฉบับ เพื่อสำรองข้อมูลทั้งหมด ที่คุณต้องการ เข้าสู่ระบบ ผ่านทาง SSH และ รันคำสั่ง (ทดสอบบนเซิร์ฟเวอร์ Ubuntu)
-### ดาวน์โหลดต้นฉบับ
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### เรียกใช้ต้นฉบับ
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-ที่ไหน
- * `PATH_TO_ESPOCRM` เป็นเส้นทาง ไปถึงการติดตั้ง EspoCRM director
- * `BACKUP_PATH` เป็นเส้นทางไปถึง การสำรองข้อมูล directory
-
-สำหรับ เซิร์ฟเวอร์ Ubuntu มันคือ :
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-หมายเหตุ: ถ้าหากผู้ใช้ MySQL ไม่จำเป็นต้องถ่ายโอนข้อมูลฐานข้อมูลของคุณ คุณจะได้รับพร้อมท์ ให้ใส่ข้อมูลรับรองของผู้ใช้ MySQL รายอื่น
-
-หลังจาก สร้างเสร็จเรียบร้อยแล้ว คุณจะได้เส้นทาง เพื่อไปยังการสำรองข้อมูลที่สร้างไว้
-
-## การ คืนค่า EspoCRM จาก การสำรองข้อมูล
-
-คุณสามารถคืนค่า EspoCRM จาก การสำรองข้อมูล ที่สร้างไว้ ตามที่ได้ อธิบายไว้ข้างต้น
-
-### ขั้นตอน ที่ 1. ยกเลิกการเก็บสำรองข้อมูล
-
-เพื่อยกเลิกการเก็บไฟล์ข้อมูล คุณสามารถใช้ Archive Manager หรือเรียกใช้ คำสั่งด้านล่างได้ ไฟล์ต้องอยู่ใน เว็บเซิร์ฟเวอร์ directory
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-ที่ไหน:
- * `/var/www/html` ในเว็บเซิร์ฟเวอร์ directory
-
-### ขั้นตอน ที่ 2. ตั้งค่าสิทธิ์ที่จำเป็น
-
-ไฟล์ ควรเป็นของผู้ใช้ เว็บเซิร์ฟเวอร์ และมีสิทธิ์ที่ถูกต้อง โปรดตั้งค่าสิทธิ์ที่จำเป็น โดยปฏิบัติตาม คำแนะนำนี้:
-[www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### ขั้นตอน ที่ 3 การนำเข้า ถ่ายโอนฐานข้อมูล
-
-การถ่ายโอนฐานข้อมูล ควร ถ่ายโอนมา ยัง ฐานข้อมูล เดียวกัน ด้วยข้อมูล รับรองผู้ใช้ เดียวกัน มิฉะนั้น จะต้องมีการแก้ไข ในการตั้งค่าไฟล์
-`ESPOCRM_DIRECTORY/data/config.php` เมื่อ ต้องการนำเข้า ฐานข้อมูลของคุณจาก การถ่ายโอน ให้เรียกใช้คำสั่ง ด้านล่างใน terminal:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### ขั้นตอน ที่ 4. การตรวจสอบ / การ กำหนดค่า crontab
-
-Check if your crontab is configured properly. Run the command below and check if a path to EspoCRM is correct:
-ตรวจสอบว่า crontab ของคุณ ได้รับการกำหนดค่าอย่างถูกต้องหรือไม่ เรียกใช้ ตามคำสั่งด้านล่างและตรวจสอบเส้นทางไปยัง EspoCRM ว่าถูกต้องหรือไม่:
-
-```bash
-sudo crontab -l -u www-data
-```
-ที่ไหน:
- * `www-data` คือ ผู้ใช้เว็บเซิร์ฟเวอร์ของคุณ
-
-ถ้าคุณต้องทำการเปลี่ยนแปลง อื่น ๆ ให้ใช้คำสั่ง ดังนี้:
-
-```bash
-sudo crontab -l -u www-data
-```
-รายละเอียด เพิ่มเติม เกี่ยวกับการกำหนดค่า crontab สำหรับ EspoCRM ได้อธิบายไว้ ที่นี้[www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
diff --git a/i18n/th_TH/administration/bpm.md b/i18n/th_TH/administration/bpm.md
deleted file mode 100644
index 24d891d70..000000000
--- a/i18n/th_TH/administration/bpm.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# การจัดการ กระบวนการ ทางธุรกิจ
-
-การจัดการกระบวนการทางธุรกิจ (BPM) ให้ความสามารถ ในการจำลองและดำเนินการกระบวนการ ทางธุรกิจโดยอัตโนมัต ิใน EspoCRM เป็นเครื่องมืออที่ดำเนิน การกระบวนการทางธุรกิจ ที่อธิบายไว้ ในมาตรฐาน BPMN 2.0 BPM เครื่องมือมีอยู่ใน [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) ส่วนขยาย.
-
-
-
-### ความแตกต่างจาก Workflows tool
-
-Workflows tool มีไว้สำหรับการดำเนินธุรกิจ โดยใช้กฎเกณฑ์ ทางธุรกิจที่เรียบง่าย, w / o รายการไหลเวียนตามลำดับ, เมื่อไม่ต้องการให้แสดงการไหลแบบกราฟิก
-
-BPM tool มีไว้ สำหรับการดำเนินธุรกิจ ที่ซับซ้อนมากยิ่่งขึ้น, ซึ่งอาจมีการกระจายและการไหลเวียนเกิดขึ้นได้, ความล่าช้า ในการดำเนินการ, ปฏิสัมพันธ์ของผู้ใช้งาน ,มุมมองของผังงาน ทำให้กระบวนการทางธุรกิจเข้าใจได้ง่ายขึ้น สำหรับมนุษย์, การบันทึกช่วยให้เห็นถึง วิธีการจัดกระบวนการ
-
-## กระบวนการ Flowcharts
-
-การเชื่อมโยงไปที่กระบวนการ flowcharts สามารถใช้งานได้ จากแผงการบริหาร นอกจากนี้ ยังสามารถเพิ่มแท็บใน navigation panel.
-
-Flowcharts มีไว้สำหรับการสร้างแบบจำลองของ กระบวนการทางธุรกิจ โดยผู้ดูแลระบบสามารถสร้างและแก้ไข flowcharts ได้ ผู้ใช้ทั่วไปสามารถดู flowcharts ได้เท่านั้น .
-
-ทุก flowchart มีประเภทที่เฉพาะเจาะจง (Target Type field). flowchart กำหนดกระบวนทำงานของ instances ในอนาคต ซึ่งประกอบไปด้วยองค์ประกอบของ Flowchart และการเชื่อมต่อระหว่าง องค์ประกอบต่างๆ
-
-หากกระบวนการผังงานมีฟิลด์ที่ 'ใช้งานอยู่' ยังไม่ถูกตรวจสอบ ระบบจะไม่เริ่มต้น initiate ของกระบวนการ
-
-หากต้องการแสดงรายละเอียดและพารามิเตอร์ขององค์ประกอบ flowchart ที่ต้องการคลิก ในโหมดแก้ไขคุณจะสามารถแก้ไข parameters ได้
-
-## กระบวนการ
-
-กระบวนการที่มีอยู่จากแผงการบริหาร การเชื่อมโยงนี้ สามารถเพิ่มเป็นแท็บ ในแผงการนำทาง
-
-โดยกระบวนการ จะแสดงถึงกระบวนการทางธุรกิจ เมื่อเริ่มต้นแล้วจะมีสถานะเป็น 'เริ่ม' เมื่อกระบวนการสิ้นสุดลงแล้ว จะมีสถานะเป็น 'จบ' กระบวนการนี้ สามารถหยุด ด้วยตนเอง โดยผู้ใช้ที่มีสิทธิ์เข้าถึง เพื่อแก้ไขกระบวนการได้ หากระบบหยุดด้วยตนเอง จะมีสถานะเป็นสถานะ "หยุด"
-
-กระบวนการดำเนินการตาม flowchart ไม่สามารถเปลี่ยนแปลง กระบวนการของ Flowchart หลังจากเริ่ม กระบวนการ ไปแล้ว
-โดย กระบวนการ จะเกี่ยวข้องกับบันทึกเป้าหมาย เพียงอย่างเดียว
-
-กระบวนการ สามารถเริ่มต้นได้ โดยอัตโนมัติ (ตามเงื่อนไขที่ระบุหรือตามเวลา) หรือด้วยตนเอง (ที่มีกิจกรรมเริ่มต้นอย่างน้อยหนึ่งอย่าง ในผังงาน) เมื่อต้องการเริ่มกระบวนการด้วยตนเองผู้ใช้ต้องคลิกที่ปุ่ม 'เริ่มกระบวนการ' ในมุมมองรายการของกระบวนการ
-
-
-## องค์ประกอบของ Flowchart
-
-### เหตุการณ์
-
-เหตุการณ์ จะปรากฏใน flowchart เป็นวงเวียน
-
-#### เริ่มเหตุการณ์
-
-ไม่มี parameters เป็นจุดเริ่มต้นของกระบวนการ เหตุการณ์เริ่มต้นสามารถ เริ่มต้นด้วยตนเอง โดยที่ผู้ใช้มีสิทธิ์เข้าถึง เพื่อสร้างกระบวนการ ผู้ใช้ต้องคลิกที่ปุ่ม 'เริ่มกระบวนการ' ในมุมมองรายการของกระบวนการ
-
-#### เงื่อนไข เหตุการณ์เริ่มต้น
-
-จุดเริ่มต้นของกระบวนการ จะเรียกใช้โดยอัตโนมัติเมื่อมีการระบุเงื่อนไขเกิดขึ้น มี trigger สองแบบ คือ : 'สร้าง หลังจากบันทึก', 'บันทึก หลังจากบันทึกแล้ว'
-
-
-#### เหตุการณ์ เริ่มจับเวลา
-
-จุดเริ่มต้นของกระบวนการ คือ เริ่มต้นกระบวนการโดยกำหนดเวลา คุณต้องระบุ รายการของรายงานที่จะส่งกลับบันทึก สำหรับการเริ่มต้น กระบวนการและการตั้งเวลาในเอกสาร crontabA
-
-#### เงื่อนไขของ เหตุการณ์ ระดับกลาง
-
-กิจกรรมนี้จะหยุดการไหลจนกว่าจะมีการระบุเกณฑ์
-
-#### เหตุการณ์ ระดับกลาง ของตัวจับเวลา
-
-เหตุการณ์นี้ จะหยุดการไหลและรอจนกว่าจะมีการระบุจาก parameters ของเหตุการณ์
-
-สำหรับการตั้งค่าตัวจับเวลาที่ซับซ้อนยิ่งขึ้นคุณสามารถใช้ประโยชน์ได้ [formula](formula.md) สูตรสคริปต์ ควรจะส่งคืนค่าวันที่-เวลา (ในเขตเวลา UTC) เมื่อถึงเวลาการไหล จะดำเนินต่อไป พร้อมกับองค์ประกอบถัดไป
-
-เมื่อใช้ฟังก์ชันสูตรที่ใกล้เคียงกับ วันเวลา \ คุณสามารถตั้งเวลาให้กับช่วงเวลาที่ต้องการได้ในอนาคต เช่น จุดเริ่มต้นของวันทำการในวันถัดไป
-
-#### เหตุการณ์ สิ้นสุด
-
-สิ้นสุด flow ของกระแส มันไม่ได้จบลงที่ flow วิ่งขนาน เมื่่อ flow ถึงเหตุการณ์ สิ้นสุดและไม่มีอะไรที่ทำงานแบบขนาน กระบวนการจึงจะ สิ้นสุดลง
-
-#### ยุติ เหตุการณ์ ที่สิ้นสุด
-
-เมื่อจบ flows ทั้งหมด กระบวนการจะสิ้นสุดลงในภายหลัง
-
-### Gateways
-
-Gateways จะแสดง เป็นรูปข้าวหลามตัด
-
-#### Gateway แบบพิเศษ
-
-สามารถแยกแยะหรือ บรรจบกันของ flows ได้ .
-
-ในกรณีที่แยกออกจากกันจะกำหนดเส้นทางของ flow (เส้นทาง) เดี่ยวที่จะเลือกตามเกณฑ์ที่ระบุ เงื่อนไขแรกที่่พบ คือ จะกำหนด flow, ถัดไป เงื่อนไขจะถูกละไว้. มีความสามารถในการระบุ flow เริ่มต้น ซึ่ง flow เริ่มต้นจะ ถูกเลือกหากไม่มีเงื่อนไขใด ๆ ที่ตรงตามเงื่อนไขที่กำหนดไว้ flow เริ่มต้น ถูกทำเครื่องหมายด้วย เครื่องหมายทับ
-
-ในกรณีของการบรรจบกันเพียงแค่นำ flow ไปยังองค์ประกอบที่ส่งออก จะไม่ได้รับการปิดกั้น แม้ว่าหลังจาก flow มา ดังนั้นกระแสคู่ขนานจะไม่ถูกผสานเข้ากับ flow
-
-
-
-
-
-#### Inclusive Gateway
-
-สามารถแยกแยะ หรือ บรรจบกัน ของ flows ได้
-
-ในกรณีที่มีการแบ่งแยกออกไป มันสามารถนำไปสู่ flows คู่ขนานได้ (path) โดยขึ้นอยู่กับความสำเร็จของเกณฑ์ flows แต่ละครั้ง และ flows เริ่มต้น จะถูกเลือกหากไม่มีเงื่อนไขใด ๆ ที่ตรงตามเงื่อนไข กระแสเริ่มต้นถูกทำเครื่องหมายด้วยเครื่องหมายทับ
-
-
-
-
-หมายเหตุ:gateways การแบ่งและการรวมกันต้องมีความสมดุล
-
-หมายเหตุ: หาก flows แบบคู่ขนานสิ้นสุดลง ด้วยเหตุผลบางประการ gateway ที่แยกกันจะไม่ได้รับการประมวลผล และกระบวนการนี้จะถูกปิดกั้น หลีกเลี่ยงการออกแบบ flowchart ที่สามารถนำมา ซึ่งสถานการณ์เช่นนี้ได้
-
-#### Parallel Gateway
-
-สามารถแยกแยะ หรือ บรรจบกัน ของ flows ได้
-
-ในกรณีที่แยกออกจากกันมันจะแบ่ง flows ออกเป็นหลาย ๆ แบบ ไม่มีพารามิเตอร์สำหรับประเภท gateway นี้
-
-ในกรณีของการบรรจบกัน รอจนกว่ากระแสที่เข้ามาทั้งหมดจะมาถึงองค์ประกอบถัดไป
-
-
-
-หมายเหตุ: gateways การแบ่งและการรวมกันต้องมีความสมดุล
-
-หมายเหตุ: หาก flows แบบคู่ขนานสิ้นสุดลง ด้วยเหตุผลบางประการ gateway ที่แยกกันจะไม่ได้รับการประมวลผล กระบวนการนี้จะถูกปิดกั้น หลีกเลี่ยง การออกแบบ flowchart ที่สามารถนำมาซึ่งสถานการณ์เช่นนี้ได้
-
-#### เหตุการณ์พื้นฐานของ Gateway
-
-สามารถแยกเฉพาะ flows ได้
-
-จะหยุด flow จนกว่าเหตุการณ์ขาออกใด ๆ จะได้รับการกระตุ้น เหตุการณ์ที่ทริกเกอร์กำหนดให้มีการไหลเดี่ยว กิจกรรมขาออกอื่น ๆ ได้รับการปฏิเสธ เฉพาะเหตุการณ์ ระดับกลางเท่านั้น ที่สามารถอยู่ในส่วนอื่น ๆ ของกระแสลำดับที่ส่งออกได้
-
-
-
-
-### กิจกรรม
-
-กิจกรรมจะแสดงเป็นสี่เหลี่ยมผืนผ้ากลม
-
-#### งาน
-
-งานสามารถดำเนินการดังต่อไปนี้:
-
-* สร้างบันทึก - สร้างบันทึกใหม่ของประเภท entity ใด ๆ;
-* สร้างบันทึกที่เกี่ยวข้อง - สร้างบันทึกใหม่ที่เกี่ยวข้องกับการบันทึกเป้าหมาย;
-* อัปเดตบันทึกเป้าหมาย;
-* อัปเดตบันทึกที่เกี่ยวข้อง - อัปเดตบันทึกหรือบันทึกที่เกี่ยวข้องกับบันทึกเป้าหมาย;
-* อัปเดตบันทึกที่สร้าง - อัปเดตเขตข้อมูลที่เฉพาะเจาะจงของบันทึกที่สร้างขึ้นในกระบวนการปัจจุบัน;
-* อัปเดตกระบวนการบันทึก - สามารถใช้เพื่อกำหนดกระบวนการเฉพาะผู้ใช้หรือทีมเฉพาะได้;
-* การเชื่อมโยงไปยังบันทึกอื่นๆ - เชื่อมโยงบันทึกเป้าหมายกับบันทึกที่ระบุไว้เฉพาะเจาะจง;
-* ยกเลิกการเชื่อมโยงจากบันทึกอื่นๆ - ยกเลิกการเชื่อมโยงบันทึกเป้าหมายจากบันทึกที่ระบุไว้เฉพาะเจาะจง;
-* ใช้กฎการกำหนด - กำหนดเป้าหมายการบันทึก กระบวนการหรือบันทึกที่สร้างโดยกระบวนการตามกฎที่ระบุไว้เฉพาะเจาะจง;
-* สร้างการแจ้งเตือน - สร้างการแจ้งเตือนในแอปสำหรับเฉพาะผู้ใช้;
-* ทำตาม - ทำให้ผู้ใช้เฉพาะติดตามบันทึกเป้าหมาย บันทึกกระบวนการหรือบันทึกที่สร้างขึ้นโดยกระบวนการ;
-* เรียกใช้คำสั่งการดำเนิน - เรียกใช้การทำงานของบริการแบบกำหนดเองที่นักพัฒนาซอฟต์แวร์ใช้
-
-คำสั่งการดำเนินการที่พร้อมใช้งาน สำหรับงานเกือบจะเหมือนกันในคุณลักษณะ Workflow ดูรายละเอียดเพิ่มเติมเกี่ยวกับ [workflow's actions](workflows.md#actions).
-
-#### ส่งข้อความงาน
-
-ส่งข้อความอีเมลไปยังผู้รับที่เฉพาะเจาะจง
-
-#### ผู้ใช้งาน
-
-ให้ความยืดหยุ่นในการโต้ตอบกับผู้ใช้ ซึ่งจะหยุดการดำเนินการจนกว่าผู้ใช้ (ระบุอย่างชัดเจนหรือตามกฎการกำหนด) จะแก้ไขงานนั้นๆ การประมวลผลบันทึกงานของผู้ใช้ จะถูกสร้างขึ้นในระบบ โดยค่าเริ่มต้นจะมี 3 ประเภท ได้แก่ : อนุมัติ, รีวิว, สำเร็จ
-
-* ประเภทของการอนุมัติต้องให้ผู้ใช้เลือกระหว่าง "อนุมัติ" และ "ปฏิเสธ"
-* ประเภทของรีวิวการตรวจทานมีเพียงหนึ่งตัวเลือก: 'ตรวจสอบแล้ว'
-* ประเภทสำเร็จมีสองตัวเลือกคือ 'เสร็จสิ้น' และ 'ล้มเหลว'
-
-ผู้ใช้ที่กำหนดให้กับกระบวนการที่สร้างขึ้น บันทึกงานของผู้ใช้จะได้รับการแจ้งเตือนในแอป โดยผู้ดูแลระบบสามารถเปิดใช้งานการแจ้งเตือนทางอีเมลได้
-
-ผู้ใช้ยังสามารถเพิ่มกระบวนการผู้ใช้ dashlet งานบน dashboard เพื่อดูงานของผู้ใช้ในกระบวนการจริง
-
-สามารถอ่านความละเอียดของงานที่ผู้ใช้ส่งผ่านภายใน gateways หรือเหตุการณ์ที่มีเงื่อนไขทำให้เกิดการแบ่งส่วนในกระบวน flow
-
-#### งาน Script
-
-ดำเนินการ script ใน [espo-formula](formula.md) ภาษา. ตัวแปรที่กำหนดทั้งหมด (`$variableName`) จะถูกจัดเก็บและพร้อมใช้งานภายในกระบวนการนี้
-
-### Flows
-
-#### Sequence Flow
-
-แสดงเป็นลูกศรทึบ การระบุลำดับองค์ประกอบของกระบวนการจะถูกดำเนินการ
-
-## เงื่อนไข
-
-เหตุการณ์ที่มีเงื่อนไข, gateways จะแยกเฉพาะและรวมกัน มีเงื่อนไขที่กำหนด flow ของกระบวนการ
-
-UI มีความสามารถในการตรวจสอบเงื่อนไขสำหรับบันทึกต่อไปนี้:
-
-* บันทึกเป้าหมาย;
-* บันทึกเกี่ยวกับเป้าหมายผ่านความสัมพันธ์ แบบจำนวนมาก - ถึง - หนึ่ง และ ความสัมพันธ์แบบเด็ก - ถึง - ครอบครัว;
-* บันทึกที่สร้างโดยกระบวนการผ่านงาน;;
-* บันทึกงานของผู้ใช้ซึ่งช่วยให้สามารถตรวจสอบความละเอียดได้
-
-นอกจากนี้ยังสามารถกำหนดเงื่อนไขได้จาก [Espo-formula](formula.md) ภาษา.
-
-เงื่อนไขในเครื่องมือ BPM เหมือนกับคุณลักษณะใน Workflow [workflow's conditions](workflows.md#conditions).
-
-## ตัวอย่าง
-
-### ตัวอย่างที่ 1
-
-
-
-### ตัวอย่างที่ 2
-
-
-
-### ตัวอย่างที่ 3
-
-
diff --git a/i18n/th_TH/administration/email-fetching.md b/i18n/th_TH/administration/email-fetching.md
deleted file mode 100644
index 7c2e3950c..000000000
--- a/i18n/th_TH/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# อีเมล
-
-เอกสารถูกย้าย ไปที่ [here](emails.md).
diff --git a/i18n/th_TH/administration/emails.md b/i18n/th_TH/administration/emails.md
deleted file mode 100644
index b8cc99660..000000000
--- a/i18n/th_TH/administration/emails.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# อีเมล
-
-> สำคัญ. [Cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) ควรกำหนดค่าในระบบเพื่อเรียกใช้งานอีเมล คุณสามารถหาข้อมูลจาก EspoCRM ได้ที่ การบริหาร > งานที่กำหนดเวลาไว้
-
-## ภาพโดยรวม
-
-EspoCRM มีความสามารถในการตรวจสอบกล่องจดหมายของ IMAP โดยสามารถจัดเก็บอีเมลได้สองวิธี: บัญชีอีเมลแบบกลุ่ม และบัญชีอีเมลส่วนบุคคล ซึ่งบัญชีขาเข้าของกลุ่ม มีไว้สำหรับกล่องจดหมายของกลุ่ม: กรณีที่พบมากที่สุดคือกล่องสนับสนุน บัญชีอีเมลส่วนบุคคล มีไว้สำหรับผู้ใช้, กล่องจดหมายส่วนบุคคล
-
-ขณะที่อีเมลกำลังจะมาถึง ระบบจะพยายามเชื่อมโยงกับบันทึกที่เหมาะสม (บัญชี, Lead, โอกาส, กรณี) ผู้ใช้ที่ติดตามบันทึกนั้น จะได้รับการแจ้งเตือนเกี่ยวกับอีเมลใหม่ในระบบ, แม้ว่าจะไม่ได้อยู่ใน To หรือ CC
-
-## บัญชีอีเมลเเบบกลุ่ม
-
-เฉพาะผู้ดูแลระบบเท่านั้น ที่สามารถตั้งค่าบัญชีอีเมลเป็นกลุ่มได้ ซึ่งบัญชีอีเมลแบบกลุ่มสามารถใช้สำหรับการรับและส่งอีเมล การส่งอีเมลจากบัญชีแบบกลุ่มมีให้บริการตั้งแต่เวอร์ชัน 4.9.0 ขึ้นไป
-
-ฟิลด์ทีมจะกำหนดว่า ทีมไหนจะได้รับอีเมลขาเข้า
-
-หากบัญชีอีเมลของกลุ่มมี SMTP และได้รับการตรวจสอบว่าถูกแชร์แล้ว การเข้าถึงจะถูกควบคุมโดย Roles ผ่านทาง บัญชีอีเมลเเบบกลุ่ม และจะใช้ฟิลด์ทีม
-ถ้าระดับการได้รับอนุญาตถูกกำหนดเป็น 'ทีม'
-
-มีความสามารถ ในการทำให้ระบบส่งการตอบกลับอัตโนมัติสำหรับอีเมลขาเข้า
-
-## อีเมล์ต่อกรณี
-
-มีตัวเลือกเพื่อให้ระบบสร้างกรณี จากอีเมลแบบกลุ่มที่เข้ามา ซึ่งคุณลักษณะนี้มีไว้สำหรับทีมสนับสนุน
-กรณีสามารถแจกจ่ายให้กับผู้ใช้จากทีมที่ระบุตามวิธีการต่อไปนี้:
-`direct assignment`, `round-robin` และ `less-busy`.
-เฉพาะอีเมลฉบับแรกในการสร้าง thread กรณีใหม่เท่านั้น
-ทุกๆ subsequent จะเชื่อมโยงกับบันทึกคดีที่มีอยู่และแสดงในแผงสตรีม
-
-เมื่อผู้ใช้ต้องการส่งคำตอบให้กับลูกค้าพวกเขาจะต้องตรวจสอบให้แน่ใจว่ากรณีถูกเลือกเป็นผู้ดูแลของอีเมลที่กำลังส่ง จะทำให้ ลูกค้าตอบกลับที่อยู่อีเมลของกลุ่มแทนที่จะเป็นอีเมลของผู้ใช้
-
-## บัญชีอีเมลส่วนบุคคล
-
-ผู้ใช้สามารถตั้งค่าบัญชีอีเมลของตัวเองที่ต้องได้รับการตรวจสอบ อีเมล > เมนูแบบเลื่อนลงตรงด้านขวามุมบนสุด > บัญชีอีเมลส่วนบุคคล ผู้ดูแลระบบสามารถจัดการบัญชีอีเมลของผู้ใช้ได้
-
-## ตัวกรองอีเมล
-
-อนุญาตให้มีการกรองอีเมลขาเข้าตามเกณฑ์ที่ระบุ เช่น ถ้าคุณไม่ต้องการให้ข้อความแจ้งเตือนที่ส่งมาจากแอ็พพลิเคชันบางตัว เพื่อจะนำเข้าไปยัง EspoCRM คุณสามารถสร้างตัวกรองเพื่อให้ EspoCRM ข้ามไปได้
-
-ผู้ดูแลระบบสามารถสร้างตัวกรองส่วนกลางและนำไปใช้กับบัญชีอีเมลทั้งหมดได้ นอกจากนี้ผู้ใช้สามารถสร้างตัวกรองสำหรับบัญชีอีเมลส่วนบุคคลของตนเองและสำหรับกล่องจดหมายทั้งหมดได้ด้วย.
diff --git a/i18n/th_TH/administration/entity-manager.md b/i18n/th_TH/administration/entity-manager.md
deleted file mode 100644
index 642e7efee..000000000
--- a/i18n/th_TH/administration/entity-manager.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# การจัดการ Entity
-
-การจัดการ Entity คือ สิ่งที่มีอยู่ในแผงการดูแลระบบ มีความสามารถในการปรับแต่งตัวอย่าง EspoCRM ของคุณได้สูง คุณสามารถทำได้ดังสิ่งต่อ ไปนี้:
-
-* เพิ่มประเภทของ entities ใหม่
-* กำหนดประเภทของ entities ที่มีอยู่: เปลี่ยนป้ายกำกับ, ลำดับการเริ่มต้นในมุมมองรายการ, เปิดหรือปิดใช้งานสตรีม
-* กำหนด ค่าฟิลด์: เพิ่มใหม่, กำหนดค่า ที่มีอยู่แล้ว
-* กำหนด ค่าความสัมพันธ์: เพิ่มใหม่, เปลี่ยนป้ายกำกับของบุคคลที่มีอยู่แล้ว
-
-## สร้าง entity ใหม่
-
-คลิกปุ่ม `Create Entity` บนหน้า Entity Manager ระบุชื่อ, ป้าย และ ประเภท ถ้าคุณเลือก ประเภท `Person` entity ของคุณจะมีอีเมล , เบอร์โทรศัพท์ , ชื่อจริง , นามสกุล และ ช่อง คำทักทาย ตรวจสอบ `Stream` ถ้าคุณต้องการให้ entity ของคุณมีแผงสตรีม และผู้ใช้สามารถติดตามหน่วยงานประเภทนี้ได้
-
-ประเภท:
-
-* ฐานข้อมูล - entity ว่างเปล่าเฉพาะกับฟิลด์พื้นฐาน เช่น ชื่อผู้ใช้, ผู้ใช้ที่ได้รับคำสั่ง, ทีม, คำอธิบาย
-* Base Plus - เหมือนฐานข้อมูล แต่มีกิจกรรม, ประวัติ, แผงงาน (มีตั้งแต่ 4.3.0)
-* เหตุการณ์ - วันที่เริ่มต้น , วันที่สิ้นสุด , ระยะเวลา , ผู้ปกครอง , ฟิลด์สถานะ พร้อมใช้งานในปฏิทินและกิจกรรม (ตั้งแต่ 4.3.0 ต้องเปิดใช้งานที่ การดูแลระบบ> การตั้งค่า)
-* บุคคล - อีเมล , โทรศัพท์ , ชื่อจริง , นามสกุล , คำอวยพร , ฟิลด์ที่อยู่ , กิจกรรม , ประวัติความเป็นมา , แผงงาน
-* บริษัท - อีเมล , โทรศัพท์, ที่อยู่สำหรับการเรียกเก็บเงิน , ที่อยู่ในการจัดส่ง , กิจกรรม . ประวัติความเป็นมา , แผงงาน
-
-## อัปเดต entity ที่มีอยู่แล้ว
-
-ถ้าหากคุณ คลิก "แก้ไข" การเชื่อมโยง ใน entity บางตัว คุณจะสามารถ เปลี่ยนพารามิเตอร์บางอย่าง ของ entity นั้นๆ ได้
-
-* ป้ายกำกับ - ชื่อจำนวนหนึ่ง และ จำนวนมาก ของ entity.
-* บันทึกคำสั่งซื้อเริ่มต้น ถูกจัดเรียงโดยมุมมองในรายการ
-* Stream - ไม่ว่าคุณลักษณะ Stream จะเปิดใช้งานสำหรับ entity นี้หรือไม่
-* ปิดการใช้งาน - ตรวจสอบว่า คุณไม่จำเป็นต้องมี entity นี้ ในระบบของคุณ
-* ช่อง ตัวกรอง ข้อความ - ฟิลด์ที่จะค้นหา ในตัวกรอง ข้อความหลักและ การค้นหาทั่วโลก
-
-## Fields
-
-โดยคลิก ที่ `Fields` การเชื่อมโยงของคุณจะถูกย้ายไปยังหน้าอื่น คุณจะสามารถสร้าง fields ใหม่ หรืออัปเดตที่มีอยู่ได้ ประเภทของฟิลด์ ดังต่อไปนี้มีอยู่ในการจัดการ Entity :
-
-* ที่อยู่ - ที่อยู่ กับ ถนน , เมือง , รัฐ , รหัสไปรษณีย์ และ ประเทศ ;
-* Array - รายการค่า , มีความสามารถในการเลือกหลายค่า (ไม่ใช่ตัวเลือกที่ดี ถ้าคุณต้องการค้นหา ด้วยข้อมูลนี้); ผู้ใช้ สามารถเพิ่มค่าของตนเองได้ ถ้าหากไม่ได้ระบุตัวเลือก
-* เอกสารแนบ - เอกสาร ที่แนบมาหลายไฟล์ ;
-* อัตโนมัติ - เพิ่มขึ้น - อ่านเฉพาะ จำนวนที่สร้าง ;
-* Boolean - ช่องทำเครื่องหมาย , จริง หรือ เท็จ ;
-* สกุลเงิน - สำหรับ ค่าสกุลเงิน ;
-* วันที่ ;
-* วันเวลา ;
-* Enum - เลือกกล่อง ที่มีความสามารถ ในการเลือก เพียงค่าเดียว ;
-* แฟ้มข้อมูล - กำลังอัปโหลด แฟ้มข้อมูลหนึ่ง ไฟล์;
-* Float - ตัวเลขที่มี ทศนิยม ;
-* Foreign - ช่อง ที่เกียวข้องกับ entity ;
-* Image - uploading image file with a preview;
-* Integer - จำนวน ทั้งหมด;
-* ตัวเลข - อัตโนมัติ - จำนวน string ที่เพิ่มขึ้น โดย ใช้คำนำหน้าและความยาวที่ระบุไว้ ;
-* Multi-enum - ค่าของ รายการ, มีความสามารถ ในการเลือกหลายค่า (ไม่ใช่ตัวเลือกที่ดี ถ้าคุณต้องการค้นหาตามช่องนี้) คล้ายกับ Array แต่ ดีกว่า
-* ข้อความ - พื้นที่ข้อความ , สำหรับ ความยาวของข้อความ multiline ;
-* Url - สำหรับ ลอิงค์ การเชื่อมต่อ ;
-* Varchar - ข้อความ สั้น ๆ ;
-* Wysiwyg - คล้ายกับ field ข้อความ , ที่มีความสามารถ ในการจัดรูปแบบของข้อความ
-
-Parameters:
-* จำเป็นต้องใช้ - การกรอกข้อมูลใน field .
-* ค่าเริ่มต้น - ค่าของ field ที่กำหนด เมื่อสร้างบันทึกใหม่
-* ตรวจสอบแล้ว - การอัปเดตของ field นี้ จะเข้าสู้ไว้ใน Stream
-
-**หมายเหตุ**: หลังจากที่คุณเพิ่ม field ใหม่ คุณต้องใส่ field บน [layouts](layout-manager.md) (Administration > Layout Manager).
-
-### Dynamic Logic
-
-มีความสามารถ ในการสร้างแบบฟอร์ม dynamic เป็นไปได้ ที่จะกำหนดเงื่อนไขการทำให้บาง fields ชัดเจนได้ ร้องขอ หรือ อ่าน - เพียงอย่างเดียว เงื่อนไข จะได้รับการตรวจสอบ โดยอัตโนมัติ เมื่อมีการเปลี่ยนแปลงข้อมูล ในแบบฟอร์ม
-
-สำหรับ Enum, Array และ Multi Enum fields เป็นไปได้ ที่จะกำหนดชุดความแตกต่าง ของตัวเลือกที่จะใช้ได้ สำหรับ field ขึ้นอยู่กับ เงื่อนไขที่ได้รับ
-
-
-## ความสัมพันธ์
-
-คุณสามารถ สร้างความสัมพันธ์ใหม่ระหว่าง both out-of-box และ entities ที่กำหนดเอง ความสัมพันธ์ที่ใช้ได้ มี 3 ประเภท :
-
-* หนึ่ง-ถึง-จำนวนมาก: หลังจากที่คุณได้สร้างความสัมพันธ์แล้ว คุณสามารถวาง field ลิงก์ลง ในเค้าโครงรายละเอียดของ entity ที่ถูกต้อง และเพิ่มแผงความสัมพันธ์กับ entity ที่ยังเหลือ;
-* จำนวนมาก-ถึง-หนึ่ง: เหมือนกับ หนึ่ง-ถึง-จำนวนมาก แต่ในทางกลับกัน;
-* จำนวนมาก-ถึง-จำนวนมาก: แผงความสัมพันธ์ ทั้งสองด้าน.
-
-Parameter 'เชื่อมโยงหลาย Field' หมายความว่า field ของ `linkMultiple` ประเภทจะถูกสร้างขึ้น พร้อมกับความสัมพันธ์ คุณสามารถวาง field บนเค้าโครง ซึ่งสะดวกต่อ
-การเลือก บันทึก ที่เกี่ยวข้อง อย่างรวดเร็ว นี่ไม่ใช่ทางเลือกที่ดี ถ้าความสัมพันธ์ของคุณมีจุดเชื่อมโยงจำนวนมาก ซึ่งอาจชะลอการดาวน์โหลด รายละเอียดของหน้าจอ
-
-
-ถ้า parameter 'ผ่านการตรวจสอบ' มีการตรวจสอบ หลังจากนั้น มีการอัปเดตความสัมพันธ์ ซึ่งจะเข้าสู่ระบบใน Stream
-
diff --git a/i18n/th_TH/administration/extensions.md b/i18n/th_TH/administration/extensions.md
deleted file mode 100644
index 6f76232d5..000000000
--- a/i18n/th_TH/administration/extensions.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# การจัดการส่วนขยาย
-
-## วิธีการติดตั้งส่วนขยาย
-
-ในการติดตั้งส่วนขยายของ EspoCRM (เช่น Advanced Pack, VoIP Integration):
-
-1. เข้าสู่ระบบในฐานะผู้ดูแลระบบ
-2. ไปที่การดูแลระบบ> ส่วนขยาย
-3. อัปโหลดแพคเกจส่วนขยายของคุณ (zip file).
-4. คลิกที่ปุ่มติดตั้ง
-
-
-## วิธีอัปเกรดส่วนขยาย
-
-ในการอัปเกรดส่วนขยายที่ได้ติดตั้งไว้แล้ว (เช่น Advanced Pack, VoIP integration) ให้เป็นเวอร์ชั่นใหม่:
-
-1. ดาวน์โหลดส่วนขยายใหม่ที่ต้องการ
-2. เข้าสู่ระบบในฐานะผู้ดูแลระบบ.
-3. ไปที่การดูแลระบบ> ส่วนขยาย
-4. อัปโหลด แพคเกจส่วนขยายใหม่ของคุณ (zip file)โดย ไม่ต้องถอนการติดตั้งเวอร์ชันเดิม ที่ติดตั้งไว้แล้ว
-5. คลิกที่ปุ่มติดตั้ง
-
-
-## วิธี การถอน การติดตั้ง ส่วนขยาย
-
-ขั้นตอน ในการถอน การติดตั้งส่วนขยายที่ติดตั้งไว้:
-
-1. เข้าสู่ระบบ ในฐานะผู้ดูแลระบบ.
-2. ไปที่การดูแลระบบ> ส่วนขยาย
-3. ค้นหา ส่วนขยายที่ต้องการ ในรายการส่วนขยายที่ใช้งาน
-4. คลิกที่ปุ่มถอนการติดตั้ง
-
-
-## วิธี ลบ ส่วนขยาย
-
-เมื่อ ถอนการติดตั้งส่วนขยายแล้ว แต่มันยังคง มีอยู่ในระบบ คุณสามารถ ลบออก ได้อย่างสมบูรณ์ โดยทำตาม ขั้นตอน ในการลบ ส่วนขยาย ดังนี้:
-
-1. เข้าสู่ระบบ ในฐานะ ผู้ดูแลระบบ.
-2. ไปที่ การดูแลระบบ> ส่วนขยาย
-3. ค้นหา ส่วนขยายที่ต้องการ ในรายการ ส่วนขยาย ที่ใช้งาน
-4. คลิกที่ปุ่ม เอาออก
diff --git a/i18n/th_TH/administration/formula.md b/i18n/th_TH/administration/formula.md
deleted file mode 100644
index af01d2fdf..000000000
--- a/i18n/th_TH/administration/formula.md
+++ /dev/null
@@ -1,268 +0,0 @@
-# การคิดคำนวณ Fields (สูตร)
-
-ในการจัดการ entity จะสามารถกำหนดสคริปต์ (สูตร) สำหรับประเภทของ entity แบบเฉพาะเจาะจงได้ สคริปต์นี้จะถูกเรียกใช้ทุกครั้งก่อนที่บันทึกจะถูกบันทึกไว้ และมีความสามารถในการตั้งค่าเฉพาะฟิลด์ (attributes) ด้วยค่าที่ได้จากการคำนวณ
-
-
-เมื่อต้องการแก้ไขสูตรให้ทำตามนี้
-การดูแลระบบ > การจัดการ Entity > คลิกเมนูแบบเลื่อนลงที่ด้านขวาบนแถวของ entity ที่ต้องการ > สูตร
-
-นอกจากนี้คุณอาจจะต้องตั้งค่าฟิลด์ด้วย, ควรจะคำนวณและ อ่าน-อย่างเดียว ผ่าน Entity Manager.
-
-
-## Syntax
-
-สูตร EspoCRM เขียนด้วยภาษาง่ายๆที่ออกแบบมาเฉพาะสำหรับคุณลักษณะนี้
-
-มีตัวดำเนินการ, คุณลักษณะและค่าที่สามารถใช้ได้ในสูตร สำนวนที่แยกออกจากกันจะต้องคั่นด้วย `;`
-
-### ตัวดำเนินการ
-
-* `=` - หน้าที่ที่ได้รับมอบหมาย.
-* `||` - ตรรกศาสตร์ หรือ,
-* `&&` - ตรรกศาสตร์ และ,
-* `!` - ตรรกศาสตร์ ไม่ใช่,
-* `+`- การบวกตัวเลข,
-* `-` - การลบตัวเลข,
-* `*` - การคุณตัวเลข,
-* `/` - การหารตัวเลข,
-* `%` - ตัวเลข modulo,
-* `==` - การเปรียบเทียบมีค่าเท่ากับ,
-* `!=` - การเปรียบเทียบมีค่าไม่เท่ากับ,
-* `>` - การเปรียบเทียบมีค่ามากกว่า,
-* `<` - การเปรียบเทียบมีค่าน้อยกว่า,
-* `>=` - การเปรียบเทียบมีค่ามากกว่าหรือเท่ากับ,
-* `<=` - การเปรียบเทียบมีค่าน้อยกว่าหนือเท่ากับ
-
-ลำดับความสำคัญของตัวดำเนินการ:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### คุณลักษณะ
-
-คุณลักษณะ แสดงค่าฟิลด์ของ entity เป้าหมาย คุณสามารถแทรก attributes ที่ใช้งานได้ โดยคลิกที่ปุ่มบวก
-
-คุณสามารถเข้าถึง attributes ที่เกี่ยวข้องกับ entities ได้ด้วยรูปแบบดังต่อไปนี้ `linkName.attributeName`.
-
-
-### ฟังก์ชั่น
-
-รูปแบบการใช้ฟังก์ชัน: `groupName\functionName(argument1, argument2, ..., argumentN)`
-
-Out-of-the-box ดังฟังก์ชั่นที่แสดงด้านล่าง
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` ถ้า CONDITION เป็นไปตามที่กำหนดแล้วทำ CONSEITION ถ้าไม่ -- ให้ทำ ALTERNATIVE.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` ถ้า CONDITION เป็นไปตามที่กำหนดแล้วทำ CONSEITION ถ้าไม่ - ไม่ต้องทำอะไรเลย
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` concatenates สตริงสองสตริงหรือสตริงที่มากกว่า
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` แยกแยะตัวอักษรออกจากสตริง ตามตำแหน่ง START และ LENGTH
-
-ถ้า LENGTH ถูกละเว้น, สตริงย่อยเริ่มต้นจาก START สายอักขระย่อยที่เริ่มจาก START จนกว่าจะสิ้นสุด STRING จึงจะถูกส่งกลับ
-
-หาก LENGTH มีค่าเป็นลบ, จากนั้นตัวอัษรหลายตัวจะถูกละเว้นจากตอนท้ายของ STRING
-
-#### string\\trim
-`string\trim(STRING)` บีบช่องว่างจากจุดเริ่มต้นและจุดสิ้นสุดของ STRING
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` แปลงตัวอักษรเป็นตัวพิมพ์เล็ก (ตั้งแต่เวอร์ชัน 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` แปลงตัวอักษรเป็นตัวพิมพ์ใหญ่ (ตั้งแต่เวอร์ชัน 5.0.0)
-
-#### datetime\\today
-`datetime\today()` ส่งกลับวันที่วันนี้
-
-#### datetime\now
-`datetime\now()` ส่งคืนวันเวลา ณ ปัจจุบัน
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` แปลง VALUE วันที่หรือวันเวลา เป็นสตริงที่จัดรูปแบบตามการตั้งค่าแอปพลิเคชัน ส่วน TIMEZONE และ FORMAT สามารถข้ามได้ ถ้า TIMEZONE ถูกข้ามไป ระบบจะใช้โซนเวลาเริ่มต้น ถ้า FORMAT ถูกละไว้ ระบบจะใช้รูปแบบเริ่มต้น
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` แสดงวันที่ของเดือน (1-31). `0` ถ้า VALUE ว่างเปล่า ถ้า TIMEZONE ถูกละไว้ระบบจะใช้เขตเวลาของระบบ (ตั้งแต่เวอร์ชัน 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` แสดงเป็นเดือน (1-12). `0` ถ้า VALUE ว่างเปล่า ถ้า TIMEZONE ถูกละไว้ระบบจะใช้เขตเวลาของระบบ (ตั้งแต่เวอร์ชัน 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` แสดงเป็นปี `0` ถ้า VALUE ว่างเปล่า ถ้า TIMEZONE ถูกละไว้ระบบจะใช้เขตเวลาของระบบ (ตั้งแต่เวอร์ชัน 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` แสดงเป็นชั่วโมง (0-23). `-1` ถ้า VALUE ว่างเปล่า ถ้า TIMEZONE ถูกละไว้ระบบจะใช้เขตเวลาของระบบ (ตั้งแต่เวอร์ชัน 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` แสดงเป็นนาที (0-59). `-1` ถ้า VALUE ว่างเปล่า ถ้า TIMEZONE ถูกละไว้ระบบจะใช้เขตเวลาของระบบ (ตั้งแต่เวอร์ชัน 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` แสดงวันในสัปดาห์ (0-6). `-1` ถ้า VALUE ว่างเปล่า `0` - สำหรับวันอาทิตย์ ถ้า VALUE ว่างเปล่า ถ้า TIMEZONE ถูกละไว้ระบบจะใช้เขตเวลาของระบบ (ตั้งแต่เวอร์ชัน 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` แสดงผลต่างระหว่างวันที่สองหรือวันเวลา INTERVAL_TYPE ควรเป็น 'ปี', 'เดือน', 'วัน', 'ชั่วโมง', 'นาที'. ส่งคืน `null` ถ้าเกิดความล้มเหลว ผลจะเป็นลบถ้า VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` เพิ่ม MINUTES เป็น VALUE วันเวลา MINUTES อาจเป็นลบได้
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` เพิ่ม HOURS เป็น VALUE วันเวลา HOURS อาจเป็นลบได้
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` เพิ่ม DAYS เป็น VALUE วันที่หรือวันเวลา DAYS อาจเป็นลบได้
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` เพิ่ม WEEKS เป็น VALUE วันที่หรือวันเวลา WEEKS อาจเป็นลบได้
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` เพิ่ม MONTHS เป็น VALUE วันที่หรือวันเวลา MONTHS อาจเป็นลบได้
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` เพิ่ม YEARS เป็น VALUE วันที่หรือวันเวลา YEARS อาจเป็นลบได้
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` ส่งคืนวันที่หรือ วันเวลา ที่ใกล้ที่สุดไปเป็น VALUE โดยอิงตาม arguments (ตั้งแต่เวอร์ชัน 5.0.0)
-
-TYPE สามารถเป็นหนึ่งในค่าต่อไปนี้: 'เวลา', 'นาที', 'ชั่วโมง', 'วัน', 'เดือน', 'วันในสัปดาห์' TARGET คือจำนวนเต็มหรือค่าสตริง IS_PAST หมายถึงการค้นหาที่ใกล้เคียงที่สุดในอดีตที่ผ่านมา ถ้า TIMEZONE ถูกละไว้ระบบจะใช้เขตเวลาเริ่มต้น
-
-ตัวอย่าง:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` จะคืนค่า วันเวลา ที่ใกล้เคียงที่สุดในอนาคตพร้อมกันเวลา 20:00 น.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` จะแสดง `2017-11-01`,วันแรกของเดือน
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` จะกลับคืนในวันจันทร์ถัดไป (จุดเริ่มต้นของวัน)
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` แปลง VALUE หมายเลข เป็นสตริงที่จัดรูปแบบ ตามรูปแบบเฉพาะหรือการตั้งค่าเริ่มต้นของแอ็พพลิเคชัน ถ้า DECIMALS, DECIMAL_MARK หรือ THOUSAND_SEPARATOR ใช้ค่าเริ่มต้นระบบ
-
-ตัวอย่าง:
-
-`number\format(2.666667, 2)` - ผล 2.67;
-
-`number\format(1000, 2)` - ผล 1,000.00;
-
-`number\format(10.1, 0)` - ผล 10.
-
-
-#### number\abs
-`number\abs(VALUE)` ค่าสัมบูรณ์ จะส่งกลับค่า null หาก VALUE ไม่ใช่ตัวเลข
-
-#### number\round
-`number\round(VALUE, PRECISION)` ส่งกลับค่าที่ปัดเศษของ VALUE ไปยัง PRECISION ที่ระบุ (จำนวนตัวเลขหลังจุดทศนิยม) PRECISION อาจเป็นค่าลบหรือศูนย์ (ค่าเริ่มต้น)
-
-#### number\floor
-`number\floor(VALUE)` ส่งกลับค่าจำนวนเต็มถัดไปต่ำสุด โดยปัดเศษค่าลงถ้าจำเป็น (ตั้งแต่เวอร์ชัน 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` ส่งกลับค่าจำนวนเต็มถัดไปสูงสุด โดยปัดเศษค่าถ้าจำเป็น (ตั้งแต่เวอร์ชัน 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` ส่งคืนค่า TRUE หาก entity ใหม่ (กำลังสร้าง) และ FALSE ถ้าไม่ใช่ (กำลังถูกอัพเดต)
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` ส่งคืนค่า TRUE หากมีการเปลี่ยนแปลง ATTRIBUTE ของ entity
-
-ตัวอย่าง:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` ส่งคืนค่า TRUE หากไม่มีการเปลี่ยนแปลง ATTRIBUTE ของ entity
-
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Attribute ถูกตั้งค่า เมื่อดึงข้อมูล entity เป้าหมายจากฐานข้อมูล ก่อนที่จะแก้ไข
-
-ตัวอย่าง:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` เพิ่ม ID ในฟิลด์ การเชื่อมโยงหลายช่อง ตัวอย่างเช่นเพิ่ม 'someTeamId' ในฟิลด์ 'teams'
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` เพิ่มรายการรหัส (ตั้งแต่เวอร์ชัน 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` ตรวจสอบว่าการเชื่อมโยงแบบ Multiple ใน field มีรหัสเฉพาะหรือไม่
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` นำ ID ที่ระบุออกจากฟิลด์ การเชื่อมโยงแบบ Multiple
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` ตรวจสอบว่า entity เป้าหมายเกี่ยวข้องกับเอนทิตีอื่นที่แสดงโดย LINK และ ID
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` ส่งคืนค่า ATTRIBUTE ของผู้ใช้ปัจจุบัน
-
-#### list
-`list(VALUE-1, ... VALUE-N)` ส่งกลับ array (ตั้งแต่เวอร์ชัน 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` ส่งกลับค่าจริงถ้า LIST มี VALUE สามารถใช้สำหรับฟิลด์ Array และ Multi-Enum (ตั้งแต่เวอร์ชัน 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` เพิ่มองค์ประกอบอย่างน้อยหนึ่งรายการในตอนท้ายของ array และส่งกลับ array ใหม่ (ตั้งแต่เวอร์ชัน 5.0.0)
-#### array\length
-`array\length(LIST)` ส่งคืนจำนวนองค์ประกอบใน LIST (ตั้งแต่เวอร์ชัน 4.8.1)
-
-
-### Values
-
-* Strings. เช่น 'some string';
-* Integer numbers. เช่น 1, 100, 40300.
-* Float numbers. เช่น 5.2.
-
-### Variables
-
-เป็นไปได้ที่จะกำหนดตัวแปรที่กำหนดค่าเองในสูตร
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## ตัวอย่าง
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## ใช้สูตรใน Workflows
-
-คุณสามารถใช้สูตรในเงื่อนไขและการทำงานใน workflow ์ได้ ดูจาก [workflows documentation](workflows.md) สำหรับข้อมูลเพิ่มเติม.
diff --git a/i18n/th_TH/administration/import.md b/i18n/th_TH/administration/import.md
deleted file mode 100644
index 17a9cc307..000000000
--- a/i18n/th_TH/administration/import.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# การนำเข้า
-
-การนำเข้า สามารถเข้าถึงได้ เฉพาะสำหรับ ผู้ใช้ ที่เป็นผู้ดูแลระบบ เท่านั้น การดูแลระบบ > นำเข้า คุณสามารถนำเข้า เฉพาะจาก ไฟล์ CSV
-
-## ขั่นตอน ที่ 1
-
-เลือก ประเภทข้อมูลที่ คุณต้องการนำเข้า (Entity Type field).
-เลือก CSV ไฟล์ ไฟล์ ควรได้รับการฟอร์แมตด้วย `UTF-8`.
-เลือก `What to do?`ตัวเลือก ที่สามารถใช้งานได้: 'สร้าง เท่านั้น', 'สร้าง & อัปเดต', 'อัปเดต เท่านั้น'.
-
-* `Create Only` - เลือก หากคุณต้องการ สร้างการบันทึกเท่านั้น.
-* `Create & Update` - บันทึกจะถูกสร้างขึ้น แต่ถ้า บันทึกที่มีค่าฟิลด์ที่ตรงกัน จะพบว่าบันทึกนั้น ได้รับการอัปเดต คุณสามารถตรวจสอบได้ ว่าจะให้ฟิลด์ใดตรงกัน เมื่อเปิด _Step 2_.
-* `Update only` - เฉพาะ บันทึกที่มีค่าฟิลด์ที่ตรงกันเท่านั้น ถึงจะมีการอัปเดต
-
-เมื่อคุณเลือกไฟล์ csv คุณจะสามารถดูว่า ควรจะแยกการวิเคราะห์ ในแผงแสดงตัวอย่าง อย่างไร เมื่อ คุณเปลี่ยนคุณสมบัติพรีวิวจะได้รับการอัปเดต
-
-* `Header Row` - ไฟล์ CSV แถวแรก มีชื่อฟิลด์หรือไม่
-* `Execute in idle` - แนะนำถ้าคุณมีบันทึกที่จะนำเข้าเป็นกลุ่มใหญ่
- การนำเข้าจะประมวลผลผ่าน cron สถานะจะเป็น "เสร็จสิ้น" เมื่อกระบวนการนำเข้าเสร็จสิ้น
-* `Skip searching for duplicates` - มันจะลดการนำเข้าตามเวลา
-
-คลิก ปุ่ม _Next_ เพื่อดำเนินการ _Step 2_ต่อไป
-
-
-
-## ขั้นตอน ที่ 2
-
-ตั้งค่า field mapping: ฟิลด์ จะตรงกับ คอลัมน์ของไฟล์ CSV อย่างไร คุณสามารถข้ามคอลัมน์ ที่ไม่จำเป็นได้ ที่นี่
-ในกรณีของ 'สร้าง & อัปเดต' และ 'อัปเดต เท่านั้น' คุณต้องตรวจสอบ fields โดยบันทึก ควรเป็นอัปเดต จึงจะค้นพบ เพิ่มค่าเริ่มต้น ที่คุณต้องการให้บันทึกใหม่ และ อัปเดตบันทึก ที่จะตั้งค่าด้วย เช่น คุณสามารถระบุฟิลด์ ผู้ใช้ หรือ ทีม ที่ได้รับมอบหมาย
-
-
-หลังจากนำเข้าเสร็จแล้วคุณจะสามารถเปลี่ยนแปลงบันทึกที่สร้างขึ้นใหม่ได้, ดูรายการที่ซ้ำกันและรบันทึกที่ได้อัปเดต. สำเนา หมายความว่า มีบันทึก ที่คล้ายกัน ในระบบ คุณสามารถ นำรายการที่ซ้ำกันทั้งหมด สามารถ นำเข้าออกได้พร้อมกัน หมายเหตุ: การย้อนกลับไม่ทำงานกับบันทึกที่อัปเดตไปแล้ว
-
-คลิกที่ปุ่ม _Run Import_ เพื่อดำเนินการต่อ อาจใช้เวลาสักครู่หนึ่ง ก่อนที่ขั้นตอน การนำเข้าจะเสร็จสิ้น ถ้าคุณต้องการนำเข้าบันทึกเป็นจำนวนมาก (ขึ้นอยู่กับการกำหนดค่าเซิร์ฟเวอร์ของคุณ,ปกติถ้ามากกว่า 200 บันทึก) คุณต้องแน่ใจว่า php parameter `set_time_limit` นั้นมีพื้นที่มากพอ.
-
-
-
-## วิธีการนำเข้าสู่รายการเป้าหมาย
-
-เมื่อคุณนำเข้าที่อยู่เพื่อติดต่อ, โอกาสในการขาย หรือ บัญชีของคุณ สามารถเพิ่มลงในรายการเป้าหมายได้. ในขั้นตอนที่ 2 คุณต้องเพิ่มรายการเป้าหมายลงใน field `Default Values` และเลือกบันทึกรายการเป้าหมายที่ต้องการ คุณยังสามารถใช้`Update only` หรือ `Create & Update` นำเข้าเพื่อเพิ่มเป้าหมายที่มีอยู่แล้ว ในรายการเป้าหมาย
diff --git a/i18n/th_TH/administration/installation.md b/i18n/th_TH/administration/installation.md
deleted file mode 100644
index 16a1115d5..000000000
--- a/i18n/th_TH/administration/installation.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# การติดตั้ง
-
-### ข้อกำหนด
-EspoCRM ทำงานกับ ผู้ให้บริการโฮสติ้งที่มากที่สุด โดยมี ข้อกำหนดรวม ๆ ดังต่อ ไปนี้:
-
-* PHP 5.6 หรือ เวอร์ชั่น รุ่นล่าสุด ของ PHP กับ pdo ที่เปิดใช้งาน, json, GD library, mcrypt extensions (โดยปกติ มักจะเปิดใช้งานตาม ค่าเริ่มต้น);
-* MySQL 5.5.3 หรือ สูงกว่า.
-
-ดู [Server Configuration](server-configuration.md) บทความสำหรับข้อมูลเพิ่มเติม
-
-### 1. ดาวน์โหลดแพ็คเกจการติดตั้ง EspoCRM
-เพื่อ รับเวอร์ชันล่าสุดของ EspoCRM ติตาม [download page](http://www.espocrm.com/download/) ลิงค์.
-
-### 2. อัปโหลดไฟล์ EspoCRM ไปยัง เซิร์ฟเวอร์ของคุณ
-
-เมื่อ การดาวน์โหลดเสร็จสิ้น ให้อัพโหลดแพคเกจไปยัง เว็บเซิร์ฟเวอร์ของคุณ
-หากต้องการอัพโหลด คุณสามารถใช้ SSH, FTP หรือ โฮสติ้งของแผงการบริหาร
-แยกเก็บข้อมูล ไปยังเว็บเซิร์ฟเวอร์ สาธารณะของคุณ (เช่น, `public_html`, `www`, etc.).
-
-_หมายเหตุ: สำหรับ FTP คุณต้องแยกที่เก็บข้อมูลก่อน ที่จะอัปโหลดไปยัง เว็บเซิร์ฟเวอร์ของคุณ._
-
-### 3. สร้างฐานข้อมูล MySQL สำหรับ EspoCRM เพื่อใช้งาน
-
-ไปที่ แผงการดูแล ระบบโฮสติ้งของคุณ, หรือ ไปที่ SSH, และ สร้างฐานข้อมูลใหม่ และ ผู้ใช้ สำหรับ EspoCRM (เช่น, `MySQL Databases` ใน cPanel).
-
-### 4. เรียกใช้กระบวนการติดตั้ง EspoCRM
-
-ตอนนี้, เปิดเว็บเบราเซอร์ของคุณ, และ ไปที่ URL กับ EspoCRM ไฟล์ (เช่น, `http://yourdomain.com/espo`).
-
-หาก คุณเห็นหน้าจอนี้ คุณมี "Permission denied" ผิดพลาด.
-ดังนั้น, คุณต้องดำเนินการตาม คำสั่งที่แสดงใน terminal โดยผ่านทาง SSH, หรือ ติดตั้ง permission ที่ถูกต้อง
-มันควรจะเป็น 755 สำหรับ directories, 644 สำหรับ ไฟล์, และ 775 สำหรับ `data` directory.
-และตรวจสอบให้แน่ใจว่าคุณมีข้อมูลถูกต้อง _owner_ and _group_.
-
-
-
-หากคุณเห็นหน้าจอต่อไปนี้, สิทธิ์ permission ถูกต้องและคุณสามารถเริ่มติดตั้ง EspoCRM ได้
-
-
-
-ในหน้านี้คุณสามารถอ่านและยอมรับข้อตกลงในใบอนุญาต
-
-
-
-ระบุรายละเอียดสำหรับฐานข้อมูล MySQL ที่จะสร้างขึ้นใหม่
-
-
-
-ระบุชื่อผู้ใช้และรหัสผ่านของผู้ดูแล EspoCRM
-
-
-
-ในหน้านี้คุณสามารถตั้งค่าเริ่มต้นของ EspoCRM, เช่น รูปแบบ วันที่ และ เวลา , เขตเวลา , สกุลเงิน และอื่น ๆ
-
-
-
-ระบุ การตั้งค่า SMTP สำหรับอีเมลขาออก, ถ้าคุณต้องการมีความสามารถในการส่งอีเมล
-
-ขั้นตอนนี้ สามารถข้ามได้ด้วย การคลิกที่ปุ่ม _Next_
-ตัวเลือกทั้งหมด เหล่านี้สามารถเพิ่ม / แลกเปลี่ยนใน EspoCRM หลังจาก ทำการติดตั้งแล้วได้ด้วย
-
-
-
-การแสดงความยินดี! การติดตั้งเสร็จสมบูรณ์แล้ว
-สิ่งสุดท้ายที่จะตั้งค่า Scheduled Tasks ให้ระบบ ของคุณดำเนินการ สามารถ ทำได้ โดยการเรียกใช้`crontab -e` ใน linux cli และ ใน _Windows Tasks Scheduler_ ใน ระบบ Windows
-
-
-
-เราหวังว่าคุณจะสนุกกับการทำงานใน EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/th_TH/administration/layout-manager.md b/i18n/th_TH/administration/layout-manager.md
deleted file mode 100644
index c440a7917..000000000
--- a/i18n/th_TH/administration/layout-manager.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# การจัดการเค้าโครง
-
-การจัดการเค้าโครง มีอยู่ในแผงควบคุม ให้ความสามารถในการปรับแต่งลักษณะที่ปรากฏของ รายละเอียด, แก้ไข, มุมมองรายการ เช่นเดียวกับตัวกรองการค้นหาและเขตข้อมูลสำหรับ ขนาด - การอัพเดท แบบฟอร์ม
-
-## รายการ
-
-เค้าโครงหลักสำหรับมุมมองรายการ กำหนดคอลัมน์และพารามิเตอร์
-
-
-
-พารามิเตอร์ที่พร้อมใช้งาน สำหรับคอลัมน์แสดงอยู่ด้านล่าง
-
-### ความกว้าง (%)
-
-ความกว้างของคอลัมน์แสดงเป็นเปอร์เซ็นต์ ว่างเปล่า หมายถึง ความกว้างอัตโนมัติ
-
-### การเชื่อมโยง
-
-หากเลือกช่อง field แล้วจะเกิดการเชื่อมโยงไปยังมุมมองรายละเอียดของบันทึก ปกติแล้วมักใช้สำหรับชื่อฟิลด์
-
-
-### ไม่สามารถจัดเรียงได้
-
-ปิดการใช้งานการจัดเรียงคอลัมน์
-
-### เส้นตรง
-
-จัดเรียงคอลัมน์ไปทางซ้ายหรือไปทางขวา
-
-## รายละเอียด
-
-เค้าโครงหลักสำหรับมุมมองรายละเอียดและมุมมองการแก้ไข กำหนดแผง,แถวและเซลล์Cells ประกอบด้วยเขตข้อมูล
-
-แถวสามารถมีสองเซลล์หรือหนึ่งเซลล์ที่ขยายไปถึงความกว้างเต็มของแถว หากต้องการเพิ่มแถวที่มีเซลล์ที่ขยายแล้ว คุณต้องเพิ่มแถวใหม่และคลิกที่เครื่องหมายลบในเซลล์ใดก็ได้
-
-
-
-## รายการ (ขนาดเล็ก)
-
-เค้าโครงรายการสำหรับแผงความสัมพันธ์ นอกจากนี้ยังสามารถใช้ในสถานที่อื่น ๆ ที่เหมาะสมในการแสดงรายการในมุมมองที่แคบ
-
-## รายละเอียด (ขนาดเล็ก)
-
-รายละเอียดมุมมอง สำหรับการสร้างอย่างรวดเร็ว, มุมมองอย่างรวดเร็วและรูปแบบการแก้ไขอย่างรวดเร็ว
-
-## ตัวกรองการค้นหา
-
-รายการ fields ที่มีอยู่ในมุมมองรายการเพื่อค้นหา
-
-## การอัปเดต Mass
-
-รายการของเขตข้อมูลที่พร้อมใช้งานในแบบฟอร์มการปรับปรุง Mass
-
-## แผงความสัมพันธ์
-
-รายการแผงความสัมพันธ์ที่แสดงในมุมมองรายละเอียดที่ด้านล่าง ซึ่งสามารถสั่งแผงใหม่ได้ คุณสามารถกำหนดสีของแผงควบคุมได้ Style parameter
-
-## แผงด้านข้าง
-
-แผงด้านข้างสำหรับรายละเอียด, แก้ไข, รายละเอียดขนาดเล็ก, การแก้ไขฟอร์มขนาดเล็ก ให้ความสามารถในการซ่อนหรือสั่งรายการสั่งซื้อใหม่, ประวัติศาสตร์, งานและอื่น ๆ แผงสามารถ colorized โดย Style parameter
-
-## เค้าโครงเพิ่มเติม
-
-ประเภท entity บางประเภทมีรูปแบบเพิ่มเติม: แปลง Lead, รายการสำหรับบัญชี
diff --git a/i18n/th_TH/administration/ldap-authorization-for-ad.md b/i18n/th_TH/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index fce54d79d..000000000
--- a/i18n/th_TH/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# การขออนุมัติ LDAP สำหรับ Active Directory
-
-ตัวอย่าง การกำหนดค่า LDAP สำหรับ เซิร์ฟเวอร์ Active Directory คู่มือคำอธิบายฉบับเต็มของการกำหนดค่า LDAP การอธิบายของการกำหนดค่า
-[here](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/th_TH/administration/ldap-authorization-for-openldap.md b/i18n/th_TH/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 423cc0631..000000000
--- a/i18n/th_TH/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# LDAP อนุมัติ สำหรับ OpenLDAP
-
-ตัวอย่าง ของการกำหนดค่า LDAP อนุมัติ สำหรับ เซิร์ฟเวอร์ OpenLDAP คำอธิบายฉบับเต็มของการกำหนดค่า LDAP การกำหนดค่าจะได้รับการอธิบาย [ที่นี้](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-รหัสผ่าน : ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: ใช่
-ฐานข้อมูล DN: cn=espo-users,ou=users,dc=espo,dc=local
-สร้างผู้ใช้ใน EspoCRM: ใช่
-คุณลักษณะ ชื่อจริง ของผู้ใช้: ชื่อจริง
-คุณลักษณะ นามสกุล ของผู้ใช้ : นามสกุล
-คุณลักษณะ หัวข้อ ของผู้ใช้: หัวข้อ
-คุณลักษณะ อีเมล ของผู้ใช้: อีเมล
-คุณลักษณะ หมายเลขโทรศัพท์ของผู้ใช้ : เบอร์โทรศัพท์
-```
-
-
diff --git a/i18n/th_TH/administration/ldap-authorization.md b/i18n/th_TH/administration/ldap-authorization.md
deleted file mode 100644
index d9f76de96..000000000
--- a/i18n/th_TH/administration/ldap-authorization.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# การให้สิทธิ์ Ldap
-
-ในคู่มือนี้จะแสดงวิธีตั้งค่าการให้สิทธิ์ LDAP สำหรับ EspoCRM ไปกันเลย.
-
-ไปที่ LDAP server ของคุณ และสร้างฐานของ DN สำหรับเชื่อมโยงผู้ใช้ EspoCRM เช่น
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-เราต้องสร้างระบบผู้ใช้ซึ่งจะมีสิทธิ์ในการเข้าถึง DN ของผู้ใช้ (“cn=espo-users,ou=users,dc=espo,dc=local”) ดังนั้น DN แบบเต็มรูปแบบ สำหรับผู้ใช้ระบบนี้จะเป็น
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-ตอนนี้, เราสามารถเพิ่มผู้ใช้ LDAP เพื่อเข้าถึง EspoCRM ได้ เช่น Espo Tester กับชื่อผู้ใช้ "tester" ภายใน “cn=espo-users,ou=users,dc=espo,dc=local” DN. โปรดทราบ: เพื่อให้สามารถใช้รูปแบบการเข้าสู่ระบบนี้สำหรับ EspoCRM คุณต้องระบุตัวเลือก "User Attribute" และ "Base DN"
-
-หลังจากนั้น, ไปที่ EspoCRM การตั้งค่าการตรวจสอบความถูกต้องในแผงผู้ดูแลระบบ, เลือก `LDAP` วิธีการและกรอกรายละเอียด LDAP:
-
-
-
-* Host – LDAP IP หรือ ชื่อ host
-* Port – การเชื่อมต่อ port.
-* Auth – เข้าถึงข้อมูลประจำตัวสำหรับเซิร์ฟเวอร์ LDAP :
- * Full User DN – DN ผู้ใช้ระบบเต็มรูปแบบซึ่งสามารถค้นหาผู้ใช้รายอื่นได้
- * Password – รหัสผ่านเพื่อเข้าใช้งานเซิร์ฟเวอร์ LDAP
-* Security – SSL หรือ TSL protocol.
-* Username Attribute – attribute เพื่อระบุผู้ใช้ สำหรับ Active Directory อาจเป็น "userPrincipalName" หรือ "sAMAccountName"
-* Account Canonical Form – ประเภทบัญชีของบัญชีของคุณ มี 4 ตัวเลือกดังต่อไปนี้
- * Dn – แบบฟอร์มในรูปแบบ `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – แบบฟอร์ม `tester`.
- * Backslash – แบบฟอร์ม `COMPANY\tester`.
- * Principal – แบบฟอร์ม `tester@company.com`.
-* Bind Requires Dn – หากต้องการจัดรูปแบบชื่อผู้ใช้ในรูปแบบ DN
-* Base Dn – ฐาน DN เริ่มต้นซึ่งใช้สำหรับค้นหาผู้ใช้
-* User Login Filter – ตัวกรองซึ่งอนุญาตให้ จำกัดผู้ใช้ที่สามารถใช้ EspoCRM ได้ เช่น. `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – โดเมนที่ใช้สำหรับการให้สิทธิ์เซิร์ฟเวอร์ LDAP
-* Account Domain Name Short – โดเมนสั้น ๆ ที่ใช้สำหรับการให้สิทธิ์เซิร์ฟเวอร์ LDAP
-* Try Username Split – ตัวเลือกในการแบ่งชื่อระหว่างผู้ใช้กับโดเมน
-* Opt Referrals – ถ้าการแนะนำผลิตภัณฑ์ควรปฏิบัติตาม
- LDAP client
-* Create User in EspoCRM – ตัวเลือกนี้อนุญาตให้ EspoCRM สร้างผู้ใช้จาก LDAP
- * User First Name Attribute – LDAP attribute ที่ใช้เพื่อระบุชื่อผู้ใช้
- * User Last Name Attribute – LDAP attribute ที่ใช้เพื่อระบุนามสกุลผู้ใช้
- * User Title Attribute – LDAP attribute ซึ่งใช้เพื่อระบุหัวข้อของผู้ใช้
- * User Email Address Attribute – LDAP attribute ซึ่งใช้เพื่อระบุที่อยู่อีเมลของผู้ใช้
- * User Phone Number Attribute – LDAP attribute ซึ่งใช้เพื่อระบุเบอร์โทรศัพท์ของผู้ใช้
-
-ตอนนี้, ไปที่หน้าเข้าสู่ระบบและระบุข้อมูลรับรองผู้ใช้
-
-
-
-ผู้ใช้ได้รับการตรวจสอบสิทธิ์และสร้างขึ้นโดยอัตโนมัติใน EspoCRM
-
-## คำแนะนำการตั้งค่าตามเซิร์ฟเวอร์ของคุณ:
-* [Active Directory server](ldap-authorization-for-ad.md)
-* [OpenLDAP server](ldap-authorization-for-openldap.md)
-
-ข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า LDAP คุณสามารถอ่านได้ที่ [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/) เนื่องจาก EspoCRM ใช้ห้องสมุดนี้
-
-
-
-
diff --git a/i18n/th_TH/administration/maps.md b/i18n/th_TH/administration/maps.md
deleted file mode 100644
index 31f82adaf..000000000
--- a/i18n/th_TH/administration/maps.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# แผนที่
-
-## วิธีแสดงแผนที่ตามฟิลด์ที่อยู่
-
-ฟิลด์ที่อยู่ทุกช่องมีฟิลด์แผนที่ตรงกัน สิ่งที่คุณต้องทำคือการวางไว้ในเค้าโครงรายละเอียด โดยใช้บริการ Google Maps
-`Administration > Layout Manager > Choose entity (Account, Contact, Lead or custom one) > Detail > Drag & Drop Map field.`
-
-ทำให้เซลล์กว้างขึ้นโดยใช้เครื่องหมายลบ
-
-นอกจากนี้คุณยังสามารถกำหนดค่าความสูงของฟิลด์ของคุณได้ด้วย
-
-`Administration > Entity Manager > Choose entity > Fields > find the map field and click on it > edit the height and save.`
-
-## Api Key
-
-ตั้งแต่ EspoCRM เวอร์ชัน 4.2.0 คุณต้องระบุ Api Key เพื่อใช้ Google Maps(Administration > Integration > Google Maps).
-
diff --git a/i18n/th_TH/administration/moving-to-another-server.md b/i18n/th_TH/administration/moving-to-another-server.md
deleted file mode 100644
index a37f53d42..000000000
--- a/i18n/th_TH/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# การย้าย EspoCRM ไปยังเซิร์ฟเวอร์เครื่องอื่นๆ
-
-ทำตามขั้นตอนต่อไปนี้เพื่อย้าย EspoCRM ไปยังเซิร์ฟเวอร์เครื่องอื่น:
-
-### ขั้นตอนที่ 1. สำรองข้อมูลไฟล์
-
-เปิดตัวจัดการไฟล์หรือเข้าสู่ระบบผ่าน SSH เพื่อเก็บไฟล์ทั้งหมดที่มีอยู่จาก directory EspoCRM รายละเอียดเพิ่มเติม: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### ขั้นตอนที่ 2. สำรองฐานข้อมูลของคุณ
-
-ข้อมูลที่จัดเก็บในฐานข้อมูล (MySQL, MariaDB) ควรได้รับการสำรองข้อมูล โปรดปฏิบัติตามคำแนะนำดังนี้:https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### ขั้นตอนที่ 3. คัดลอกไฟล์และการสำรองฐานข้อมูลไปยังเซิร์ฟเวอร์เครื่องอื่น
-
-คัดลอกการสำรองข้อมูลของไฟล์และฐานข้อมูลของคุณไปยังเซิร์ฟเวอร์ใหม่
-
-### ขั้นตอนที่ 4 ยกเลิกการเก็บสำรองข้อมูล
-
-หากต้องการยกเลิกการเก็บไฟล์สำรองข้อมูล คุณสามารถใช้ Archive Manager หรือตามคำแนะนำดังนี้ได้: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-หมายเหตุ: ไฟล์ต้องอยู่ใน directory เว็บเซิร์ฟเวอร์
-
-### ขั้นตอนที่ 5. การกำหนดค่าเซิร์ฟเวอร์
-
-กำหนดค่าเซิร์ฟเวอร์ใหม่ตามคำแนะนำ ที่นี่: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### ขั้นตอนที่ 6 สิทธิ์ที่ถูกต้อง
-
-การตั้งค่าสิทธิ์และเจ้าของไฟล์, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### ขั้นตอนที่ 7 การนำเข้าการสำรองฐานข้อมูลของคุณ
-
-เริ่มต้น, คุณต้องสร้างฐานข้อมูลใหม่กับผู้ใช้ใน MySQL เมื่อต้องการนำเข้าฐานข้อมูลของคุณจากข้อมูลสำรองให้ทำตามคำแนะนำดังนี้: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### ขั้นตอนที่ 8 การกำหนดค่า EspoCRM ที่ถูกต้อง
-
-หลังจากประสบความสำเร็จในการนำเข้าและกำหนดค่าเซิร์ฟเวอร์ โปรดแก้ไขการกำหนดค่า EspoCRM ในไฟล์ `ESPOCRM_DIRECTORY/data/config.php`:
-
- * การตั้งค่าการเชื่อมต่อฐานข้อมูล:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - ถ้าชื่อโดเมนของคุณ (URL) มีการเปลี่ยนแปลง:
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * เจ้าของไฟล์เริ่มต้น (เฉพาะในกรณีที่ต่างกัน):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- โดยที่ `www-data` เป็นผู้ใช้เว็บเซิร์ฟเวอร์ของคุณ
-
-### ขั้นตอนที่ 9. ตั้งค่า crontab
-
-ตั้งค่า crontab, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-หมายเหตุ: ควรกำหนดค่าภายใต้ผู้ใช้เว็บเซิร์ฟเวอร์ของคุณ
-
-นั่นคือทั้งหมด ตอนนี้ EspoCRM instance ของคุณกำลังทำงานบนเซิร์ฟเวอร์เครื่องใหม่
diff --git a/i18n/th_TH/administration/nginx-server-configuration.md b/i18n/th_TH/administration/nginx-server-configuration.md
deleted file mode 100644
index 2fcf7e43a..000000000
--- a/i18n/th_TH/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# การกำหนดค่าเซิร์ฟเวอร์ Nginx สำหรับ EspoCRM
-
-คำแนะนำเหล่านี้เป็นส่วนเสริมของ [Server Configuration](server-configuration.md) ข้อแนะนำ โปรดทราบว่าการตั้งค่าทั้งหมดที่ระบุไว้ในที่นี้ สามารถทำได้บนเซิร์ฟเวอร์ Ubuntu
-
-## ข้อกำหนด PHP
-
-การติดตั้งไลบรารีที่จำเป็นทั้งหมด, เรียกใช้คำสั่งเหล่านี้ใน terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## การแก้ไขปัญหา "ข้อผิดพลาด API: EspoCRM API ที่ไม่พร้อมใช้งาน”:
-
-ใช้ขั้นตอนที่จำเป็นเท่านั้น หลังจากแต่ละขั้นตอนให้ตรวจสอบว่าปัญหาได้รับการแก้ไขแล้วหรือยัง
-
-### 1. การเปิดใช้งานกฎการเขียนใหม่ในเซิร์ฟเวอร์ Nginx
-
-ให้เพิ่มรหัสนี้ลงในไฟล์ config ของเซิร์ฟเวอร์ Nginx (/etc/nginx/sites-available/YOUR_SITE) ภายใน “server” บล็อก:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-หากคุณไม่มีไฟล์นี้ คุณต้องสร้างไฟล์ สำหรับการเปิด terminal นี้และเรียกใช้คำสั่ง:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-และเพิ่มรหัสที่ระบุข้างต้น สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการกำหนดค่า Virtual Host ใหม่บน Nginx, โปรดอ่านที่นี้ [ guideline](nginx-virtual-host.md).
-
-เรียกใช้คำสั่งนี้ใน terminal เพื่อตรวจสอบว่าทุกอย่างเรียบร้อยดีหรือไม่:
-
-```
-sudo nginx -t
-```
-
-ถ้าใช่ ให้เรียกใช้คำสั่งเพื่อรีสตาร์ทเซิร์ฟเวอร์ nginx:
-
-```
-sudo service nginx restart
-```
-
-### 2. เพิ่ม RewriteBase path
-
-เปิดไฟล์ /ESPOCRM_DIRECTORY/api/v1/.htaccess และแทนที่ด้วยบรรทัดต่อไปนี้:
-```
-# RewriteBase /
-```
-กับ
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-ที่ REQUEST_URI เป็นส่วนหนึ่งของ URL เช่น สำหรับ “http://example.com/espocrm/”, REQUEST_URI คือ “espocrm”.
diff --git a/i18n/th_TH/administration/nginx-virtual-host.md b/i18n/th_TH/administration/nginx-virtual-host.md
deleted file mode 100644
index 9a527587c..000000000
--- a/i18n/th_TH/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# การกำหนดค่า Virtual Host บน Nginx สำหรับ EspoCRM
-
-ในคู่มือนี้เราจะแสดงวิธีตั้งค่า virtual host บน Nginx สำหรับ EspoCRM บนเซิร์ฟเวอร์ Ubuntu
-
-## สร้างไฟล์บล็อกเซิร์ฟเวอร์
-
-ในการสร้างไฟล์นี้ ให้เปิด terminal และรันคำสั่ง:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-ตอนนี้ เปิดไฟล์นี้ (/etc/nginx/sites-available/espocrm.conf) และแก้ไขรหัสตามรูปแบบที่พิมพ์ด้านล่าง (การตั้งค่าบางอย่างอาจแตกต่างกันขึ้นอยู่กับการกำหนดค่าของคุณ):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## การเปิดใช้งานบล็อกเซิร์ฟเวอร์นี้
-
-สร้างสัญลักษณ์ลิงค์:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-เรียกใช้คำสั่งนี้ เพื่อที่จะตรวจสอบว่าทุกอย่างเรียบร้อยดีหรือไม่:
-
-```
-sudo nginx -t
-```
-
-และรีสตาร์ทเซิร์ฟเวอร์ Nginx:
-
-```
-sudo service nginx restart
-```
-
-## กำหนดค่าโฮสต์ ภายในเครื่องของคุณ (ไม่บังคับ, สำหรับโดเมนท้องถิ่นเท่านั้น)
-
-ถ้าคุณเพิ่มโดเมนท้องถิ่น, คุณต้องกำหนดค่าในคอมพิวเตอร์ของคุณด้วย (ไม่ไช่บนเซิร์ฟเวอร์). สำหรับ Ubuntu, ให้เปิดไฟล์ `/etc/hosts` และเพิ่มบรรทัดนี้ลงไป:
-
-```
-192.168.1.1 espocrm.local # specify the IP address of your Nginx server
-```
-
-สำหรับ Windows, โปรดทำตามขั้นตอนเหล่านี้ [instructions](http://support.microsoft.com/kb/923947).
diff --git a/i18n/th_TH/administration/portal.md b/i18n/th_TH/administration/portal.md
deleted file mode 100644
index ec450bc17..000000000
--- a/i18n/th_TH/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Portal
-
-Portal ให้ความสามารถในการเข้าถึงข้อมูลเฉพาะเจาะจงและฟังก์ชัน crm สำหรับลูกค้าและคู่ค้าของคุณ ผู้ดูแลระบบสามารถสร้าง portal ได้หลายแบบ แต่ละ portal สามารถตั้งค่าได้เอง, dashlboard, รายชื่อผู้ใช้, การตั้งค่าควบคุมการเข้าใช้งาน
-
-เพื่อสร้าง portal ผู้ดูแลระบบ > Portals, คลิกที่ปุ่มสร้าง Portal
-
-* `Is Active`. ถ้าไม่ตรวจสอบ Portal จะไม่สามารถใช้ได้สำหรับทุกคน
-* `Is Default`.หมายความว่า portal จะพร้อมใช้งานโดยที่ URL สั้นกว่า: http (s): // YOUR_ESPO_URL / portal.
-* `Roles`. ระบุบทบาทหนึ่ง หรือ portal หลายบทบาท ที่จะใช้กับผู้ใช้ที่ล็อกอินเข้าสู่ portal ข้อมูลเพิ่มเติมเกี่ยวกับบทบาทของ portal อยู่ด้านล่าง
-* `Tab List`. แท็บที่จะปรากฏในแถบ navigation
-* `Dashboard Layout`. ระบุ dashlets ที่จะแสดงในโฮมเพจของ portal. โปรดทราบว่าผู้ใช้ portal ไม่สามารถกำหนดค่า dashboard ได้
-* `URL`. อ่านแค่ field อย่างเดียว ที่จะแสดงลิงก์ที่คุณสามารถเข้าถึงด้วย portal
-
-## ผู้ใช้ Portal
-
-ผู้ดูแลระบบสามารถสร้างผู้ใช้ portal ได้
-
-1. ผู้ดูแลระบบ > ผู้ใช้.
-2. คลิกเมนูแบบเลื่อนลงด้านขวาถัดจากสร้างผู้ใช้.
-3. คลิกสร้างผู้ใช้ Portal
-4. เลือกติดต่อผู้ใช้ portal จะเชื่อมโยงด้วย
-5. กรอกแบบฟอร์มและคลิกบันทึก
-
- ผู้ใช้ Portal ควรเชื่อมโยงกับบันทึก Portal เพื่อให้สามารถเข้าถึง Portal ดังกล่าวได้
-
-## บทบาท Portal
-
-บทบาทของ Portal คล้ายคลึงกับบทบาทปกติใน EspoCRM แต่มีความแตกต่างเล็กน้อย
-
-* `not-set` ระดับปฏิเสธการเข้าถึง
-* `own` ระดับหมายความว่าบันทึกถูกสร้างขึ้นโดยผู้ใช้ เช่น ผู้ใช้ portal ได้ระบุบางกรณีและกรณีนี้เป็นของผู้ใช้รายนี้
-* `account` ระดับหมายความว่าบันทึกเกี่ยวข้องกับบัญชีและผู้ใช้ portal รายนี้ เกี่ยวข้องกับบัญชีเหมือนกัน
-* `contact` ระดับหมายความว่าบันทึกเกี่ยวข้องกับรายชื่อผู้ติดต่อ portal ที่เกี่ยวข้อง
-
- fields ผู้ใช้และทีม ที่ได้รับมอบหมายจะอ่านเฉพาะสำหรับผู้ใช้ portal เท่านั้น
-
-### ตัวอย่าง
-
-`Portal users should be able to create cases, view cases related to their account; they should be able to view knowledge base.`
-
-1. เปิดแบบฟอร์มบทบาท Portal (ผู้ดูแล > บทบาท Portal > สร้างบทบาท).
-2.เปิดใช้งานการเข้าถึง Cases, การตั้งค่า: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. เปิดใช้งานการเข้าถึงฐานความรู้,การตั้งค่า `create - no, read - account, edit - no, delete - no`.
-4. แก้ไขบันทึก Portal ของคุณ (ผู้ดูแล > Portals)เลือกบทบาท Portal ของคุณ ในช่องบทบาทแล้วเลือกบันทึก
-
-## การเข้าถึง Portal
-
-คุณสามารถค้นหา url สำหรับ portal ของคุณได้ในฟิลด์ 'URL' บันทึกของ portal นอกจากนี้คุณยังสามารถใช้เครื่องมือในกำหนดค่าเซิร์ฟเวอร์ (เช่น mod_rewrite) เพื่อให้สามารถเข้าถึงได้โดยใช้ URL อื่นๆ ในกรณีนี้คุณต้องกรอกข้อมูลในฟิลด์ 'URL ที่กำหนดเอง'
-
-### การเข้าถึง portal โดย URL ที่กำหนดเอง สำหรับ Apache server
-
-Custom URL: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Mod rewrite rules
-
-ระบุรหัส portal record แทนที่ `{PORTAL_ID}` รหัส Portal record สามารถใช้ได้ในแถบที่อยู่เว็บของคุณเมื่อคุณเปิดมุมมองรายละเอียดของ portal record เช่น: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 คือรหัส portal record
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/th_TH/administration/roles-management.md b/i18n/th_TH/administration/roles-management.md
deleted file mode 100644
index 5611914a4..000000000
--- a/i18n/th_TH/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# การจัดการบทบาท
-
-## Overview
-
-เพื่อ จำกัด การเข้าถึงสำหรับผู้ใช้บางรายคุณต้องใช้บทบาท ผู้ดูแลระบบสามารถจัดการบทบาทในแผงการจัดการ แต่ละบทบาทกำหนดการเข้าใช้งานเฉพาะบางพื้นที่ (ขอบเขต) ซึ่งใช้กับผู้ใช้ที่เป็นเจ้าของบทบาทนั้นๆ
-
-ผู้ใช้รายหนึ่งสามารถมีได้หลายบทบาท สามารถเลือกบทบาทเหล่านี้สำหรับผู้ใช้ที่เฉพาะเจาะจงได้ (‘บทบาท’ ในรายการผู้ใช้) และ/หรือ สืบทอดจากทีมที่ผู้ใช้เป็นสมาชิก
-
-ถ้าผู้ใช้มีหลายบทบาท พวกเขาจะถูกรวมเข้าด้วยกันเพื่อให้กฎที่อนุญาตมีลำดับความสำคัญที่สูงกว่า ซึ่งช่วยให้ผู้ดูแลระบบสามารถจัดการการควบคุมระดับการเข้าถึงได้อย่างง่ายดายและคล่องตัว
-
-คุณสามารถดูว่ามีการใช้สิทธิ์กับผู้ใช้บางรายได้โดยคลิกที่ปุ่ม "เข้าถึง" ในมุมมองรายละเอียดของผู้ใช้
-
-
-
-## ตัวอย่าง
-
-ตัวอย่างเช่น, ถ้าผู้ใช้อยู่ในทีม "ขาย" ทีมงานคนนี้จะมีบทบาทเพียงอย่างเดียวคือเป็น "พนักงานขาย" ดังนั้นผู้ใช้ทั้งหมดจากทีมนี้จะได้รับบทบาทเป็น "พนักงานขาย"
-
-บทบาทของ "พนักงานขาย" มีดังต่อไปนี้:
-
-Lead:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-ผู้ใช้จะสามารถอ่านได้เฉพาะ leads และ opportunities เท่านั้น ซึ่งเป็นของทีม "ฝ่ายขาย" (‘ทีม’ ข้อมูล).
-ผู้ใช้จะสามารถแก้ไขได้เฉพาะ leads และ opportunities เท่านั้น ซึ่งพวกเขาจะได้รับมอบหมายหรือเป็นผู้ที่สร้างขึ้นมา
-ผู้ใช้จะไม่สามารถย้าย leads หรือ opportunities ได้
-
-เราต้องการให้สิทธิแก่ผู้ใช้บางรายที่มีตำแหน่งเป็นผู้จัดการฝ่ายขายใน บริษัท. ซึ่งพนักงานคนนี้ต้องมีความสามารถในการ อ่าน/แก้ไข/ลบ บันทึกทั้งหมด จากทีม ‘การขาย’ ผู้ใช้ควรเป็นส่วนหนึ่งของทีม "การขาย" ของเราแต่เราจำเป็นต้องสร้างบทบาทใหม่สำหรับ 'ผู้จัดการฝ่ายขาย' และเลือกบทบาทนี้สำหรับผู้ใช้รายนั้นในฟิลด์ "บทบาท"
-
-บทบาทของ ‘ผู้จัดการฝ่ายขาย’ มีการกำหนดวิธีการดังต่อไปนี้:
-Lead:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Opportunity:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-ผู้ใช้ของเราจะสามารถจัดการ leads และ opportunities ทั้งหมดได้จากทีม "การขาย"
-
-
-## สิทธิ์พิเศษ
-
-### การมอบหมายงาน
-
-ตั้งค่า parameter นี้เพื่อจำกัดความสามารถในการกำหนดบันทึกใหม่ให้กับผู้ใช้ และ/หรือ ทีมอื่น ถ้าคุณตั้งค่า `team` - จากนั้นจะสามารถกำหนดให้กับผู้ใช้จากทีมของตนเองเท่านั้น. ถ้า `no` - ผู้ใช้จะไม่สามารถมอบหมายงานใหม่ได้ทั้งหมด
-
-นอกจากนี้ยังกำหนดว่าผู้ใช้สามารถโพสต์ไปยังสตรีมของผู้ใช้ / ทีมอื่นได้
-
-### สิทธิ์ผู้ใช้
-
-ช่วยให้ผู้ใช้สามารถ จำกัด มุมมองของกิจกรรม, ปฏิทินและสตรีมของผู้ใช้รายอื่นได้
-
-### สิทธิ์ของ Portal
-
-กำหนดการเข้าถึงข้อมูล portal , ความสามารถในการโพสต์ข้อความไปยังผู้ใช้ portal
-
-### การอนุญาตบัญชีอีเมลกลุ่ม
-
-กำหนดการเข้าถึงกลุ่มบัญชีอีเมล, ความสามารถในการส่งอีเมลจากกลุ่ม SMTP
-
-### การอนุญาตการส่งออก
-
-การป้องกันไม่ให้ผู้ใช้มีความสามารถในการส่งออกบันทึก (ตั้งแต่เวอร์ชัน 4.9.0)
-
-## สิทธิ์ตามค่าเริ่มต้น
-
-โดยค่าเริ่มต้น (ถ้าไม่มีผู้ใดนำมาใช้) ผู้ใช้สามารถอ่านและแก้ไขบันทึกทั้งหมดได้ แต่ไม่สามารถลบข้อมูลใด ๆ ยกเว้นไฟล์ที่สร้างขึ้นและได้รับการกำหนดให้ในเวลาเดียวกัน
-
-ความสามารถในการ จำกัด การเข้าถึงโดยค่าเริ่มต้น โดยการเปิดใช้งาน 'ACL Strict Mode' ที่การดูแลระบบ> การตั้งค่า
-
-## Field Level Security
-
-ช่วยให้สามารถควบคุมการเข้าถึงฟิลด์เฉพาะเจาะจงได้
-
-โดยค่าเริ่มต้นผู้ใช้สามารถอ่านฟิลด์ทั้งหมดถ้าสามารถอ่านบันทึกได้ ผู้ใช้สามารถแก้ไขฟิลด์ใดก็ได้ ถ้าสามารถแก้ไขบันทึกได้ คุณสามารถ จำกัด การเข้าถึงเฉพาะฟิลด์โดยใช้ Field Level Security
-
-ในการแก้ไขข้อมูลบที่ันทึกของบทบาท ในระดับเขตข้อมูลให้คลิกไอคอนบวก ถัดจากขอบเขตที่ระบุจากนั้นเลือกฟิลด์ที่ต้องการ จากนั้นคุณจะสามารถระบุระดับการเข้าถึงคำสั่ง `read` และ `edit` ได้ มีตัวเลือกให้เลือกคือ: `yes` และ `no`.
-
-
diff --git a/i18n/th_TH/administration/server-configuration.md b/i18n/th_TH/administration/server-configuration.md
deleted file mode 100644
index 09c03f9e1..000000000
--- a/i18n/th_TH/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# การกำหนดค่าเซิร์ฟเวอร์สำหรับ EspoCRM
-
-EspoCRM สามารถติดตั้งได้ที่ Apache ([instructions](apache-server-configuration.md)), Nginx ([instructions](nginx-server-configuration.md)), หรือเซิร์ฟเวอร์ IIS ที่สนับสนุน PHP เวอร์ชัน 5.6 หรือสูงกว่าและ MySQL เวอร์ชัน 5.1 หรือสูงกว่า
-
-## คำแนะนำการกำหนดค่า
-
-### PHP Requirements
-
-EspoCRM ต้องใช้ PHP 5.6 หรือสูงกว่าโดยเปิดใช้งานส่วนขยายดังต่อไปนี้:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – การเข้าถึง MySQL ใน PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – แหล่งข้อมูลใช้รูปแบบนี้ (metadata, รูปแบบ, ภาษา, และอื่นๆ);
-* [GD](http://php.net/manual/en/book.image.php) – เพื่อจัดการรูปภาพ;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – เพื่อให้แน่ใจว่าการป้องกันสูงสุด;
-* [Zip](http://php.net/manual/en/book.zip.php) – เพื่อให้สามารถอัพเกรด EspoCRM และติดตั้งส่วนขยายได้;
-* [IMAP](http://php.net/manual/en/book.imap.php) – การตรวจสอบกล่องจดหมายใน EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-นอกจากนี้ยังแนะนำให้มี [mailparse](https://pecl.php.net/package/mailparse)การติดตั้งส่วนขยาย pecl จำเป็นสำหรับการทำงานของคุณลักษณะการเรียกดูอีเมลได้อย่างราบรื่น
-
-php.ini settings:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### MySQL Requirements
-
-EspoCRM สนับสนุน MySQL เวอร์ชั่น 5.1 หรือสูงกว่า
-สิ่งเหล่านี้ไม่มีลักษณะพิเศษ การตั้งค่าเริ่มต้นทั้งหมดเหมาะสำหรับ EspoCRM
-
-## สิทธิ์ที่จำเป็นสำหรับ Unix-based Systems
-
-ไฟล์และ directories ควรมีสิทธิ์ดังต่อไปนี้
-
-* `/data`, `/custom`, `/client/custom` – ควรเป็นไฟล์ที่สามารถเขียนได้ทั้งหมด, directories และ subdirectories (664 สำหรับไฟล์, 775 สำหรับ directories, รวมทั้ง subdirectories และไฟล์ทั้งหมด);
-* `/application/Espo/Modules`, `/client/modules` – ควรจะเขียน directory ปัจจุบัน (775 สำหรับ directory ปัจจุบัน, 644 สำหรับไฟล์, 755 สำหรับ directories และ subdirectories);
-* ไฟล์และ directories อื่น ๆ ทั้งหมดควรอ่านได้ (644 สำหรับไฟล์, 755 สำหรับ directories).
-
-ในการตั้งค่าสิทธิ์ ให้เรียกใช้คำสั่งเหล่านี้ใน terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-ไฟล์ทั้งหมดควรเป็นเจ้าของและเป็นเจ้าของกลุ่มโดยผ่านกระบวนการของเว็บเซิร์ฟเวอร์ ควรจะเป็น “www-data”, “daemon”, “apache”, “www”, อื่นๆ.
-หมายเหตุ: เมื่อใช้ Bitnami Stack, ไฟล์ควรเป็นเจ้าของและเป็นเจ้าของกลุ่มโดยผู้ใช้ "daemon"
-หมายเหตุ: ในโฮสต์ที่ใช้ร่วมกัน ไฟล์ควรเป็นของเจ้าของและเป็นของกลุ่ม โดยบัญชีผู้ใช้ของคุณ
-
-ในการตั้งค่าเจ้าของและเจ้าของกลุ่มทให้ดำเนินการคำสั่งเหล่านี้ใน terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## การตั้งค่า crontab
-
-การติดตั้ง crontab บน UNIX system, สามารถทำตามขั้นตอนดังต่อไปนี้:
-
-* 1. เข้าสู่ระบบในฐานะผู้ดูแลระบบใน EspoCRM instance ของคุณ
-* 2. ไปที่ส่วนกำหนดงานในส่วนการจัดการระบบของคุณ (เมนู> การจักการ> งานที่กำหนดเวลาไว้ และคัดลอกสตริงสำหรับ crontab มีลักษณะดังนี้:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. เปิด terminal และเรียกใช้คำสั่งนี้:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER can be one of the following “www”, “www-data”, “apache”, etc (depends on your webserver).
-* 4. วางสตริงที่คัดลอกไว้ (จากขั้นตอนที่ 2) และบันทึกไฟล์ crontab (Ctrl+O, then Ctrl+X สำหรับ nano editor).
-
-## คำแนะนำในการกำหนดค่าตามเซิร์ฟเวอร์ของคุณ:
-
-* [Apache server configuration](apache-server-configuration.md).
-* [Nginx server configuration](nginx-server-configuration.md).
diff --git a/i18n/th_TH/administration/troubleshooting.md b/i18n/th_TH/administration/troubleshooting.md
deleted file mode 100644
index 6f379077d..000000000
--- a/i18n/th_TH/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# การแก้ไขปัญหา
-
-## ตรวจสอบบันทึก
-
-เพื่อที่จะแก้ไขปัญหา, คุณต้องตรวจสอบแฟ้มบันทึกข้อผิดพลาด
-
-#### บันทึกข้อผิดพลาด EspoCRM
-
-บันทึก EspoCRM อยู่ที่ `/logs/*.log` และมีข้อมูลข้อผิดพลาดบางอย่าง
-
-#### บันทึกข้อผิดพลาดของ Apache
-
-สำหรับเซิร์ฟเวอร์ Ubuntu มีบันทึกข้อผิดพลาดของ apache อยู่ที่ `/var/log/apache2/error.log` และมีข้อมูลข้อผิดพลาดทั้งหมด ตำแหน่งของแฟ้มบันทึกอาจแตกต่างกันในระบบอื่น ๆ
-
-## Enable debugging mode
-
-เพื่อเปิดใช้งานโหมดดีบัก, ไปที่ติดตั้ง EspoCRM directory, เปิดแฟ้มข้อมูล `data/config.php` และเปลี่ยนค่า:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-to
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## งานที่กำหนดเวลาไว้ไม่ทำงาน
-
-#### ปัญหาที่ 1: crontab ของคุณไม่ได้รับการกำหนดค่า
-
-1. เข้าสู่ระบบผ่าน SSH ไปยังเซิร์ฟเวอร์ของคุณ
-
-2.ตั้งค่าคอนฟิก crontab โดยทำตามขั้นตอนดังต่อไปนี้: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-หมายเหตุ: ควรกำหนดค่า Crontab ภายใต้ผู้ใช้เว็บเซิร์ฟเวอร์ เช่น `crontab -e -u www-data`.
-
-3. รอสักครู่และตรวจสอบงานที่จัดกำหนดการไว้ เพื่อดูว่ามีงานหรือไม่ (see a Log panel)
-
-#### ปัญหาที่ # 2 มีการกำหนดค่า Crontab แต่ Scheduled Jobs ไม่ทำงาน
-
-เพื่อให้แน่ใจว่าไม่มีข้อผิดพลาดเมื่อรัน cron ให้ลองเรียกใช้คำสั่ง cron ใน terminal:
-
-1. เข้าสู่ระบบผ่าน SSH ไปยังเซิร์ฟเวอร์ของคุณ
-
-2. ไปที่ directory ที่มีการติดตั้ง EspoCRM เช่น สำหรับ directory `/var/www/html/espocrm` คำสั่งคือ :
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. เรียกใช้คำสั่ง crontab:
-
-```bash
-php cron.php
-```
-
-หมายเหตุ: ควรดำเนินการภายใต้ผู้ใช้เว็บเซิร์ฟเวอร์ ถ้าคุณล็อกอินด้วย root คำสั่งควรเป็น (เช่น สำหรับ Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-ที่ไหนที่ `www-data` เป็นผู้ใช้เว็บเซิร์ฟเวอร์
-
-4. หากไม่มีข้อผิดพลาดให้ตรวจสอบงานที่จัดกำหนดการไว้เพื่อดูว่ามีงานใดหรือไม่(see a Log panel).
-
-## EspoCRM ไม่โหลดหลังจากทำการอัปเดตแล้ว
-
-สิ่งนี้อาจเกิดขึ้นได้ใน hostings ที่ใช้ร่วมกันบางครั้ง
-
-ตรวจสอบสิทธิ์ของไฟล์:
-/index.php
-/api/v1/index.php
-
-ควรจะเป็น 644 ถ้าไฟล์ใดมีสิทธิ์เป็น 664 คุณต้องเปลี่ยนเป็น 644 ใช้แผงควบคุมของโฮสติ้งหรือคำสั่ง chmod
-
-```
-chmod 644 /path/to/file
-```
-ข้อมูลเพิ่มเติมเกี่ยวกับสิทธิ์ของไฟล์: [here](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/th_TH/administration/upgrading.md b/i18n/th_TH/administration/upgrading.md
deleted file mode 100644
index f69c7f3ae..000000000
--- a/i18n/th_TH/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# วิธีการอัปเกรด EspoCRM
-
-EspoCRM สามารถอัปเกรดเป็นเวอร์ชันล่าสุดได้ตามขั้นตอนดังต่อไปนี้:
-
-### ขั้นตอนที่ 1. ตรวจสอบเวอร์ชันปัจจุบันของคุณ
-
-หากต้องการตรวจสอบเวอร์ชันปัจจุบันของคุณให้ไปที่หน้าการดูแลระบบ> หน้าการอัปเกรด
-
-### ขั้นตอนที่ 2. ดาวน์โหลดแพ็กเกจการอัปเกรดที่ต้องการ
-
-ไปที่หน้าการอัปเกรด https://www.espocrm.com/download/upgrades/ และฐานข้อมูลแพคเกจเวอร์ชั่นปัจจุบันที่คุณต้องการ
-
-### ขั้นตอนที่ 3. สร้างข้อมูลสำรอง(ไม่จำเป็น)
-
-สร้างข้อมูลสำรองแฟ้ม EspoCRM ของคุณ และข้อมูลก่อนที่คุณจะอัปเกรด ดังนี้[these instructions](https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md) เพื่อทำมันให้เสร็จ
-
-### ขั้นตอนที่ 4. การอัปเกรด
-
-ไปที่การดูแลระบบ> อัปเกรด อัปโหลดและติดตั้งแพ็กเกจการอัปเกรดทีละชุด
-
-คุณสามารถตรวจสอบได้ว่าคุณมีเวอร์ชันล่าสุด ตรงนี้ เมนู> เกี่ยวกับ
-
-## อัปเกรดผ่านCLI
-
-นอกจากนี้คุณยังสามารถเรียกใช้การอัปเกรดผ่านทางคำสั่ง ซึ่งคุณต้องดำเนินการคำสั่งต่อไปนี้จาก EsproCRM จุดกำเนิด directory::
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/th_TH/administration/workflows.md b/i18n/th_TH/administration/workflows.md
deleted file mode 100644
index 028b976f7..000000000
--- a/i18n/th_TH/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Workflows
-
-Workflows คุณลักษณะที่มีอยู่ใน [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Workflows ทำให้ขั้นตอนทางธุรกิจของคุณง่ายขึ้น คุณสามารถค้นหาได้ในแผงการดูแลระบบ ในการสร้างกฎ workflow คุณสามารถทำได้ดังนี้:
-
-* Target Entity - ประเภทของ entity ที่ workflow ได้นำไปใช้;
-* Trigger Type - เมื่อ workflow จะถูก triggered;
-* Conditions - เงื่อนไขที่ต้องทำเพื่อเรียกใช้ workflow;
-* Actions - ต้องทำอะไร ถ้าหาก workflow คือ triggered.
-
-
-## ประเภทของ Trigger
-
-### หลังจากสร้างบันทึก
-
-เรียกใช้เฉพาะเมื่อสร้างบันทึกใหม่เท่านั้น หากมีการระบุเงื่อนไขไว้การดำเนินการจะถูกดำเนินการ
-
-### หลังจากบันทึกถูกบันทึก
-
-เรียกใช้เมื่อมีการสร้างหรือมีการปรับปรุงบันทึกที่มีอยู่ หากมีการระบุเงื่อนไขไว้การดำเนินการจะถูกดำเนินการ
-
-สำหรับกฎของ workflow กับประเภทของ trigger นี้ เป็นเรื่องปกติที่จะมีเงื่อนไขที่จะตรวจสอบว่ามีบางฟิลด์หรือไม่ 'changed' เช่น หากสถานะ Case เปลี่ยนไปแล้วให้ดำเนินการบางอย่าง
-
-### Scheduled
-
-Triggered การกำหนดเวลาตามที่กำหนด คุณสามารถตั้งค่าการเรียกใช้งานทุกวัน,ทุกสัปดาห์ , ฯลฯ. การดำเนินการจะใช้กับบันทึกที่ส่งกลับมา โดยรายงานตามที่ระบุ ดังนั้นคุณต้องสร้างรายงานรายการด้วย
-
-Scheduling ถูกระบุไว้ในสัญกรณ์ของ crontab
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### Sequential
-
-จะไม่ค่อยได้ใช้ ควรจะดำเนินการโดย workflow อื่น มีความสามารถในการสร้างตรรกะที่ซับซ้อน
-
-หมายเหตุ: สำหรับ sequential workflows ขอแนะนำให้ใช้ [BPM tool](bpm.md) ไม่ใช่คุณลักษณะของ Workflows
-
-## เงื่อนไข
-
-คุณสามารถระบุเงื่อนไขที่ต้องปฏิบัติตาม trigger workflow ได้ โดยมีสองช่องทางที่เงื่อนไขสามารถระบุได้ : ด้วยตัวสร้างเงื่อนไข UI และด้วย formula
-
-### ตัวสร้างเงื่อนไข UI
-
-เงื่อนไขบางประเภทที่ใช้ได้:
-
-* _equals_ - ฟิลด์ที่เท่ากับค่าเฉพาะหรือค่าของฟิลด์อื่น;
-* _was equal_ - ฟิลด์ที่เท่ากับค่าที่ระบุก่อน workflow จะเป็น triggered;
-* _not equals_ - ฟิลด์ที่ไม่เท่ากับค่าเฉพาะหรือค่าของฟิลด์อื่น
-* _was not equal_ - ฟิลด์ที่ไม่เท่ากับค่าที่ระบุก่อน workflow จะเป็น triggered;
-* _empty_ - ค่าของฟิลด์ว่างเปล่า;
-* _not empty_ - ค่าของฟิลด์ไม่ว่างเปล่า;
-* _changed_ - ฟิลด์มีการเปลี่ยนแปลง;
-* _not changed_ - ฟิลด์ไม่มีการเปลี่ยนแปลง
-
-### เงื่อนไขของ Formula
-
-Formula ให้ความสามารถในการกำหนดเงื่อนไขของความซับซ้อนใด ๆ อ่านเกี่ยวกับ formula ได้ที่นี้ [this article](formula.md).
-
-หมายเหตุ: ไม่ควรมีตัวคั่น `;` ในรหัส formula เมื่อมีการกำหนดเงื่อนไข
-
-## ข้อปฏิบัติ
-
-### ส่งอีเมล
-
-ระบบจะส่งอีเมลโดยใช้แม่แบบอีเมลที่ระบุ ที่อยู่อีเมลของผู้รับสามารถนำมาจากบันทึกเป้าหมาย้, บันทึกใด ๆ ที่เกี่ยวข้อง, ผู้ใช้ปัจจุบัน, ผู้ติดตาม, ทีมผู้ใช้หรือที่ระบุไว้ อีเมลสามารถส่งได้ทันทีหรือล่าช้าเป็นระยะเวลาหนึ่ง
-
-### สร้างบันทึก
-
-ระบบจะสร้างบันทึกใหม่ของ entity ประเภทใด ๆ ถ้ามีความสัมพันธ์ระหว่างบันทึกเป้าหมายกับการสร้างบันทึก มันเป็นไปได้ที่จะเกี่ยวข้องกับบันทึก
-
-มีความสามารถในการกำหนดสูตรเพื่อคำนวณฟิลด์
-
-### สร้างบันทึกที่เกี่ยวข้อง
-
-ระบบจะสร้างบันทึกที่เกี่ยวข้องกับบันทึกเป้าหมาย มันเป็นไปได้ที่จะกำหนดสูตรเพื่อคำนวณฟิลด์
-
-### อัปเดตบันทึกเป้าหมาย
-
-ช่วยให้สามารถเปลี่ยนฟิลด์เฉพาะของบันทึกเป้าหมายได้ เป็นไปได้ที่จะกำหนดสูตรเพื่อคำนวณฟิลด์
-
-หากต้องการเพิ่มรายการใหม่ลงในฟิลด์ Link-Multiple w/o การสูญเสียข้อมูลที่มีอยู่ (เช่น ทีม) คุณต้องใช้ entity สูตรของฟังก์ชัน \addLinkMultipleId. ตัวอย่าง: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### อัปเดตบันทึกที่เกี่ยวข้อง
-
-อนุญาตให้มีการเปลี่ยนแปลงเฉพาะเขตข้อมูลของบันทึก หรือบันทึกที่เกี่ยวข้อง เป็นไปได้ที่จะกำหนดสูตรเพื่อคำนวณฟิลด์
-
-### เชื่อมโยงกับบันทึกอื่นๆ
-
-เชื่อมโยง entity เป้าหมายกับ entity เฉพาะอื่นๆ เช่น. เพิ่มทีมเฉพาะลงในบันทึก
-
-### ยกเลิกการเชื่อมโยงกับบันทึกอื่นๆ
-
-ไม่เชื่อมโยงกับ entity เป้าหมายจาก entity เฉพาะรายอื่นๆ เช่น. นำทีมเฉพาะออกจากบันทึก
-
-### ใช้กฎการกำหนด
-
-กำหนดบันทึกเป้าหมายให้กับผู้ใช้ตามกฎการแจกจ่าย มีกฎอยู่สองข้อคือ Round-Robin และ Least-Busy
-
-* Round-Robin - ผู้ใช้จะถูกเลือกจากด้านบนลงด้านล่างของรายการ (ทีม) และจากนั้นจะเริ่มต้นอีกครั้ง
-* Least-Busy - ผู้ใช้ที่มีบันทึกที่ได้รับมอบหมายน้อยกว่าจะได้รับเลือกสำหรับการมอบหมาย
-
-_List Report_ - สำหรับการแจกจ่าย Least-Busy จะพิจารณาว่าบันทึกใดจะนำมาพิจารณาในการคำนวณจำนวนบันทึกที่ได้รับมอบหมาย เช่น สำหรับกรณีที่เราต้องใช้เฉพาะบันทึกที่มีสถานะใช้งานอยู่
-
-### สร้างการแจ้งเตือน
-
-แจ้งผู้ใช้เฉพาะที่มีข้อความ สามารถใช้ตัวยึดตำแหน่งในเทมเพลตข้อความได้: {entity} - บันทึกเป้าหมาย, {user} - ผู้ใช้ปัจจุบัน
-
-### Make Followed
-
-บังคับใช้ผู้ใช้เฉพาะติดตาม entity เป้าหมายหรือระบุ entity ที่เกี่ยวข้อง
-
-### เรียกใช้กระบวนการทำงานอื่น
-
-ช่วยให้สามารถทำ workflow ตามลำดับได้ เป็นไปได้ที่จะแบ่งสาขางานตามเงื่อนไข: คุณสามารถตั้งค่า workflow เพื่อเรียกใช้งาน workflow สองประเภทที่มีเงื่อนไขต่างกันที่กำหนดไว้ใน workflow นั้น ๆ
-
-อาจทำให้เกิดความล่าช้าในการดำเนินการ workflow ตามลำดับ ใน wokflow คุณสามารถกำหนดเงื่อนไขที่จะตรวจสอบว่าเขตข้อมูลเฉพาะมีการเปลี่ยนแปลงหรือไม่ เนื่องจาก wokflow หลักถูกเรียกใช้โดยใช้เงื่อนไข _changed และ _Was Equal_
-
-หมายเหตุ: สำหรับ wokflow ตามลำดับขอแนะนำให้ใช้ [BPM tool] (bpm.md) แทนที่จะเป็นคุณลักษณะ wokflow
-
-### เรียกใช้บริการการดำเนินงาน
-
-อนุญาตให้เรียกใช้สคริปต์บริการเฉพาะ โดยค่าเริ่มต้นมีการดำเนินการดังต่อไปนี้ให้บริการ:
-
-* Send Invitations - สำหรับการประชุม / การโทร;
-* Add Quote Items - สำหรับการให้คำปรึกษา
-
-นักพัฒนาซอฟต์แวร์สามารถเขียนการดำเนินการบริการของตนเองได้ ดูจาก [more detail](../development/workflow-service-actions.md).
-
-## การใช้สูตรในการดำเนินการ
-
-เป็นไปได้ที่จะกำหนดสูตรคำนวณฟิลด์สำหรับสร้างบันทึก, อัปเดตบันทึกเป้าหมาย, สร้างบันทึกที่เกี่ยวข้อง, อัปเดตบันทึกที่เกี่ยวข้อง สำหรับสองสิ่งสุดท้าย, เพื่อเข้าถึง attributes ของ entity เป้าหมายคุณควรใช้ฟังก์ชัน `targetEntity\attribute` เพื่อเข้าถึง attributes ของ entity เป้าหมายที่ตั้งค่าไว้ก่อนที่ workflow จะมีการเรียกใช้ฟังก์ชัน `targetEntity\attributeFetched`.
-
-ตัวอย่าง:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/tl_PH/README.md b/i18n/tl_PH/README.md
deleted file mode 100644
index 212ae066d..000000000
--- a/i18n/tl_PH/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# EspoCRM Documentation
-
-### Administrasyon
-* [Konpigurasyon sa serber](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/server-configuration.md)
- * [Apache](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/apache-server-configuration.md)
- * [Nginx](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/nginx-server-configuration.md)
-* [Pag-iinstall](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/installation.md)
-* [Paggawa ng pagbabago](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/upgrading.md)
-* [Pangangasiwa ng mga gagampanan (kontrol sa akses)](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/roles-management.md)
-* [Mga koreo](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/emails.md)
-* Pag-customize
- * [Tagapangasiwa ng Entidad: mga entidad, Mga larangan, mga relasyon](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/entity-manager.md)
- * [Tagapangasiwa ng Layout](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/layout-manager.md)
- * [Mga Ekstensyon](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/extensions.md)
-* Pag-aawtomatik
- * [Tagapangasiwa ng proseso sa larangan ng Business (BPM)](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/bpm.md)
- * [Daloy ng mga trabaho](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/workflows.md)
- * [Kinalkulang mga larawan (Formula)](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/formula.md)
-* [Pag-angkat ng mga datos](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/import.md)
-* [Portal](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/portal.md)
-* [Pag-aawtorisa ng LDAP](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/ldap-authorization.md)
- * [Aktibong direktorya](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/ldap-authorization-for-ad.md)
- * [OpenLDAP](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/ldap-authorization-for-openldap.md)
-* [Paghahanap ng mali](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/troubleshooting.md)
-* Misc
- * [Mga mapa](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/maps.md)
- * [B2C mode](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/b2c.md)
- * [Backup at Pagpapanumbalik](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/backup-and-restore.md)
- * [Paglilipat sa ibang serber](https://github.com/espocrm/documentation/blob/master/i18n/tl_PH/administration/moving-to-another-server.md)
-
-
-### Patnubay para sa mga gumagamit
-* [Mga koreo](https://github.com/espocrm/documentation/blob/master/user-guide/emails.md)
-* [Stream](https://github.com/espocrm/documentation/blob/master/user-guide/stream.md)
-* [tagapangasiwa ng mga nabenta](https://github.com/espocrm/documentation/blob/master/user-guide/sales-management.md)
-* [tagapangasiwa ng kaso](https://github.com/espocrm/documentation/blob/master/user-guide/case-management.md)
-* [Mga aktibidad at mga koreo](https://github.com/espocrm/documentation/blob/master/user-guide/activities-and-calendar.md)
-* [maramihang koreo](https://github.com/espocrm/documentation/blob/master/user-guide/mass-email.md)
-* [Mga ulat](https://github.com/espocrm/documentation/blob/master/user-guide/reports.md)
-* [Mga Quote](https://github.com/espocrm/documentation/blob/master/user-guide/quotes.md)
-* Misc
- * [Pag-print sa PDF](https://github.com/espocrm/documentation/blob/master/user-guide/printing-to-pdf.md)
- * [Sintaks ng markdown](https://github.com/espocrm/documentation/blob/master/user-guide/markdown.md)
- * [Suporta sa browser](https://github.com/espocrm/documentation/blob/master/user-guide/browser-support.md)
-
-### Pag-unlad
-* [API](https://github.com/espocrm/documentation/blob/master/development/api.md)
-* [ORM: paano pangasiwaan ang mga entidad](https://github.com/espocrm/documentation/blob/master/development/orm.md)
-* [Metadata](https://github.com/espocrm/documentation/blob/master/development/metadata.md)
-* [Pasadya na mga pananaw](https://github.com/espocrm/documentation/blob/master/development/custom-views.md)
-* [pag-link ng maramihang patlang na may pangunahing rekord](https://github.com/espocrm/documentation/blob/master/development/link-multiple-with-primary.md)
-* [Mga pakete na ekstensyon](https://github.com/espocrm/documentation/blob/master/development/extension-packages.md)
-* [Hooks](https://github.com/espocrm/documentation/blob/master/development/hooks.md)
-* [Pasadyang paggawa ng mga nakaschedule na trabaho](https://github.com/espocrm/documentation/blob/master/development/scheduled-job.md)
-* [Pagtukoy ng mga bagong punksiyon para sa mga Formula](https://github.com/espocrm/documentation/blob/master/development/new-function-in-formula.md)
-* [Pasadyang Tipo ng larangan](https://github.com/espocrm/documentation/blob/master/development/custom-field-type.md)
-
-
-[Dokumentasyon sa website](https://www.espocrm.com/documentation/)
diff --git a/i18n/tl_PH/administration/apache-server-configuration.md b/i18n/tl_PH/administration/apache-server-configuration.md
deleted file mode 100644
index bd7bdc476..000000000
--- a/i18n/tl_PH/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Configuration ng Apache server para sa EspoCRM
-
-Ang mga tagubilin na ito ay pandagdag sa [Server Configuration](server-configuration.md) na guideline. Mangyaring tandaan na lahat ng configuration settings na nakalista dito ay ginawa sa Ubuntu server.
-
-## Mga Requirement sa PHP
-
-Para i-install ang mga kinakailangang mga library, patakbuhin ang mga command na ito sa isang terminal:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## Pag-ayos sa isyu na "API Error: EspoCRM API is unavailable":
-
-Gawin lamang ang mga kinakailangang hakbang. Pagkatapos ng bawat hakbang, tingnan kung resolba naba ang isyu.
-
-### 1. Paganahin ang "mod_rewrite" support sa Apache
-
-Para paganahin ang "mod-rewrite," patakbuhin ang mga command na ito sa isang terminal:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. Paganahin ang .htaccess support
-
-Para paganahain ang .htaccess support, i-add o i-edit ang Server Configuration Settings /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf or /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Pagkatapos nito, patakbuhin and command na ito sa isang terminal:
-
-```
-sudo service apache2 restart
-```
-
-### 3. Pagdagdag ng RewriteBase path
-
-Buksan ang file na /ESPOCRM_DIRECTORY/api/v1/.htaccess at palitan ang sumusunod na linya:
-
-```
-# RewriteBase /
-```
-
-ng
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-kung saan ang REQUEST_URI ay parte ng URL, e.g. para sa “http://example.com/espocrm/”, ang REQUEST_URI ay "espocrm".
-
-## Paganahin ang HTTP Authorization support (para lamang sa FastCGI)
-
-Ang FastCGI ay hindi sumusuporta ng HTTP AUTHORIZATION batay sa default. Kung gagamitin mo ng FastCGI, kailangan mo itong paganahin sa iyong Virtualhost or /etc/apache2/apache2.conf (httpd.conf) sa pamamagitan ng pagdagdag ng mga sumusunod na code:
-
-Para sa Fcgid module:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-Para sa FastCgi module:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Upang suriin kung aling module ang kasalukuyang ginagamit, patakbuhin ang command na ito at hanapin ang module:
-
-```
-apache2ctl -M
-```
\ No newline at end of file
diff --git a/i18n/tl_PH/administration/b2c.md b/i18n/tl_PH/administration/b2c.md
deleted file mode 100644
index 4e74ce44f..000000000
--- a/i18n/tl_PH/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#Ang pag-configure ng EspoCRM para sa B2C (Business-to-Client)
-
-Batay sa default, ang EspoCRM ay naka-configure na gamitin para sa B2B na negosyo. Ngunit maaari mo itong ma set up nang madali para sa B2C.
-
-* Baguhin ang `b2cMode` sa true sa iyong config file `data/config.php`. Dahil ang bersyon 4.3.0 ay maaaring ma-configure ito sa Administration > Settings.
-* Alisin ang *Account* tab mula sa navigation menu (Administration > User Interface)
-* Alisin ang mga *Account* field mula sa iyong mga layout (administration > Layout Manager).
-* I-disable ang access sa *Account* scope para sa lahat ng iyong mga tungkulin (Administration > Roles.)
-* Alisin ang Account mula sa mga picklist ng lahat ng parent fields (Administration > Entity Manager > {Meeting/Call/Task/Email} > Fields > Parent).
diff --git a/i18n/tl_PH/administration/backup-and-restore.md b/i18n/tl_PH/administration/backup-and-restore.md
deleted file mode 100644
index 8b7377734..000000000
--- a/i18n/tl_PH/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Ang Pag-back up at Pag-restore
-
-## Paano mag-backup ng EspoCRM nang mano-mano
-
-Ang EspoCRM ay binubuo ng mga file at data ng database. Kailangan ang lahat ng data na ito upang lumikha ng isang buong backup ng EspoCRM. Narito ang mga instruction kung paano ito gagawain sa Ubuntu server sa pamamagitan ng MySQL.
-
-### Unang Hakbang. Ang pag-backup ng files
-
-Gumawa ng isang archive ng mga nilalaman ng direktoryo kung saan naka-install ang EspoCRM. Para sa Ubunto, ang default path ay `/var/www/html`. Maaari mong gamitin ang command na ito:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### Pangalawang Hakbang. Ang pag-backup ng database
-
-Upang i-backup ang lahat ng iyong data, kailangan mong alamin ang pangalan ng database at access kredensyal. Maaari mong hanapin ang pangalan ng database sa configuration file `/ESPOCRM_DIRECTORY/data/config.php` sa ilalim ng seksyon na `database`. Maaari mong gamitin ang command na ito up[ang i-backup ang iyong database.
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### Pangatlong Hakbang. Kopyahin ang backup
-
-Iyon lang. Ngayon, kailangan mong kopyahin ang ginawa mong backup sa isang ligtas na lugar.
-
-## Paano i-backup ang EspoCRM gamit ang script
-
-Pwede kang gumamit ng script para mag-backup ng lahat ng kinakailangan mong data. Mag-login gamit ang SSH at patakbohin ang mga command (nasubukan ito sa Ubuntu na server).
-
-### I-download ang script
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Ipatakbo ang script
-
-```bash
-bash ./backup.sh PATH_PATUNGO_SA_ESPOCRM BACKUP_NA_PATH
-```
-kung saan
- * `PATH_TO_ESPOCRM` ay isang path para mainstall ang EspoCRM na directory.
- * `BACKUP_PATH` ay isang path patungo sa backup na directory.
-
-Para sa Ubuntu server ito ay:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Tandaan: Kung ang iyong MySQL na user ay wala right na mag-dump ng iyong database, ikaw ay sasabihan na mag enter ng mga kredensiyal ng iyong ibang user.
-
-Pagkatapos nga pagkagawa, ikaw ay bibigyan ng path patungo sa nagawang backup.
-
-## Pag-restore ng EspoCRM galing sa backup
-
-Pwede mong irestore ang EspoCRM galing sa backup na nagawa mo gamit ang mga instruction sa taas.
-
-### Unang Hakbang. I-unarchive ang mga backup file
-
-Para i-unarchive ang mga file, pwede mong gamitin ang Archive Manager o ipatakbo ang command sa baba. Ang mga file ay kinakailangan na ilagay sa web-server na directory.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-kung saan:
- * `/var/www/html` ay isang web-server na directory.
-
-### Pangalawang Hakbang. I-set ang mga kinakailangang mga permission
-
-Ang mga file ay kinakailangang pag-aari ng isang web-server na user at mayroon itong mga saktong mga permission. Paki-set ang mga kinakailangang mga permission gamit ang mga sumusunod na mga instruction: [www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### Pangatlong Hakbang. I-import ang database dump
-
-Ang database dump ay dapat naimport sa parehong database gamit ang parehong user credentials, dahil kong hindi ang koreksyon ay dapat ginawa sa loob ng configuration file `ESPOCRM_DIRECTORY/data/config.php`. Para maimport ang iyong database galing sa dump, ipatakbo ang command sa ibaba sa loob ng isang terminal:
-
-```bash
-mysql --user=IYONG_DATABASE_USER --password=IYONG_DATABASE_PASSWORD IYONG_DATABASE_NAME < db.sql
-```
-
-### Pang-apat na Hakbang. I-check/I-configure ang crontab
-
-I-check kung ang iyong crontab ay naconfigure ng maayos. Ipatakbo ang command sa ibaba at i-check kung ang path patungo sa EspoCRM ay tama:
-
-```bash
-sudo crontab -l -u www-data
-```
-kung saan:
- * `www-data` ay ang iyong web-server user.
-
-If you have to make any changes, use this command:
-Kung kailangan mong gumawa ng mga pagbabago, gamitin ang command na ito:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Para sa iba pang mga detalye tungkol sa pag-configure ng crontab para sa EspoCRM na inilarawan dito [www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
diff --git a/i18n/tl_PH/administration/bpm.md b/i18n/tl_PH/administration/bpm.md
deleted file mode 100644
index 6039b4812..000000000
--- a/i18n/tl_PH/administration/bpm.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# Business Process Management
-
-Ang Business Process Management (BPM) tool ay nagbibigay kakayahang mag-model at mag-automate ng isang business process sa EspoCRM. Ito ay isang engine na nagpapatupad ng business process na inilalarawan sa BPMN 2.0 standard. Ang BPM tool ay makukuha sa [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) na extension.
-
-
-
-### Pagkakaiba mula sa Workflows tool
-
-Ang workflows tool ay ginawa para sa automation ng mga simpleng business rules, nang walang mga sequential flow items, kung kailan hindi na kailangang ipakita ang flow graphically.
-
-Ang BPM tool ginawa para sa mga komplikadong business flows, kung saan mayroong mga diverging at converging na mga flow, execution delays at user interaction. Ginagawa ng flowchart view ang business process na mas madaling maunawaan ng isang tao, ang isang log ay pumapahintulot na makita kung paaano ginawa nag proseso.
-
-### Mga Proseso na Flowchart
-
-Ang link ng mga proseso na flowchart ay makukuha mula sa administration panel. Maaari rin itong idagdag bilang isang tab sa navigation panel.
-
-Ang mga flowchart ay nilalayon para sa pag-momodelo ng mga business process. Ang isang administrador ay maaaring lumikha at mag-edit ng mga flowchart. Ang mga regular na user ay maaari lamang tingnan ang flowcharts.
-
-Ang bawat flowchart ay mayroong tiyak na uri ng entity (Target Type na field). Tinutukoy ng flowchart ang pagpapatupad ng mga darating na mga process instance. Binubuo ito ng mga elemento ng flowchart at mga koneksyon sa pagitan ng mga elemento.
-
-Kung ang proseso flowchart ay mayroong 'Is Active'field na walang check, hindi ito magsisimula ng mga proseso instance.
-
-Upang ipakita ang mga detalye at parameter ng isang tiyak na elemento ng flowchart, kailangan mo itong i-click. Sa mode ng pag-edit, magagawa mong i-edit ang mga parameter.
-
-## Mga Process
-
-Ang mga proseso ay makikita mula sa administration panel. Ang link ay maaari ding idagdag bilang isang tab sa navigation panel.
-
-Ang proseso ang kumakatawan ng isang business process instance. Kapag ito ay sinimulan, ito ay makakakuha ng status na 'Started.' Kapag ang proseso ay natapos na, ito ay makakakuha ng status na 'Ended.' Ang proseso ay maaari ding itigil ng manu-mano sa pamamagitan ng isang user na may access upang i-edit ang process. Kapag ito ay itinigil ng manu-mano, ito ay makakuha ng status na 'Stopped.'
-
-Ang proseso ay isinasagawa ayon sa flowchart. Ang flowchart ng proseso ay hindi na mababago kapag nasimulan na ang process.
-
-Ang proseso obligatorily ay may kaugnayan sa single target record.
-
-Ang mga proseso ay maaring magsimula ng kusa (sa mga partikular na kondisyon o sa pag-iiskedyul) o manu-mano (kung saan mayroong kahit na isang Start Event sa flowchart). Upang masimulan ang proseso ng manu-mano, dapat i-click ng user ang 'Start Process' na button sa list view ng mga process.
-
-## Mga Flowchart Element
-
-### Mga Event
-
-Ang mga event ay naka-display sa isang flowchart bilang mga bilog.
-
-#### Start Event
-
-Walang mga parameter. Ito ay isang panimulang punto ng isang proseso. Ang Start Event ay maaaring simulan ng manu-mano ng isang user na may access upang lumikha ng isang proseo. Dapat i-click ng user ang 'Start Process' na button sa list view ng mga process.
-
-#### Kondisyonal na Start Event
-
-Panimulang punto ng proseso. Ito ay dapat na ma trigger ng kusa kapag ang mga tinutukoy na mga kondisyon ay natutugunan. Mayroong dalawang klase ng trigger: 'After rekord created,' 'After rekord saved.'
-
-#### Timer Start Event
-
-Panimulang punto ng proseso. Sinisimulan nito ang mga proseso sa pamamagitan ng pag-iiskedyul. Kailangan mong tukuyin ang list report na nagbabalik ng mga rekord para sa pagsisimula ng mga proseso at pag-iiskedyul sa crontab notation.
-
-#### Kondisyonal Intermediate Event
-
-Ang event na ito ay pumipigil sa flow hanggang ang specified criteria ay natugunan na.
-
-#### Timer Intermediate Event
-
-Ang event na ito ay pumpipil sa flow and naghihintay hanggat tinutukoy ng mga event's parameter.
-
-Para sa mga mas komplikadong timer settings, maaari mong gamitin ang [formula](formula.md). Dapat ibalik ng formula scripts ang Date-Time value (sa UTC timezone). Kapag ang oras na ito ay dumating, ang flow ay magpapatuloy sa susunod na elemento.
-
-Sa pamamagitan ng paggamit ng datetime\closest formula function, posible ng maitakda ang timer sa isang tiyak na oras sa hinaharap, e.g. ang simula ng susunod na araw ng pagtatrabaho.
-
-#### End Event
-
-Nagtatapos ng kasalukuyang flow. Hindi nito tinatapos ang mga flow na tumatakbo nang makapareho. Kapag ang flow ay umabot na sa dulo at wala ng kung ano mang pinatatakbo nang magkapareho, hihinto na ang process.
-
-#### Terminate End Event
-
-Nagtatapos ng lahat ng mga flow. Ang proseso ay kasunod na natatapos.
-
-### Mga Gateway
-
-Ang mga gateway ay idini-display bilang mga diamante.
-
-#### Eksklusibo na Gateway
-
-Ay maaaring mag-diverge o mag-converge ng mga flow.
-
-Kung sakaling ito ay diverging, tumutukoy ito ng iisang flow (path) na pwedeng piliin ayon sa tinutukoy na kriterion. Ang unang natupad na kondisyon ay tumutukoy sa flow, ang sumusunod na kondisyon ay tinatanggal. Maayroon itong kakayahan na tukuyin ang default flow. Ang default flow ang pinipili kung mayroong mga kondisyon na hindi natutupad. Ang default flow ay minamarkahan ng slash sign.
-
-Kung sakaling ito ay converging, dinidirekta ang flow sa palabas na elemento. Hindi ito bina-block kahit na nakarating na ang flow, kaya ang mga parallel flow ay hindi pagsasama-samahin upang maging isang solo na flow.
-
-
-
-
-
-#### Inclusive na Gateway
-
-Ay maaaring mag-diverge o mag-converge ng mga flow.
-
-Kung sakaling ito ay diverging, maaari itong idirekta sa isa or maramihang parallel flow (paths), depende sa pagtatapos ng kriterion ng bawat flow. Ang default flow ay pinipili kung walang nakikitang kondisyon. Ang default flow ay minimarkahan na may slash sign.
-
-Kung mayroong isang pangangailangan na pagsamahin ang mga parallel flow na nagawa sa pamamagitan ng divering inclusive gateway, kailangan mong gumamit ng isang convering inclusive gateway. Ito ay maghihintay para sa lahat ng papasok na flow at pagkatapos ay magpapatuloy sa papalabas na elemento.
-
-
-
-Tandaan: Ang mga divering at converging gateway ay dapat na balanse.
-
-Tandaan: Kung ang isang parallel flow ay natapos na para sa ilang kadahilanan, kung gayon ang divering gateway ay hindi mapoproseso. Ang proseso ay maba-block. Iwasan ang flowchart design na maaaring magdulot ng gayong sitwasyon.
-
-#### Parallel Gateway
-
-Ay maaaring mag-diverge o mag-converge ng mga flow.
-
-Kung sakaling ito ay divering, hinahati nito ang flow sa loob ng maramihang parallel flow. Walang mga parameter sa ganitong klaseng gateway.
-
-Kung sakaling ito ay converging, naghihintay ito hanggang sa lahat ng papasok nga flow ay dumating at pagkatapos ay magpapatuloy sa susunod na papalabas na elemento.
-
-
-
-Tandaan: Ang mga divering at converging gateway ay dapat na balanse.
-
-Tandaan: Kung ang isang parallel flow ay natapos na para sa ilang kadahilanan, kung gayon ang divering gateway ay hindi mapoproseso. Ang proseso ay maba-block. Iwasan ang flowchart design na maaaring magdulot ng gayong sitwasyon.
-
-#### Event Based Gateway
-
-Ay maaaring lamang mag-diverge ng mga flow.
-
-Hinihinto nito ang flow hanggang sa anumang palabas na event ay matri-trigger. Ang isang triggered event ay tumutukoy sa solong flow. Ang iba pang papalabas na event ay tinatanggihan.
-
-Ang mga intermediate event lamang ang maaaring nasa kabilang dulo ng mga papalabas na sequence flow.
-
-
-
-### Mga Aktibidad
-
-Ang mga aktibidad ay idi-display bilang mga bilogang rektanggulo.
-
-#### Gawain
-
-Ang gawain ay maaaring mag-execute ng mga sumusunod na mga aksyon:
-
-* Lumika ng rekord - lumikha ng bagong rekord ng anumang entity type;
-* Lumikha nga kaugnay na rekord - lumikha ng bagong rekord na may kaugnayan sa target record;
-* Mag-update ng target record;
-* Mag-update ng kaugnay na rekord - Ina-update ang rekord o records na may kaugnayan sa target record;
-* Mag-update ng nilikhang rekord - ina-update ang tiyak na field ng anumang rekord sa kasalukuyang proseso;
-* Mag-update ng naproseso na rekord - maaaring gamitin para magtalaga ng proseso sa tinutukoy na user o team;
-* Mag ugnay sa ibang rekord - inuugnay ang target na rekord sa isang tinutukoy na rekord;
-* I-unlink mula sa ibang rekord - ini-unlink ang target na rekord mula sa tinutukoy na rekord;
-* Mag-apply ng patakaran sa pagtakda - magtalaga sa target na rekord, sa prinosesong rekord o anumang nilikhang rekord ng proseso ayon sa tinutukoy na panuntunan;
-* Lumikha ng notipikasyon - lumilikha ng in-app notipikasyon para sa mga tinutukoy na user;
-* Gawing Followed - ina-assign ang mga tiyak na user na sumunod sa target na rekord, sa prinosesong rekord or anumang nilikhang rekord ng proseso;
-* Paganahin ang serbisyo na aksyon - pinapagana ang custom na serbisyo na action na ipinapatupad ng nag-develop.
-
-Ang mga aksyon na magagamit para sa gawain ay halos kapareho ng tampok ng Workflow. Tingnan ang higit pang mga detalye tungkol sa [workflow's actions](workflows.md#actions).
-
-#### Magpadala ng Message Task
-
-Magpadala ng email na mensahe para sa partikular na tatanggap.
-
-#### Gawain ng User
-
-Nagbibibay ng pleksibol na kakayahan ng user interaksyon. Tinitigil nito ang pagpapatupad hanggang ang user (tinutukoy ng tahasaon o tuntunin ng pagtatalaga) ay naayos ang gawain. Ang prinosesong user task rekord ay lilikhain sa parehong sistema.
-
-* Ang approve type ay mangangailan sa user na pumili sa pagitan ng 'Approved' at 'Declined.'
-* Ang review type ay nagbibigay lamang ng isang pagpipilian: 'Reviewed.'
-* Ang accomplish type ay mayroong dalawang pagpipilian: 'Completed' at 'Failed.'
-
-
-Ang user na naka-assign sa nilikang prinosesong user task rekord ang siyang tatanggap ng in-app notipikasyon. Ang administrador ay maaari ding mag-enable ng email notipikasyon.
-
-Ang mga user ay maaaring ding magdagdag ng prinosesong user task dashlet sa kanilang dashboard para makita ang aktwal na prinosesong user tasks.
-
-Possible ding mabasa ang resolution ng lumipas ng user taks loob ng mga diverging gateway o mga kondisyonal na mga event, na gumagawa ng ramification sa process flow.
-
-#### Script Task
-
-Isinasagawa ang script sa [espo-formula](formula.md) na lengguwahe. Lahat ng naka-set na variable (`$variableName`) ay itatabi at gagamitin sa loob ng proseso.
-
-### Flows
-
-#### Sequence Flow
-
-Inilalarawan bilang isang solid na arrow. Pinapahiwatig ang kaayusan kung saan ang prinosesong elemento ay isasagawa.
-
-## Mga Kondisyon
-
-Ang mga kondisyonal na event, ekslusibo at mga kasamang divering gateway ay may mga kondisyon na tumutukoy sa daloy ng proseso.
-
-Sa pamamagitan ng UI, may kakayahan itong i-check ang mga kondisyon para sa mga sumusunod na mga rekord:
-
-* Target rekord;
-* Mga rekord na kaugnay ng target sa pamamagitan ng many-to-one at children-to-parent na kaugnayan;
-* Ang mga rekord na nilikha ng proseso sa pamamagitan ng mga gawain;
-* Mga user task rekord, na nagpapahintulot sa pag-check sa resolusyon.
-
-Posible rin na tukuyin ang mga kondisyon sa [Espo-formula](formula.md) na lengguwahe.
-
-Ang mga kondisyon sa BPM tool ay pareho sa tampok na Workflow. Tingnan ang higit pang mga detalye
-tungkol sa [workflow's conditions](workflows.md#conditions).
-
-## Mga Halimbawa
-
-### Unang Halimbawa
-
-
-### Pangalawang Halimbawa
-
-
-#### Pangatlong Halimbawa
-
\ No newline at end of file
diff --git a/i18n/tl_PH/administration/dynamic-logic.md b/i18n/tl_PH/administration/dynamic-logic.md
deleted file mode 100644
index 1cce82736..000000000
--- a/i18n/tl_PH/administration/dynamic-logic.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Dynamic Logic (dinamikang mga form)
-
-Ang dinamikang kilos ng mga form ay maaaring makuha sa pamamagitan ng paggamit ng tampok na Dynamic Logic. Mayroong mga parametro ng Dynamic Logic sa bawat field. Ang mga parametro ay makikita sa Entity Manager kapag ikaw ay nag-edit or lumikha ng isang field.
-
-Pinapayagan ng Dynamic Logic na tukuyin ang mga kundisyon upang ang mga field ay nakikita, kinakailangan o read-only. Automatikong sinusuri ang mga kundisyon kapag ang datos sa form ay nabago.
-
-Para sa Enum, Array at Multi-Enum nga mga field, posible na tukuyin ang iba't ibang hanay ng mga pagpipilian na magagamit para sa field depende sa kung anong kondisyon ang natutugunan.
-
-Ang mga kondisyon ay isinaayos sa pamamagitan ng user interface, walang kinakailangang coding.
\ No newline at end of file
diff --git a/i18n/tl_PH/administration/email-fetching.md b/i18n/tl_PH/administration/email-fetching.md
deleted file mode 100644
index f2ba1d1a5..000000000
--- a/i18n/tl_PH/administration/email-fetching.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Mga Email
-
-Ang dokumentong ito ay inilipat [dito](emails.md).
diff --git a/i18n/tl_PH/administration/emails.md b/i18n/tl_PH/administration/emails.md
deleted file mode 100644
index 27b265322..000000000
--- a/i18n/tl_PH/administration/emails.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Mga Email
-
-> Importante. Ang [Cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) ay dapat nakaconfigure sa iyong sistema para gumawa ng email fetching na task. Makikita mo impormasyon na ito sa iyong EspoCRM sa Administration > Scheduled Jobs.
-
-## Kabuuran
-
-Ang EspoCRM ay may abilidad na magmonitor ng mga IMAP mailbox. Ang email ay pwede i-archive sa pamamagitan ng dalawang paraan: Group Email Accounts at Personal Email Accounts. Ang Group Inbound Accounts ay ginawa para sa mga group mailbox: ang pinaka pangkaraniwang uri ay ang support box. Ang Personal Email Accounts ay ginawa para sa mga personal na mailbox ng user.
-
-Habang may paparating na email, ang sistema ay susubukang i-link ito sa angkop na rekord (Accounts, Lead, Opportunity, Case). Ang mga user na sumusunod sa rekord na ito ay makakatanggap ng notipikasyon tungkol sa bagong email sa loob ng sistema, kahit na wala sila sa To o CC.
-
-## Mga Group Email Account
-
-Ang administrador lang ang may kakayahang mag-setup ng mga Group Email Accounts. Ang Group Email Accounts ay pwedeng gamitin para sa pagtanggap at pagpapadala ng mga email. Ang pagpapadala ng mga email galing sa mga group account ay maari ng gawin mula sa 4.9.0 na version.
-
-Ang Teams na field ay nagtutukoy kung sa anong team i-aasign ang paparating na email.
-
-Kung ang group email account ay may SMTP at ito ay naicheck bilang shared, kung ganoon ang access ay makokontrol ng mga Role gamit ang Group Email Account na permission.
-
-Mayroong abilidad para ma-set ang sistema na mag magpadala ng auto-reply para sa mga paparating na mga email.
-
-## Email-to-Case
-
-Mayroong opsyon para ma-set ang sistema na gumawa ng mga kaso galing sa paparating na mga group email.
-Ang feature na ito ay ginawa para sa pagsuporta ng mga team.
-Ang mga kaso ay pwede i-distribute sa mga user galing sa isang espesikong team ayon sa mga paraang ito:
-`direct assignment`, `round-robin` and `less-busy`.
-Ang unang email lang ng thread ang pwedeng gumawa ng bagong case.
-Ang mga susunod na mga email ay ililink sa mga nagawa ng case record at ididisplay sa Stream panel nito.
-
-Kung ang mga user ay gustong magpadala ng reply sa mga customer, kinakailangan nilang siguradohin na ang case ay nakaselect bilang parent ng email na pinapadala. Dahil nito, ang customer ay magrereply na sa group email address sa halip na sa address ng user.
-
-## Mga Personal Email Account
-
-Ang mga user ay pwedeng mag-setup ng kanilang sariling email account na kailangang imonitor. Emails > Top Right Dropdown Menu > Personal Email Accounts. Ang administrador ay pwede ring mamahala ng mga email account ng user.
-
-## Mga Email Filter
-
-Ang mga ito ay pinapahintulutang magfilter ng mga paparating na email ayon sa specified na kriterya. E.g. kung hindi mo gustong makatanggap ng mga mensaheng notipikasyon galing sa ibang application para iimport sa EspoCRm, pwede kang gumawa ng filter para laktawan ito ng EspoCRM.
-
-Ang admin ay pwedeng gumawa ng mga global filter, na iaapply sa lahat ng mga email account. Ang mga user ay pwede gumawa ng mga filter para sa kanilang personal na email account at para sa kanilang buong inbox.
diff --git a/i18n/tl_PH/administration/entity-manager.md b/i18n/tl_PH/administration/entity-manager.md
deleted file mode 100644
index d4167889a..000000000
--- a/i18n/tl_PH/administration/entity-manager.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Entity Manager
-
-Ang Entity Manager ay makikita sa Administration panel. Ito ay nagbibigay ng kakayahan upang lubos na ma-customize ang iyong EspoCRM instance. Maaari mong gawin ang mga sumusunod:
-
-* Magdagdag nga mga bagong urin ng entity.
-* I-customize ang mga existing na uri ng entity: baguhin ang mga label, i-order batay sa default ang list view, i-enable o i-disable ang stream.
-* Mag-configure ng mga field: magdagdag ng bago, i-customize ang mga existing na.
-* Mag-configure ng mga relationship: magdagdag ng bago, baguhin ang mga label ng mga existing na.
-
-## Paglikha ng Bagong Entity
-
-I-click ang `Create Entity` na button sa Entity Manager page. I-specify ang pangalan, mga label at uri. Kung pipiliin mo ang `Person` type, ang iyong entity ay magkakaroon ng Email, Telophono, Unang Pangalan, Apelyido at mga Salutation field. I-check ang `Stream` kung gusto mong magkaroon ng stream panel at mga user ang iyong entity upang masundan ang ganitong uri nga mga entity.
-
-Mga Uri:
-
-* Base - ini-empty ang entity ng mga basic field gaya ng Pangalan, Naka-assign na User, mga Team, Deskripsyon.
-* Base Plus - gaya ng Base pero mayroong mga Aktibidad, History, mga Tasks panel (magagamit mula 4.3.0).
-* Event - Field ng Petsa ng Pagsisimula, Petsa ng Pagtatapos, Katagalan, Magulang, Status. Magagamit sa Calendar at Activities panel (mula 4.3.0, dapat ma-enable sa Administration > Settings).
-* Person - Field ng Email, Telepono, Unang Pangalan, Apelyido, Salutation, Address. Panel ng mga Aktibidad, History, Tasks.
-* Company - Field ng Email, Telepono, Billing Address, Shipping Address. Panel ng mga Actibidad, History, Tasks.
-
-## Pag-update ng existing entity
-
-Kung nag-click ka ng `Edit` link sa isang partikular na entity, maaari mong baguhin ang ilang mga parameter ng nasabing entity.
-
-* Labels - isahan at maramihang pangalan ng entity.
-* Ang mga default order rekord ay isinasaayos sa pamamagitan ng mga list view.
-* Stream - kung ang Stream na feature ay dapat na i-enable sa entity na ito.
-* Disabled - Chini-check kung kakailanganin mo ang entity na ito sa iyong system.
-* Text Filter Fields - kung anonog mga field ang dapat i-search para sa iyong main text filter at global search.
-
-
-## Mga Field
-
-Sa pamamagitan ng pag-click ng `Fields` link, malilipat ka sa isang hiwalay na page. Doon ay maaari kang lumikha nga panibagong mga field o i-update ang mga existing na. Ang mga sumusunod na mga fields are matatagpuan sa Entity Manager:
-
-* Address - address na may kale, syudad, estate, postal code at bansa;
-* Array - listahan ng mga value, na may kakayahan nga mag-select ng maramihan nga mga value (hindi magandang opsyon kung kailangang mong mag-search sa field na ito); ang mga user ay maaaring magdagdag ng sarili nilang mga value kung ang mga opsyon ay hindi nakatukoy.
-* Attachment Multiple - maramihan nga mga file attachment;
-* Auto-increment - read only generated na numero;
-* Boolean - checkbox, tama o mali;
-* Currency - para sa mga currency value;
-* Date;
-* DateTime;
-* Enum - selectbox, may kakayang pumili ng iisang value;
-* File - pag-upload ng isang file;
-* Float - numero na may decimal na parte;
-* Foreign - field na may kaugnay na entity;
-* Image - pag-upload ng isang image file na may preview;
-* Integer - buong numero;
-* Number - paga-awto-increment ng numero sa string type na may posibleng prefix at may isang tiyak na haba;
-* Multi-enum - listahan ng mga value, may kakayahang mag-select ng maramihan na mga values (indi magandang opsyon kung kailangang mong mag-search sa field na ito), kapareho ng Array ngunit mas mahusay.
-* Text - area ng text, para sa mahabang nga multiline text;
-* Url - para sa mga link;
-* Varchar - maikling teksto;
-* Wysiwyg - kapareho ng Text field, may kakayahang mag-format ng text.
-
-Mga Parameter:
-* Required - kung ang pag-fill in ng field ay kinakailangan.
-* Default Value - Value ng field na naka-set sa sandaling may bagong rekord na nalikha.
-* Audited - mga update ng field ay ila-log sa Stream.
-
-**Tandaan**: Pagkatapos mong madagdag ang bagong field, kailangan mong ilagay ang field na ito sa [layouts](layout-manager.md) (Administration > Layout Manager).
-
-### Dynamic na Lohika
-
-Nagbibigay ng kakayahang gawing dynamic ang mga form. Posible na tukuyin ang mga kundisyon upang ang mga partikular na mga field ay makikita, kinakailangan o read-only. Ang mga kundisyon ay pwedeng i-check ng awtomatiko kung ang data sa form ay babaguhin.
-
-Para sa Enum, Array at Multi Enum na mga field, posible na tukuyin ang iba't ibang set ng mga opsyon na magagamit para sa field depende sa kung anong kondisyon ang natutugunan.
-
-
-## Mga Relasyon
-
-Maaari kang lumikha ng mga bagong relasyon sa pagitan out-of-box at custom entity. Mayroong tatlong klase ng relasyon:
-
-* One-to-Many: pagkatapos mong likhain ang relasyon na ito, maari mong lagyan ng link field ang detail layout ang kanang entity at dagdagan ng relationship panel sa kaliwang entity;
-* Many-to-One: kapareho ng One-to-Many pero bisebersa;
-* Many-to-Many: mga relationship panel sa magkabilang panig.
-
-Ang parameter na 'Link Multiple Field' ay nagpapahiwatig na ang field ng `linkMultiple` type ay maaaring gawing kasama ng relationship. Maaari kang maglagay ng ganitong field sa layout. Ito ay nakatutulong para sa mabilis na pagpili ng mga kaugnay na rekord. Hindi ito magandang opsyon kung ang iyong relasyonay nakalaan na magkaroon ng maraming naka-link na mga rekord na maaaring makapagpabagal ng loading ng detalye ng view screen.
-
-Kung ang parameter na 'Audited' ay naka-check, kung gayon ang mga update ng relasyon ay ila-log sa Stream.
diff --git a/i18n/tl_PH/administration/extensions.md b/i18n/tl_PH/administration/extensions.md
deleted file mode 100644
index 2437c6edf..000000000
--- a/i18n/tl_PH/administration/extensions.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Pag-manage ng mga extension
-
-## Paano mag-install ng extension
-
-Para mag-install ng EspoCRM na extension (e.g. Advanced Pack, VoIP Integration):
-
-1. Mag-login bilang administrador.
-2. Pumuta sa Administration > Extensions.
-3. Upload your extension package (zip file).
-3. I-upload ang iyong extension package (zip file).
-4. I-click ang Install na pindutan.
-
-
-## Paano mag-upgrade ng extension
-
-Para mag-upgrade ng naka-install na na extension (e.g. Advanced Pack, VoIP integration) sa isang mas bagong bersyon:
-
-1. Mag-download ng bagong bersyon ng kinakailangang extension.
-2. Mag-login bilang isang administrador.
-3. Pumuta sa Administration > Extensions.
-4. I-upload ang iyong extension package (zip file) habang hindi ini-uninstall ang naka-install na na bersyon.
-5. I-click ang Install na pindutan.
-
-
-## Paano i-uninstall ang extension
-
-Mga hakbang para i-uninstall ang naka-install na na extension:
-
-1. Mag-login bilang isang administrador.
-2. Pumuta sa Administration > Extensions.
-3. Hanapin ang mga kinakailangang extension sa listahan ng mga available na mga extension.
-4. I-click ang Uninstall na pindutan.
-
-
-## Paano i-delete ang extension
-
-Kung ang extension ay naka-uninstalled, ito ay makikita pa rin sa loob ng sistema. Ito ay maaaring tanggalin ng ganap. Ang mga hakbang para i-delete ang extension:
-
-1. Mag-login bilang isang administrador.
-2. Pumuta sa Administration > Extensions.
-3. Hanapin ang mga kinakailangang extension sa listahan ng mga available na mga extension.
-4. I-click ang Remove na pindutan.
diff --git a/i18n/tl_PH/administration/formula.md b/i18n/tl_PH/administration/formula.md
deleted file mode 100644
index 09be9fb84..000000000
--- a/i18n/tl_PH/administration/formula.md
+++ /dev/null
@@ -1,268 +0,0 @@
-# Mag Kinalkulang Field (Formula)
-
-Sa entity manager, posible na tukuyin ang script (formula) para sa partikular na entity type. Ang script na ito ay isasagawa sa bawat oras bago mai-save ang rekord.
-Nagbibigay ito ng kakayahan na awtomatikong ma-set ang mga tiyak na field (attribute) na may mga halaga na mula sa pagkalkula.
-
-Upang ma-edit ang formula, sundin ang Administration > Entity Manager dropdown menu sa kanan sa hanay ng kinakailangang entity > Formula.
-
-Maaari mo ring kailanganin ang mag-set ng mga field, na dapat kalkulahin, Read-only sa pamamagitan ng Entity Manager.
-
-
-## Syntax
-
-Ang EspoCRM formula ay nakasulat sa simpleng lengguwahe na partikular na idinisenyo para sa tampok na ito.
-
-May mga operator, function, mga attribute at mga value na maaaring magamit sa formula. Ang mga hiwalay na expression ay dapat na ma-delimit sa pamamagitan ng character `;`.
-
-### Mga Operator
-* `=` - assignment.
-* `||` - lohikal na OR,
-* `&&` - lohikal na AND,
-* `!` - lohikal na NOT,
-* `+`- numeric na sumasyon,
-* `-` - numeric na subtraction,
-* `*` - numeric na multiplication,
-* `/` - numeric na division,
-* `%` - numeric na modulo,
-* `==` - pantay na paghahambing,
-* `!=` - di pantay na paghahambing,
-* `>` - mas mahigit pa na paghahambing,
-* `<` - mas mababa pa na paghahambing,
-* `>=` - pantay o mas mahigit pa na paghahambing,
-* `<=` - pantay o mas mababa pa na paghahambing.
-
-Prayoridad ng mga operator:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Mga Attribute
-
-Ang mga attribute ay kumakatawan ng mga field value ng target entity. Maari mong i-insert ang mga magagamit na attribute sa pamamagitan ng pag-click ng plus buton.
-
-Posible na ma-access ang mga attribute ng mga ka ugnay na entity sa pamamagitan ng sumusunod na format `linkName.attributeName`.
-
-
-### Mga Function
-
-Format ng paggamit ng function: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Ang mga out-of-the-box function ay nakalista sa ibaba.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` Kung ang CONDITION ay natugunan, saka gawin ang CONSEQUENT. Kung hindi -- saka gagawin ang ALTERNATIVE.
-
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` Kung ang CONDITION ay natugunan, saka gawin ang CONSEQUENT. Kung hindi, wala kang gagawin.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` Pinagsasama-sama ang dalawa o higit pang mga string.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` Ini-extract ang mga character mula sa isang STRING sa pamamagitan ng START na posisyon at LENGTH.
-
-Kung ang LENGTH ay tinanggal, ang substring na nagmula sa START hanggang sa huli ng string ay ibabalik.
-
-Kung ang LENGTH ay negatibo, kung gayon ay tatanggalin ang maraming mga characer mua sa dulo ng string.
-
-#### string\\trim
-`string\trim(STRING)` Tinatanggal ang whitespace mula sa simula at dulo ng STRING.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Pinapalitan ang mga letra upang maging lower case. (mula pa sa bersyon 5.0.0)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Pinapalitan ang mga letra upang maging upper case. (mula pa sa bersyon 5.0.0)
-
-#### datetime\\today
-`datetime\today()` Binabalik ang petsa sa kasalukuyan.
-
-#### datetime\now
-`datetime\now()` Binabalik ang kasalukuyang datetime.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])`Pinapalitan ang petsa o datetime value upang maging string na na-format ayon sa setting ng application. Ang TIMEZONE at FORMAT ay maaaring tanggalin. Kung ang TIMEZONE ay tatanggalin, ang ang time zone batay sa default ang gagamitin. Kung ang FORMAT ay tatanggalin, ang format batay sa default ang gagamitin.
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Ibinabalik ang petsa ng kasaulukuyang buwan (1-31). `0` kung ang VALUE ay walang laman. Kung ang TIMEZONE ay tatanggalin, ang system timezone ang gagamitin. (mula pa sa bersyon 4.7.0)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Ibinabalik ang kasalukuyang buwan (1-12). `0` kung ang VALUE ay walang laman. Kung ang TIMEZONE ay tatanggalin, ang system timezone ang gagamitin. (mula pa sa bersyon 4.7.0)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Ibinabalik ang kasalukuyang taon. `0` kung ang VALUE ay walang laman. Kung ang TIMEZONE ay tatanggalin, ang system timezone ang gagamitin. (mula pa sa bersyon 4.7.0)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Ibinabalik ang kasalukuyang oras (0-23). `-1` kung VALUE ay walang laman. Kung ang TIMEZONE ay tatanggalin, ang system timezone ang gagamitin. (mula pa sa bersyon 4.7.0)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Ibinabalik ang kasalukuyang minuto (0-59). `-1` kung ang VALUE ay walang laman. Kung ang TIMEZONE ay tatanggalin, ang system timezone ang gagamitin. (mula pa sa bersyon 4.7.0)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Ibinabalik ang araw ng kasalukuyang linggo (0-6). `-1` kung ang VALUE ay walang laman. `0` - para sa Linggo. Kung ang TIMEZONE ay tatanggalin, ang system timezone ang gagamitin. (mula pa sa bersyon 4.7.3)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` Ibinabalik ang agwat sa pagitan ng dalawang petsa o datetime. Ang INTERVAL_TYPE ay maaaring maging 'year', 'month', 'days', 'hours', 'minutes'. Ibinabalik sa `null` kapag may failure. Magiging negatibo ang resulta kung ang VALUE_1 < VALUE_2.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Nagdadagdag ng minuto sa datetime VALUE. Ang MINUTES ay pwedeng maging negatibo.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Nagdadagdag ng oras sa datetime VALUE. Ang HOURS ay pwedeng maging negatibo.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Nagdadagdag ng araw sa petsa o datetime VALUE. Ang DAYS ay pwedeng maging negatibo.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Nagdadagdag ng linggo sa petsa o datetime VALUE. Ang WEEKS ay pwedeng maging negatibo.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Nagdadagdag ng buwan sa petsa o datetime VALUE. Ang MONTHS ay pwedeng maging negatibo.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Nagdadagdag ng taon sa petsa o datetime VALUE. Ang YEARS ay pwedeng maging negatibo.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` Ibinabalik ang pinakamalapit na petsa o datetime sa VALUE base sa nakaraang mga argumento. (mula pa sa bersyon 5.0.0)
-
-Ang TYPE ay pwedeng maging isa sa mga sumusunod na mga value: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. Ang TARGET ay isang integer value o isang string value. IS_PAST ay nangangahulugang ang paghahanap ng pinakamalapit sa nakaraan. Kung ang TIMEZONE ay tatanggalin, ang default timezone ang gagamitin.
-
-Mga Halimbawa:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Ay magbabalik ng pinakamalapit na datetime value sa hinaharap sa 20:00 na oras.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` Ay magbabalik ng `2017-11-01`, ang unang araw ng buwan.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Ay magbabalik ng susunod na Lunes (ang simula ng araw).
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Pinapalitan ang numeric VALUE ng string na naka-format ayon sa partikular na format o setting ng application batay sa default. Kung DECIMALS, DECIMAL_MARK OR THOUSAND_SEPARATOR, ang mga system default ang gagamitin.
-
-Mga Halimbawa:
-
-`number\format(2.666667, 2)` - results 2.67;
-
-`number\format(1000, 2)` - results 1,000.00;
-
-`number\format(10.1, 0)` - results 10.
-
-
-#### number\abs
-`number\abs(VALUE)` Ganap na halaga. Ibinabalik ang null kung ang VALUE ay hindi numeric.
-
-#### number\round
-`number\round(VALUE, PRECISION)` Ibinabalik ang rounded value ng VALUE sa tinutukoy na PRECISION (bilang nga mga digit pagkatapos ng decimal point). Ang PRECISION pwedeng maging negatibo o sero (default).
-
-#### number\floor
-`number\floor(VALUE)` Ibinabalik ang susunod na pinakababang integer value sa pamamagitan ng pag round down ng value kung kinakailangan. (mula pa sa bersyon 4.9.0)
-
-#### number\ceil
-`number\ceil(VALUE)` Ibinabalik ang susunod na pinakamataas na integer value a pamamagitan ng pag round up ng value kung kinakailangan. (mula pa sa bersyon 4.9.0)
-
-#### entity\isNew
-`entity\isNew()` Ibinabalik sa TRUE kung ang entity ay bago lang (nilika) at FALSE kung hindi (ina-update).
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Ibinabalik sa TRUE kung ang ATTRIBUTE ng entity ay nabago.
-
-Halimbawa:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Ibinabalik sa TRUE kung ang ATTRIBUTE ng entity ay hindi nabago.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Ang Attribute na na-set nang ang target entity ay kinuhamula sa database. Bago ito nabago.
-
-Halimbawa:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Nagdadagdag ng ID sa Link Multiple field. Halimbawa, magdagdag ng 'someTeamId' sa 'teams' field.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Nagdadagdag ng listahan ng mga id. (mula pa sa bersyon 4.8.3)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Nagche-check kung ang Link Multiple field ay may tikayk na ID.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Nag-aalis ng partikular na ID mula sa Link Multiple field.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Nagche-check kung ang target entity ay may kaugnayan sa ibang entity na kinakatawan ng LINK at ID.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Ibinabalik ang ATTRIBUTE ng kasalukuyang user.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Ibinabalik ang array. (mula pa sa bersyon 4.7.0)
-
-#### array\includes
-`array\includes(LIST, VALUE)` Babalik bilang true kung ang LIST ay naglalaman ng VALUE. Ay pwedeng gamitin para sa Array at Multi-Enum fields. (mula pa sa bersyon 4.7.0)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Nagdadagdag ng isa o higit pang mga elemento sa dulo ng ng isang array at ibinabalik ang panibagong array. (mula pa sa bersyon 5.0.0)
-
-#### array\length
-`array\length(LIST)` Ibinabalik ang bilang ng mga elemento sa LIST. (mula pa sa bersyon 4.8.1)
-
-
-### Mga Value
-
-* Strings. E.g. 'some string';
-* Number ng mga Integer. E.g. 1, 100, 40300.
-* Number ng mga float. E.g. 5.2.
-
-### Mga Variable
-
-It's possible to define custom variables in formula.
-Posible na tukuyin ang mga custom na variable sa formula.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Mga Halimbawa
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## Pag-gamit ng Formula sa mga Workflow
-
-Maaari mong gamitin ang formula sa mga kondisyon at aksyon ng workflow. Tingnan ang [workflows dokumentasyon](workflows.md) para sa karagdagang impormasyon.
diff --git a/i18n/tl_PH/administration/import.md b/i18n/tl_PH/administration/import.md
deleted file mode 100644
index 045da4e4b..000000000
--- a/i18n/tl_PH/administration/import.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# Import
-
-Ang import ay naa-access lamang ng mga admin user. Administration > Import. Maaari kang mag-import mula sa mga CSV file.
-
-## Unang Step
-
-Piliin kung anong uri ng mga rekord ang kailangan mong i-import (Entity Type field).
-Pumili ng isang CSV file. Ang isang file ay dapat naka-format sa `UTF-8`.
-Piliin ang `What to do?`. Mga Pwedeng Pagpilian: 'Create Only', 'Create & Update', 'Update Only'.
-
-* `Create Only` - piliin ito kung nais mo lamang lumikha ng rekord.
-* `Create & Update` - Ang mga rekord ay gagawin ngunit kung mayroong mga rekord na may magkatugmang field value, ito ay ia-update.Maaari mong i-check kung anong mga field ang pwedeng itugma sa _Step 2_.
-* `Update only` - ang mga matatagpuang rekord na may magkatugmang field value lamang ang ia-update.
-
-Kapag pumili ka ng isang csv file, maaari mong makita kung papaano mo ito mapa-parse sa Preview panel. Kapag binago mo ang mga property, ang preview ay maa-update.
-
-* `Header Row` - kung ang CSV file ay may mga field name sa unang row.
-* `Execute in idle` - inirerekomenda kung mayroon kang isang malaking grupo ng rekord na dapat i-import. Ang import ay mapopo-proseso sa pamamagitan ng cron. Ang status ay isi-set sa 'Complete' kung ang import process ay tapos na.
-* `Skip searching for duplicates` - binabawasan ang import runtime.
-
-I-click ang _Next_ button para magpatauloy sa _Step 2_.
-
-
-
-## Pangalawang Hakbang
-
-I-setup ang field mapping: kung papaano tumutugma ang mga field sa mga column ng csf file. Maaari mong i-skip ang mga hindi kinakailangang mga column.
-Sa mga kaso ng 'Create & Update' at 'Update only' kailangan mong i-check ang mga field kung saan ang mga rekord nga dapat i-update ay matatagpuan.
-I-dagdag ang mga default value na gusto mong maging bago at ang mga na-update na mga rekord na gusto mong i-set. E.g. pwede mong tukuyin ang Assigned User o ang mga Teams field.
-
-Pagkatapos mong gawing ang pag-import, maaari mong ibalik ang mga rekord na nalikha na at tingnan ang mga duplicate at mga rekord na na-update na. Ang mga duplicate ay mga magkaparehong rekord na nasa system. Maaari mong alisin ang lahat ng na-import nga mga duplicate nang sabay-sabay. Tandaan: Ang revert ay hindi gumagana sa mga rekord na na-update na.
-
-I-click ang _Run Import_ button upang mapgtauloy. Maaaring tumagal ng ilang oras bago matapos ang isang import process. Kung gusto mong mag-import ng isang malaking grupo ng mga rekord (depende sa iyong server configuration, kadalasan ay higit sa 200 na mga rekord), kailangan mong tiyakin na ang php parameter `set_time_limit` ay sapat ang kalakihan.
-
-
-
-## Paano Mag-import sa Target List
-
-Kapag nag-import ka ng mga Contact, Lead or Account, pwede mo silang idagdag sa ilang mga target list. Sa pangalawang hakbang, kailangan mong idagdag ang Target List field sa `Default Values` panel at piliin ang kinakailangang target list rekord. Maaari mo ring gamitin ang `Update only` o `Create & Update` import upang idagdag ang existing na mga target sa isang target list.
\ No newline at end of file
diff --git a/i18n/tl_PH/administration/installation.md b/i18n/tl_PH/administration/installation.md
deleted file mode 100644
index 76b4fdfde..000000000
--- a/i18n/tl_PH/administration/installation.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Pag-install
-
-### Mga Kinakailangan
-Ang EspoCRM ay gagana sa karamihan ng mga hosting provider. Ang mga kakailanganin ay ang mga sumusunod:
-
-* PHP 5.6 o ang pinakabagong bersyon ng PHP na mayroong enabled pdo, json, GD library, mcrypt nga mga extension (kadalasan ay enabled batay sa default);
-* MySQL 5.5.3 o mas mataas pa.
-
-Tingnan ang [Server Configuration](server-configuration.md) na artikulo para sa karagdagang impormasyon.
-
-### 1. I-download ang EspoCRM installation package
-Upang makakuha ng pinakabagong bersyon ng EspoCRM, sundin ang [download page](http://www.espocrm.com/download/) na link.
-
-### 2. I-upload ang mga EspoCRM File sa Iyong Server
-
-Kapag nakumpleto na ang pag-download, i-upload ang package sa iyong web serber.
-Para i-upload ito, maaari mong gamitin ang SSH, FTP o ang hosting administration panel.
-I-extract ang archive sa iyong publikong web serber direktoryo (e.g., `public_html`, `www`, etc.).
-
-_Tandaan: Para sa FTP, kailangang mong i-extract ang archive bago mag-upload sa iyong web serber._
-
-### 3. Gumawa ng isang MySQL Database para magamit ng EspoCRM
-
-Pumunta sa iyong hosting administration panel, o sa SSH, at gumawa ng isang panibagong database at user para sa EspoCRM (e.g., `MySQL Databases` in cPanel).
-
-### 4. Patakbuhin ang proseso ng pag-install ng EspoCRm
-
-Ngayon, buksan ang iyong web browser, at pumunta sa URL na may mga EspoCRM na file (e.g., `http://yourdomain.com/espo`).
-
-Kapag nakita mo ang screen na ito, mayroon kang "Permission denied" na error.
-Kaya kailangang mong i-execute ang nakadisplay na command sa terminal sa pamamagitan ng SSH, o i-set ang tamang permiso.
-Dapat 755 para sa mga direktoryo, 644 para sa mga file, at 775 para sa `data` na direktoryo.
-Tiyakin din na mayroon kang tamang _owner_ at _group_.
-
-
-
-Kapag nakita mo ang screen na ito, ang permiso ay tama at maaari mo ng simulan na i-install ang EspoCRM.
-
-
-
-Sa pahinang ito, pwede mong basahin at tanggapin ang License Agreement.
-
-
-
-Ilagay ang mga detalye ng iyong bagong nabuong MySQL database.
-
-
-
-Ilagay ang pangalan ng user at password ng Administrator EspoCRM.
-
-
-
-Sa page na ito ay maaari mong i-set ang mga default setting ng EspoCRM, tulad ng date at time format, timezone, currency at iba pa.
-
-
-
-I-enter ang mga SMTP setting para sa mga outgoing email, kung gusto mong makapagpadala ng mga email.
-Ang step na ito ay maaaring laktawan sa pamamagitan ng pag-click ng _Next_ pindutan.
-Ang lahat ng mga opsyon na ito ay maaaring idagdag/baguhin sa EspoCRM pagkatapos ng instalasyon.
-
-
-
-Congratulation! Ang installation ay kumpleto na.
-Ang huling bagay ay ang pag-setup ng mga Scheduled Task na patatakbuhin ng iyong sistema. Magagawa ito sa pamamagitan ng pagpapatakbo ng `crontab -e` sa linux cli at sa _Windows Tasks Scheduler_ sa mga Windows na sistema.
-
-
-
-Umaasa kami na masisiyahan kang magtrabaho sa EspoCRM.
-
-
-
-
-
-
-
diff --git a/i18n/tl_PH/administration/layout-manager.md b/i18n/tl_PH/administration/layout-manager.md
deleted file mode 100644
index b5393a4bc..000000000
--- a/i18n/tl_PH/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Ang Layout Manager
-
-Ang Layout Manager ay makikita sa administration panel. Nagbibigay kakayahang ma-customize ang anyo ng mga detalye, edit, list view pati na rin ng mga search filter at field para sa mga mass-update form.
-
-## Listahan
-
-Ang pangunahing layout para sa list view. Tumutukoy sa mga column at mga parameter nito.
-
-
-
-Ang mga magagamit na mga parameter para sa mga column ay nakalista sa ibaba.
-
-### Lapad (%)
-
-Ang lapad ng column sa porsiyento, ang walang laman ay nangangahulugang auto-width.
-
-### Link
-
-Kung naka-check, kung gayon ay ang field ay idi-display bilang isang link ng detail view record. Kadalasang ginagamit para sa mga name field.
-
-### Hindi Sortable
-
-Dini-disable ang pag-sort ng column.
-
-### Ihanay
-
-Ihinahanay ang column sa kaliwa o kanan.
-
-## Detalye
-
-Ang pangunahing layout para sa detail view at ng edit view. Tumutukoy ng mga panel, ng mga row at mga cell. Ang mga cell ay naglalaman ng mga field.
-
-Ang row ay maaaring maglaman ng dalawang cell o isang cell na pinalawak hanggang sa buong lapad ng row. Upang i-add amg row na may pinalaking cell kailangan mong i-add ang bagong row at i-click ang minus sign sa kahit na anong cell.
-
-
-
-## Listahan (Maliit)
-
-Ang list layout para sa mga relationship panel. Maaari ring gamitin sa iba pang mga lugar kung saan ito ay lohikal na i-display ang mga listahan sa isang narrow view.
-
-## Detalye (Maliit)
-
-Ang detail view para sa mga quick create, quick view at quick edit form.
-
-## Mga Search Filter
-
-Ang listahan ng mga field sa list view na maaaring i-search.
-
-## Bultohang Pag-update
-
-Ang listahan ng mga field na makikita sa Mass Update form.
-
-## Mga Relationship Panel
-
-Ang listahan ng mga relationship panel na naka-display sa detail view sa ibaba. Ang mga panel ay maaaring pagsunod-sunurin. Maaari ring mag takda nga kolor ng panel kasama ang Style parameter.
-
-## Mmga Side Panel
-
-Ang mga side panel para sa mga Detail, Edit, Detail Small, Edit Small form. Nagbibigay ng kakayahan nga itago or ire-order ang mga panels list Activities, History, Tasks at iba pa. Ang mga panel ay maaaring kulayan sa pamamagitan ng Style parameter.
-
-## Mga Karagdagang Layout
-
-Ang ilang uri ng mga entity ay naglalaman nga mga karagdagang layout: Convert Lead, List for Account.
diff --git a/i18n/tl_PH/administration/ldap-authorization-for-ad.md b/i18n/tl_PH/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index a1d13427e..000000000
--- a/i18n/tl_PH/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Awtorisasyon ng LDAP para sa Active Directory
-
-Halimbawa ng pag-configure ng awtorisasyon ng LDAP para sa Active Directory server. Ang buong guide para sa pag-configure ng awtorisasyon ng LDAP ay inilalarawan [dito](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/tl_PH/administration/ldap-authorization-for-openldap.md b/i18n/tl_PH/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 94a11600c..000000000
--- a/i18n/tl_PH/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Awtorisasyon ng LDAP para sa OpenLDAP
-
-Halimbawa ng pag-configure ng awtorisasyon ng LDAP para sa OpenLDAP server. Ang buong guide ng pag-configure ng awtorisasyon ng LDAP ay inilalarawan [dito](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/tl_PH/administration/ldap-authorization.md b/i18n/tl_PH/administration/ldap-authorization.md
deleted file mode 100644
index c0d58ceed..000000000
--- a/i18n/tl_PH/administration/ldap-authorization.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Awtorisasyon ng Ldap
-
-Sa guide na ito, ipapakita namin kung papaano i-configure ang awtorisasyon ng LDAP para EspoCRM. Tara na!
-
-Pumunta sa iyong LDAP serber at gumawa ng isang base DN para sa mga EspoCRM user gaya ng
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Kailangan nating lumikha ng isang system user na magkakaroon ng access sa users DN (“cn=espo-users,ou=users,dc=espo,dc=local”). Kaya ang buong DN para sa system user na ito ay magiging
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Ngayon ay maaari na nating idagdag ang LDAP user para ma-acces ang EspoCRM. E.g. Espo Tester na may username “tester” sa loob ng “cn=espo-users,ou=users,dc=espo,dc=local” DN. Paalala: para magamit ang login format na ito para sa EspoCRM, kailangan mong tukuying ang “Username Attribute” at “Base DN” na mga opsyon.
-
-Pagkatapos ay pumunta sa mga EspoCRM Authentication setting sa Administrator panel, i-select ang `LDAP` method at punan ang mga LDAP na detalye:
-
-
-
-* Host – LDAP IP o pangalan ng host.
-* Port – port ng koneksyon.
-* Auth – pag-access ng mga credential para LDAP serber:
- * Full User DN – ang buong system user DN na nagpapahintulot na i-search ang ibang mga user.
- * Password – ang password para ma-access ang LDAP serber.
-* Security – protokol ng SSL o TSL.
-* Username Attribute – ang katangian upang kilalanin ang user. Para sa Active Directory maaari itong maging “userPrincipalName” o “sAMAccountName”.
-* Account Canonical Form – uri ng iyong account canonical form. Mayroong apat na opsyon:
- * Dn – ang form sa format `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – ang form na `tester`.
- * Backslash – ang form na `COMPANY\tester`.
- * Principal – ang form na `tester@company.com`.
-* Bind Requires Dn – kung kinakailangang i-format ang username sa DN form.
-* Base Dn – ang base DN batay sa default na ginagamit sa pag-search ng mga user.
-* User Login Filter – ang filter na nagpapahintulot na i-restrict ang mga user na maaring gumamit ng EspoCRM. E.g. `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – Ang domain na ginagamit para sa awtorisasyon ng LDAP serber.
-* Account Domain Name Short – Ang short domain ginagamit para sa awtorisasyon ng LDAP serber.
-* Try Username Split – ang opsyo na hahati sa username kasama ang domain.
-* Opt Referrals – kung nag mga referral ay dapat sundin ng LDAP client.
-* Create User in EspoCRM – ang opsyon na itoy ay nagpapahintulot sa EspoCRM na gumawa ng user mura sa LDAP.
- * User First Name Attribute – katangian ng LDAP na ginagamit upang matukoy ang unang pangalan ng user.
- * User Last Name Attribute – katangian ng LDAP na ginagamit upang matukoy ang apelyido ng user.
- * User Title Attribute – katangian ng LDAP na ginagamit upang matukoy ang user title.
- * User Email Address Attribute – katangian ng LDAP na ginagamit upang matukoy email address ng user.
- * User Phone Number Attribute – katangian ng LDAP na ginagamit upang matukoy ang numero ng telepono ng user.
-
-Ngayon ay pumunta sa login page at i-enter ang mga user credential.
-
-
-
-Ang user ay na-authenticate na at awtomatiko ng nalikha sa EspoCRM.
-
-## Ang mga Instruksiyon ng Configuration base sa iyong serber:
-* [Active Directory serber](ldap-authorization-for-ad.md)
-* [OpenLDAP serber](ldap-authorization-for-openldap.md)
-
-Para sa karagdagang impormasyon sa pag-configure ng LDAP, maaari mong basahin sa [Zend\Ldap library](https://zendframework.github.io/zend-ldap/intro/) page, sapagkat ang EspoCRM ay gumagamit ng library na ito.
-
-
-
-
diff --git a/i18n/tl_PH/administration/maps.md b/i18n/tl_PH/administration/maps.md
deleted file mode 100644
index 4dd41c5b9..000000000
--- a/i18n/tl_PH/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Mga Mapa
-
-## Paano ipapakita ang mapa batay sa isang address field
-
-Ang bawat Address field ay mayroong katumbas na Map field. Ang kailangan mo lang ay ilagay ito sa Detail layout. Ito ay gumagamit ng Google Maps service.
-
-`Administration > Layout Manager > Choose entity (Account, Contact, Lead or custom one) > Detail > Drag & Drop Map field.`
-
-Palawakin ang cell gamit ang minus sign.
-
-Maaari mo ring i-configure ang tangkad ng iyong field.
-
-`Administration > Entity Manager > Piliin ang entity > Fields > hanapin ang map field at i-click ito > i-edit ang tangkad at i-save.`
-
-## Api Key
-
-Dahil ito ay EspoCRM bersyon 4.2.0, kailangan mong tukuyin ang Api Key upang magamit ang Google Maps (Administration > Integration > Google Maps).
-
diff --git a/i18n/tl_PH/administration/moving-to-another-server.md b/i18n/tl_PH/administration/moving-to-another-server.md
deleted file mode 100644
index 4814b0be2..000000000
--- a/i18n/tl_PH/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Ang Paglilipat ng EspoCRM sa Ibang Server
-
-Sundan ang mga step na ito para malipat ang EspoCRM sa ibang server:
-
-### Unang Hakbang. Mga Backup na file
-
-Buksan ang file manager o login sa pamamagitan ng SSH upang ma-archive lahat ng mga magagamit na file mula sa direktoryo ng EspoCRM. Mga karagdagang detalye: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### Pangalawang Hakbang. Mag-backup ng iyong database
-
-Ang data na naka-istore sa database (MySQL, MariaDB) ay dapat na i-back up. Mangyaring sunding ang rekomendasyong ito: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### Pangatlong Hakbang. Kopyahin ang mga file at mga backup ng database backup sa isa pang server
-
-Kopyahin ang mga backup ng mga file at ng iyong database sa isang bagong server.
-
-### Pang-apat na Hakbang. Ang Pag-unarchive ng mga backup file
-
-Upang ma-unarchive ang mga backup file, maaari mong gamiting ang Archive Manager o ang instruksyon na ito: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-Tandaan: Kinakailangang mailagay ang mga file sa direktoryo ng web-server.
-
-### Panglimang Hakbang. I-configure ang server
-
-I-configure ang bagong server batay sa mga rekomendasyon dito: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### Pang-anim na Hakbang. Itama ang mga Permiso
-
-I-set ang mga kailangang permiso at mga may-ari ng file, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### Pangpitong Hakbang. I-import ang iyong database backup
-
-Kailangan mo munang lumikha ng isang bagong database na may isang user sa MySQL. Para i-import ang iyong database mula sa backup, sundin ang instruksyon: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### Pangwalong Hakbang. Itama ang mga configuruation ng EspoCRM
-
-Pagkatapos na matagumpay na ma-import at ma-configure ang server, pakitama ang mga configuration ng EspoCRM sa file na `ESPOCRM_DIRECTORY/data/config.php`:
-
- * mga setting ng koneksyon sa database:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - kung ang pangalan ng iyong domain (URL) ay binago:
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * default files owner (kung kakaiba lamang):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- kung saan ang `www-data` ay ang user ng iyong web-server.
-
-### Pangsiyam na Hakbang. I-setup ang crontab
-
-I-setup ang crontab, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-Tandaan: dapat itong i-configure sa ilalim ng user ng web-server.
-
-Iyon lang. Ngayon, ang iyong EspoCRM ay tumatakbo na sa isang bagong server.
diff --git a/i18n/tl_PH/administration/nginx-server-configuration.md b/i18n/tl_PH/administration/nginx-server-configuration.md
deleted file mode 100644
index b4d2a8083..000000000
--- a/i18n/tl_PH/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Ang Configuration ng Nginx server para sa EspoCRM
-
-Ang mga instruksiyon na ito ay suplimentaryo para sa [Server Configuration](server-configuration.md) na guideline. Pakatandaan na hindi lahat ng configuration setting na nakalista dito ay ginawa sa Ubunto server.
-
-## Mga Requirement sa PHP
-
-Upang ma-install ang mga kakailanganing library, patakbuhin ang mga command na ito sa isang termina:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## Pag-aayos ng isyu na “API Error: EspoCRM API is unavailable”:
-
-Gawin lamang ang mga kinakailangang mga hakbang. Pagkatapos ng bawat hakbang, i-check kung naresolba na ang isyu.
-
-### 1. Paganahin ang mga rewrite rule sa Nginx server
-
-Idagdag ang code na ito sa iyong Nginx server block config file (/etc/nginx/sites-available/YOUR_SITE) inside “server” block:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Kung wala ka ng file na ito, kailangan mo itong likhain. Para dito, mag-open ng isang terminal at patakbuhin ang command:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-At idagdag ang code the nakalista sa itaas. Para sa karagdagang impormasion kung paano i-configure ang isang bagong Virtual Host sa Nginx, pakibasa ito [ guideline](nginx-virtual-host.md).
-
-Patakbuhin ang command na ito sa isang terminal para ma-check kung lahat ay gumagana:
-
-```
-sudo nginx -t
-```
-
-Kung gayo, patakbuhin ang command upang muling simulan ang nginx server.
-
-```
-sudo service nginx restart
-```
-
-### 2. Idagdag ang RewriteBase path
-
-Buksan ang file /ESPOCRM_DIRECTORY/api/v1/.htaccess at palitan ang sumusunod na line:
-
-```
-# RewriteBase /
-```
-with
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-kung saan ang where REQUEST_URI are parte ng URL, e.g. for “http://example.com/espocrm/”, REQUEST_URI ay “espocrm”.
diff --git a/i18n/tl_PH/administration/nginx-virtual-host.md b/i18n/tl_PH/administration/nginx-virtual-host.md
deleted file mode 100644
index 13cbe4097..000000000
--- a/i18n/tl_PH/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Ang pag-konpigyura ng isang Virtual Host sa Nginx para sa EspoCRM
-
-Sa guide na ito, ipapakita namin kung paano i-konpigyura ang isang virtual na host sa Nginx para sa EspoCRM sa Ubuntu serber.
-
-## Lumikha ng isang serber block file
-
-Upang likhain ang file na ito, buksan ang isang terminal at patakbuhin ang command:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Ngayon ay buksan ang file na ito (/etc/nginx/sites-available/espocrm.conf) at baguhin ang code na sumusunod sa format na nakasulat sa ibaba (some settings may be different based on your configuration):
-
-```
-serber {
- listen 80;
- listen [::]:80;
-
- serber_name espocrm.local; # Palitan ang espocrm.local ng pangalan ng iyong domain
- root /var/www/html/espocrm; # Tukuyin ang iyong EspoCRM document root
-
- index index.php index.html index.htm;
-
- # configuration ng SSL
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # isama ang mga snippet/snakeoil.conf;
-
- # Tukuyin ang iyong PHP (php-cgi or php-fpm) batay sa iyong configuration
- lokasyon ~ \.php$ {
- isama ang mga snippet/fastcgi-php.conf;
-
- # Kasama ang php7.0-cgi lamang:
- # fastcgi_pass 127.0.0.1:9000;
-
- # Kasama ang php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Idagdag ang mga patakaran ng rewrite
- lokasyon / {
- try_files $uri $uri/ =404;
- }
-
- lokasyon /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- lokasyon ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- lokasyon ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- lokasyon ^~ /data/logs/ {
- deny all;
- }
- lokasyon ^~ /data/\.backup/ {
- deny all;
- }
- lokasyon ^~ /data/config.php {
- deny all;
- }
- lokasyon ^~ /data/cache/ {
- deny all;
- }
- lokasyon ^~ /data/upload/ {
- deny all;
- }
- lokasyon ^~ /application/ {
- deny all;
- }
- lokasyon ^~ /custom/ {
- deny all;
- }
- lokasyon ^~ /vendor/ {
- deny all;
- }
- lokasyon ~ /\.ht {
- deny all;
- }
-}
-```
-
-## I-enable ang server block
-
-Lumikha ng isang symbolic na link:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Patakbuhin ang command na ito para isigurado kung lahat ay maayos:
-
-```
-sudo nginx -t
-```
-
-At i-restart ang Nginx server:
-
-```
-sudo service nginx restart
-```
-
-## I-konpigyura ang iyong mga local host (opsyonal, para sa isang lokal na domain lamang)
-
-Kung nagdagdag ka ng isang lokal na domain, kailangan mong itong i-konpigyura sa iyong lokal na kompyuter (hindi sa iyong serber). Para sa Ubuntu, buksan ang file na `/etc/hosts` at idagdag ang linya na:
-
-```
-192.168.1.1 espocrm.local # tukuyin ang IP address ng iyong Nginx server
-```
-
-Para sa windows, mangyaring sunding ang ito [mga instruksyon](http://support.microsoft.com/kb/923947).
diff --git a/i18n/tl_PH/administration/portal.md b/i18n/tl_PH/administration/portal.md
deleted file mode 100644
index e1a2edc83..000000000
--- a/i18n/tl_PH/administration/portal.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Ang Portal
-
-Ang portal ay nagbibigay kakayahan na ma-access ang partikular na crm data at mga tungkulin para sa iyong mga kostomer at kasosyo. Ang administrador ay maaaring lumikha ng maramihang portal. Ang bawat portal ay maaaring magkaroon nga sarili nitong mga setting, dashboard, listahan ng user, mga access control setting.
-
-Upang lumikha ng portal ay sundin ang Administration > Portals, i-click ang buton ng Create Portal.
-
-* `Is Active`. Kung hindi naka-check, ang portal ay hindi magagamit ng kahit na sino.
-* `Is Default`. Nangangahulugang ang portal ay magagamit sa pamamagitan ng mas maikling url: http(s)://YOUR_ESPO_URL/portal.
-* `Roles`. Tumutukoy ng isa o maramihang mga tungkulin ng portal na ina-apply sa mga user na naka-log in sa portal. Karagdagang impormasyon tungkol sa mga tungkulin ng portal ay nasa ibaba.
-* `Tab List`. Ang mga tab na ipapakita sa navigation bar.
-* `Dashboard Layout`. Tumutukoy ng mga dashlet na idi-display sa home page ng portal. Tandaan na ang mga user ng portal ay hindi maaaring mag-configure ng kanilang dashboard.
-* `URL`. Read only field na nagdi-display ng link na maaari mong ma-access gamit ang portal.
-
-## Mga User ng Portal
-
-Ang mga administrador ay maaaring lumikha nga mga user ng portal.
-
-1. Administrasyon > Mga User.
-2. I-click ang dropdown sa kanan malapit sa Create User.
-3. I-click ang Create Portal User.
-4. Piliin ang contact na uugnayan ng portal user.
-5. Punan ang form at i-click ang save.
-
-Ang portal user ay dapat nakaugnay sa Portal record upang ma-access ang portal na iyon.
-
-## Mga Tungkulin ng Portal
-
-Ang mga tungkulin ng portal ay katulad ng regular na mga tungkulin sa EspoCRM ngunit may ilang mga pagkakaiba.
-
-* `not-set` lebel ay tumatanggi ng isang access.
-* `own` lebel ay nangangahulugang ang rekord ay nilikha ng user. E.g. ang portal user ay nag-case ng ilang mga kaso at ang kaso na ito ay pag-aari ng user.
-* `account` lebel ay nangangahulugang ang rekord ay nakaugnay sa account na may kaugnayan sa portal user.
-* `contact` lebel ay nangangahulugang ang rekord ay nakaugnay sa kontact na may kaugnayan sa portal user.
-
-Ang Assigned User at mga Teams field ay read only para sa mga portal user.
-
-### Halimbawa
-
-`Ang mga user ng portal ay dapat makagawa ng mga kaso, tingnan ang mga kaso na may kaugnayan sa kanilang mga account; dapat din nilang makita ang knowledge base.`
-
-1. Buksan ang form ng Create Portal Role (Administrasyon > mga tungkulin ng Portal > Create Role).
-2. I-enable ang access sa mga kaso, i-set ang: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. I-enable ang access sa Knowledge Base, i-set ang `create - no, read - account, edit - no, delete - no`.
-4. I-edit ang rekord ng iyong portal (Administration > mga Portal). Piliin ang mga tungkulin ng iyong portal sa Roles field at pagkatapos ay i-save.
-
-## Ang Access sa Portal
-
-Maaari mong makita ang url para sa iyong portal sa field ng 'URL' ng rekord ng portal. Posible ding gamitin ang mga tool ng server configuration (gaya ng mod_rewrite) upang ma-access ng ibang url. Para sa kasong ito ay kailangan mong punan ang field ng 'Custom URL'.
-
-### Ang Pag-access ng portal sa Pamamagitan ng Custom URL para sa Server ng Apache
-
-Custom na URL: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Mga Patakaran ng Mod rewrite
-
-Tukuyin ang portal record ID sa halip ng `{PORTAL_ID}`. Ang Portal record ID ay makikita sa address bar ng iyong web browser kapag binuksan mo ang detail view ng rekord ng iyong portal. Gaya ng: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 ay isang portal record id.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/tl_PH/administration/roles-management.md b/i18n/tl_PH/administration/roles-management.md
deleted file mode 100644
index c4d9b8c88..000000000
--- a/i18n/tl_PH/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Pamamahala ng mga Tungkulin
-
-## Pangkalahatang Ideya
-
-Upang mahadlangan ang access para sa ilang mga user, kailangan mong gumamit ng mga tungkulin. Ang administrador ay maaaring mamahala ng mga tungkulin sa Administration panel. Ang bawat tungkulin ay tumutukoy sa isang access ng ilang mga mga parte (mga scope) na inilalapat sa mga gumagamit na nagmamay-ari ng tungkulin na iyon.
-
-Ang isang user ay maaaring magkaroon ng maraming mga tungkulin. Ang mga tungukulin na iyon ay maaaring piliin para sa isang partikular na user (field ng ‘Roles’ sa User entry) at/o ay maaaring kunin mula sa mga pangkat kung saan nabibilang ang user.
-
-Kung ang user ay mayroong maraming tungkulin, ito ay pagsasama-samahin upang ang permissive rule ay magkakaroon ng mas mataas na priyoridad. Iyon ay nagbibigay-daan sa admnistrador na madaling pamahalaan ang access lebel kontrol.
-
-Posible ring makita ang mga permiso na i-aaply sa isang partikular na user sa pamamagitan ng pag-click ng 'Access'na buton sa detail view ng user.
-
-
-
-## Halimbawa
-
-Halimbawa, ang user ay kabilang sa grupo na ‘Sales’. Ang grupo ay mayroong isang tungkulin ‘Salesman’. Kaya lahat ng mga user sa grupo na itoy ay makakakuha ng ‘Salesman’ na tungkulin.
-
-‘Salesman’ na tungkulin ay tutukuyin sa sumusunod na paraan:
-
-Mga Lead:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Mga Oportunidad:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Ang mga user ay maaari lamang mag read only ng mga lead at oportunidad na iyon na kabilang sa grupo ng ‘Sales Department’ (‘Teams’ field).
-Ang user ay maaaring lamang mag-edit ng mga lead at mga oportunidad na itinalaga sa kanila o sa mga nilikha nila.
-Abg mga user ay hindi maaaring mag-alis nga mga lead at oportunidad.
-
-Gusto naming magbigay ng mas maraming karapatan sa isang partikular na user more rights to a certain user na may hawak ng posisyon ng sales manager sa kompanya. Ang empleyado na ito ay dapat mayroong kakayahan na magbasa/mag-edit/mag-alis nga mga rekord mula sa grupo ng ‘Sales’. Ang user ay dapat maging parte ng grupo ng ‘Sales’. Ngunit kailangan nating lumikha ng panibagong tungkulin na ‘Sales Manager’ at piliin ang tungkulin para sa user na iyon sa ‘Roles’ field.
-
-Ang tungkulin ng ‘Sales Manager’ role ay tinutukoy sa sumusunod na paraan:
-
-Ang Lead:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Ang Oportunidad:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Ang ating user ay maaaring mamahala sa lahat ng mga lead at oportunidad mula sa grupo ng ‘Sales’.
-
-## Mga Espesyal na Permiso
-
-### Ang Assignment na Permiso
-
-I-set ang parametro na ito upang hadlangan ang pag re-assign ng mga rekord sa ibang user at/o mga grupo. Kung ise-set mo ang `team` - posibleng magtakda ng mga user mula lamang sa sariling grupo. Kung `no` - ang mga user ay hindi maaaring mag re-assign sa anumang paraan.
-
-Ito rin ay tumutukoy kung ang user ay pwedeng magpost sa stream ng ibang mga user o grupo.
-
-### Permiso ng User
-
-Humahadlang sa mga user na mag-view ng mga actibidad, kalendaryo at stream ng iba pang mga user.
-
-### Permiso ng Portal
-
-Tumutukoy sa pag-access sa impormasyon ng portal at ang kakayahan na mag-post ng mga mensahe sa mga user ng portal.
-
-### Permiso ng Group Email Account
-
-Tumutukoy sa pag-access ng mga group email account, at kakayahang magpadala ng mga email mula sa group SMTP.
-
-### Permiso ng Pag-export
-
-tumutukoy kung ang user ay may kakayahang mag-export, ng mga rekord. (mula bersyon 4.9.0)
-
-## Mga Permiso Batay sa Default
-
-Batay sa default (kung walang naka-apply) ang mga user ay maaaring magbasa at mag-edit ng mga rekord. Ngunit hindi maaaring mag-delete ng kahit na ano maliban lamang doon sa nilikha nila at doon sa mga naka-assign na sa parehong oras.
-
-Mayroon din itong kakayahan na hadlangan ang pag-access na naka-apply na batay sa default sa pamamagitan ng pag-enable ng 'ACL Strict Mode' at Administration > Settings.
-
-## Seguridad ng Field Lebel
-
-Hinahayaang mag-kontrol ng pag-access para sa mga partiukar na mga filed.
-
-Batay sa default, ang user ay maaaring magbasa ng lahat ng mga filed kung ito ay makakapagbasa ng rekord. Ang user ay maaari ring mag-edit ng kahit na anong field kung ito ay makakapag-edit ng rekord. Maari mo ring hadlangan ang pag-access sa mga partikular na mga field gamit ang Field Level Security.
-
-Sa edit view ng isang role record sa seksyon ng Field lebel, i-click ang plus icon kasunod ng partikular na scope at piliin ang kinakailangang field. Pagkatapos ay maaari mo ng tukuyin ang access level para sa `read` at `edit` na mga aksyon. Mayroong dawalang mga opsyon: `yes` at `no`.
-
-
diff --git a/i18n/tl_PH/administration/server-configuration.md b/i18n/tl_PH/administration/server-configuration.md
deleted file mode 100644
index 2b0404d43..000000000
--- a/i18n/tl_PH/administration/server-configuration.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Ang Pag-configure ng Serber para sa EspoCRM
-
-Ang EspoCRM ay maaaring ma-install sa Apache ([mga instruksyon](apache-server-configuration.md)), sa Nginx ([mga instruksyon](nginx-server-configuration.md)), o IIS serber na may suporta na PHP bersyon 5.6 o higit pa at MySQL bersyon 5.1 o higit pa.
-
-## Mga Rekomendasyon sa Pag-configure
-
-### Mga Kailangan sa PHP
-
-Ang EspoCRM ay nangangailangan ng PHP 5.6 o higit pa, na mayroon ng sumusunod na mga ekstensiyon na naka-enable:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – sa pag-access ng MySQL sa PHP;
-* [JSON](http://php.net/manual/en/book.json.php) – ang mga resource ay gumagamit ng format na ito (metadata, layout, mga lengguwahe, at iba pa);
-* [GD](http://php.net/manual/en/book.image.php) – upang manipulahin ang mga imahe;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – upang matiyak ang pinakamataas na proteksyon;
-* [Zip](http://php.net/manual/en/book.zip.php) – upang ma-upgrade ang EspoCRM at ma-install ang mga ekstensiyon;
-* [IMAP](http://php.net/manual/en/book.imap.php) – upang ma-monitor ang mga mailbox sa EspoCRM;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Inirerekomenda din na magkaroon ng [mailparse](https://pecl.php.net/package/mailparse) pecl na ekstensiyon na naka-install. Ito ay kinakailangan para sa maayos na pagtakbo ng tampok na pag-fetch ng email.
-
-php.ini na mga setting:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### Mga Kinakailangan sa MySQL
-
-Ang EspoCRM ay sumusuporta sa MySQL bersyon 5.1 o higit pa.
-Walang mga ispesyal na kakaibhan. Lahat ng mga setting batay sa default ay angkop para sa EspoCRM.
-
-## Mga Kinakailangang mga Permiso para sa mga Unix-based System
-
-Ang mga file at direktoryo ay dapat may mga sumusunod na mga persmiso:
-
-* `/data`, `/custom`, `/client/custom` – ay dapat na writable, lahat ng mga file, direktoryo at subdirectory (664 para sa mga file, 775 para sa mga direktoryo, kabilang ang lahat ng mga subdirectory at file);
-* `/application/Espo/Modules`, `/client/modules` – ay dapat na writable, ang kasalukuyang direktoryo (775 para sa kasalukuyang direktoryo, 644 para sa mga file, 755 para sa mga direktoryo at subdirectory);
-* Ang lahat ng iba pang mga file at direktoryo ay dapat na madaling mabasa (644 para sa mga file, 755 para sa mga direktoryo).
-
-Upang i-set ang mga permiso, isagawa ang mga command na ito sa terminal:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Ang lahat ng mga file ay dapat pag-aari at group-owned ng proseso ng webserver. Maaari itong maging “www-data”, “daemon”, “apache”, “www”, etc.
-Tandaan: Sa Bitnami Stack, ang mga file ay dapat pag-aari at group-owned ng user ng “daemon”.
-Tandaan: Sa mga shared host, ang mga file ay dapat pag-aari at group-owned ng user account.
-
-Upang i-set ang may-ari at group-owner, isagawa ang mga command na ito sa terminal:
-
-```
-cd
-chown -R : .;
-```
-
-## Ang Pag-setup ng crontab
-
-Upang i-setup ang crontab sa isang UNIX system, gawin ang sumusunod ng mga step:
-
-* 1. Mag-login bilang administrador sa iyong EspoCRM instance.
-* 2. Pumunta sa seksyon ng mga naka-iskedyul nga mga gawain sa administrator panel (Menu > Administration > Scheduled Jobs) at kopyahin ang string para sa crontab. Mukhang gaya nito:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Buksan ang terminal at patakbuhin ang command na ito:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER ay maaaring maging isa sa mga sumusunod “www”, “www-data”, “apache”, etc (depende sa iyong webserver).
-* 4. I-paste ang kinopyang string (mula sa pangalawang hakbang) at i-save sa file ng crontab (Ctrl+O, pagkatapos ay Ctrl+X para sa nano editor).
-
-## Mga Instruksiyon sa Pag-configure base sa iyong serber:
-
-* [Apache server configuration](apache-server-configuration.md).
-* [Nginx server configuration](nginx-server-configuration.md).
diff --git a/i18n/tl_PH/administration/troubleshooting.md b/i18n/tl_PH/administration/troubleshooting.md
deleted file mode 100644
index 5bdceb515..000000000
--- a/i18n/tl_PH/administration/troubleshooting.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Pag-troubleshoot
-
-## Ang Pag-check ng mga log
-
-Upang malaman ang problema, kailangan mong suriin ang mga error ng log file.
-
-#### Mga log ng EspoCRM na mga Error
-
-Ang mga EspoCRM log ay matatagpuan sa `/logs/*.log` at naglalaman ng ilang mga impormasyon ng error.
-
-#### Mga log ng Apache na mga Error
-
-Para sa Ubuntu serber, ang isang log ng apache error ay matatagpuan sa `/var/log/apache2/error.log` at naglalaman ng lahat ng impormasyon ng error. Ang lokasyon ng mga log file ay maaaring hindi magkapareho sa iba pang mga system.
-
-## Pag-enable ng debugging mode
-
-Upang i-enable ang debugging mode, pumunta sa mga naka-install na direktorya ng EspoCRM, buksan ang file `data/config.php` at baguhin ang value:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-to
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Ang mga Naka-iskedyul na Gawain ay Hindi Gumagana
-
-#### Unang Problema: Ang iyong crontab ay hindi na-configure
-
-1. Mag-login sa pamamagitan ng SSH sa iyong serber.
-
-2. I-configure ang iyong crontab sa pamamagitan ng sumusunod na mga step: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-Tandaan: Ang Crontab ay dapat i-configure sa ilalim ng user ng web-server, e.g. `crontab -e -u www-data`.
-
-3. Maghintay ng ilang sandali at i-check ang mga naka-iskedyul na gawain upang makita kung ang anumang mga gawain ay naisakatuparan (tingnan ang Log panel).
-
-#### Pangalawang Problema. Ang Crontab ay naka-configure, pero ang mga naka-iskedyul na mga gawain ay hindi gumagana
-
-Upang masiguro na walang mga error kapag tumatakbo ang cron, subukang patakbuhin ang cron command sa isang terminal:
-
-1. Mag-login sa pamamagitan ng SSH sa iyong serber.
-
-2. Pumunta sa direktoryo kung saan naka-install ang EspoCRM. E.g. para sa `/var/www/html/espocrm` na direktoryo, ang command ay:
-
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Patakkbuhin ang crontab command:
-
-```bash
-php cron.php
-```
-
-Tandaan: Ito ay dapat isinasagawa sa ilalim ng user ng web-server. Kung ikaw ay naka-login bilang root, ang command ay dapat na (e.g para sa Ubuntu):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-kung saang ang `www-data` ay isang user ng web-server.
-
-4. Kung walang mga error, i-check ang mga naka-iskedyul na gawain upang makita kung ang anumang gawain ay naisakatuparan. (tingnan ang Log panel).
-
-## Ang EspoCRM ay hindi naglo-load pagkatapos mag-upgrade
-
-Ito ay maaaring mangyari minsan sa ilang mga shared hosting.
-
-I-check ang mga permiso ng mga file:
-/index.php
-/api/v1/index.php
-
-Dapat silang 644. Kung alinman sa mga file na iyon ang may permiso na 664, kailangan mong baguhin ito sa 644. Gamitin ang control panel o chmod command ng iyong hosting.
-
-```
-chmod 644 /path/to/file
-```
-Karagdagang impormasyon tungkol sa mg permiso ng file: [dito](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/tl_PH/administration/upgrading.md b/i18n/tl_PH/administration/upgrading.md
deleted file mode 100644
index e6e5f6350..000000000
--- a/i18n/tl_PH/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Paano mag-upgrade ng EspoCRM
-
-Ang EspoCRM ay maaaring ma-upgrade sa pinakabagong bersyon sa pamamagitan ng sumusunod na hakbang:
-
-### Unang Hakbang. I-check ang kasalukuyang bersyon
-
-Upang i-check ang iyong kasalukuyang bersyon, pumunta sa Administration > Upgrade na page.
-
-### Pangalawang Hakbang. I-download ang mga kinakailangang upgrade package
-
-Pumunta sa upgrade page https://www.espocrm.com/download/upgrades/ at base sa iyong kasalukuyang bersyon, i-download ang kinakailangang mga package.
-
-### Pangatlong Hakbang. Lumikha ng backup (optional)
-
-Lumikha ng backup ng iyong mga EspoCRM file at data bago mag-upgrade. Sundin [ang mga instruksiyon na ito](https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md) upang magawa ito.
-
-### Pang-apat na Hakbang. I-upgrade ang proseso
-
-Pumunta sa Administration > Upgrade. I-upload at i-install isa-isa ang mga upgrade package.
-
-Pwede mong i-check kung mayroon kang pinakabagong bersyon sa Menu > About.
-
-## Pag-upgrade sa Pamamagitan ng CLI
-
-Pwede ka rin mag-upgrade sa pamamagitan ng command line interface. Kailangan mong isagawa ang mga sumusunod na command mula sa ESpoCRM root directory:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/tl_PH/administration/workflows.md b/i18n/tl_PH/administration/workflows.md
deleted file mode 100644
index ebd4981f5..000000000
--- a/i18n/tl_PH/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# Mga Workflow
-
-Ang tampok na mga Workflow ay makukuka sa [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Ang mga Workflow ay nag-aawtomeyt ng iyong proseso sa negosyo sa madaling paraan. Makikita mo ito sa Administration panel. Upang lumikha ng patakaran ng workflow, kailangan mong liwanagin ang:
-
-* Target Entity - kung anong entity type workflow ang i-aaply;
-* Uri ng Trigger - kung kailan paaandarin ang workflow;
-* Mga kondisyon - ang mga kondisyon ay dapat matugunan upang paandarin ang workflow;
-* Mga Aksyon - ang mga kailangan gawin kung ang workflow ay napa-andar na.
-
-
-## Mga Uri ng Paandar
-
-### Pagkatapos na Likhain ang Rekord
-
-Umaandar lamang kapag ang isang bagong rekord ay nilikha. Kung ang mga tinukoy na mga kondisyon ay natugunan, ang mga aksyon ay maisasakatuparan.
-
-### Pagkatapos na i-save ang rekord
-
-Umaandar lamang kapag ang isang bagong rekord ay nilikha o ang kasalukuyang rekord ay na-update. Kung ang mga tinukoy na mga kondisyon ay natugunan, ang mga aksyon ay maisasakatuparan.
-
-Para sa mga patakaran ng workflow na maayroong ganitong klaseng paandar, nakagawian na na kailanganin ang isang kondisyon upang ma-check kung may ilang mga field na 'nabago'. E.g. Kung ang estado ng kaso ay nabago, saka isagawa ang ilang mga aksyon.
-
-### Nakaiskedyul
-
-Pinapaandar ayon sa naitukoy na pag-iiskedyul. Maaari mo itong i-setup na patakbuhin araw-araw,bawat lingo, atbp. Ang mga aksyon ay i-aaply para sa mga rekord na ibinalik ng isang partikular na list report. Kaya kailangan mo ring lumikha ng isang list report.
-
-Ang pag-iiskedyul ay tinutukoy sa isang notasyon ng crontab.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### Sekwensyal
-
-Bihirang ginagamit. Dapat na pinapatakbo ng isa pang workflow. Nagbibigay kakayahang gumawa ng kumplikadong lohika.
-
-Tandaan: Para sa mga workflow na sunud-sunod, inirerekomenda na gumamit ng [BPM tool](bpm.md) sa halip ng isang Workflows feature.
-
-## Mga Kondisyon
-
-Maaari mong detreminahin ang mga kondisyon na dapat matugunan upang mapaandar ang workflow. Mayroong dalawang paraan kung saan ang mga kondisyon ay maaaring matukoy: sa pamamagitan ng UI condition builder at ng formula.
-
-### UI condition builder
-
-Ilang magagamit na mga uri ng kondisyon:
-
-* _equals_ - ang field ay katumbas ng tiyak na halaga o isang halaga ng ibang field;
-* _was equal_ - ang field ay katumbas ng tiyak na halaga bago pa napaandar ang workflow;
-* _not equals_ - ang field ay hindi katumbas ng tiyak na halaga o isang halaga ng ibang field;
-* _was not equal_ - ang field ay hindi katumbas ng tiyak na halaga bago pa napaandar ang workflow;
-* _empty_ - ang halaga ng field ay walang laman;
-* _not empty_ - ang halaga ng field ay hind bakante;
-* _changed_ - ang field ay binago;
-* _not changed_ - ang field ay hindi binago.
-
-### Mga Kondisyon ng Pormula
-
-Ang pormula ay nagbibigay kakayahang determinahin ang mga kondisyon ng anumang pagiging kumplikado. Upang basahin ang tungkol sa syntax ng pormula, sundin [ang artikulo na ito](formula.md).
-
-Tandaan: Hindi dapat magkaroon ng anumang `;` delimiter na ginagamit sa code ng pormula kapag tumutukoy ito sa isang kondisyon.
-
-## Mga Aksyon
-
-### Pagpapadala ng Email
-
-Ang system ay magpapadala ng isang email gamit ang isang tiyak na template ng email. Ang email address ng tatanggap ay maaaring kunin mula sa target na rekord, anumang kaugnay na rekord, ang kasalukuyang user, mga follower, mga team user o tinukoy. Ang email ay maaaring ipadala kaagad o para sa isang tiyak na periyod.
-
-### Paglikha ng Rekord
-
-Ang system ang lilikha ng panibagong rekord ng anumang uri ng entity. Kung mayroong koneksyon sa pagitan ng target na rekord at ng rekord na nilikha, posible na mag-ugnay ng mga rekord.
-
-Mayroong kakayahang tukuyin ang pormula upang kalkulahin ang mga field.
-
-### Paglikha ng Kaugnay na Rekord
-
-Ang system ang lilikha ng rekord na may kaugnayan sa target na rekord. Posible na matukoy ang pormula upang ma-kalkula ang mga field.
-
-### Pag-update ng Target na Rekord
-
-Nagpapahintulot sa pagbabago ng mga tiyak na field ng target na rekord. Posible na matukoy ang pormula upang ma-kalkula ang mga field.
-
-Kung kailangan mong magdagdag ng mga bagong item sa Link-Multiple field nang hindi nawawalan ng mga kasalukuyang datos, (hal. mga Team) kailangan mong gamitin ang pormula function na entity\addLinkMultipleId. Halimbawa: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### Pag-update ng mga Kaugnay na Rekord
-
-Nagpapahintulot sa pagbabago ng mga tiyak na mga field ng kaugnay na rekord o mga rekord. Posible na matukoy ang pormula upang ma-kalkula ang mga field.
-
-### Pag-link sa Ibang Rekord
-
-Iniuugnay ang target entity na may isa pang partikular na entity. E.g. Nagdadagdag ng partikular na team sa rekord.
-
-### Pag-unlink sa Ibang Rekord
-
-Nagtatanggal ng kaugnayan ng target entity mula sa isang partikular na entity. E.g. Nagtatanggal ng partikular na team mula sa rekord.
-
-### Pag-apply ng Patakaran ng Pagtatalaga
-
-Magtalaga ng target na rekord sa user sa pamamagitan ng patakaran ng distribusyon. Mayroong dalawang magagamit na patakaran: Round-Robin at Least-Busy.
-
-* Round-Robin - ang mga user ay pinipili mula sa itaas hanggang sa ibaba ng isang listahan (team) at pagkatapos ay magsisimula muli.
-* Least-Busy - ang user na may mas kaunting itinalagang mga rekord ay pipiliin para sa pagtatalaga.
-
-_List Report_ - Para sa distribusyon ng Least-Busy, tinutukoy kung anong mga rekord ang isasaalang-alang upang kalkulahin ang bilang nga mga nakatalagang mga rekord. E.g. para sa mga kaso ay kailangang kunin lamang ang mga rekord na may aktibong status.
-
-### Paglikha ng Notipikasyon
-
-Nag-aabiso sa mga partikular na mga user sa pamamagitan ng mensahe. Posible na gumamit ng mga placeholder sa mga template ng mensahe: {entity} - target na rekord, {user} - kasalukuyang user.
-
-### Make Followed
-
-Pinipilit ang mga partikular na nga mga user na sundin ang target entity o partikular na kaugnay na entity.
-
-### Pagpapa-andar ng Ibang Workflow
-
-Ay nagbibigay-daan upang gumawa ng mga sequential workflow. Posible na pagsanga-sangahin ang sequential workflow sa pamamagitan ng kondisyon: pwede mong i-setup ang workflow para paandarin ang dalawang workflow na mayroong magkaibang mga kondisyon na natukoy sa nasabing workflow.
-
-Posible din ang pagpapaliban ng pagsasagawa ng sequential workflow. Sa sequential wokflow, maaari mong tukuyin ang kondisyon na nagche-check kung ang mga partikular na mga field ay binago pagkat ang parent workflow ay napaandar na sa pamamagitan ng paggamit ng _Changed_ and _Was Equal_ na mga uri ng kondisyon.
-
-Tandaan: Para sa mga sequential workflow, inirerekomenda na gamitin ang [BPM tool](bpm.md) sa halip na Workflows feature.
-
-### Pagpapatakbo ng Service Action
-
-Ay nagbibigay daan na patakbuhin ang mga partikular na service script. Batay sa default, may mga sumusunod na mga aksyon na magagamit:
-
-* Pagpapadala ng mga imbitasyon - para sa mga miting/tawag;
-* Pagdagdag ng mga Quote Item - para sa mga Quote.
-
-Ang mga developer ay maaaring magsulat ng sariling mga service action. Tingnan [karagdagang detalye](../development/workflow-service-actions.md).
-
-## Paggamit ng mga Pormula sa mga Aksyon
-
-Posibleng tukuyin ang pormula upang kalkulahin ang mga field para sa Create Rekord, Update Target Rekord, Create Related Rekord, Update Related Rekord. Para sa huling dalawa, upang ma-access ang mga katangian ng target entity dapat mong gamitin ang function na `targetEntity\attribute`. Para ma-access ang mga katangian ng target entity na na-iset bago pinaandar ang workflow, gamitin ang function na `targetEntity\attributeFetched`.
-
-Halimbawa:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/tl_PH/development/api.md b/i18n/tl_PH/development/api.md
deleted file mode 100644
index a95c4a4bf..000000000
--- a/i18n/tl_PH/development/api.md
+++ /dev/null
@@ -1,224 +0,0 @@
-# Ang REST API
-
-Ang EspoCRM ay isang solong page application kaya ang frontend ay gagamit ng REST API upang kumonekta sa isang backend.
-
-Lahat ng mga operasyon na iyong isasagawa gamit ang UI ay maaari mong gawin sa pamamagitan ng mga API call gamit ang iyong lengguwahe ng iyong programa.
-Maaari mong matutunan kung paano gumagana ang API kung susubaybayan mo kung ano ang nangyayari sa network tab sa iyong browser console.
-
-Karamihan sa mga function ng API ay bumabalik bilang JSON. Ang mga POST, PATCH call ay kadalasang nangangailang ng ilang datos ng JSON sa payload.
-
-Ang base URL ng EspoCRM API ay: `api/v1/`. Kailangan mo itong i-prepend sa mga ekspresyon sa reference na ito. Halimbawa:
-
-`GET http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Pagpapatunay
-
-Ang EspoCRM API ay gumagamit ng [Basic na Awtentikasyon](http://en.wikipedia.org/wiki/Basic_access_authentication). Ang username at password/token ay dumadaan sa `Authorization` na header na naka-encode sa base64.
-
-`"Authorization: Basic " + base64Encode(username + ':' + password)`
-
-
-Mas mabuting gamitin ang auth token sa halip na password kapag nagtatrabaho ka sa api. Sa kasong ito, kailangan mong magbigay ng username at password/token sa `Espo-Authorization` header.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-
-1. Kumuha ng access token sa pamamagitan ng `GET App/user` request kasama ang username at password na dumadaan sa `Espo-Authorization` header.
-2. Gamitin ang token na ito sa halip na password sa `Espo-Authorization` header sa lahat ng mga karagdagang mga request.
-3. Kung ang request ay bumabalik bilang 403 error, ito ay nangangahulugang ang alinman sa username/password ay mali o ang token ay hindi na balido.
-
-#### Ang Token ng Authentication / User Specific Data
-
-`GET App/user`
-
-Nababalik bilang:
-
-* `token` - access token na gagamitin;
-* `acl` - impormasyon tungkol sa acccess ng user;
-* `preferences` - mga kagustuhan ng user;
-* `user` - mga katangian ng user na rekord.
-
-
-## Mga Operasyon na CRUD
-
-#### Mga List Entity
-
-`GET {entityType}`
-
-Mga parameter ng GET:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) maximum na sukat;
-* `where` - (array) mga filter;
-* `sortBy` - (string) ang field na pwedeng mag-sort ayon sa;
-* `asc` - (bool) direksyon ng sort.
-
-_Halimbawa_
-
-`GET Account?offset=0&maxSize=20`
-
-Nagbabalik ng:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Ang Read Entity
-
-`GET {entityType}/{id}`
-
-Nagbabalik ng mga katangian bilang JSON object.
-
-_Halimbawa_
-
-`GET Account/5564764442a6d024c`
-
-#### Paglikha ng Entity
-
-`POST {entityType}`
-
-Payload: Ang object ng katangian ng mga entity.
-
-Nagbabalik ng mga katangian ng entity sa JSON object.
-
-_Halimbawa_
-
-`POST Account`
-
-Payload:
-```
-{
- "name": "Test",
- "assignedUserId": "1"
-}
-```
-
-#### Ang Pag-update ng Entity
-
-`PATCH {entityType}/{id}`
-
-o
-
-`PUT {entityType}/{id}`
-
-Payload: Ang object ng mga katangian ng entity ay kailangang baguhin.
-
-Nagbabalik ng mga katangian sa JSON object.
-
-_Halimbawa_
-
-`PATCH Account/5564764442a6d024c`
-
-Payload:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Ang Pag-tanggal ng Entity
-
-`DELETE {entityType}/{id}`
-
-_Halimbawa_
-
-`DELETE Account/5564764442a6d024c`
-
-
-## Mga Kaugnay na Entity
-
-#### Pag-lista nga mga Entity
-
-`GET {entityType}/{id}/{link}`
-
-* `offset` - (int) offset;
-* `maxSize` - (int) maximum na sukat;
-* `where` - (array) mga filter;
-* `sortBy` - (string) ang field na pwedeng mag-sort ayon sa;
-* `asc` - (bool) ang direksyon ng sort.
-
-_Halimbawa_
-
-`GET Account/5564764442a6d024c/opportunities`
-
-Nagbabalik ng:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Pag-link ng Entity
-
-`POST {entityType}/{id}/{link}`
-
-Ang Payload:
-
-1. `id` katangian.
-2. `ids` array na katangian.
-3. `"massRelate": true` at `"where": {...}` nag-uugnay ng mga maraming rekord ayon sa mga search criteria.
-
-_Halimbawa_
-
-`POST Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Ang Pag-unlink ng Entity
-
-`DELETE {entityType}/{id}/{link}`
-
-Ang Payload:
-
-1. JSON na may `id` na katangian.
-2. JSON na may `ids` array na katangian.
-
-_Halimbawa_
-
-`DELETE Account/5564764442a6d024c/opportunities`
-
-Ang Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-## Pag-stream
-
-#### Pag-lista nga mga entry ng stream para sa kasalukuyang user
-
-`GET Stream`
-
-Kumuha ng mga parameter:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) maximum na sukat;
-
-#### Pag-lista ng mga entry ng stream na may kaugnayan sa isang partickular na rekord
-
-`GET {entityType}/{id}/stream`
-
-Kumuha ng mga parameter:
-
-* `offset` - (int) offset;
-* `maxSize` - (int) maximum na bilang;
-
-#### Pag-follow na rekord
-
-`PUT {entityType}/{id}/subscription`
-
-#### Pag-unfollow na rekord
-
-`DELETE {entityType}/{id}/subscription`
-
-
-
diff --git a/i18n/tl_PH/development/custom-field-type.md b/i18n/tl_PH/development/custom-field-type.md
deleted file mode 100644
index e6b295b0b..000000000
--- a/i18n/tl_PH/development/custom-field-type.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Pag-likha ng uri ng Kustom na Field
-
-### Depinisyon ng Field
-
-Lumika ng isang file `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` na may mga kinakailangang parameter.
-```
-{
- "view": "custom:views/fields/{field-type}"`
-}
-```
-
-Gamitin ang mga uri ng out-of-the-box field bilang mga halimbawa: `/application/Espo/Resources/metadata/fields`.
-
-### Pagsasalin
-
-Ang label na ginagamit sa Entity Manager ay maaaring ma-set sa `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` sa seksyon ng `fieldTypes`.
-Kung kailangan mong magdagdag ng pagsasalin sa ibang lengguwahe, gamitin ang kinakailangang lengguwahe [code ng lengguwahe](https://en.wikipedia.org/wiki/ISO_639-1)_[country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) sa halip na `en_US`. Sa `data/config.php` sa seksyon ng `languageList` maaari mong makita ang listahan ng mga kasama na lengguwahe.
-
-### Pag-view
-
-Lumikha ng view para sa field `client/custom/src/views/fields/{field-type}.js` at tukuyin ang mga template nito.
-```
-Espo.define('custom:views/fields/[field-type]', 'views/fields/base', function (Dep) {
-
- return Dep.extend({
-
- });
-});
-```
-
-Gamitin ang mga out-of-the-box na uri ng field bilang mga halimbawa:
-- `/client/src/views/fields` - mga view;
-- `/client/res/templates/fields` - mga template.
-
-Pagkatapos ay kailangan mong patakbhuin ang rebuild sa administration panel.
diff --git a/i18n/tl_PH/development/custom-views.md b/i18n/tl_PH/development/custom-views.md
deleted file mode 100644
index a463c2475..000000000
--- a/i18n/tl_PH/development/custom-views.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Mga Kustom na View
-
-## Mga Record View
-
-Ang framework ng EspoCRM ay nagbibigay ng mga kakayahan na madaling iakma para matukoy ang mga kustom view para sa mga partikular na uri ng entity. Dapat silang tukuyin bilang `clientDefs` na kategorya ng metadata.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-Ang rekord/detail view ay naglalaman ng lahat ng mga panel na may mga field, mga kaugnayan at ibang pang datos na makikita mo sa detail view. Hindi ito naglalaman ng header at mga buton sa tuktok na kanang sulok.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Here is your custom template. Omit if you don't need it.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Here is your custom view. Omit if you don't need it.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Here is your custom view. Omit if you don't need it.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Here is your custom view. Omit if you don't need it.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Custom initalization logic here. Like binding listening to model changes.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Custom code to be invoked right after rendering, when DOM is avaiable.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-Maaari kang lumikha ng isang kustom na template kasama ang sumusunod na path:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-Ang detail view ay naglalaman ng Rekord/Detail view at Header.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-Kagaya ng detail pero ito ay ginagamit kung ang rekord ay nililikha o ini-edit na hindi sa inline-edit na mode.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-Ang list view ay naglalaman ng Rekord/List view, Header at Search Form View.
-
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-Ang List/Rekord view ay naglalaman ng mga hanay ng rekord.
-
-
-Karapat-dapat na banggitin na kailangan mong ma-inherit ang iyong klase ng view mula sa partikular na klase para sa iyong entity kung mayroon na nito.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Mga Field View
-
-Ang mga kustom view para sa mga partikular na field ay dapat na matukoy sa entityDefs na seksyon ng metadata.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
-
diff --git a/i18n/tl_PH/development/dynamic-forms.md b/i18n/tl_PH/development/dynamic-forms.md
deleted file mode 100644
index e492c5849..000000000
--- a/i18n/tl_PH/development/dynamic-forms.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# Dynamic na mga form
-
-Tandaan: Mula sa bersyon na 4.3.0 posible ng tukuyin ang dynamic na form sa pamamagitan ng UI ng admin sa Entity Manager.
-
-Mayroon itong kakayahan na tukuyin ang form behavior sa EspoCRM.
-
-## Halimbawa
-
-> Kailangan ipakita ang _nextStep_ field sa isang Opportunity detail view lamang kung ang yugto ay 'Closed Won'.
->
-
-Pag-likha ng file `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Ito ay nangangahulugang ang _nextStep_ na field ay itatago batay sa default at ipapakita kung ang yugto ay katumbas na ng 'Closed Won'.
-
-Ang listahan ng mga magagamit na mga aksyon: `show`, `hide`, `setRequired`, `setNotRequired`.
-
-Mayroon itong kakayahan na itago/ipakita ang mga panel. Tukuyin ang pangalan ng mga panel sa `panels`, ipagpalagay ito sa parehong paraan ng `fields`.
diff --git a/i18n/tl_PH/development/extension-packages.md b/i18n/tl_PH/development/extension-packages.md
deleted file mode 100644
index 1bc2561be..000000000
--- a/i18n/tl_PH/development/extension-packages.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Mga Pakete ng Ekstensiyon
-
-Ang mga ekstensiyon ay nagbibigay ng karagdagang kakayahan para sa EspoCRM. Maaari itong ma-install sa pamamagitan ng Administration panel sa ilalim ng seksyon ng `Customization`.
-
-## Kung Paano Gumawa ng Isang Pakete ng Ektensiyon
-
-Isang Istraktura ng file ng pakete:
-
-* `/manifest.json` – isang file na naglalaman ng mga katangian ng ekstensiyon;
-* `/files` – isang direktoryo na naglalaman ng mga file ng ekstensiyon;
-* `/scripts` – naglalaman ng mga script ng ekstensiyon.
-
-### Manipesto
-```json
-{
- "name": "Extension Name",
- "version": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "author": "Your Name",
- "description": "Description of your extension",
- "delete": []
-}
-```
-
-* Syntax ng `version` at `acceptableVersions` ay inilalarawan ng v2.0.0 espesipikasyon na makikita sa http://semver.org.
-* `delete` - ay ang listahan ng mga core file na kailangang tanggalin. Ang parameter na ito ay hindi inirerekomendang gamitin. Maaari mo itong laktawan.
-
-### Mga File
-
-Ang lahat ng file ng ekstensiyon ay dapat ilagay sa direktoryo ng mga `files`. Sila ay makokopya sa EspoCRM core na direktoryo.
-
-### Mga Script
-
-Para sa iba't ibang mga layunin, ang EspoCRM ay sumusuporta sa mga sumusunod na uri ng mga script. Ang lahat ng mga ito ay dapat ilagay sa direktoryo ng mga `scripts`.
-
-* `BeforeInstall.php` – isang script na dapat isinasagawa bago pa ang proseso ng pag-install;
-* `AfterInstall.php` – isinasagawa kapag ang proseso ng pag-install ay natapos na;
-* `BeforeUninstall.php` – isinasagawa bago pa ang proseso ng pag-uninstall;
-* `AfterUninstall.php` – isinasagawa kapag ang proseso ng pag-uninstall ay natapos na.
-
-Halimbawa:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Packete
-
-Sa dulo, kailangan nating i-pack ang lahat ng mga file na ito sa archive na .zip.
diff --git a/i18n/tl_PH/development/hooks.md b/i18n/tl_PH/development/hooks.md
deleted file mode 100644
index 789973aad..000000000
--- a/i18n/tl_PH/development/hooks.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Mga Hook
-
-## Gumawa ng Hook
-Upang lumikha ng hook, kailangan mo:
-- lumikha ng isang file `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- ideklara ang hook type action;
-- burahin ang Cache sa Administrasyon.
-
-## Mga Uri ng Hook
-
-Ang mga pangunahing uri ng hook ay:
-
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove;
-- afterRelate;
-- afterUnrelate;
-- afterMassRelate.
-
-### Panibagong Uri ng Hook
-Maaari mong gamitin ang iyong sariling uri ng hook at simulan ito sa pamamagitan ng
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Pagkakasunud-sunod ng Hook
-Kung mayroon kang ilang mga hook, na may kaugnayan sa isang Entity Type at at may parehong uri ng hook, at ang pagpapatakbo ng order ay mahalaga, maaari kang magtakda ng isang `public static $order` na katangian sa isang integer value.
-
-Pataas na order - ang hook na may pinakamaliit na numero ng order ang unang tatakbo.
-
-## Halimbawa
-Ang halimbawa na ito ay nagtatakda ng pangalan ng Account para sa mga bagong Lead, kung hindi ito naka-set.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-use Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Mga Global Hook
-Kung kailangan mong mag-apply ng hook para sa lahat nga mga entity, maaari mong gamitin ang karaniwang mga hook. Upang gawin ito, ilagay ang klase ng iyong hook sa Karaniwang direktoryo, e.g. `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/tl_PH/development/how-to-create-a-dashlet.md b/i18n/tl_PH/development/how-to-create-a-dashlet.md
deleted file mode 100644
index 4f99705c8..000000000
--- a/i18n/tl_PH/development/how-to-create-a-dashlet.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Paano Gumawa ng Dashlet
-
-Lumikha ng isang file `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` gamit ang conpigyurasyon ng iyong dashlet.
-
-Dito ay kailangan mong tukuyin ang `"view"`, at maaari mong itakda ang `"aclScope"`, `"entityType"`, at `"options"`.
-
-Kung ito ay karaniwang listahan ng dashlet, gamitin ang `"view":"views/dashlets/abstract/record-list"`, kung hindi, lumikha ng sariing view (https://github.com/espocrm/documentation/blob/master/development/custom-views.md).
-
-## Mga Opsyon
-Batay sa default sa mga opsyon ng dashlet, maaari mong itakda ang _Title_ at _Auto-refresh Interval_.
-
-Ang mga karagdagang opsyon ng mga field ay maaari mong itakda sa `"options"` > `"fields"`.
-
-Upang tukuyin ang posisyon ng ng mga field, itakda ang layout sa `"options"` > `"layout"` > `"rows"`
-
-Maaari mo ring tukuyin ang iba pang mga opsyon, kung ang iyong view ay nangangailangan pa ng mas maraming datos.
-
-## Halimbawa
-
-`application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json`
-
-```
-{
- "view":"views/dashlets/abstract/record-list",
- "aclScope": "Case",
- "entityType": "Case",
- "options": {
- "fields": {
- "title": {
- "type": "varchar",
- "required": true
- },
- "autorefreshInterval": {
- "type": "enumFloat",
- "options": [0, 0.5, 1, 2, 5, 10]
- },
- "displayRecords": {
- "type": "enumInt",
- "options": [3,4,5,10,15]
- },
- "expandedLayout": {
- "type": "base",
- "view": "views/dashlets/fields/records/expanded-layout"
- }
- },
- "defaults": {
- "sortBy": "createdAt",
- "asc": false,
- "displayRecords": 5,
- "expandedLayout": {
- "rows": [
- [
- {
- "name": "number"
- },
- {
- "name": "name",
- "link": true
- },
- {
- "name": "type"
- }
- ],
- [
- {
- "name": "status"
- },
- {
- "name": "priority"
- }
- ]
- ]
- },
- "searchData": {
- "bool": {
- "onlyMy": true
- },
- "primary": "open"
- }
- },
- "layout": [
- {
- "rows": [
- [
- {"name": "title"}
- ],
- [
- {"name": "displayRecords"},
- {"name": "autorefreshInterval"}
- ],
- [
- {"name": "expandedLayout"},
- false
- ]
- ]
- }
- ]
- }
-}
-```
-May makikita kang ilang halimbawa dito `application/Espo/Modules/Crm/Resources/metadata/dashlets`.
-
-## Ang Pagsasalin
-
-Ang pagsasalin sa dashlet ay nasa `Global` na scope, sa seksyon ng `"dashlets"`.
-
-__Pagkatapos ng lahat, huwag kalimutan na burahin ang Cache sa Administrasyon.__
diff --git a/i18n/tl_PH/development/link-multiple-with-primary.md b/i18n/tl_PH/development/link-multiple-with-primary.md
deleted file mode 100644
index fc78ebf98..000000000
--- a/i18n/tl_PH/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Ang Pag-uugnay ng Maramihang field sa Primarya
-
-~Para sa EspoCRM 3.6.0 at higit pa.~
-
-Minsan mayroong kang `hasMany` na kaugnayan at kailangan mong magkaroon ng kakayahan na pumili ng pangunahing rekord sa mga nauugnay. Bilang halimbawa, ang field ng `Contacts` Case entity.
-
->Kailangang gumawa ng `contacts` linkMultiple na field kasama ang isang primarya para sa ating custom entity na `Stock`.
->
-
-###Unang Hakbang
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-###Pangalawang Hakbang
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-###Pangatlong Hakbang
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-###Pang-apat na Hakbang
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-###Pang-limang Hakbang
-Patakbuhin ang Rebuild
-
-###Pang-anim na Hakbang
-Isagawa ang SQL na query
-```sql
-UPDATE stock
-JOIN contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
-
diff --git a/i18n/tl_PH/development/metadata.md b/i18n/tl_PH/development/metadata.md
deleted file mode 100644
index c540b02e3..000000000
--- a/i18n/tl_PH/development/metadata.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Ang Metadata
-
-Ang metadata ay para sa: pagtatago ng system data gaya ng mga field ng entity at mga kaugnayan; pagtukoy ng mga frontend controller, view, panel; pagtakda ng mga field, dashlet; at iba pang mga datos na kinakailangan para sa applikasyon.
-
-
-## Kung Paano Ma-access
-
-#### Backend
-
-Ang object ng metadata ng `Espo\Core\Utils\Metadata` na klase ay maaaring ma-access mula sa lalagyan. Ang path sa isang kinakailangang parametro ay tinutukoy gamit ang mga tuldok `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-will return `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-will return an associative array of all fields.
-
-#### Frontend
-
-Ang object ng metadata ay naa-access mula sa lahat ng mga view object sa pamamagitan ng pamamaraan ng `#getMetadata`. Ito ay gumagana sa parehong paraan ng backend.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## Paano ito Tinatago
-
-Ang metadata ay tinatago sa mga file ng JSON na matatagpuan sa iba't ibang lugar:
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-Kapag na-access mo ang data sa pamamagitan ng path na `clientDefs.Account.views.edit` ang unang lexeme `clientDefs` ay tumutugon sa pangalan ng dir, ang pangalawa sa `Account` sa pangalan ng file na `Account.json`. Ang lahat ng sumusunod na mga lexeme ay tumutugon sa path sa JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-Ang lahat ng JSON file mula sa mga direktoryo na ito ay pinag-samasama sa rekursibong pamamaraan sa isang solong php array at nakatago sa isang cache file
-
-
-## Pagpapalawig
-
-Pagkat ang metadata ay pinag-samasama sa rekursibong pamamaraan maaari mong madaling tukuyin muli ang mga json object at array sa _custom_ at sa iyong _module_. Gayundin maaari kang magdagdag sa mga kasalukuyang array sa pamamagitan ng paggamit ng `__APPEND__` (mula bersyon 2.6.0) bilang unang elemento ng array.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/tl_PH/development/new-function-in-formula.md b/i18n/tl_PH/development/new-function-in-formula.md
deleted file mode 100644
index 73159db05..000000000
--- a/i18n/tl_PH/development/new-function-in-formula.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Pagtukoy sa mga Bagong Function para sa Pormula
-
-Ang EspoCRM nagbibigay ng posibilidad na lumikha ng mga kustom na function na maaaring magamit sa pormula.
-
-Kung ang iyong function ay may kaugnayan sa isa sa mga grupo tulad ng String, Lohika, Petsa, lumikha ng isang file sa __{GroupName}Group__ na polder, na nagngagalan ng __{FunctionName}Type.php__ kasama ng __{FunctionName}Type__ deklarasyon ng klase. Kailangan mong tukuyin ang pamamaraan na __'process'__.
-
-Halimbawa, gumawa tayo ng bagong string na function para sa pagsusuri kung ang isang string (HAYSTACK) ay naglalaman ng isa pang string (NEEDLE) na may posibleng offset (OFFSET).
-
-Lumikha ng isang file na `application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` na may code na:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-use \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Pagdagdag ng function sa listahan
-
-Upang idagdag ang nilikhang function sa listahan ng function ng pormula, lumikha ng isang file na `custom/Espo/Custom/Resources/metadata/app/formula.json` at idagdag ang code na:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Burahin ang cache__ at gamitin ang function na ito sa pormula. Maaari mo itong i-type `string\contains(HAYSTACK, NEEDLE, OFFSET)` o pumili mula sa listahan ng function, kung idagdag mo ito.
-
diff --git a/i18n/tl_PH/development/orm.md b/i18n/tl_PH/development/orm.md
deleted file mode 100644
index d06450ac0..000000000
--- a/i18n/tl_PH/development/orm.md
+++ /dev/null
@@ -1,227 +0,0 @@
-# Ang ORM, Paano pamahalaan ang mga entity at magsagawa ng mga query
-
-Ang EspoCRM ay mayroong built-in na sariling ORM (Object-relational na pagmamapa). Napakadaling lumikha, mag-update, magbasa, magtanggal at maghanap ng mga entity. Ang lahat ng mga operasyong ito ay magagamit sa pamamagitan ng EntityManager object. Ang EntityManager ay makikita sa mga record Service sa pamamagitan ng pamamaraan ng `#getEntityManager()`.
-
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Paglikha ng Bagong Entity
-```php
-$account = $entityManager->getEntity('Account')
-```
-or
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Pagkuha ng existing
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-or
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Pagkuha value
-```php
-$fieldValue = $account->get('fieldName');
-```
-
-#### Mayroong value
-```php
-$fieldNameIsSet = $account->has('fieldName'); // true or false
-```
-
-#### Pagtakda ng value
-```php
-$account->set('fieldName', 'Test Account');
-```
-
-```php
-$account->set(array(
- 'name' => 'Test Account',
- 'assignedUserId' => '1'
-));
-```
-
-#### Pag-istore
-```php
-$entityManager->saveEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Pagtanggal
-```php
-$entityManager->removeEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Paghanap
-```php
-$accountList = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer'
-])->find();
-```
-
-Descending order:
-
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', true)->find();
-```
-
-Ascending order:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt')->find();
-```
-
-or:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', 'DESC')->find();
-```
-
-#### Paghanap ng pinakauna
-```php
-$account = $entityManager->getRepository('Account')->where([
- 'type' => 'Customer',
-])->findOne();
-```
-
-#### Paghanap ng kaugnay
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
-```
-
-#### Mga Kaugnay na Entity
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
-```
-
-#### Pag-unrelate ng mga entity
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
-```
-
-### Pagpili ng mga parametro ng Query
-
-#### Kung Saan ang Clause ay
-
-##### Mga Operator ng Paghahambing
-
-Suportadong mga operator ng paghahambing: `>`, `<`, `>=`, `<=`, `=`, `!=`.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'amount>=' => 100
-])->find();
-```
-
-##### IN at NOT IN na mga operator
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage' => ['Closed Lost', 'Closed Won']
- ])->find();
-```
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'stage!=' => ['Closed Lost', 'Closed Won']
-])->find();
-```
-
-##### Mga LIKE na operator
-
-Suportadong mga operator:
-* `*` - LIKE,
-* `!*` -- NOT LIKE.
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- 'name*' => '%service%'
-])->find();
-```
-
-##### OR, AND na mga operator
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->where([
- [
- 'OR' => [
- ['stage' => 'Closed Won'],
- ['stage' => 'Closed Lost']
- ],
- 'AND' => [
- 'amountConverted>' => 100,
- 'amountConverted<=' => 999
- ]
- ]
-])->findOne();
-```
-
-#### Naiiba
-
-```
-$opportunityList = $entityManager->getRepository('Opportunity')->distinct()->where(...)->find();
-```
-
-#### Pagdudugtong-dugtong
-
-```
-$contactList = $entityManager->getRepository('Contact')->distinct()->join('opportunities')->where([
- 'opportunities.stage' => 'Closed Won'
-])->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()->leftJoin('opportunities')->where(...)->find();
-```
-
-```
-$contactList = $entityManager->getRepository('Contact')
-->distinct()
-->join(['opportunities', 'aliasForJoinedTable'])
-->where([
- 'aliasForJoinedTable.stage' => 'Closed Won'
-])->find();
-```
-
-#### Pag-grupogrupo
-
-```
-$selectParams = [
- 'select' => ['MONTH:closeDate', 'SUM:amountConverted']
- 'groupBy' => ['MONTH:closeDate'],
- 'whereClause' => [
- 'stage' => 'Closed Won'
- ],
- 'orderBy' => 1 // ordering by the first column
-];
-
-// applying left joins for currency convertion
-$this->getEntityManager()->getRepository('Opportunity')->handleSelectParams($selectParams);
-
-$pdo = $this->getEntityManager()->getPDO();
-$sql = $this->getEntityManager()->getQuery()->createSelectQuery('Opportunity', $selectParams);
-$sth = $pdo->prepare($sql);
-$sth->execute();
-
-// results
-$rowList = $sth->fetchAll(\PDO::FETCH_ASSOC);
-```
diff --git a/i18n/tl_PH/development/scheduled-job.md b/i18n/tl_PH/development/scheduled-job.md
deleted file mode 100644
index 7cf8150fd..000000000
--- a/i18n/tl_PH/development/scheduled-job.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Paglikha ng Nakaiskedyul na Gawain
-
-Upang tukuyin ang kustom na Nakaiskedyul na Gawain lumikha ng isang file na `custom/Espo/Custom/Jobs/{JOB_NAME}.php` kasama ang nilalaman.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //all the logic needs to be defined in the method run
- }
-}
-```
-
-Gayundin, maaari kang magtakda ng isang label para sa iyong gawain (`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-Upang ipatupad ang mga pagbabago, pumunta sa panel ng Administrasyon at I-burahin ang Cache.
\ No newline at end of file
diff --git a/i18n/tl_PH/development/workflow-service-actions.md b/i18n/tl_PH/development/workflow-service-actions.md
deleted file mode 100644
index d3baeb6f9..000000000
--- a/i18n/tl_PH/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Pagdaragdag ng aksyon ng serbisyong pangmamimili sa Workflow
-
-Pinapayagan ang mga workflow na lumikha ng mga pasadyang pagkilos ng serbisyo. Ang halimbawang ito ay magpapakita kung paano ito magagawa para sa isang Entidad ng tawag.
-
-## Unang Hakbang. Lumikha ng klase ng Serbisyo
-
-```php
- i- Clear ang Cache. Ngayon ang aksyon ng serbisyo ay magagamit para sa Mga Workflow sa form ng Run Service Action.
diff --git a/i18n/tl_PH/user-guide/activities-and-calendar.md b/i18n/tl_PH/user-guide/activities-and-calendar.md
deleted file mode 100644
index 2b95dd393..000000000
--- a/i18n/tl_PH/user-guide/activities-and-calendar.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Mga Aktibidad at kalendaryo
-
-May tatlong uri ng mga aktibidad na magagamit sa EspoCRM bilang default:
-
-* Mga Pulong;
-* Mga tawag;
-* Mga Gawain.
-
-Ang administrador ay makakalikha ng pasadyang entidad na uri ng pangyayari. Pagkatapos ay sa Administrasyon >Mga Setting > Mga aktibidad ay posible na itakda ang uri ng entidad na ito bilang isang Aktibidad at magagamit ito sa Kalendaryo.
-
-Mayroong 'Ang aking mga Aktibidad' na dashlet na nagpapakita ng aktwal at paparating na mga talaan ng aktibidad na nauugnay sa kasalukuyang gumagamit.
-
-Mga Account, Mga Contact, Mga Lead,Mga Opportunity, at mga Kaso ay may panel ng aktibidad sa detalyadong view. Ang mga pasadyang entidad ng tipo ng Base plus ay mayroon ding panel ng mga aktibidad.
-
-## Mga Pulong, Mga Tawag
-
-### Mga Lumahok
-
-May tatlong uri ng lumalahok na sinusuportahan: Mga User, Mga Contact, at Mga Lead. Sa bawat isang lumalahok ay posibleng tukuyin ang estado ng pagtanggap: Tinanggap, Pansamantala, at di tinanggap. Mayroong kaakayan na magpadala ng mga email na imbitasyon sa mga lumahok sa paraan ng pag-klik ng pindutan sa kanang taas na bahagi sa may bandang sulok. Ang mga lumahok ay may kakayahan din na i-set ang estado ng pagtanggap sa pamamagitan ng pag-klik ng susunon na link sa email.
-
-### Mga Paalala
-
-May dalawang uri ng paalala: Popup (in-app na mensahe) at Email.
-
-### Default na Tagal
-
-Ang default na tagal ay pwedeng baguhin ng administrador at Administrasyon > Tagapamahala ng Entidd > Mga Pulong / Mga tawag > Mga patlang > tagal > Default. Dapat tiyakin na ito ay sa segundo.
-
-## Mga Gawain
-
-Petsa ng Pagsisimula at Petsa ng Pagtatapos na mga patlang ay hindi kinakailangan. Ang mga petsa ay pwedeng tukuyin meron o wala mang mga parte ng oras.
-
-### Mga paalala
-
-Ang mga Paalala sa rekord gawain ay magagamit lang kung ang petsa ng pagtatapos ay natukoy na at mayroong parte ng oras.
-
-## Kalendaryo
-
- Ang kalendaryo ay magpapakita ng Mga Pulong, Mga Tawag at Mga Gawain. Posible din na ipakita ang mga pasadyang entidad ng uri ng Pangyayari.
-
-Mga sinusuportahang view:
-
-* Buwan;
-* Linggo;
-* Araw;
-* Timeline.
-
-Ang mga gumagamit ay pwedeng magdagdag ng kelndaryo sa kanilang dashboard.
-
-May posibilidad na pwedeng tingnan ang kalendaryo ng ibang gumagamit (kung ikaw ay binigyan ng pahintulot bata sa mga tungkulin). Ang pindutan ng kalendaryo ay mahahanap sa Detalyadong view ng gumagamit.
-
-### Ibinahaging Kalendaryo
-
-Ang mga Ibinahaging Kalendaryo ay makikita o mahahanap lang sa detalyadong view lamang. Pinapayagan nito na tingnan ang mga kaganapan ng maramihang mga gumagamit.
diff --git a/i18n/tl_PH/user-guide/browser-support.md b/i18n/tl_PH/user-guide/browser-support.md
deleted file mode 100644
index df613dfed..000000000
--- a/i18n/tl_PH/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Suporta sa Browser
-
-Inirerekomenda naming na gamitin ang ponakabagong bersyon ng Google Chrome oh Mozilla Firefox. Gumagana ang EspoCRM mas mahusay sa mga browser na ito. Regular naming sinusubok ang lahat ng mga tampok sa mga browser na ito.
-
-Ang Microsoft at and Safari ay sinusuportahan din, ngunit mas mababa ang mga garantiya na lahat ng bagay ay gumagana nang maayos.
-
-Hindi namin nirerekomenda sa mataas na lebel ang paggamit ng Internet Explorer 11.
diff --git a/i18n/tl_PH/user-guide/case-management.md b/i18n/tl_PH/user-guide/case-management.md
deleted file mode 100644
index a14c45036..000000000
--- a/i18n/tl_PH/user-guide/case-management.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Pamamahala ng Kaso
-
-Ang mga kaso ay nagbibigay ng kakayahan na tukuyan oh sundan ang anumang isyu.Ito ay isang pangunahing aspeto ng serbisyo sa mamimili ng EspoCRM. Ang terminong ginamit sa tiket ay maaari rin na gamitin para sa mga kaso.
-
-Ang entidad ng kaso ay pwedeng maugnay sa isang Account o kaya naman sa maraming Contacts.
-
-Ang mga bagong kaso ay dapat na nilikha ng mga sumusunod na sitwasyon:
-
-* Mano-mano ng mga gumagamit ng CRM;
-* Mano-mano ng mga gumagamit ng portal ng mamimili;
-* Sa pamamagitan ng paggamit ng APO (e.g. sa paggamit ng web form);
-* Awtomatiko kapag may bagong email ang dumatin sa isang tukoy na mailbox.
-* Awtomatiko sa pamamagitan ng panuntunan ng workflow.
-
-Ang rekord ng case ay mayroong stream na pwedeng gamitin para sa isang komunikasyon sa pagitan ng customer at serbisyo. Ang mga gumagamit ng CRM ay maaari ring gumawa ng mga panloob na post na hindi makikita sa isang portal ng mamimili.
-
-Kapag ang isang bagong kaso ay ginawa ng gumagamit ng portal na hindi naka-assign sa kahit na kaninong gumagamit. Sa paggamit ng [Workflows](https://github.com/espocrm/documentation/blob/master/administration/workflows.md) ay ang administrador ay makakalikha ng panuntunan na magbibigay alam sa ibang gumagamit tungkol sa panibagong kaso sa sistema. Ang mga workflow din ay nakakapagbigay ng abilidad na mag apply ng bagong panuntunan na asaynment sa mga bagong kaso, i.e. Round-Robin at Least-Busy na mga panuntunan. Para sa mga karagdagang komplikadong budiness na mgaa form ay inrerekomenda na gamiting ang [Kagamitang BPM](https://github.com/espocrm/documentation/blob/master/administration/bpm.md).
-
-Para maiwasan na makaligtaan ang mga bagong kaso ay ang gumagamit ay pwedeng dumagdaag ng tipo ng entidad na kaso sa Pangkalahatang listahn ng auto-follow at mga preperansiya. Awtomatiko nilang susundan ang mga panibagong kaso.
-
-Paalala : Kung walang gumagamit ng protal na konektado sa naka-link na contact bagkus ay ang customer ay hindi makakatanggap ng mga abiso sa email tungkol sa mga update sa Stream. Kailangan mong gumamit ng mga email para sa komunikasyon sa mga mamimili.
-
-### Email-sa-Kaso
-
-Ang Administrador ay kayang mag-setup ng Email Account na pang-grupo na sadyang lilikha ng mga bagong kaso sa bawat email na papasok. Para sa karagdagang impormasyon [Tingnan Dito](https://github.com/espocrm/documentation/blob/master/administration/emails.md).
-
-### Batayang Kaalaman
-
-Ang mga gumagamit ay maaaring mag-uugnay sa mga base ng kaalaman sa mga artikulo sa talaan ng kaso.
-
-### Portal ng mamimili
-
-Ang mga Administrator ay makakalikha ng isang [portal](https://github.com/espocrm/documentation/blob/master/administration/portal.md) kung saan ang mga mamimili ay may kakayahang makaliha ng mga kaso.
-
-Dahil awtomatikong sinusunod ng mga gumagamit ng portal ang kanilang mga kaso, makakatanggap sila ng mga abiso sa email tungkol sa mga bagong mensahe sa Stream.
diff --git a/i18n/tl_PH/user-guide/emails.md b/i18n/tl_PH/user-guide/emails.md
deleted file mode 100644
index f634f529a..000000000
--- a/i18n/tl_PH/user-guide/emails.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Mga Alituntunin sa Paggamit ng Email
-
-Ang EspoCRM ay nagbibigay ng abilidad na kuning ang mga email mula IMAP box. Ito ay nagbibigay ng posibilidad na gamitin ang EspoCRM bilang isang kliyente ng email kasama ang mga tukoy na tampok ng CRM.
-
-## Mga Account na Imap
-
-*Paalala: kailangan ay mayroon kang [cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) na iniayos ng maayos sa iyong sistema ng magkaroong ng gumaganang pagdating ng mga email.*
-
-Ang gumagamit ay kayang mag-setup ng IMAP na account sa sariling pahina ng email na account (Tab ng mga email > kanang taas na menu > Mga account ng sariling email).
-
-Tukuyin kung saan na mga folder ang susundan sa mga patlang ng sinusundan na mga folder. Bilang default ay hindi ito nakasset-up sa inbox. Kung ikaw ay gumagamit ng eksternal na email na kliyente sa pagpapadala ng mga email ay pwede kang magdagdag ng folder ng pinadala para maitago ang mga email na iyon.
-
-Ang *Kunin mula* ay nagpapahintulot sa iyo na pumili ng araw kung kelan itatago ang mga email. i-set ito sa ibang araw mula ngayon kung kinakailangan mo na itago ang mga lumang email.
-
-Mayroong kakayan na tukuyin ang *Folder* sa Account na pansariling email. Ang mga papasok na email ay malalagay sa folder na iyon.
-
-## Mga SMTP na Account
-
-Ang mga gumagamit ay kayang mag-setup ng mga settings sa SMTP sa mga preprensiya gayundin sa kanilang mga sariling email na mga account. Ang Administrador ay kaya din na magpahintulot ng paggamit ng sistema ng SMTP (Ibahagi ito).
-
-Ang mga gumagamit ay may kakayah na magkaroon ng maraming SMTP na account (mula noong bersyon 4.2.0). Ngunit ang gumagamit ng mga address ng email ay pwedeng magpadala ng email mula tinutukoy ng mga address ng email sa talaan ng *gumagamit*.
-
-## Pagtatrabaho sa mgaa Email
-
-Ang mga email ay kinukuha ng cron (sa background) kada ilang minuto (ang panahon aay maaaring tukuyin ng administrador).
-Makikita mo ang lahat ng email tab ng mga email. Mayroong karaniwang folder ng Inbox, Pinadala, Di pa tapos na mga email sa bandang kaliwa.
-
-*Estado* na patlang. `Napadala` ay nanganahulugan na pinadala galing sa CRM, `Archived` – nalakap galing sa IMAP na account o tinago ng mano-mano, `Draft` – ay nangangahulugan naa ang email ay nagawa bilang draft.
-
-Kung may bagong email na dumarating ay sinusubukan ng sistema na alamin kung saang talaan ang email na ito ay nabibilang. Ito ay pwede i-link sa Account, Lead, Opportunity, Case (at Contact sa B2C na mode) etc. Kung hindi ito nakilala ay sa halip ang gumagamit ay pwedeng i-link ito ng manomano pagkatapos ay punan ang patlang ng *parent*.
-
-Kung may isang email na dumating na mula sa kliyenteng may potensyal ay may kapangyarihan ang gumagamit na **i-convert bilan Lead**. Buksan ang Email na entry at i-klik ang Gawa ng Lead sa kanang itaas na bahagi na menu.
-
-May posibilidad din na **Lumikha ng gagawin o kaso** galing sa isang talaaan ng email.
-
-Kung ang mga adddress na email ay (from, to, cc) nasa talaan email na kilala sa sistema ay ipapakitaa nito sa tao kung sila ay may kaugnayaan sa (Contact, Lead, Gumagamit etc).Kung ang ibang email na address ay bago, ikaw ay may kayang **Gumawa ng contact** mula doon.
-
-Ang lahat ng mga email ng may kaugnayan sa tukoy na rekord ay makikita sa panel na History ng record na iyon. Kung ang ibang email ay magkaugnay, halimbawa, sa opportunity pero ang opportunity ay may ugnyan sa account, Ito ay makikita ng pareho sa opportunity at account.
-
-## Pagpapadala ng mga email
-
-maaari kang gumawa ng bagong email gamit ang mga konting pamamaraan:
-* *Gumawa ng Email* na pindutan sa on list na view ng email;
-* magreply sa ibang email;
-* pagclick ng isang email address sa iibang rekord;
-* *Gumawa ng Email* na aksyon ng panel ng mga activities.
-
-May kakayan din na **pumili ng template** sa iyong email.
-
-Pwede kang magset-up ng **Lagda sa email** sa preperensiya.
-
-## Mga Folder ng Email
-
-Ang mga gumagamit ay maaring gumawa ng mga sariling folder na paglalagyan ng mga email para sa iyong ikabubuti.Ang Listahan ng pwedeng gamitin na mga folder ay makikitaa sa pahina ng mga email sa kaliwang banda. Para makagawa at maka-edit ng mga folder ay sundin ang mga Email > dropdown in sa kanang-taas na bahagi sa sulok > Folders. `Laktawan ang abiso` ay nangangahulugan ng ayaw mong makatanggap ng balita ukol sa mga paparating na mga email na mahuhulog sa ibang folder. Sa pamamagitan ng paggamit ng pansala o filterng email ay may posibilidad na ilagay ang mga email sa mga folder sa pamamaraang awtomatiko ukol sa tukoy na pamamaraan.
-
-## Mga pansala sa email
-
-Ang mga administrador ay kayang makagawa ng pangkalahatang pang-sala ng email para laktawan ang mga di kasiya-siyang mga email. Ito ay magaganap sa adminitrador > Pangsala ng email.
-
-Ang mga regular na gumagamit ay pwedeng gumawa ng salaan ng email para sa kanilang mga pansariling Account ng email or para sa pangkalahatang inbox. Ang lahat ng ito ay mahahanap sa Mga Emails > dropdown sa nasa kanang bahagi sa sulok > Mga pangsala.
-
-May dalawang klase ng pagsasala:
-* Laktaw - ang email ay ilalagaay sa *basurahan* o hindi na-import kung ang pagsasala ay may kaugnayan sa Personal na Email na Account;
-* Ilagay sa folder - Ang mga na-import na email ay awtomatikong malalagay sa iyang tukoy na folder ng gumagamit.
-
-## Mga Templates sa Email
-
-Ang mga email na templates ay makikita sa Mga Email > dropdown na nasa kanang itaas na sulok > Mga email na template. Ang mga ito ay magagamit kapwa sa pagpapadala ng maramihang email at sa mga email na regular. `Isa-off` na checkbox ay nangangahulugan na ang email na template ay pwede lamang gamitin ng isang beses, kung ano ang karaniwan para sa pagmemerkado sa email.
-
-May posibilidad na pwedeng gumamit ng mga placeholder sa katawan at paksa ng template ng email e.g. {Account.Pangalan}, {tao.emailAddress}. Sila ay papalitan ng mga halaga na kaugnay sa talaan.
-
-Maari kang gumamit ng karagdagang nakalaan na mga placeholder sa katawan ng template: {optOutUrl} at {optOutLink}.
-
-```
-umiwas
-```
-Ito ay link sa pag-iwas sa serbisyo mula sa maramihang email
diff --git a/i18n/tl_PH/user-guide/markdown.md b/i18n/tl_PH/user-guide/markdown.md
deleted file mode 100644
index 342bb3c41..000000000
--- a/i18n/tl_PH/user-guide/markdown.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Sintaks ng Markdown
-
-Ang mga patlang ng teksto ay sinusuportahan ng sinktaks ng markdown.
-
-## Ang Code
-```
-`ibang teksto`
-```
-
-`ibang teksto`
-
-## Multiline na code
-
-```
-```ibang teksto```
-```
-
-```ibang teksto```
-
-## Malakas na teksto
-
-```
-**ibang teksto**
-```
-
-**ibang teksto**
-
-## May diin na teksto
-
-```
-*ibang teksto*
-```
-
-*ibang teksto*
-
-## Binurang teksto
-
-```
-~~ibang teksto~~
-```
-
-~~ibang teksto~~
-
-## Blockquote
-
-```
-> Ibang
-> Teksto
-```
-
-> Ibang
-> teksto
-
-## Link
-
-```
-[text ng link](https://www.espocrm.com)
-```
-[text ng link](https://www.espocrm.com)
-
-## Listahang naka-numero
-
-```
-1. ibang teksto
-2. panibagong aytem
-```
-
-1. ibang teksto
-2. panibagong aytem
-
-## Listahang di naka-numero
-
-```
-* ibang teksto
-* panibagong aytem
-```
-
-* ibang teksto
-* panibagong item
-
-## Pahalang na linya
-
-```
-___
-```
-
diff --git a/i18n/tl_PH/user-guide/mass-email.md b/i18n/tl_PH/user-guide/mass-email.md
deleted file mode 100644
index 177bc0535..000000000
--- a/i18n/tl_PH/user-guide/mass-email.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Maramihang Email
-
-## Paano magpadala ng maramihang email
-
-Kinakailangan na ikaw ay magkaroon ng kahit isang Target na listahan na may mga ulat ng target at Template ng Email sa iyong crm.
-
-1. Gumawa ng panibagong kampanya na may katayuan na `Email` o `Newsletter` . Pumili ng isa o ilang mga kaunting listahan ng target sa `Mga Listahan ng Target` na patlang.
-2. Pagkatapos gawin ang talaan ng kampanya ay gumawa ng maramihang email para sa kampanyang ito: I-klik ang plus sa panel ng maramihang Email. Tukuyin ang _Date Start_ - kung ang mga email ay kailangan na ipadala, at piliin ang _Email Template_. Siguraduhin na ang _Status_ ay itinakda nilang `Nakabinbin`.
-
-Ang mga email ay maipapalabas kung ang lahat ng pagset-up ay tama. Kailangang maipadala kada oras na may mga bahagi (Pwede mong palitan ng kaki ng bahagi sa Administrastyon> Palabas na mga email). Pwede baguhin ito ng mga Administrador sa pamamagitan ng pag-update na `Scheduling` na patlang ng `Check Group Email Accounts` na naka-iskedyul na trabaho.
-
-Maaari mong suriin kung ang mga email ay ipinadala sa log ng panel in.
-
-## Subukan kung ano ang mapapadala sa mga padadalhan
-
-I-klik ang right na dropdown sa hanay ng maramihang email sa _Mass Email_ na panel at pagkatapos ay i-klik ang _Send Test_.
-
-## Log
-
-Sa log ay iyong makikita ang mga sumusunod:
-* Mga email na pinadala;
-* Mga email na binuksan ng pinadalhan;
-* Mga link na na-klik ng pinadalhan;
-* Mga pinadalhan na nagpasyang sumali;
-* Mga email na bumalik (mga hindi napadala sa pinadalhan).
-
-## Link para sa Pagsali
-
-Bilang default ang sistema ay magsasama ng pagsali sa lahat ng mga pinadalang email. Ngunit pwede kang gumawa ng isang pinasadya sa iyong Templat na Email.
-
-Halimbawa:
-```html
-Hindi na sasali sa listahan na papadalhan ng email.
-```
-
-Ang administrador ay kayanag di paganahin ang sapilitang ling ng pagsasali na dinagdag ng sistema sa Administrasyon > Palabas na mga Email.
-
-## Pagsubaybay ng URL
-
-Kung may balak kang malaman kung ang pinadalhan mo ba ay binuksan ang link mula sa iyong email, kailangan mo gumawa ng URL ng pagsubaybay. Tumukoy ng kahit na anong _Ngalan_
- at _URL_ kung saan ang iyong link ay dapat humantong. Pagkatapos ay kailangan mong ipaste ang code na nalikha sa iyong Template ng email.
-
- Halimbawa:
- ```html
-Subukan ang aming demo
- ```
-
-## Listahan ng mga Target
-
-Ang mga listahan ng target ay naglalaman ng mga listahan ng mga Accounts,mga Contacts, mga Leads at mga talaan ng gymagamit.
-
-Ang mga gumagamit ay kayang magparami ng mga listahan ng taget ng mano-mano gamit ang _Pumili_ na aksyon sa kaukulang panel sa detalyadong view ng listahan ng target. Mayroong abilidad para gumawa ng pagsasala at pagkatapos ay piliin ang lahat ng resulta ng paghahanap.
-
-## Pagpaparami ng mga listahan ng target na may mga ulat
-
- Ang [ulat](reports.md#syncing-with-target-lists) na tampok ay nagbibigay ng abilidad na paramihin ang mga listahan ng target na may mga rekord na tumutugma sa isang tiyak na pamantayan.
-
-## Pagliban ng mga Listahan ng Target
-
-Tukuyin ang pagliban ng mga listahan ng target para maiwasan ang maramihang pagpapadala ng email sa mga piling padadalhan. Kung may isang rekord sa isang address ng email na tumutugma sa address ng email ng rekord ng mga hindi kasali, ang unang rekord ang hindi sasali kung gayon man.
-
-## Log ng kampanya
-
-Sa log ng kampanya ay iyong makikita ang mga email na iyong ipinadala, mga nabuksang email, mga bumalik na email, mga sumali, at ang mga taong nag-klik ng link sa email. May posibilidad na magamit ang log na ito sa paraan ng paggawa ng Listahan ng Target(ang dropdown ay nasa bandang kanan sa itaas na sulok ng panel) na batay sa mga rekord na galing sa log. For example, you pick only contacts that clicked on the link (tracking url).
-
-## Pag-troubleshoot
-
-_Para sa mga Administrador_
-
-#### Ano ang gagawin kung ang mga email ay hindi napadala
-
-1. Tingnan kung ang _test ng pagpadala_ ay gumana. kung hindi gumagana, sa halip ay tingnan kung ang mga setting ng SMTP na sistemaay tama.
-2. Tingnan kung ikaw ay naka-setup ng cron para sa iyong sistema.
-3. Tingnan kung mayroon kang `Magpadala ng Maramihang Email` na naka-iskedyul na tarabaho at ito ay `Aktibo` (Administraston > Naka-iskedyul na Trabaho > Magpadala ng mga maramihang email). Tingnan kung mayroong kakaiba sa Log.
-
-
-#### Paano kung ang URL ng pagsubaybay ay may maling url na hindi pinahahantong sa iyong crm.
-
-Tingnan ang 'siteUrl' na parameter sa `data/config.php` na file. Iyon ay kailangang itakda bilang URL ng iyong EspoCRM na pwedeng pasukan ng mundong nasa labas.
-
-#### Ang mga bumalik na email ay hindi na-log
-
-Ang mga bumalik na e-mail ay pwede lang hawakan ng account ng email na grupo. Tiyakin kong mayroon kang isang Eamail na account na panggrupo na sumusubaybay sa mailbox kung saan ang bumalik na email ay pinadala.
-
-Gayundin ang ilang mga tagabigay ng serber ng mail ay maaaring lumihis mula sa mga pamantayan, kaya ang mga bumalik na email ay hindi basta-bastang makikilala.
diff --git a/i18n/tl_PH/user-guide/printing-to-pdf.md b/i18n/tl_PH/user-guide/printing-to-pdf.md
deleted file mode 100644
index 5b1975faf..000000000
--- a/i18n/tl_PH/user-guide/printing-to-pdf.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Pag-print bilang PDF
-
-Paalala: Ang tampok na ito ay magagamit hanggang sa EspoCRM 5.0.5 na bersyon.
-
-Ang pag-print bilang PDF ay nagbibigay ng abilidad na makabuo ng mga dokumentong PDF na may talaan na datos. Ang nilalaman ng dokumento ay tinukoy ng Template.
-
-
-1. Kailangan ay mayroon ka na hindi bababa sa isang Template para sa uri ng entidad ng rekord na gusto mong i-print.
-2. 'Pag-print bilang PDF' ay magagamit sa view ng detalye sa ilalim ng dropdown sa tabi ng pindutang 'I-edit'.
-
-## Mga Template
-
-Ang tab ng mga template ay nakatago bilang default. Maaaring idagdag ito ng Administrador sa Administrasyon> Interface ng gumagamit.
-
-Para sa mas tumpak na pag-eedit ay inirerekumenda na gamitin ang Code View na mode.
-
-Maaari kang mag-print ng mga patlang ng rekord pati na rin ang mga patlang ng mga kaugnay na mga tala sa pamamagitan ng paggamit ng mga placeholder sa iyong template.
-
-Mga Halimbawa:
-
-* `{{Pangalan}}` – Pangalan ng Rekord;
-* `{{assignednaPangan}}` – Naka-assign na gumagamit;
-* `{{account.pangalan}}` – Pangalan ng account na may kaugnayan.
-
-Posibleng mag-print ng mga patlang ng larawan:
-```
-
-```
-
-kung saan `ImaheId` – ang pangalan ng pasadyang imahe na patlang, na konektado sa suffix na `Id`.
-
-Upang maipakita ang mga numero ng float ng walang parte na praksyonal (as integer) ay gamitin ang mga sumusunod na ekspresyon:
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Pasadyang pag-format para sa mga halaga ng pera:
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-
-Ang halagang `10000.5` ay i-print bilang `10 000,50`.
-
-Upang mapakita ang mga patlang ng teksto (multiline) ay gumamit ng tatlong tirante: ```{{{Deskripsyon}}}```.
diff --git a/i18n/tl_PH/user-guide/quotes.md b/i18n/tl_PH/user-guide/quotes.md
deleted file mode 100644
index cba0ad806..000000000
--- a/i18n/tl_PH/user-guide/quotes.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Mga Quote
-
-Ang mga tampok ng quote ay magagamit sa [Paketeng Advanced](https://www.espocrm.com/extensions/advanced-pack/).
-
-Ang mga quote ay tiyak na pangkat ng mga produkto o serbisyo na may kanya-kanyang mga dami at mga presyo na binabanggit mo sa mga tagabili..
-
-Ang mga Quote ay may relasyon kay Opportunity. Maaari kang magdagdag ng mga panel ng Mga Quote sa view ng detalye ng Opportunity sa Administrasyon > Layout Manager > Mga Opportunity > Mga relasyon. Kapag lumilikha ng isang bagong quote na naka-link sa isang Opportunity ay ililipat ng Opportunity ang mga aytem sa quote.
-
-Maaari kang magdagdag ng mga panel ng Mga Quote sa view ng detalye ng Account upang makakakita ng mga kaugnay na quote. Magagawa mo ito sa Administrasyon> Manager na Layout> Mga Account> Mga Relasyon.
-
-## Mga Aytem ng Quote
-
-May isang listahan ng mga aytem ang quote. Ang bawat aytem ay maaaring kumatawan sa isang partikular na produkto o isang serbisyo na may paglalarawan, dami, antas ng buwis, presyo ng listahan at presyo ng yunit na mga patlang. Ito ay posible upang maiayos nang manu-mano ang mga aytem.
-
-May kakayahang magdagdag ng mga pasadyang patlang para sa Entidad ng Aytem ng Quote gamit ang manager ng entidad.
-
-## Mga Template
-
-Bilang default mayroong dalawang magagamit na mga template: Quote at ang Invoice. Pwede kang gumawa ng mga bagong template (mga Quote na list na view > top-right ng dropdown na menu > mga Template) pati na rin ang pag-edit ng mga umiiral sa ngayon.
-
-Para sa mas tumpak na pag-edit inirerekumenda na gamitin ang Code View na mode.
-
-Maaari kang mag-print ng mga patlang na tala ng Quote pati na rin ang mga patlang ng mga kaugnay na mga tala sa pamamagitan ng paggamit ng mga placeholder sa iyong template.
-
-Mga Halimbawa:
-`{{NgalanNgAccount}}` – Pangalan ng Account,
-
-`{{{billingAddressStreet}}}` – kalye,
-
-`{{account.tipo}}` – uri ng kaugnay na account,
-
-`{{nakatalagang gumagamit.HulingPangalan}}` – huling pangalan ng nakatalagang gumagamit.
-
-Kung ang iyong aytem na linya ay isang produkto ay maaari mong i-print ang mga patlang ng produkto.
-
-Mga halimbawa:
-`{{Produkto.haba}}`,
-
-`{{Produkto.kulay}}`.
-
-Ang haba at kulay ay mga pasadyang larangan ng entidad ng Produkto sa mga halimbawa.
-
-Pag-loop sa pamamagitan ng mga quote na aytem:
-
-```
-
-
{{{Gusto}}
-
{{Pangalan}}
-
{{Dami}}
-
{{produkto.bigat}}
-
{{ListahanNgPresyo}}
-
{{YunitNgPresyo}}
-
{{halagat}}
-
-```
-
-Posibleng mag-print ng mga patlang ng imahe:
-
-```
-
-```
-where `ImaheId` – ang pangalan ng pasadyang imahe ng patlang, na kinonekta sa suffix na`Id`.
-
-Para sa aytem na linya ng produkto:
-```
-
-```
-
-Upang ipakita ang mga numero ng float (like quantity, unitPrice etc.) ng walang parte na fraksyunal (as integer) ay ikaw'y gagamit ng sumusunod na ekspresyon (simula noong bersyon 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Pasadyang pagformat para sa mga halaga ng pera (simula noong bersyon na 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Ang halagang `10000.5` ay magiging `10 000,50` sa pag-print.
-
-Para ipakita ang mga patlang ng teksto (multiline) ay gumamit ng tatlong tirante : `{{{description}}}`.
-
-## Pag-print bilang PDF
-
-Ang mga Quote ay pwedeng ma-print bilang PDF. Ang aksyon na ito ay magagamit sa dropdown sa tabi ng pindutang edit sa view ng detalye ng quote. Pagkatapos ay sasabihan ka upang piliin ang Template.
-
-## Quote na koreo
-
-Ang Quote na PDF aiy pwedeng ipadala sa koreo bilang karagdagan na file. Buksan ang talaan ng quote, i-klik ang dropdown na sunod sa pindutang Edit at pagkatapos ay i-klik ang Email PDF.
-
-## Awtomatikong Pagnunumero
-
-Maaari kang lumikha ng patlang ng numero sa pamamagitan ng manager ng entidad para sa uri ng Entidad ng Quote. Administrasyon > Manager ng entidad > Quote > Mga patlang > Magdagdag ng patlang > Numero. Pagkatapos ay kailangan mong ilagay ito sa view ng detalye gamit ang Manager ng Layout.
-
-Ang halaga ay idadagdag sa bawat bagong quote. May kakayahan itong tukuyin ang susunod na numero pati na rin ang prefix nito.
-
-## Default na Buwis
-
-Magagamit mula noong 4.8.0 na bersyon ng EspoCrm.
-
-1.Tukuyin ang default na tala ng Buwis sa Administrasyon > Manager ng Entidad > Mga Quote > mga Patlang > Buwis > Default.
-2.Tukuyin ang default na rate ng buwis sa Pangangasiwa > Manage ng Entidad > Mga quote > Mga Patlang > presiyo ng buwis > Default.
-
-## Mga Invoice
-
-Ang quote ay pwedeng ituring bilang invoice kung ang estado nito ay naging `Approved`. Pagkatapos ay ang _Date Invoiced_, _Invoice Number_ fields ay magpapakita Maaari mong gamitin ang iba 't ibang template para sa mga invoice para sa pag-print.
diff --git a/i18n/tl_PH/user-guide/reports.md b/i18n/tl_PH/user-guide/reports.md
deleted file mode 100644
index d9bb8247a..000000000
--- a/i18n/tl_PH/user-guide/reports.md
+++ /dev/null
@@ -1,101 +0,0 @@
-# Mga ulat
-
-Ang tampok ng ulat ay makikita at makukuha sa [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-May dalawang uri ng ulat: List at Grid.
-
-## List na mga ulat
-
-listahang pang-ulat ng mga resulta mula sa listahan ng mga talaan na kayang matugunan ang mga tinukoy na pamantayan.
-
-Para lumikha ng listahang pang-ulat, i-click ang tab ng mga Ulat at i-click ang lumikha ng ulat na pindutan. Piliin ang kinakailangang tipo ng entidad at i-click ang Lumikha na pindutan at seksyon ng List Report.
-
-Sa _Columns_ na patlang ay pumili ng mga patlang na gusto mong i-displey. Sa ibaba nito ay maaari mong tukuyin ang mga parameter ng displey para sa bawat hanay e.g. lapad at paghanay.
-
-Piliin ang mga kinakailangan na mga pag-ayos sa _List Order_ field.
-
-Sa _Filters_ na seksyon ay maaari mong tukuyin ang pamantayan na tumutukoy kung anong mga talaan ang maiilista sa iyong ulat. Maaari mong gamitin ang lohikal na na mga operator na 'OR' at 'AND' dito.
-
-Ang _Runtime Filters_ ay nagbibigay-daan sa iyo upang tukuyin ang iba't ibang mga pagsasala bago mo patakbuhin ang iyong ulat.
-
-pwede mong i-export ang listahan ng mga reulta ng iyong ulat sa excel at csv na mga format.
-
-## Ang mga ulat na grid
-
-ang resulta ng mga ulat na grid ay nagbubuod ng mga halaga na nakagrupo batay sa tukoy na larangan. Ang mga ulat na ito ay pwedeng i-displey bilang isang tsart .
-
-
-
-Para gumawa ng bogaong ulat na grid ay i-klik ang tab ng mga ulat at pagkatapos ay i-klik ang Gumawa ng bagong ulat na button. Piliin ang kakailanganing tukoy na entidad at pagkatapos ay i-klik ang Gumawa na button at seksyon ng ulat na grid.
-
-Ang _Group By_ na na patlang ay pwede kang pumili ng isa o dalawa na mga patlang na gusto mo na makita sa datos ng iyong report na nakagrupo. posibleng igrupo ayon sa taon, buwan, at araw sa mga patlang ng panahon. Kung binuo mo ayon sa dalawang larangan ang iyong report ay ituturing ito bilang three-dimensional.
-
-Sa _Columns_ na patlang ay pumili ng isa o dalawang aggregate na mga punksiyon kagaya ng COUNT, SUM (summation), MIN, MAX, AVG (average).
-
-Ang _Order by_ na patlang ay naglalarawan kung paano ang datos na ulat ay pinagsunod-sunod.
-
-Sa _Filters_ na seksyon ay maaari kang tumukoy ng gagamitin na batayan na tutukoy sa kung ano ang nakatala sa iyong report. Pwede kang gumamit ng lohikal na operators kagaya ng 'OR' at 'AND' dito.
-
-Ang _Runtime Filters_ ay nagpapahintulot sa iyo na tukuyin ang iba't ibang mga pagsala bago ka maubusan ng ulat
-
-Ang ulat na grid ay nagpapahintulot sa iyo na i-displey ang mga resulta sa paraan ng tsart. Mayroong following _chart types_: Bar (Horizontal), Bar (Vertical), Pie, at Line.
-
-Posibleng i-export ang mga resulta ng ulat na grid sa excel at csv na mga format.
-
-## Mga Pagsala
-
-### Patlang ng pagsala
-
-Simpleng gamitin ang mga tipo ng mga pagsala. Maari mo din na piliin ang mga larangan na target na entidad pati na rin ang mga kaugnay na mga entidad.
-
-
-
-
-### OR na grupo
-
-Ang OR ay nangangahulugan na hindi dapat bababa sa isang kalagayan sa ilalim ng grupo ang dapat matugunan.
-
-
-
-### AND na grupo
-
-Ang AND ay nangangahulugan na lahat dapat na kalagayan sa ilalim ng grupo ang dapat matugunan.
-
-### NOT na grupo
-
-Nagbibigay ng kakayahan na isala ang mga talaan na di kayang matugunan ang mga tinukoy na pamantayan. E.g. Paglilista ng mga account na wala ni anumang pagkakataon na saradong panalo o saradong talo na katayuan.
-
-
-
-### Komplikadong Pagpapahayag
-
-Para sa mas mga advanced na gumagamit. Maaari mong ilapat ang punksyon para sa ilang mga haligi ng database at ihambing ito sa resulta ng [formula](../administration/formula.md) na pamamahayag.
-
-Paalala: Kung kailangan mong ikumpara lang sa isang simpleng string na halaga ay dapat na ilagay ito sa iisang quote na `'some string'`.
-
-Paalala: Ang mga punksyon na nilayon upang makipag-ugnayan sa talaaan ng entidad ay hindi gagana dito dahil ang formula ay hindi nailapat sa tiyak na talaaan.
-
-
-
-### Meron na grupo
-
-Ang meron na grupo ay magbibigay ng abilidad na magsala gamit ang aggregate na mga punksyon na COUNT, SUM, MAX, MIN, at AVG.
-
-Ilan sa mga ginagamit na mga kaso:
-
-* Ilista ang mga account na magkakaroon ng higit sa isang pagkakataon. `COUNT / opportunities.id / Grater Than / 1`.
-* Ipinapakita sa salaysay na Nakagrupo ayon sa industriya kung saan ang kita ay higit sa 1,000 ang ulat na grid. `SUM / opportunities.amount / Greater Than / 1000`.
-
-Paalala: Kompatibol sa bersiyon ng EspoCRM 5.1.0 at mas mataas.
-
-## Pag-displey sa dashboard
-
-Maaari mong i-displey ang anumang ulat sa dashboard. Para dito ay kailangan mo na idagdag ang dashlet ng ulat at pagkatapos ay pumili ng kinakailangang ulat sa dashlet na mga pagpipilian.
-
-## Pagpapadala ng Koreo
-
-May posibilidad na ipagawa sa sistema na magpadala ng mga ulat ng mga resulta sa ilang mga gumagamit sa regular na batayan ayon sa tinakdang oras. Ito ay dapat na isinaayos para sa ilang mga ulat na paisa-isa.
-
-## Isini-sync sa Target list
-
-May posibilidad na magkaroon ng listahan ng mga target na naka-sync sa listahan ng mga resulta ng ulat. Mas maginhawa ang maramihang koreo kapag gusto mong magpadala ng mga koreo sa mga kontak lamang na kayang tugunan ang ilang pamantayan sa sandali ng pagpapadala. Ang tampok na ito ay makukuha sa view na mga detalye ng anumang listahan ng target sa 'Sync sa report' na panel.
diff --git a/i18n/tl_PH/user-guide/sales-management.md b/i18n/tl_PH/user-guide/sales-management.md
deleted file mode 100644
index 01ad15907..000000000
--- a/i18n/tl_PH/user-guide/sales-management.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Pamamahala ng mga nabenta
-
-## Mga Lead
-
-Ang lead ay nagrerepresenta ng isa tao o isang organisasyon na sa kasalukuyan ay hindi isang mamimili, pero may potensyal na maging mamimili. Sa paglilikha ng isang talaan ng lead ay karaniwang unang hakbang sa proseso ng pagbenta. Habang dumadami ang impormasyon na nakakalap ukol sa Lead, pwedeng mangyari na ang lead ay magiging isang account, contact at opurtunity.
-
-ang mga bagong lead ay dapat nilikha sa pamamagitan ng sumusunod na mga sitwasyon:
-
-* Nang manu-mano sa pamamagitan ng mga gumagamit ng CRM;
-* Sa pamamagitan ng API (e.g. sa pamamagitan ng mga for ng web);
-* Awtomatiko sa pamamagitan ng isang patakaran sa daloy ng trabaho.
-
-Sa pamamagitan ng pagamit ng [Mga daloy ng trabaho](https://github.com/espocrm/documentation/blob/master/administration/workflows.md) ang mga namumuno ay may kayang maset-up ang sistema at mag-aplay ng isang patakaran ng partikular na tungkulin sa mga bagong leads, i.e. Round-Robin at Least-Busy na mga tungkulin. Para sa mga mas kumplikadong daloy ng negosyo nirerekomendang gumamit ng [BPM tool](https://github.com/espocrm/documentation/blob/master/administration/bpm.md).
-
-Para maiwasan ang sobrang pagtingin sa mga bagong lead. Ang mga gumagamit ay pwede magdagdag ng mga Lead na tipo ng entidad sa Global Auto-follow na listahan at mga preperensiya. Pagkatapos ay awtomatik nilang susundan ang bawat lead na bago.
-
-## Mga Opurtunity
-
-Ang opportunity ay nagrerepresenta ng mga potensiyal oh saradong kalakaran. Ang mga opportunity na nasa istage ng 'Saradong Panalo' ay tinatandaan para sa pagkalkula ng mga kita ng pagbenta.
-
-Ang mga sumusunod na yugto ay makukuha sa pamamagitan ng default:
-
-* Pagmamanupaktura;
-* Kwalipikasyon;
-* Panukala;
-* Negosasyon;
-* Saradong panalo;
-* Saradong talo.
-
-Maitatakda ng tagapangasiwa ang mga pasadyang yugto depende sa daloy ng negosyo ng kumpanya. Ngunit ito ay hindi inirerekomenda na alisin ang 'Saradong panalo' na yugto dahil ito ay ginagamit para kalkulahin ang isang kita.
-
-## Analitiks sa mga benta
-
-Ang sumusunod na tsart ay makukuha sa dashboard bilang default:
-
-* Mga benta na naka-ayos ayon sa buwan;
-* Mga opportunity na nakaayos ayon sa Lead Source;
-* Mga opportunity na nakaayos ayon sa yugto;
-* Pipeline ng mga pagbenta.
-
-Sa paggamit ng [Kagamitang pang-tala](https://github.com/espocrm/documentation/blob/master/user-guide/reports.md) Posibleng matingnan ang Istatistika ng mga benta na batay sa mga tiyak na pamantayan. Ang mga tsart ng mga ulat ay maaaring maipakita sa dashboard.
-
-### Ulat ng mga kita
-
-1. Lumikha ng isang bagong ulat ng grid para sa tipo ng entidad ng pagkakataon.
-2. Magdagdag ng ' buwan: malapit na petsa ' sa grupo sa patlang.
-3. Magdagdag ng ' SUM: halaga Weighted' sa patlang ng kolum.
-4. Magdagdag ng mga 'Malapit petsa' sa patlang ng oras ng takbo ng salaan.
-5. i-select ang'Bar (vertical)' na tipo ng tsart.
-
-Ang ulat na ito ay magpapakita sa ulat ng kita batay sa mga probabilidad ng pagkakataon.
-
-Pwedeng idagdag ng mga gumagamit ang ulat na ito sa kanilang mga dashboard kung sila ay may akses dito
diff --git a/i18n/tl_PH/user-guide/stream.md b/i18n/tl_PH/user-guide/stream.md
deleted file mode 100644
index fa509ea55..000000000
--- a/i18n/tl_PH/user-guide/stream.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Stream
-
-Ang Stream sa EspoCRM ay isang feed na kung saan ay iyong makikita ang mga pagbabago at ang mga bagong dinagdag para sa mga rekord na iyong sinusundan. Ikaw din ay pwedeng makasulat or makadaragdag sa sarili mong stream at mag-stream sa ibang gumagamit (mula noong bersyon 3.8.0). May dalawang uri ng stream sa EspoCRM: stream na rekord at stream na gumagamit.
-
-Sa default nito ang mga sumusunod na mga entidad ay may isang stream: Mga Account, Mga Contacts, Mga Leads, Mga Oportunity, Mga kaso. Ang mga Administrador ay may kayang paganahin oh hindi paganahin ang stream para sa partikular na entidad sa [Tagapamahala ng Entidad](../administration/entity-manager.md).
-
-## Stream na Rekord
-
-Ang Stream na Rekord na ipinapakita sa isang panel ng stream sa isang tiyak na talaan sa pananaw na Detalye. Ang mga koreo, mga pagbabago at ang mga bagong dinagdag na may kaugnayan sa kasalukuyang talaan ay makikita dito.
-
-## Stream na User
-
-Ang mga Gumagamit ay may kayang makita ang stream sa dashlet na stream pati na sa ilalim ng stream tab. Ang mga gumagamit ay may kayang makita din ang stream ng ibang mga gumagamit sa pananaw ng gumagamit na detalye, kung sila ay may akses na kontrolado ng `User Pemission` sa larangan ng mga tungkulin.
-
-Sa stream ng gumagamit ay kaya mong makita ang mga koreo, mga pagbabago at ang mga bagong dinagdag na may kaugnayan sa mga talaan na sinusundan ng mga gumagamit. Ikaw din ay pwede mong makita ang mga koreo na nakapangalan sa mga gumagamit. Mga koreo na walang kaugnayan sa kahit na anong talaan.
-
-## Mga Abiso
-
-Ikaw ay makakatanggap ng mga abiso tungkol sa mga bagong pagbabagp sa iyong stream na sanhi ng ibang gumagamit.
-
-## Mga koreo
-
-Ikaw ay makakagawa ng koreo na may kaugnayan sa isang tiyak na talaan. Ikaw din ay pwedeng maglagay o magdagdag ng maraming files at mga larawan sa iyong koreo. Kung gusto mong banggitin ang isang tao sa iyong koreo ay kailangan mo lang na itype ang simbolo na `@` at simulang itype ang pangalan ng gumagamit. Ang gumagamit na iyong binaggit sa iyong koreo ay makakatanggap ng abiso ukol dito.
-
-## Ang mga koreo ng mga gumagamit
-
-_Ang tampok na ito ay magagamit lang hanggang sa bersyon na 3.8.0._
-
-Ang mga gumagamit ay pwedeng maglagay ng mga koreo sa ilang mga gumagamit, sa ilang mga grupo, sa lahat ng mga gumagamit at sa sarili. Ang akses sa mga ganitong abilidad ay kontrolado ng `Assignment Permission` sa larangan ng mga tungkulin.
-
-## Pagsasala
-
-Pwede mong salain kung ano ang makikita sa stream: `All`, `Posts` or `Updates`.
-
diff --git a/i18n/tr_TR/README.md b/i18n/tr_TR/README.md
deleted file mode 100644
index 7241d9b80..000000000
--- a/i18n/tr_TR/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# EspoCRM Belgeleme
-
-### Yönetim
-* [Sunucu Yapılandırması](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md)
- * [Apache](https://github.com/espocrm/documentation/blob/master/administration/apache-server-configuration.md)
- * [Nginx](https://github.com/espocrm/documentation/blob/master/administration/nginx-server-configuration.md)
-* [Kurulum](https://github.com/espocrm/documentation/blob/master/administration/installation.md)
-* [Yükseltme](https://github.com/espocrm/documentation/blob/master/administration/upgrading.md)
-* [Rol Yönetimi (erişim kontrolu)](https://github.com/espocrm/documentation/blob/master/administration/roles-management.md)
-* [Emailler](https://github.com/espocrm/documentation/blob/master/administration/emails.md)
-* Customization
- * [Varlık Yöneticisi: varlıklar, alanlar, ilişkiler](https://github.com/espocrm/documentation/blob/master/administration/entity-manager.md)
- * [Düzenleme Yöneticisi](https://github.com/espocrm/documentation/blob/master/administration/layout-manager.md)
- * [Uzantılar](https://github.com/espocrm/documentation/blob/master/administration/extensions.md)
-* Automation
- * [İş Akış Yönetimi (BPM)](https://github.com/espocrm/documentation/blob/master/administration/bpm.md)
- * [İş Akışları](https://github.com/espocrm/documentation/blob/master/administration/workflows.md)
- * [Hesaplanan Alanlar (Formül)](https://github.com/espocrm/documentation/blob/master/administration/formula.md)
-* [Veri Alımı](https://github.com/espocrm/documentation/blob/master/administration/import.md)
-* [Portal](https://github.com/espocrm/documentation/blob/master/administration/portal.md)
-* [LDAP Yetkilendirme](https://github.com/espocrm/documentation/blob/master/administration/ldap-authorization.md)
- * [Aktif Rehber](https://github.com/espocrm/documentation/blob/master/administration/ldap-authorization-for-ad.md)
- * [OpenLDAP](https://github.com/espocrm/documentation/blob/master/administration/ldap-authorization-for-openldap.md)
-* [Sorun Giderme](https://github.com/espocrm/documentation/blob/master/administration/troubleshooting.md)
-* Çeşitli
- * [Haritalar](https://github.com/espocrm/documentation/blob/master/administration/maps.md)
- * [B2C modu](https://github.com/espocrm/documentation/blob/master/administration/b2c.md)
- * [Yedekleme ve onarım](https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md)
- * [Başka bir sunucuya taşıma](https://github.com/espocrm/documentation/blob/master/administration/moving-to-another-server.md)
-
-
-### Kullanıcı Rehberi
-* [Emailler](https://github.com/espocrm/documentation/blob/master/user-guide/emails.md)
-* [Akış](https://github.com/espocrm/documentation/blob/master/user-guide/stream.md)
-* [Kitle Emaili](https://github.com/espocrm/documentation/blob/master/user-guide/mass-email.md)
-* [Raporlar](https://github.com/espocrm/documentation/blob/master/user-guide/reports.md)
-* [Alıntılar](https://github.com/espocrm/documentation/blob/master/user-guide/quotes.md)
-* [Markdown sözdizimi](https://github.com/espocrm/documentation/blob/master/user-guide/markdown.md)
-* Çeşitli
- * [Tarayıcı Desteği](https://github.com/espocrm/documentation/blob/master/user-guide/browser-support.md)
-
-### Development
-* [API](https://github.com/espocrm/documentation/blob/master/development/api.md)
-* [ORM: Varlıklar nasıl yönetilir?](https://github.com/espocrm/documentation/blob/master/development/orm.md)
-* [Metadata](https://github.com/espocrm/documentation/blob/master/development/metadata.md)
-* [Özel Görünümler](https://github.com/espocrm/documentation/blob/master/development/custom-views.md)
-* [Dinamik Formlar](https://github.com/espocrm/documentation/blob/master/development/dynamic-forms.md)
-* [Bir Primer kayıtla Link Çoklu alanı](https://github.com/espocrm/documentation/blob/master/development/link-multiple-with-primary.md)
-* [Uzantı paketleri](https://github.com/espocrm/documentation/blob/master/development/extension-packages.md)
-* [Askılar](https://github.com/espocrm/documentation/blob/master/development/hooks.md)
-* [Özel zamanlanmış işler oluşturma](https://github.com/espocrm/documentation/blob/master/development/scheduled-job.md)
-* [Formül için yeni fonksiyonlar tanımlama](https://github.com/espocrm/documentation/blob/master/development/new-function-in-formula.md)
-* [Özel alan türü](https://github.com/espocrm/documentation/blob/master/development/custom-field-type.md)
-
-
-[Websitede belgeleme](https://www.espocrm.com/documentation/)
diff --git a/i18n/tr_TR/administration/apache-server-configuration.md b/i18n/tr_TR/administration/apache-server-configuration.md
deleted file mode 100644
index 482aee66e..000000000
--- a/i18n/tr_TR/administration/apache-server-configuration.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# EspoCRM için Apache sunucu yapılandırması
-
-Bu talimatlar [Sunucu Yapılandırması](server-configuration.md) klavuzuna tamamlayıcıdır. Burada listelenen tüm yapılandırma ayarlarının Ubuntu sunucusunda yapıldığını lütfen unutmayın.
-
-## PHP gereksinimleri
-
-Gerekli tüm kütüphaneleri yüklemek için bu komutları bir terminalde çalıştırın:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service apache2 restart
-```
-
-## API Hatası: EspoCRM API'sı kullanılamıyor sorunu giderildi:
-
-Gerekli adımları yapın. Her adımda sorunun çözülüp çözülmediğini kontrol edin.
-
-### 1. Apache'de "mod_rewrite" desteğini etkinleştirin
-
-"mod_rewrite" işlevini etkinleştirmek için bu komutları bir terminalde çalıştırın:
-
-```
-sudo a2enmod rewrite
-sudo service apache2 restart
-```
-
-### 2. .htaccess desteğini etkinleştirin
-
-.htaccess desteğini etkinleştirmek için, ekle/düzelt Sunucu Yapılandırma Ayarları /etc/apache2/sites-available/ESPO_VIRTUAL_HOST.conf ya da /etc/apache2/apache2.conf (/etc/httpd/conf/httpd.conf):
-
-```
-
-AllowOverride All
-
-```
-
-Daha sonra, bu komutu bir terminalde çalıştırın:
-
-```
-sudo service apache2 restart
-```
-
-### 3. RewriteBase yolunu ekleyin
-
-/ESPOCRM_DIRECTORY/api/v1/.htaccess dosyasını açın ve aşağıdaki satırı değiştirin:
-
-```
-# RewriteBase /
-```
-
-ile
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-REQUEST_URI, URL'nin bir parçasıdır; ör: "http://example.com/espocrm/" için REQUEST_URI "espocrm" dur.
-
-
-## HTTP YETKİLENDİRME desteğini etkinleştir (sadece FastCGI için).
-
-FastCGI varsayılan olarak HTTP YETKİLENDİRME'yi desteklemez. FastCGI kullanıyorsanız, aşağıdaki kodu ekleyerek VirtualHost veya /etc/apache2/apache2.conf dosyanızda (httpd.conf) etkinleştirmeniz gerekir:
-
-Fcgid modülü için:
-
-```
-
- FcgidPassHeader Authorization
- FcgidPassHeader Proxy-Authorization
- FcgidPassHeader HTTP_AUTHORIZATION
-
-```
-
-FastCgi modülü için:
-
-```
-
- FastCgiConfig -pass-header Authorization \
- -pass-header Proxy-Authorization \
- -pass-header HTTP_AUTHORIZATION
-
-```
-
-Hangi modülün şuanda kullanıldığını kontrol etmek için bu komutu çalıştırın ve modülü bulun:
-
-```
-apache2ctl -M
-```
diff --git a/i18n/tr_TR/administration/b2c.md b/i18n/tr_TR/administration/b2c.md
deleted file mode 100644
index c9b78cc30..000000000
--- a/i18n/tr_TR/administration/b2c.md
+++ /dev/null
@@ -1,9 +0,0 @@
-#B2C için (İşyerinden Müşteriye) EspoCRM'yi yapılandırma
-
-EspoCRM, B2B işletmesi için kullanılacak şekilde varsayılan olarak yapılandırılmıştır. Ancak B2C için kolayca kurabilirsiniz.
-
-* `Data / config.php` yapılandırma dosyasında `b2cMode` parametresini değiştirin. Yönetim>Ayarlar bölümünden Sürüm 4.3.0'dan itibaren yapılandırılabilir.
-* Navigasyon menüsünden *Hesap* sekmesini kaldırın (Yönetim>Kullanıcı Arayüzü).
-* *Hesap* alanlarını Layout'larınızdan kaldırın (Yönetim>Layout Yöneticisi).
-* *Hesap* kapsamına erişimi için tüm rollerinizi devre dışı bırakın (Yönetim> Roller).
-* Tüm ana alanların seçim listelerinden Hesabı kaldırın (Yönetim> Kuruluş Yöneticisi> {Toplantı / Arama / Görev / E-posta}> Alanlar> Ebeveyn)
diff --git a/i18n/tr_TR/administration/backup-and-restore.md b/i18n/tr_TR/administration/backup-and-restore.md
deleted file mode 100644
index 535ab7806..000000000
--- a/i18n/tr_TR/administration/backup-and-restore.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Yedekleme ve Geri Yükleme
-
-## Nasıl EspoCRM'yi manuel olarak yedeklemerim?
-
-EspoCRM, dosyalar ve veritabanı verilerini içerir.Tüm bu veriler, EspoCRM'nin tam bir yedek kopyasını oluşturmak için gereklidir. Burada Ubuntu sunucusunda MySQL ile nasıl yapılacağına dair talimatlar var.
-
-### 1. Adım Dosyaları Yedekleme
-
-Yüklü EspoCRM'nin dizin içeriğinin bir arşivini oluşturun. Ubuntu için varsayılan yol `/var/www/html`'dir. Bu komutu kullanabilirsiniz.
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### 2. Adım Veritabanı Yedekleme
-
-Tüm verilerinizi yedeklemek için, veritabanı adını ve erişim kimlik bilgilerini bilmeniz gerekmektedir. Veritabanı adını `database` bölümündeki `/ESPOCRM_DIRECTORY/data/config.php` yapılandırma dosyasında bulabilirsiniz. Veritabanınızı yedeklemek için bu komutu kullanabilirsiniz:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### 3. Adım Yedeklemeyi Kopyalamak
-
-Hepsi bu kadar. Şimdi oluşturulan yedeklemeyi güvenli bir yere kopyalamanız gerekiyor.
-
-## EspoCRM bir script ile nasıl yedeklerim?
-
-Gerekli tüm verileri yedeklemek için bir komut dizini kullanabilirsiniz. SSH ile giriş yapın ve komutları çalıştırın (Ubuntu sunucusunda test edilmiştir).
-
-### Komut Dosyasını İndir
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### Komut Dosyasını Çalıştır
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-nerede:
- * `PATH_TO_ESPOCRM` kurulu EspoCRM dizininin bir yoludur.
- * `BACKUP_PATH` yedekleme dizininin bir yoludur.
-
-Ubuntu sunucusu için:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-Not: MySQL kullanıcınız veritabanınızı boşaltmak için gerekli haklara sahip değilse, başka bir MySQL kullanıcısının kimlik bilgilerini girmeniz istenecektir.
-
-Başarılı oluşturmadan sonra, oluşturulan yedekleme yolunu edininiz.
-
-## EspoCRM'yi yedekten geri yükleme
-
-EspoCRM'yi, yukarıda açıklandığı gibi oluşturulan yedeklemeden geri yükleyebilirsiniz.
-
-### 1. Adım Yedek Dosyalarını arşivden çıkartma
-
-Dosyaları arşivden çıkartman için Arşiv Yöneticisi'ni kullanabilir veya aşağıdaki komutu çalıştırabilirsiniz. Dosyaların Web sunucusu dizinine yerleştirilmesi gerekir.
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-nerede:
- * `/var/www/html` bir web sunucusu yoludur.
-
-### 2. Adım Gerekli İzinleri Ayarlamak
-
-Dosyaların bir web sunucusu kullanıcısına ait olması ve doğru izinlere sahip olması gerekir. Lütfen şu talimatları izleyerek gerekli izinleri ayarlayın: [www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems).
-
-### 3. Adım Veritabanı Dökümünü Almak
-
-Veritabanı dökümü aynı kullanıcı kimlik bilgileriyle veritabanına alınmalıdır, aksi halde düzeltme yapılandırma `ESPOCRM_DIRECTORY/data/config.php` dosyasında yapılmalıdır. Veritabanınızın dökümlerini almak için, bir terminalde aşağıdaki komutu çalıştırın:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### 4. Adım Crontabı kontrol etmek/yapılandırmak
-
-Crontab'ınızın düzgün yapılandırıldığını kontrol ediniz. Aşağıdaki komutu çalıştırın ve EspoCRM'ye giden yolun doğru olup olmadığını kontrol edin:
-
-```bash
-sudo crontab -l -u www-data
-```
-nerede:
- * `www-data` is your web-server user.
-
-Herhangi bir değişiklik yapmanız gerekiyorsa şu komutu kullanın:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-Crontab'ı EspoCRM için yapılandırmayla ilgili daha fazla ayrıntı burada açıklanmaktadır[www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab).
-
diff --git a/i18n/tr_TR/administration/bpm.md b/i18n/tr_TR/administration/bpm.md
deleted file mode 100644
index 8c1d55b1f..000000000
--- a/i18n/tr_TR/administration/bpm.md
+++ /dev/null
@@ -1,213 +0,0 @@
-# İş Süreçleri Yönetimi
-
-İş Süreçleri Yönetimi (BPM) aracı, EspoCRM'deki iş süreçlerini modelleme ve otomatikleştirme imkanı sağlar. BPMN 2.0 standardında açıklanan iş süreçlerini yürüten bir motordur. BPM aracı, [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/) uzantısında bulunur.
-
-
-
-### İş Akışı araçlarının farkı
-
-İş akışı aracı, akışın grafiksel olarak görüntülenmesine gerek olmadığı zaman, ardışık akış öğeleri olmaksızın basit işletme kurallarının otomasyonu için tasarlanmıştır.
-
-BPM aracı, birbirinden uzaklaşan ve yaklaşan akışlar, uygulama gecikmeleri ve kullanıcı etkileşimleri gibi daha karmaşık iş akışları için tasarlanmıştır. Bir akış şeması görünümü, iş süreçlerini bir insan için daha anlaşılır kılmakta, bir günlük işlemin nasıl yapıldığının görülmesini sağlamaktadır.
-
-## İşlem Akış Şemaları
-
-İşlem akış çizelgelerine bağlantısı, yönetim panelinden edinilebilir.Gezinme panelinde bir sekme da olarak eklenebilir.
-
-Akış çizelgeleri, iş süreçlerin modellemesi için tasarlanmıştır.Yönetici akış şemalarını oluşturabilir ve düzenleyebilir. Normal kullanıcılar yalnızca akış çizelgelerini görüntüleyebilirler.
-
-Her akış şemasının sipesifik bir varlık türü (Hedef Türü alanı) vardır. Akış çizelgesi gelecek işlem örneklerinin yürütülmesini belirtir. Bu, akış elemanları ve elemanlar arasındaki bağlantıları içerir.
-
-İşlem akış şeması denetlenmemiş 'Etkin mi?' Alana sahipse süreç örneklerini başlatmaz.
-
-Belli bir akış şeması öğesinin ayrıntılarını ve parametrelerini görmek için üzerini tıklamanız gerekir.Düzenleme modunda parametreleri düzenleyebileceksiniz.
-
-## İşlemler
-
-İşlemler yönetim panelinde mevcuttr. Bağlantı, gezinme panelinde bir sekme olarak da eklenebilir.
-
-İşlem, iş süreci örneğini temsil eder. Başlatıldığında 'Başlamış' durumuna gelir. İşlem tamamlandığında 'Sona Erdi' durumu alır. Süreç, işlemi düzenlemeye erişimi olan bir kullanıcı tarafından da manuel olarak durdurulabilir. El ile durdurulursa durum 'Durduruldu' durumuna gelir.
-
-İşlem akış şemasına göre gerçekleştirilir. İşlem başladıktan sonra akış şeması değiştirilemez.
-
-Süreç tek bir hedefe kayıt ile ilgilidir.
-
-Süreçler otomatik olarak (belirli koşullar veya çizelgeleme ile) veya manuel olarak (akış şemasında en az bir Başlama Olayı olduğunda) başlatılabilir. İşlemin manuel olarak başlatılması için, kullanıcının süreçlerin listelenmiş görünümünde 'İşlemi Başlat' butonuna tıklaması gerekir.
-
-## Akış Şeması Öğeleri
-
-### Etkinlikler
-
-Olaylar akış şemasında daireler şeklinde gösterilir.
-
-#### Etkinliği Başlat
-
-Parametre yok. Bu sürecin başlangıç noktasıdır. Etkinliğin başlatılması, süreç oluşturma erişimine sahip bir kullanıcı tarafından manuel olarak başlatılabilir. Kullanıcı, işlemlerin listelenmiş görünümünde 'İşlemi Başlat' butonuna tıklamalıdır.
-
-#### Şartlı Başlama Olayı
-
-Sürecin başlangıç noktası. Belirtilen koşullar sağlandığında otomatik olarak tetiklenmesi gerekiyor. İki tür tetikleyici vardır: 'Kayıt oluşturulduktan sonra' ve 'Kaydedildikten sonra'.
-
-#### Zamanlayıcı Başlatma Olayı
-
-İşlemin başlama noktası. Süreçleri zaman çizelgesi ile başlatır. İşlem başlatma ve crontab gösteriminde zamanlama için kayıtları döndüren listeleme raporunun belirtilmesi gerekir.
-
-#### Koşullu Ara Durum
-
-Bu olay, belirtilen ölçütler yerine getirilene kadar akışı durdurur.
-
-#### Zamanlayıcı Ara Olayı
-
-Bu olay akışını durdurur ve olayın parametreleri tarafından belirtildiği sürece bekler.
-
-Daha karmaşık zamanlayıcı ayarları için [formula](formula.md) kullanabilirsiniz. Formül komut dosyaları, Tarih-Saat değerlerini döndürmelidir(UTC saat dilimi içinde). Zamanı geldiğinde akış bir sonraki elemana ilerletilecektir.
-
-Tarih-saate en yakın formül fonksiyonunu kullanarak, zamanlayıcıyı ilerideki belirli bir zamana ayarlamak mümkündür, örn. bir sonraki iş gününün başlangıcı şeklinde.
-
-#### Etkinlik Sonu
-
-Akımı sonlandırır. Paralel olarak çalışan akışları sona erdirmez. Akış son olaya ulaştığında ve paralel çalışan hiçbir şey olmadığında işlem son bulur.
-
-#### Olayı sona erdirmek
-
-Tüm akışları bitirir. İşlem daha sonra bitirilir.
-
-### Ağ geçitleri
-
-Ağ geçitleri elmas olarak görüntülenir.
-
-#### Özel Ağ Geçidi
-
-Akışları ayırabilir veya bir araya getirebilir.
-
-Sapma durumunda, belirtilen kriterlere göre seçilecek tek bir akış (yol) tanımlanır. İlk karşılaşılan koşul akışı belirler, sonraki koşullar atlanır. Akışı varsayılan olarak belirtme olanağı vardır. Varsayılan akış, herhangi bir karşılanmış koşulları yoksa seçilir.
-Varsayılan akış, eğik çizgi işareti ile işaretlenmiştir.
-
-
-Yakınsama durumunda, akış sadece giden elemana yönlendirilir. Akış geldiğinde bloke olmaz, paralel akışlar tek bir akışla birleştirilmez.
-
-
-
-
-
-
-#### Kapsamlı Ağ Geçidi
-
-Akışı ayrıştırabilir veya bir araya getirebilir.
-
-Ayrılması durumunda, her bir akışın ölçütlerinin başarısına bağlı olarak bir veya birden çok paralel akışa (yollar) yönlendirilebilir.
-Varsayılan yol, herhangi bir karşılanma koşulları yoksa seçilir. Varsayılan akış, eğik çizgi işareti ile işaretlenmiştir.
-
-Genişleyen bir kapsayıcı ağ geçidi tarafından üretilen paralel akışları birleştirmek gerekiyorsa, kapsayıcı bir ağ geçidi kullanmanız gerekir. Gelen akışların hepsini bekleyecek ve giden öğeye devam edecektir.
-
-
-
-Not: Ayrılan ve birbirine yaklaşan ağ geçitleri dengelenmelidir.
-
-Not: Paralel akışlardan bir tanesi herhangi bir nedenden dolayı kesilirse, ayrılan ağ geçidi hiçbir zaman işlenmeyecektir. İşlem bloke edilecektir. Böyle bir durumu getirebilecek bir akış şeması tasarımından kaçınınız.
-
-#### Paralel Ağ Geçidi
-
-Akışı ayrıştırabilir veya bir araya getirebilir.
-
-Ayrışması durumunda akış birden fazla paralel akışa bölünür. Bu ağ geçidi için hiçbir parametre mevcut değil.
-
-Yakınsama durumunda tüm gelen akışlar gelene kadar beklenir ve bir sonraki giden elemana geçilir.
-
-
-
-Not: Ayrışan ve birbirine yaklaşan ağ geçitleri dengelenmelidir.
-
-Not: Paralel akışlardan bir tanesi herhangi bir nedenden dolayı kesilirse, farklı ağ geçidi hiçbir zaman işlenmeyecektir. Böyle bir durumu gerçekleştirebilecek bir akış şeması tasarımından kaçınınız.
-
-#### Etkinlik Tabanlı Ağ geçidi
-
-Akışı yalnızca birbirinden uzaklaştırabilir.
-
-Giden olaylardan herhangi biri tetiklenene kadar akışı durdurur. Başlatılan olay tek akışı belirler.Diğer giden olaylar reddedilir.
-
-Giden dizi akışlarının diğer ucunda sadece orta dereceli olaylar olabilir.
-
-
-
-
-### Aktiviteler
-
-Olaylar dönen dikdörtgenler halinde gösterilir.
-
-#### Görev
-
-Görev, işlemlerin ardından gerçekleştirebilir:
-
-* Kayıt Oluştur - Herhangi bir varlık türünün yeni kaydını oluşturur;
-* İlişkili Kayıt Yarat - hedef kayıtla ilgili yeni kayıt oluşturur;
-* Hedef Kaydı Güncelle;
-* İligili Kaydı Güncelleme - kayıtları veya hedef kaydıyla ilgili kayıtları günceller;
-* Oluşturulan Kaydı Güncelle - geçerli işlemlerle oluşturulan herhangi bir kaydın belirli alanını günceller;
-* İşlem Kaydı Güncelleme - işlemi belirli bir kullanıcıya veya ekibe atamak için kullanılabilir;
-* Diğer Kayıt Bağlantısı - hedef kaydı belirlenmiş bir kayıtla birleştirir;
-* Diğer Kayıttan Bağlantısını Kaldırın - hedef kaydın belirtilen kayıttan kaldırılmasını sağlayın;
-* Atama Kuralını Uygula - Hedef kaydı, süreç kaydını veya proses tarafından oluşturulan herhangi bir kaydı belirli kurallara göre atar;
-* Bildirim Oluştur - belirli kullanıcılar için uygulama içi bildirim oluşturur;
-* Takip Etmek - belirli kullanıcıların hedef kaydı, işlem kaydını veya süreç tarafından oluşturulan herhangi bir kaydı izlemesini sağlar;
-* Hizmet Eylemini Çalıştır - geliştiriciler tarafından uygulanan özel hizmet eylemlerini çalıştırır.
-
-Görev için uygulanabilir işlemler, iş Akışı özelliğinde olduğu gibi hemen hemen aynıdır. [Iş akışının eylemleri] hakkında daha fazla ayrıntıya bakmak için(workflows.md#actions).
-
-#### Mesaj Gönderme Görevi
-
-Belirli bir alıcıya e-posta mesajı gönderir.
-
-#### Kullanıların Görevi
-
-Kullanıcı etkileşimi için esnek bir yetenek sağlar. Kullanıcı (açıkça belirtilmiş veya atama kuralı tarafından) görevi tamamlayana kadar yürütmeyi durdurur. İşlem Kullanıcılı Görevi kaydı sistemde yaratılacaktır. Varsayılan olarak üç eylem türü vardır: Onayla, Gözden Geçir, Başar.
-
-* Onay türü, kullanıcının "Onaylandı" ve "Reddedildi" seçeneklerinden birini seçmesini gerektirir.
-* İnceleme türü yalnızca bir seçenek sunar: 'İncelendi'.
-* Başarılı tipte iki seçenek vardır: 'Tamamlandı' ve 'Başarısız'.
-
-
-Oluşturulan İşlem Kullanıcılı Görevi kaydına atanan kullanıcı, uygulama içi bildirim alacaktır. Yönetici ayrıca e-posta bildirimlerini de etkinleştirebilir.
-
-Kullanıcılar gerçek işlem kullanıcılı görevlerini görmek için gösterge tablolarına İşlem Kullanıcılı görevlerin dashletini de ekleyebilirler.
-
-Geçen ağ geçitlerinde veya koşullu olaylarda geçen kullanıcı görevinin çözünürlüğünü okumak mümkündür, böylece süreç akışında dallanma meydana gelir.
-
-#### Komut Dosyası Görevi
-
-Komut dosyasını [espo-formula](formula.md) dili ile çalıştırır. Ayarlanan tüm değişkenler (`$ variableName`) süreç içinde saklanır ve kullanılabilirdir.
-
-### Akımlar
-
-#### Dizi Akışı
-
-Katı bir ok şeklinde temsil edilir. İşlem öğelerinin yürütülme sırasını belirtir.
-
-## Koşullar
-
-Şartlı olaylar, özel ve kapsayıcı ayrılan ağ geçitleri, işlemin akışını belirleyen koşullara sahiptir.
-
-UI aracılığıyla aşağıdaki kayıtların koşullarını kontrol etme olanağı vardır:
-
-* Kayıtlı hedef;
-* Bire bir ile çocuk-ebeveyn ilişkileri yoluyla hedefle ilgili kayıtlar;
-* İşlem tarafından görevler vasıtasıyla yaratılan kayıtlar;
-* Çözünürlüğün kontrol edilmesini sağlayan kullanıcı görev kayıtları.
-
-[Espo-formula](formula.md) dilinde koşulları tanımlamak da mümkündür.
-
-BPM aracındaki koşullar İş Akışı özelliğindeki koşullarla aynıdır. [Iş akışı koşulları] hakkında daha fazla ayrıntıya buradan bakın(workflows.md#conditions).
-
-## Örnekler
-
-### Örnek 1
-
-
-
-### Örnek 2
-
-
-
-### Örnek 3
-
-
diff --git a/i18n/tr_TR/administration/emails.md b/i18n/tr_TR/administration/emails.md
deleted file mode 100644
index 54d3784a9..000000000
--- a/i18n/tr_TR/administration/emails.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# E-Postalar
-
-> Önemli. E-posta alma işini yapmak için sisteminizde yapılandırılmalıdır [Cron] (https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab). Bilgileri, Yönetim> Zamanlanmış İşler bölümünde EspoCRM'yi bulabilirsiniz.
-
-## Genel Bakış
-
-EspoCRM, IMAP posta kutularını izleyebilme özelliğine sahiptir. E-posta iki şekilde arşivlenebilir bunlar: Grup E-posta Hesapları ve Kişisel E-posta Hesaplarıdır. Grup Gelen Hesaplar, grup posta kutuları için tasarlanmıştır: en yaygın olanı bir destek kutusudur.Kişisel E-posta Hesapları, kullanıcıların kişisel posta kutularına yönelik tasarlanmıştır.
-
-
-Bir e-posta geldiğinde sistem uygun kaydı (Hesapları, Rehberi, Fırsatı, Durumu) bağlamaya çalışır. Bu kaydı takip eden kullanıcılar CC değillerse bile, sistemdeki yeni bir e-postayla ilgili bildirim alırlar.
-
-## Grup E-posta Hesapları
-
-Grup E-posta Hesaplarını yalnızca yöneticiler kurabilir. Grup E-posta Hesapları hem e-posta alma hem de gönderme için kullanılabilir.
-Grup hesaplarından e-posta göndermek 4.9.0 sürümünden beri mevcuttur.
-
-Takım alanları hangi ekiplerin gelen e-postalara atanacağını belirtirler.
-
-Eğer grup e-posta hesabının SMTP'si varsa ve paylaşılan olarak işaretlenmişse erişim, Grup E-posta Hesabının izni aracılığıyla Roller tarafından kontrol edilecektir. İzin seviyesi 'takım' olarak ayarlanırsa, Takımlar alanı kullanılacaktır.
-
-Sistemin, gelen e-postalar için otomatik cevap göndermesini sağlayan bir özelliği vardır.
-
-## Kutuya E-postayla Gönder
-
-Sistemin, gelen grup e-postalarından kutular oluşturmasını sağlamak için bir seçenek vardır.
-Bu özellik, destek ekipleri için tasarlanmıştır.
-Durumlar, belirtilen takımdaki kullanıcılara şu şekillerde dağıtılabilir:
-`direct assignment`, `round-robin` and `less-busy`.
-Sadece ilk e-posta tredin içerisinde yeni bir kutu oluşturur.
-Ardından gelen her biri, mevcut kutu kaydına bağlanır ve akış panelinde görüntülenir.
-
-Kullanıcılar müşteriye bir cevap göndermek istediğinde, gönderilen e-postanın ebeveyni kutunun seçili olduğundan emin olunmalıdır. Bu, kullanıcının kendine değil müşterinin grup e-posta adresine cevap vermesini sağlayacaktır.
-
-## Kişisel E-posta Hesapları
-
-Kullanıcılar, izlenmesi gereken kendi e-posta hesaplarını kurabilirler. E-postalar>En Sağdaki Açılır Menü>Kişisel E-posta Hesapları. Yönetici aynı zamanda kullanıcıların e-posta hesaplarını yönetebilir.
-
-## E-posta Filtreleri
-
-Bunlar, gelen e-postaların belirtilen kriterlere göre filtrelenmesine izin verir. Örneğin. Bazı uygulama tarafından gönderilen bildirim mesajlarının EspoCRM'ye aktarılmasını istemiyorsanız, EspoCRM'yi geçmek için filtre oluşturabilirsiniz.
-
-
-Yönetici, tüm e-posta hesaplarına uygulanan genel filtreler oluşturabilir. Kullanıcılar kendi kişisel e-posta hesapları ve bütün gelen kutuları için filtreler oluşturabilirler.
diff --git a/i18n/tr_TR/administration/entity-manager.md b/i18n/tr_TR/administration/entity-manager.md
deleted file mode 100644
index 91de1eb86..000000000
--- a/i18n/tr_TR/administration/entity-manager.md
+++ /dev/null
@@ -1,82 +0,0 @@
-# Varlık Yöneticisi
-
-Varlık Yöneticisi, Yönetici panelinde kullanılabilir. EspoCRM örneğini iyi derecede özelleştirmek için bir olanak sağlar. Aşağıdakileri yapabilirsiniz:
-
-* Yeni varlık türlerini ekleyin.
-* Varlık türlerini özelleştirin: etiketleri değiştirin, liste görünümünde varsayılan sıralama, akışı etkinleştirin veya devre dışı bırakın.
-* Alanları yapılandırın: yeni alan ekleyin, mevcut alanları özelleştirin.
-* İlişkileri yapılandırın: yeni ekleyin, mevcut olanların etiketlerini değiştirin.
-
-## Yeni varlık oluşturmak
-
-Varlık Yöneticisi sayfasındaki 'Varlık Yarat' düğmesini tıklayın. Adını, etiketlerini ve türünü belirtin. Eğer 'Kişi' türünü seçerseniz, varlığınız E-posta, Telefon, İsim, Soyisim ve Selamlaşma alanlarına sahip olacaktır. Varlığınızın akış paneli olmasını ve kullanıcıların bu tür varlıkları takip etmesini istiyorsanız "Akış"'ı kontrol edin.
-
-
-Türler:
-
-* Taban - Sadece isim, atanmış kullanıcı, takımlar, açıklamalar gibi temel alanlar içeren boş varlıklar.
-* Taban Artı - Tabana benzer ancak Aktiviteler, Geçmiş ve Görevler panelleriyle birlikte. (4.3.0'dan itibaren kullanılabilir).
-* Etkinlik - Başlangıç Tarihi, Bitiş Tarihi, Süre, Ebeveyn, Durum alanlarıdır.Takvim ve Etkinlikler panelinde mevcuttur (4.3.0'dan bu yana, Yönetim> Ayarlar'da etkinleştirilmelidir).
-* Kişi - E-posta, Telefon, Adı, Soyadı, Selamlama, Adres alanlarını. Etkinlikler, Tarihçe, Görevler panellerini barındırır.
-* Şirket - E-posta, Telefon, Fatura Adresi, Nakliye Adresi alanlarını. Etkinlikler, Tarihçe, Görevler panellerini barındırır.
-
-## Mevcut varlığı güncelle
-
-Belli bir varlık üzerinde `Düzenle` bağlantısını tıklarsanız, o varlığın bazı parametrelerini değiştirebileceksiniz.
-
-* Etiketler - varlığın tekil ve çoğul adı..
-* Varsayılan sipariş kayıtları liste görünümlerine göre sıralanır.
-* Akış - Akış özelliğinin bu varlık için etkinleştirilip etkinleştirilmediği.
-* Devre dışı - sisteminizde bu öğeye ihtiyacınız yok ise kontrol edin.
-* Metin Filtresi Alanları - ana metin filtresi ve genel arama için hangi alanları arayacaklarını.
-
-
-## Alanlar
-
-'Alanlar' bağlantısını tıklayarak ayrı bir sayfaya geçeceksiniz. Orada yeni alanlar oluşturabilir veya mevcut alanları güncelleyebilirsiniz. Varlık Yöneticisinde şu alan türleri mevcuttur:
-
-* Adres - sokak, şehir, eyalet, posta kodu ve ülke iledir adres;
-* Dizi - birden fazla değeri seçebilme olanağıyla değerlerin listesidir (bu alana arama yapmanız gerekiyorsa iyi bir seçenek değildir); seçenekler belirtilmemişse, kullanıcılar kendi değerlerini ekleyebilir.
-* Çoklu Eklenti - çoklu dosya ekleri;
-* Otomatik artış - yalnızca üretilen sayıları okumak;
-* Boolean - onay kutusu, doğru veya yanlış;
-* Para birimi - para birimlerine değer vermek için;
-* Tarih;
-* Tarih Saat;
-* Enum - yalnızca bir değer seçme olanağı bulunan kutuyu seçin;
-* Dosya - bir dosya yüklemek;
-* Float - ondalık kısmı olan sayı;
-* Yabancı - varlık ile lgili bir alan;
-* Görüntü - önizleme ile görüntü dosyasını yükleme;
-* Tamsayı - tamsayı;
-* Sayı - mümkün ön ek ve belirli bir uzunluk ile otomatik artan sayıda dize türü;
-* Çoklu-enum - değerlerin listesi, birden fazla değer seçme yeteneğine sahipken (Diziye benzer şekilde değilse iyi bir seçenek değil) Diziye benzerdir ancak daha güzeldir.
-* Metin - metin alanı, uzun satırlı metinler için;
-* Url - bağlantılar için;
-* Varchar - kısa metin;
-* Göründüğü gibi çıktı - Metin formatının becerisi ile text alanına benzer;
-
-Parametreler:
-* Gerekli - alanın doldurulması zorunludur.
-* Varsayılan Değer - Yeni kayıt oluştururken alanın değeridir.
-* Denetlendi - alandaki güncellemeler Akış'da günlüğe kaydedilecek.
-
-**Not**: Yeni alanı ekledikten sonra [düzenlerini] (layout-manager.md) (Yönetim> Düzen Yöneticisi) üzerine bu alanı koymanız gerekir..
-
-### Dinamik Mantık
-
-Formları dinamik hale getirme olanağı sağlar. Bazı alanları görünür, gerekli veya sadece okunan hale getiren koşulları tanımlamak mümkündür. Formdaki veriler değiştirildiğinde koşullar otomatik olarak kontrol edilir.
-
-Enum, Dizi ve Çoklu-Enum alanlarında, karşılaşılan koşullara bağlı olarak alan için kullanılabilecek farklı seçenek kümeleri tanımlamak mümkündür.
-
-## İlişkiler
-
-Hem başlangıçtaki hem de özel öğeler arasında yeni ilişkiler oluşturabilirsiniz. Kullanılabilir 3 ilişki türü vardır bunlar:
-
-* Birden Çok'a: Bu ilişkiyi oluşturduktan sonra, doğru varlığın ayrıntılı düzenine bir bağlantı alanı yerleştirebilir ve solundaki varlık için ilişki paneli ekleyebilirsiniz;
-* Çoktan Bir'e: Birden çoğa benzer ama tam terside olabilir.
-* Çoktan çoğa: Her iki taraftaki ilişki panelleri.
-
-'Birden Fazla Bağlantı' parametresi, 'çoklu bağlantı' alanının ilişkiyle birlikte oluşturulacağını belirtir. Düzene böyle bir alan koyabilirsiniz. İlgili kayıtların hızlıca toplanması için uygundur. İlişkileriniz, ayrıntılı görünüm ekranının yüklenmesini yavaşlatan çok sayıda bağlantılı kayıt içeriyorsa, bu iyi bir seçenek değildir.
-
-Parametre 'Denetlendi' işaretlendiyse ilişkinin güncellemeleri Akış'daki günlüğe kaydedilir.
diff --git a/i18n/tr_TR/administration/extensions.md b/i18n/tr_TR/administration/extensions.md
deleted file mode 100644
index bf2c9bf13..000000000
--- a/i18n/tr_TR/administration/extensions.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Uzantıları Yönet
-
-## Uzantıları nasıl yüklerim?
-
-EspoCRM uzantısını yüklemek için (ör. Gelişmiş Paket, VoIP Entegrasyonu):
-
-1. Yönetici olarak giriş yapın.
-2. Yönetim > Uzantılara gidin.
-3. Uzantı paketinizi yükleyin (zip dosyası).
-4. Yükleme butonuna basın.
-
-
-## Uzantıyı nasıl güncellerim?
-
-Zaten yüklü olan bir uzantının (örneğin, Gelişmiş Paket, VoIP entegrasyonu) yeni bir sürümüne yükseltmek için:
-
-1. Gerekli uzantının yeni sürümünü indirin.
-2. Yönetici olarak giriş yapın.
-3. Yönetim > Uzantılara gidin.
-4. Zaten yüklü olan sürümü silmeden yeni uzantı paketini (zip dosyası) yükleyin.
-5. Yükleme butonuna basın.
-
-
-## Bir uzantıyı nasıl kaldırırım?
-
-Yüklü olan bir uzantıyı kaldırma adımları:
-
-1. Yönetici olarak giriş yapın.
-2. Yönetim > Uzantılara gidin.
-3. Mevcut uzantılar listesindeki istenilen uzantıyı bulun.
-4. Silme butonuna tıklayın.
-
-
-## Bir uzantıyı nasıl silerim?
-
-Bir uzantı kaldırıldığında, sistemde yine de kullanılabilir. Tamamen silinebilir. Bir uzantıyı silmek için gerçekleştirilecek adımlar:
-
-1. Yönetici olarak giriş yapın.
-2. Yönetim > Uzantılara gidin.
-3. Mevcut uzantılar listesindeki istenilen uzantıyı bulun.
-4. Kaldırma butonuna tıklayın.
-
diff --git a/i18n/tr_TR/administration/formula.md b/i18n/tr_TR/administration/formula.md
deleted file mode 100644
index 0e7579bb2..000000000
--- a/i18n/tr_TR/administration/formula.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# Hesaplanan Alanlar (Formül)
-
-Varlık modunda spesifik varlık türü için script (formül) tanımlamak mümkündür. Bu script kayıt kaydedilmesinden önce her zaman gerçekleştirilmiş olacaktır.
-
-Hesaplamadan elde edilmiş değerler ile otomatik olarak spsifik alanları (semboller) ayarlamak için bir yetenek sağlar.
-
-Formülü düzenlemek için şunu izleyin, Yönetim > Varlık Yöneticisi > gerekli varlık sırasındaki sağdaki açılır menü > Formül.
-
-Ayrıca hesaplanmış varsayılan, Varlık Yöneticisi aracılığıyla salt okunur alanları ayarlamanız gerekebilir.
-
-## Sözdizimi
-
-EspoCRM formülü bu özellik için spesifik olarak tasarlanmış basit dilde yazılır.
-
-Formülde kullanılan operatörler, fonksiyon simgeleri ve değerler vardır. Ayrılmış ifadeler `;` karakteri ile sınırlandırılmış olmalıdır.
-
-### Operatörler
-
-* `=` - atama.
-* `||` - mantıksal OR,
-* `&&` - mantıksal AND,
-* `!` - mantıksal NOT,
-* `+`- sayısal toplama,
-* `-` - sayısal çıkarma,
-* `*` - sayısal çarpma,
-* `/` - sayısal bölme,
-* `%` - sayısal modulo,
-* `==` - karşılaştırma eşit,
-* `!=` - karşılaştırma eşit değil,
-* `>` - karşılaştırma daha büyük,
-* `<` - karşılaştırma daha küçük,
-* `>=` - karşılaştırma daha büyük veya eşit,
-* `<=` - karşılaştırma daha küçük veya eşit.
-
-Operatörlerin önceliği:
-* `=`;
-* `||`, `&&`;
-* `==`, `!=`, `>`, `<`, `>=`, `<=`;
-* `+`, `-`;
-* `*`, `/`, `%`.
-
-### Semboller
-
-Semboller hedef varlığın alan değerlerini temsil eder. Artı butonuna tıklayarak geçerli simgeleri girebilirsiniz.
-
-Takip eden `linkName.attributeName` format ile ilgili varlıkların sembollerine erişim mümkündür.
-
-### Fonksiyonlar
-
-Fonksiyon kullanım biçimi: `groupName\functionName(argument1, argument2, ..., argumentN)`.
-
-Kutu dışındaki fonksiyonlar aşağıda listelenmiştir.
-
-#### ifThenElse
-`ifThenElse(CONDITION, CONSEQUENT, ALTERNATIVE)` CONDITION ile karşılaşılırsa CONSEQUENT yap. Değilse -- o zaman ALTERNATIVE yap.
-
-#### ifThen
-`ifThen(CONDITION, CONSEQUENT)` CONDITION ile karşılaşılırsa CONSEQUENT yap. Değilse -- hiçbir şey yapma.
-
-#### string\concatenate(
-`string\concatenate(STRING_1, STRING_2)` İki veya daha fazla diziyi sıralar.
-
-#### string\substring
-`string\substring(STRING, START, LENGTH)` START konumu ve LENGTH ile bir STRING'den karakterleri çıkarır.
-
-LENGTH çıkarılırsa, START'tan STRING'in sonuna kadar başlatılan alt dizi getirilmiş olacak.
-
-LENGTH negatifse, o zaman bu birçok karakter STRING'in sonundan çıkarılmış olacak.
-
-#### string\\trim
-`string\trim(STRING)` Başlangıçtan ve STRING'in sonundan beyazalanı çıkarır.
-
-#### string\\lowerCase
-`string\lowerCase(STRING)` Harfleri küçük harfe dönüştürür. (Sürüm 5.0.0'den beri)
-
-#### string\\upperCase
-`string\upperCase(STRING)` Harfleri büyük harfe dönüştürür. (Sürüm 5.0.0'den beri)
-
-#### datetime\\today
-`datetime\today()` Bugünün tarhini getirir.
-
-#### datetime\now
-`datetime\now()` Geçerli tarih saati getirir.
-
-#### datetime\format
-`datetime\format(VALUE, [TIMEZONE], [FORMAT])` Tarih veya tarih saat VALUE'yu uygulama ayarlarına göre biçimlendirilmiş diziye dönüştürür. TIMEZONE ve FORMAT çıkarılablir. TIMEZONE çıkarılırsa o zaman varsayılan zaman dilimi kullanılır. FORMAT çıkarılırsa o zaman varsayılan format kullanılır.
-
-#### datetime\date
-`datetime\date(VALUE, [TIMEZONE])` Ayın gününü getirir (1-31). `0` VALUE boşsa. TIMEZONE çıkarılırsa o zaman sistem zaman dilimi kullanılır. (4.7.0 sürümünden beri)
-
-#### datetime\month
-`datetime\month(VALUE, [TIMEZONE])` Ayı getirir (1-12). `0` VALUE boşsa. TIMEZONE çıkarılırsa o zaman sistem zaman dilimi kullanılır. (4.7.0 sürümünden beri)
-
-#### datetime\year
-`datetime\year(VALUE, [TIMEZONE])` Yılı getirir. `0` VALUE boşsa. TIMEZONE çıkarılırsa o zaman sistem zaman dilimi kullanılır. (4.7.0 sürümünden beri)
-
-#### datetime\hour
-`datetime\hour(VALUE, [TIMEZONE])` Saati getirir (0-23). `-1` VALUE boşsa. TIMEZONE çıkarılırsa o zaman sistem zaman dilimi kullanılır. (4.7.0 sürümünden beri)
-
-#### datetime\minute
-`datetime\minute(VALUE, [TIMEZONE])` Dakikayı getirir (0-59). `-1` VALUE boşsa. TIMEZONE çıkarılırsa o zaman sistem zaman dilimi kullanılır. (4.7.0 sürümünden beri)
-
-#### datetime\dayOfWeek
-`datetime\dayOfWeek(VALUE, [TIMEZONE])` Haftanın günlerini getirir (0-6). `-1` VALUE boşsa. `0` Pazar için. TIMEZONE çıkarılırsa o zaman sistem zaman dilimi kullanılır. (4.7.0 sürümünden beri)
-
-#### datetime\diff
-`datetime\diff(VALUE_1, VALUE_2, INTERVAL_TYPE)` İki tarih veya zaman dilimi arasındaki farkı getirir. INTERVAL_TYPE 'yıllar', 'aylar', 'günler', 'saatler', 'dakikalar' olabilir. Başarısız olursa `null` getirir. VALUE_1 < VALUE_2 sağlanırsa sonuç negatif olacaktır.
-
-#### datetime\addMinutes
-`datetime\addMinutes(VALUE, MINUTES)` Zaman dilimi VALUE'ya MINUTES ekler. MINUTES negatif olabilir.
-
-#### datetime\addHours
-`datetime\addHours(VALUE, HOURS)` Zaman dilimi VALUE'ya HOURS ekler. HOURS negatif olabilir.
-
-#### datetime\addDays
-`datetime\addDays(VALUE, DAYS)` Zaman veya zaman dilimi VALUE'ya DAYS ekler. DAYS negatif olabilir.
-
-#### datetime\addWeeks
-`datetime\addWeeks(VALUE, WEEKS)` Zaman veya zaman dilimi VALUE'ya WEEKS ekler. WEEKS negatif olabilir.
-
-#### datetime\addMonths
-`datetime\addMonths(VALUE, MONTHS)` Zaman veya zaman dilimi VALUE'ya MONTHS ekler. MONTHS negatif olabilir.
-
-#### datetime\addYears
-`datetime\addYears(VALUE, YEARS)` Zaman veya zaman dilimi VALUE'ya YEARS ekler. YEARS negatif olabilir.
-
-#### datetime\closest
-`datetime\closest(VALUE, TYPE, TARGET, [IS_PAST], [TIMEZONE])` En yakın zaman veya zaman dilimini geçmiş argümana bağlı VALUE'ye getirir. (Sürüm 5.0.0'dan beri)
-
-TYPE sıralanan şu değerlerden biri olabilir: 'time', 'minute', 'hour', 'date', 'month', 'dayOfWeek'. TARGET bir tamsayı değeri veya bir dizi değeridir. IS_PAST geçmişteki en yakını bulmak anlamına gelir. TIMEZONE çıkarılırsa o zaman varsayılan zaman dilimi kullanılır.
-
-Örnekler:
-
-`datetime\closest(datetime\now(), 'time', '20:00')` Gelecekteki en yakın zaman dilimini 20:00 zamanı getirecek.
-
-`datetime\closest('2017-11-20', 'date', 1, true)` `2017-11-01`, ayın ilk gününü getirecek.
-
-`datetime\closest(datetime\now(), 'dayOfWeek', 1)` Gelecek Pazartesi'yi (günün başlangıcı) getirecek.
-
-#### number\format
-`number\format(VALUE, [DECIMALS], [DECIMAL_MARK], [THOUSAND_SEPARATOR])` Sayısal VALUE'yu bir spesifik biçime veya varsayılan uygulama ayarlarına göre biçimlendirilmiş diziye dönüştürür. DECIMALS, DECIMAL_MARK OR THOUSAND_SEPARATOR ise, o zaman sistem varsayılanları kullanılır.
-
-Örnekler:
-
-`number\format(2.666667, 2)` - 2.67 sonuçlar;
-
-`number\format(1000, 2)` - 1,000.00 sonuçlar;
-
-`number\format(10.1, 0)` - 10 sonuçlar.
-
-
-#### number\abs
-`number\abs(VALUE)` Kesin değer. VALUE sayısal değilse geçersiz olarak getirir. .
-
-#### number\round
-`number\round(VALUE, PRECISION)` VALUE'nun yuvarlanmış değerini belirli PREECISION'a getirir (ondalık noktadan sonraki basamak sayısı). PRECISION negatif veya sıfır (varsayılan) olabilir.
-
-#### number\floor
-`number\floor(VALUE)` Gerekliyse aşağı yuvarlayarak sonraki en küçük tam sayı değeerini getirir. (4.9.0 sürümünden beri)
-
-#### number\ceil
-`number\ceil(VALUE)` Gerekliyse yukarı yuvarlayarak sonraki en büyük tam sayı değeerini getirir. (4.9.0 sürümünden beri)
-
-#### entity\isNew
-`entity\isNew()` Varlık yeniyse (oluşturuluyorsa) TRUE ve değilse (güncelleniyorsa) FALSE getirir.
-
-#### entity\\isAttributeChanged
-`entity\isAttributeChanged(ATTRIBUTE)` Varlığın ATTRIBUTE'u değiştirilmişse TRUE getirir.
-
-Örnek:
-
-`entity\isAttributeChanged('status')`
-
-#### entity\isAttributeNotChanged
-`entity\isAttributeNotChanged(ATTRIBUTE)` Varlığın ATTRIBUTE'u değiştirilmemişse TRUE getirir.
-
-#### entity\attributeFetched
-`entity\attributeFetched(ATTRIBUTE)` Hedef varlık veritabanından çekildiğinde ayarlanmış simge. Değiştirilmeden önce.
-
-Örnek:
-
-`entity\isAttributeChanged('assignedUserId')`
-
-#### entity\addLinkMultipleId
-`entity\addLinkMultipleId(LINK, ID)` Link Çoklu alana kimlik ekler. Örneğin, 'teams' alanına 'someTeamId' ekle.
-
-`entity\addLinkMultipleId(LINK, ID_LIST)` Kimliklerin listesini ekler. (4.8.3 sürümünden beri)
-
-#### entity\hasLinkMultipleId
-`entity\hasLinkMultipleId(LINK, ID)` Link Çoklu alanın belirli kimliğinin olup olmadığını denetler.
-
-#### entity\removeLinkMultipleId
-`entity\removeLinkMultipleId(LINK, ID)` Link Çoklu alandan belirli bir kimlik kaldırır.
-
-#### entity\isRelated
-`entity\isRelated(LINK, ID)` Hedef varlığın LINK ve ID ile temsil edilen başka bir varlık ile ilgili olup olmalığını denetler.
-
-#### env\userAttribute
-`env\userAttribute(ATTRIBUTE)` Geçerli kullanıcının ATTRIBUTE'unu getirir.
-
-#### list
-`list(VALUE-1, ... VALUE-N)` Sıralama getirir. (4.7.0 sürümünden beri)
-
-#### array\includes
-`array\includes(LIST, VALUE)` LIST, VALUE içeriyorsa true getirir. Sıralama ve ÇokluSıra alanlarında kullanılabilir. (4.7.0 sürümünden beri)
-
-#### array\push
-`array\push(LIST, VALUE1 [, VALUE2 ...])` Bir sıralamanın sonuna bir veya daha fazla eleman ekler ve yeni sıralama getirir. (5.0.0 sürümünden beri)
-
-#### array\length
-`array\length(LIST)` LIST içindeki eleman sayısını getirir. (4.8.1 sürümünden beri)
-
-
-### Değerler
-
-* Diziler. Örn. 'bazı diziler';
-* Tam sayılar. Örn. 1, 100, 40300.
-* Kesirli sayılar. Örn. 5.2.
-
-### Değişkenler
-
-Formülde özel değişkenler tanımlamak mümkündür.
-```
-$someVariableName = 'Test';
-description = $test;
-```
-
-
-## Örnekler
-
-```
-ifThen(
- entity\isNew() && assignedUserId == null,
- assignedUserId = 'managerId'
-);
-
-ifThen(
- entity\isNew() && closeDate == null && stage == 'Closed Won',
- datetime\today()
-);
-```
-
-```
-amount = product.listPrice - (product.listPriceConverted * discount / 100.0);
-amountCurrency = 'USD';
-```
-
-```
-someField = string\concatenate(firstName, " '", middleName, "' ", lastName);
-```
-
-```
-ifThenElse(
- entity\isNew() && status == 'Planned' && dateStart == null,
- dateStart = datetime\addDays(datetime\now(), 10),
- ifThen(
- status == 'Held' && dateStart == null,
- dateStart = datetime\now()
- )
-);
-
-```
-
-## İş akışında formül kullanımı
-
-İş akışı durumlarında ve çalışmalarında formülden yararlanabilirsiniz. Daha fazla bilgi için [workflows documentation](workflows.md)'ye bakın.
-
diff --git a/i18n/tr_TR/administration/import.md b/i18n/tr_TR/administration/import.md
deleted file mode 100644
index e9b3c2bcd..000000000
--- a/i18n/tr_TR/administration/import.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# İçeri Aktarmak
-
-İçeri veri aktarma yalnızca yönetici kullanıcıları tarafından erişilebilir. Yönetim>İçe Aktar. Yalnızca CSV dosyalarından içe aktarabilirsiniz.
-
-## 1. Adım
-
-İhtiyacınız olan gereken kayıt türünü seçin (Varlık Türü alanı).
-Bir CSV dosyası seçin. Bir dosya, `UTF-8` formatı ile biçimlendirilmelidir.
-`Ne yapacaksınız?`ı seçin. Mevcut seçenekler: 'Yalnızca Oluştur', 'Oluştur ve Güncelle', 'Sadece Güncelle'.
-
-* `Sadece Oluştur` - kaydı sadece yaratmak istiyorsanız seçiniz.
-* `Oluştur & Güncelle`- kayıtlar oluşturulur, ancak eşleşen alan değerlerine sahip kayıtlar bulunursa değiştirilir._2. Adım_'da hangi alanların eşleşeceğini kontrol edebileceksiniz.
-* `Sadece güncelle` - eşleşen alan değerlerine sahip kayıtlar güncellenecektir.
-
-Bir CSV dosyasını seçtikten sonra Önizleme panelinde nasıl ayrıştırılacağını görebilirsiniz.Özelliklerini güncellediğinizde önizleme değişecektir.
-
-
-* `Başlık Satırı`- CSV dosyasının alan adlarına sahip ilk satıra sahip olup olmadığını.
-* `Boşta çalıştır`- içeri aktarılacak büyük bir kayıt grubunuz varsa önerilir. Aktarım, cron üzerinden işlenecektir. İçe aktarma işlemi tamamlandığında durum 'Tamamlandı' olarak ayarlanacaktır.
-* `Kopyalama için aramayı geçmek` - içeri aktarım çalışma süresini azaltacaktır.
-
-
-_ 2. Adım_ işlemine geçmek için _Next_ düğmesini tıklayın.
-
-
-
-## 2. Adım
-
-Alan eşlemesini ayarlayın: alanların CSV dosyasının sütunlarına nasıl karşılık geldiğini belirleyin. Burada gerekli olmayan sütunları atlayabilirsiniz.'Oluştur & Güncelle' ve 'Sadece güncelle' durumlarında, güncellenecek kayıtların bulunup bulunmadığını kontrol etmeniz gerekmektedir.Yeni ve güncellenmiş kayıtlardan ayarlanmasını istediğiniz varsayılan değerleri ekleyiniz. Örneğin. Atanmış Kullanıcı veya Ekip alanları belirtebilirsiniz.
-
-İçe aktarma işlemi tamamlandıktan sonra oluşturulan kayıtları geri alabilir, kopyalayabilir ve güncellenmiş kayıtları görebilirsiniz.Kopyalanan, sistemde benzer kayıt olduğu anlamına gelir.İçe aktarılan tüm kopyaları aynı anda kaldırabilirsiniz.Not: Geri çevirmek, güncellenmiş kayıtlarla çalışmaz.
-
-Devam etmek için _Run Import_ düğmesine tıklayın. İçe aktarma işlemi bitmeden biraz zaman alabilir. Bir sürü kayıt ithal etmek istiyorsanız (sunucu yapılandırmasına bağlı, genellikle 200'den fazla kayıt varsa), php parametresinin `set_time_limit` yeterince büyük olduğundan emin olmanız gerekir.
-
-
-
-## Hedef Listeye nasıl aktarılır?
-
-Kişileri, Rehberleri veya Hesapları içe aktardığınızda bunları bazı hedef listelerine ekleyebilirsiniz. 2. Adım'da 'Varsayılan Değerler' paneline Hedef Liste alanını eklemeniz ve gerekli bir hedef liste kaydını seçmeniz gerekmektedir. Var olan hedefleri bir hedef listesine eklemek için 'Sadece güncelle' veya 'Oluştur ve Güncelle' işlemini kullanabilirsiniz.
diff --git a/i18n/tr_TR/administration/installation.md b/i18n/tr_TR/administration/installation.md
deleted file mode 100644
index 8097db873..000000000
--- a/i18n/tr_TR/administration/installation.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Kurulum
-
-### Gereksinimler
-EspoCRM çoğu hosting sağlayıcıda çalışır. Gereksinimler aşağıdakileri içerir:
-
-* PHP 5.6 veya PHP'nin pdo, json, GD library, mcrypt uzantıları (genellikle varsayılan olarak etkin) ile etkinleştirilmiş son sürümü;
-* MySQL 5.5.3 veya daha yükseği.
-
-Daha fazla bilgi için [Server Configuration](server-configuration.md) makalesine bakın.
-
-### 1. EspoCRM kurulum paketini indir
-EspoCRM'in son sürümünü edinmek için [download page](http://www.espocrm.com/download/) linkini takip edin.
-
-### 2. EspoCRM Dosyalarını Sunucunuza Yükleyin
-
-İndirme biter bitmez, paketi web sunucunuza yükleyin.
-Yüklemek için SSH, FTP veya hosting yönetim panelini kullanabilirsiniz.
-Arşivi genel web sunucu dizininize çıkarın (Örn., `public_html`, `www`, vs.).
-
-_Not: FTP için, web sunucunuza yüklemeden önce arşivi çıkarmalısınız.._
-
-### 3. EspoCRM için kullanılacak bir MySQL Veritabanı oluşturun
-
-Hosting yönetim panelinize veya SSH'e gidin ve EspoCRM için yeni bir veritabanı ve kullanıcı oluşturun (örn, cPanel'de `MySQL Databases`).
-
-### 4. EspoCRM kurulum ilerlemesini çalıştırın
-
-Şimdi web tarayıcınızı açın ve EspoCRM dosyalarının olduğu URL'ye gidin (örn, `http://yourdomain.com/espo`).
-
-Bu ekranı görüyotsanız, bir "Erişim reddedildi" hatanız var.
-Yani, SSH aracılığıyla terminaldeki görüntülenen komutu uygulamalısınız veya doğru izin ayarlamalısınız.
-Dizinler için 755, dosyalar için 644 ve `data` dizini için 775 olmalıdır.
-Ayrıca doğru _owner_ ve _group_'unuz olduğuna emin olun.
-
-
-
-Aşağıdaki ekranı görüyorsanız, izin doğrudur ve EspoCRM kurulumunu başlatabilirsiniz.
-
-
-
-Bu sayfada, Lisans Anlaşması'nı okuyup kabul edebilirsiniz.
-
-
-
-Yeni oluşturduğunuz MySQL veritabanı detaylarını girin.
-
-
-
-Yönetim EspoCRM'in kullanıcı adı ve şifresini girin.
-
-
-
-Bu sayfada tarih ve zaman biçimi, zaman dilimi, para birimi ve diğerleri gibi EspoCRM'in varsayılan ayarlarını ayarlayabilirsiniz.
-
-
-
-Emailler gönderebilmek istiyorsanız, giden emailler için SMTP ayarlarını girin.
-_Next_ butonuna tıklayarak bu adım geçilebilir.
-Bu seçeneklerin tümü kurulumdan sonra EspoCRM'de eklenebilir/değiştirilebilir.
-
-
-
-Tebrikler! Kurulum tamamlandı.
-Zamanlanmış Görevlerin sisteminiz tarafından çalışır olmasını kurmak için son şey. Linux cli'da ve Windows sistemlerde _Windows Tasks Scheduler_'de `crontab -e` çalışarak yapılabilir.
-
-
-
-EspoCRM'de çalışmaktan keyif alacağınızı umuyoruz.
-
-
-
-
-
-
-
-
diff --git a/i18n/tr_TR/administration/layout-manager.md b/i18n/tr_TR/administration/layout-manager.md
deleted file mode 100644
index 0ed38bc24..000000000
--- a/i18n/tr_TR/administration/layout-manager.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Düzen Yöneticisi
-
-Düzen Yöneticisi, yönetim panelinde bulunmaktadır. Ayrıntılı görünümünü özelleştirme, düzenlem, listeleme ve kütle-güncelleme formları için arama filtreleri ve alanlarını düzenleme özelliğini sağlar.
-
-## Liste
-
-Liste görünümünün ana düzenidir. Sütunları ve parametreleri tanımlanır.
-
-
-
-Sütunlar için kullanılabilen parametreler aşağıda listelenmiştir.
-
-### Genişlik (%)
-
-Sütun genişliği yüzdesi boş ise otomatik genişlik anlamına gelmektedir.
-
-### Bağlantı
-
-Onaylanırsa, alan kayıtın ayrıntı görünümünde bir bağlantı olarak gösterilir.Genellikle isim alanlarında kullanılır.
-
-### Sınıflanırılamaz
-
-Sütun sıralama özelliğini devre dışı bırakır.
-
-### Hızalama
-
-Sütunu sola veya sağa hizalayın.
-
-## Detay
-
-Ayrıntılı görünüm ve düzenleme görünümü için ana düzenleme. Panelleri, satırları ve hücreleri tanımlamaktadır. Hücreler alanlar içerir.
-
-Satır, satırın tam boyutunda genişletilmiş iki hücre veya bir hücre içerebilir. Genişletilmiş bir hücre ile satırı eklemek için, yeni satırı ekleyin ve herhangi bir hücrenin negatif işaretine tıklatmanız gerekmektedir.
-
-
-
-## Liste (Küçük)
-
-İlişki panelleri için liste düzenidir. Ayrıca, sınırlı görünümde listeleri görüntülemek makul olan diğer yerlerde de kullanılabilir.
-
-## Detay (Küçük)
-
-Hızlı oluşturma, hızlı görünüm ve hızlı düzenleme formları için ayrıntılı görünümdür.
-
-## Arama Filtreleri
-
-Liste görünümünde bulunan alanların listesi ile aramak içindir.
-
-## Kütleyi Güncellemek
-
-Toplu Kütle Güncelleştirme formunda bulunan alanların listesi.
-
-## İlişki Panelleri
-
-Alttaki detay görünümünde gösterilen ilişki panellerinin listesi. Paneller yeniden düzenlenebilir. Stil parametresi ile panel rengini tanımlamak mümkündür.
-
-## Yan paneller
-
-Yan paneller; Detay, Düzen, Küçük Detay, Küçük Formları düzenlemek içindir. Panel listesinde Faaliyetler, Tarih, Görevler ve diğerlerini gizlemeyi ya da yeniden düzenleme özelliğini sağlar.Paneller Stil parametresi ile renklendirilebilir.
-
-## İlave Düzenlemeler
-
-Bazı varlık türleri ek düzenleri içerir: Rehper Dönüştürme, Hesap Listesi.
diff --git a/i18n/tr_TR/administration/ldap-authorization-for-ad.md b/i18n/tr_TR/administration/ldap-authorization-for-ad.md
deleted file mode 100644
index 8e8e0025b..000000000
--- a/i18n/tr_TR/administration/ldap-authorization-for-ad.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# LDAP authorization for Active Directory
-
-Example of configuration LDAP authorization for the Active Directory server. The full guide of configuration LDAP authorization is described [here](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: sAMAccountName
-User ObjectClass: person
-Account Canonical Form: Principal
-Bind Requires DN: no
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Account Domain Name: espo.local
-Account Domain Name Short: ESPO
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/tr_TR/administration/ldap-authorization-for-openldap.md b/i18n/tr_TR/administration/ldap-authorization-for-openldap.md
deleted file mode 100644
index 6eba88088..000000000
--- a/i18n/tr_TR/administration/ldap-authorization-for-openldap.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# LDAP authorization for OpenLDAP
-
-Example of configuration LDAP authorization for OpenLDAP server. The full guide of configuration LDAP authorization is described [here](ldap-authorization.md).
-
-```
-Host: espo.local
-Port: 389
-Full User DN: cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-Password: ******
-Username Attribute: uid
-User ObjectClass: inetOrgPerson
-Account Canonical Form: Dn
-Bind Requires DN: yes
-Base DN: cn=espo-users,ou=users,dc=espo,dc=local
-Create User in EspoCRM: yes
-User First Name Attribute: givenName
-User Last Name Attribute: sn
-User Title Attribute: title
-User Email Address Attribute: mail
-User Phone Number Attribute: telephoneNumber
-```
-
-
diff --git a/i18n/tr_TR/administration/ldap-authorization.md b/i18n/tr_TR/administration/ldap-authorization.md
deleted file mode 100644
index abcb8e2e4..000000000
--- a/i18n/tr_TR/administration/ldap-authorization.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# LDAP Yetkilendirme
-
-Bu kılavuzda, EspoCRM için LDAP yetkilendirmesinin nasıl yapılandırılacağını göstereceğiz. Hadi başlayalım.
-
-LDAP sunucunuza gidiniz ve EspoCRM kullanıcıları için bir temel DN oluşturunuz.
-
-```
-cn=espo-users,ou=users,dc=espo,dc=local
-```
-
-Kullanıcıların DN'lerine ("c =espo-users, ou=users, dc=espo, dc=local") erişebilecek bir sistem kullanıcısı yaratmak zorundayız. SYani, bu sistem kullanıcısı için tam DN olacakır.
-```
-cn=LDAP User,cn=espo-users,ou=users,dc=espo,dc=local
-```
-Şimdi, EspoCRM'ye erişmek için LDAP kullanıcısı ekleyebiliriz. Örneğin. "Cn = espo-users, ou = users, dc = espo, dc = local" DN içinde "tester" kullanıcı adıyla Espo Tester'dir. Lütfen dikkat edin: Bu giriş biçimini EspoCRM için kullanabilmek için "Kullanıcı Adı Özelliği" ve "Temel DN" seçeneklerini belirtmeniz gerekmektedir.
-
-Ardından, Yönetici panelinde EspoCRM Kimlik Doğrulaması ayarlarına gidini<, `LDAP` yöntemini seçin ve LDAP ayrıntılarını giriniz:
-
-
-
-* Host – LDAP IP veya ana makine adı.
-* Port – bağlantı noktası.
-* Auth – LDAP sunucusuna erişim için kimlik bilgileri:
- * Full User DN – diğer kullanıcıları aramaya izin veren tam sistem kullanıcı DN'sidir.
- * Password – LDAP sunucusuna erişmek için kullanılan paroladır.
-* Security – SSL veya TLS protokolü.
-* Username Attribute – kullanıcıyı belirten özellik. Aktif Dizin için "userPrincipalName" veya "sAMAccountName" olabilir.
-* Account Canonical Form – hesap kanonik formunuzun türü. 4 seçenek vardır:
- * Dn – formattaki form `CN=tester,CN=Espocrm,DC=company,DC=com`.
- * Username – formu `tester`.
- * Backslash – formu `COMPANY\tester`.
- * Principal – formu `tester@company.com`.
-* Bind Requires Dn – formatı istiyorsanız DN kullanıcı adını oluşturunuz.
-* Base Dn – Kullanıcıları aramak için kullanılan varsayılan taban DN'si.
-* User Login Filter – EspoCRM'yi kullanabilen kullanıcıları kısıtlamaya izin veren filtredir.Örneğin, `memberOf=cn=espoGroup,cn=espo-users,ou=users,dc=espo,dc=local`.
-* Account Domain Name – LDAP sunucusunun yetkilendirilmesi için kullanılan etki alanıdır.
-* Account Domain Name Short – LDAP sunucusunun yetkilendirilmesi için kullanılan kısa alandır.
-* Try Username Split – bir kullanıcı adını, alan adıyla bölme seçeneğidir.
-* Opt Referrals – Eğer yönlendirmelerde LDAP istemcisinin izlenmesi gerekiyorsa.
-* Create User in EspoCRM – bu seçenek EspoCRM'nin LDAP'den bir kullanıcı oluşturmasına izin vermektedir.
- * User First Name Attribute – Kullanıcının ilk adını belirlemek için kullanılan LDAP özniteliğidir.
- * User Last Name Attribute – Kullanıcının soyadını belirlemek için kullanılan LDAP özniteliğidir.
- * User Title Attribute – Kullanıcının ünvanını belirlemek için kullanılan LDAP özniteliğidir.
- * User Email Address Attribute – Kullanıcının e-posta adresini belirlemek için kullanılan LDAP özniteliğidir.
- * User Phone Number Attribute – Kullanıcının telefon numarasını belirlemek için kullanılan LDAP özniteliğidir.
-
-Şimdi, giriş sayfasına gidin ve kullanıcı kimlik bilgilerinizi giriniz.
-
-
-
-Kullanıcı kimliği doğrulanmış ve otomatik olarak EspoCRM'de oluşturulmuştur.
-
-## Sunucunuza dayalı yapılandırma talimatları:
-* [Aktif Server Dizini](ldap-authorization-for-ad.md)
-* [OpenLDAP server](ldap-authorization-for-openldap.md)
-
-EspoCRM'nin bu kütüphaneyi kullandığı için [Zend \ Ldap kütüphanesinde] (https://zendframework.github.io/zend-ldap/intro/) sayfasında okuyabileceğiniz LDAP yapılandırması hakkında daha fazla bilgi bulunur.
-
-
-
diff --git a/i18n/tr_TR/administration/maps.md b/i18n/tr_TR/administration/maps.md
deleted file mode 100644
index d2182618f..000000000
--- a/i18n/tr_TR/administration/maps.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Maps
-
-## How to show the map based on an address field
-
-Every Address field has its corresponding Map field. All you need is to put it on Detail layout. It uses Google Maps service.
-
-`Administration > Layout Manager > Choose entity (Account, Contact, Lead or custom one) > Detail > Drag & Drop Map field.`
-
-Make the cell wide using the minus sign.
-
-You can also configure the height of your field.
-
-`Administration > Entity Manager > Choose entity > Fields > find the map field and click on it > edit the height and save.`
-
-## Api Key
-
-Since EspoCRM version 4.2.0 you need to specify Api Key to use Google Maps (Administration > Integration > Google Maps).
-
diff --git a/i18n/tr_TR/administration/moving-to-another-server.md b/i18n/tr_TR/administration/moving-to-another-server.md
deleted file mode 100644
index f10421452..000000000
--- a/i18n/tr_TR/administration/moving-to-another-server.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# EspoCRM'yi başka bir sunucuya taşımak
-
-EspoCRM'yi başka bir sunucuya taşımak için şu adımları izleyiniz:
-
-### 1. Adım Dosyaları Yedekleyiniz
-
-EspoCRM dizininden mevcut tüm dosyaları arşivlemek için dosya yöneticisini açın veya SSH ile giriş yapın. Daha fazla detay: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-backup-files.
-
-### 2. Adım Veritabanını Yedekleyiniz
-
-Veritabanında saklanan veriler (MySQL, MariaDB) yedeklenmelidir. Lütfen bu öneriyi uygulayın: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-2-backup-database.
-
-### 3. Adım Dosyaların ve veritabanının yedeklerini başka bir sunucuya kopyalayınız
-
-Dosyaların ve veritabanınızın yedeklerini yeni bir sunucuya kopyalayınız.
-
-### 4. Adım Yedeklenmiş dosyala arşivden çıkartınız
-
-Yedeklenmi dosyaların arşivden çıkartılması için Arşiv Yöneticisini veya şu talimatları kullanabilirsiniz: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-1-unarchive-backup-files.
-Not: Dosyaların web sunucusu dizinine yerleştirilmesi gerekmektedir.
-
-### 5. Adım Bir Sunucu yapılanrınız
-
-Buradaki önerilere dayanan yeni bir sunucu yapılandırınız: https://www.espocrm.com/documentation/administration/server-configuration/.
-
-### 6. Adım Uygun İzinler
-
-Gerekli izinleri ve dosya sahiplerini ayarlayınız, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems.
-
-### 7. Adım Veritabanı yedeklerinizi içe aktarınız
-
-
-Öncelikle, MySQL'de bir kullanıcıyla yeni bir veritabanı oluşturmanız geremektedir. Veritabanınızı yedeklerini içeri aktarmak için aşağıdaki talimatları uygulayınız: https://github.com/espocrm/documentation/blob/master/administration/backup-and-restore.md#step-3-import-database-dump.
-
-### 8. Adım Uygun EspoCRM yapılandırmaları
-
-Sunucuyu başarılı bir şekilde içe aktardıktan ve yapılandırdıktan sonra, `ESPOCRM_DIRECTORY/data/config.php` dosyasındaki EspoCRM yapılandırmalarını düzeltiniz:
-
- * veritabanı bağlantı ayarları:
-
- ```php
- 'database' => [
- 'driver' => 'pdo_mysql',
- 'dbname' => 'YOUR_DATABASE_NAME',
- 'user' => 'YOUR_USER',
- 'password' => 'YOUR_DATABASE_PASSWORD',
- 'host' => 'localhost',
- 'port' => ''
- ],
- ```
-
- * "siteUrl" - Eğer alan adınız (URL) değiştirilirse:
-
-
- ```php
- 'siteUrl' => 'https://new-link.com',
- ```
-
- * varsayılan dosya sahipleri (sadece farklıysa):
-
- ```php
- 'defaultPermissions' => [
- 'user' => 'www-data',
- 'group' => 'www-data'
- ]
- ```
-
- Neredeki 'www-data' web sunucusu kullanıcısıdır?
-
-
-### 9. Adım bir crontab kurulumu
-
-Bir crontab kurulumu için, https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-Not: web-sunucu kullanıcısı altında yapılandırılmalıdır.
-
-Hepsi bu kadar. Şimdi, EspoCRM örneğiniz yeni bir sunucuda çalışıyor.
diff --git a/i18n/tr_TR/administration/nginx-server-configuration.md b/i18n/tr_TR/administration/nginx-server-configuration.md
deleted file mode 100644
index 37c8477f2..000000000
--- a/i18n/tr_TR/administration/nginx-server-configuration.md
+++ /dev/null
@@ -1,123 +0,0 @@
-# EspoCRM için Nginx sunucu yapılandırması
-
-Bu talimatlar, [Sunucu Yapılandırması] (server-configuration.md) yönergesine tamamlayıcıdır. Lütfen Burada listelenen tüm yapılandırma ayarlarının Ubuntu sunucusunda yapıldığını unutmayınız.
-
-## PHP Gereksinimleri
-
-Gerekli tüm kütüphaneleri kurmak için bu komutları bir terminalde çalıştırınız:
-
-```
-sudo apt-get update
-sudo apt-get install php-mysql php-json php-gd php-mcrypt php-zip php-imap php-mbstring php-curl
-sudo phpenmod mcrypt imap mbstring
-sudo service nginx restart
-```
-
-## "API Hatası: EspoCRM API'sı kullanılamıyor" sorunu giderildi:
-
-Gerekli adımları atınız. Her adımın ardından sorunun çözülüp çözülmediğini kontrol ediniz.
-
-### 1. Nginx Sunucusunda yeniden yazma kurallarını etkinleştirin
-
-Bu kodu, "sunucu" bloğundaki Nginx sunucu bloğu yapılandırma dosyanıza (/etc/nginx/sites-available/YOUR_SITE) ekleyiniz:
-
-```
-server {
- # ...
-
- client_max_body_size 50M;
-
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location /portal/ {
- try_files $uri $uri/ /portal/index.php?$query_string;
- }
-
- location /api/v1/portal-access {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/portal-access/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-Bu dosyaya sahip değilseniz onu oluşturmanız gerekmektedir. Bunun için bir terminal açın ve aşağıdaki komutu çalıştırınız:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Ve yukarıda listelenmiş kodu ekleyiniz. Yeni bir Sanal Ana Makinayı Nginx'te nasıl yapılandıracağınız hakkında daha fazla bilgi için lütfen bu [yönerge] (nginx-virtual-host.md) dosyasını okuyunuz.
-
-Her şeyin yolunda olup olmadığını kontrol etmek için bu komutu bir terminalde çalıştırınız:
-
-```
-sudo nginx -t
-```
-
-Eğer öyleyse, nginx sunucusunu başlatmak için komutu çalıştırınız:
-
-```
-sudo service nginx restart
-```
-
-### 2. Temel Yeniden yazma yolunu ekle
-
-/ESPOCRM_DIRECTORY/api/v1/.htaccess dosyasını açınız ve aşağıdaki satırı değiştiriniz:
-
-```
-# RewriteBase /
-```
-ile
-
-```
-RewriteBase /REQUEST_URI/api/v1/
-```
-
-Nerede REQUEST_URI, URL'nin bir parçasıdır; örneğin. "http://example.com/espocrm/" için REQUEST_URI "espocrm" dir.
-
diff --git a/i18n/tr_TR/administration/nginx-virtual-host.md b/i18n/tr_TR/administration/nginx-virtual-host.md
deleted file mode 100644
index db1b766d6..000000000
--- a/i18n/tr_TR/administration/nginx-virtual-host.md
+++ /dev/null
@@ -1,120 +0,0 @@
-# Configuring a Virtual Host on Nginx for EspoCRM
-
-In this guide we will show how to configure a virtual host on Nginx for EspoCRM on Ubuntu server.
-
-## Create a server block file
-
-To create this file, open a terminal and run the command:
-
-```
-sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/espocrm.conf
-```
-
-Now, open this file (/etc/nginx/sites-available/espocrm.conf) and modify the code following the format printed below (some settings may be different based on your configuration):
-
-```
-server {
- listen 80;
- listen [::]:80;
-
- server_name espocrm.local; # Replace espocrm.local to your domain name
- root /var/www/html/espocrm; # Specify your EspoCRM document root
-
- index index.php index.html index.htm;
-
- # SSL configuration
- #
- # listen 443 ssl;
- # listen [::]:443 ssl;
- # include snippets/snakeoil.conf;
-
- # Specify your PHP (php-cgi or php-fpm) based on your configuration
- location ~ \.php$ {
- include snippets/fastcgi-php.conf;
-
- # With php7.0-cgi alone:
- # fastcgi_pass 127.0.0.1:9000;
-
- # With php7.0-fpm:
- fastcgi_pass unix:/run/php/php7.0-fpm.sock;
- }
-
- # Add rewrite rules
- location / {
- try_files $uri $uri/ =404;
- }
-
- location /api/v1/ {
- if (!-e $request_filename){
- rewrite ^/api/v1/(.*)$ /api/v1/index.php last; break;
- }
- }
-
- location ~ /reset/?$ {
- try_files /reset.html =404;
- }
-
- location ^~ (data|api)/ {
- if (-e $request_filename){
- return 403;
- }
- }
- location ^~ /data/logs/ {
- deny all;
- }
- location ^~ /data/\.backup/ {
- deny all;
- }
- location ^~ /data/config.php {
- deny all;
- }
- location ^~ /data/cache/ {
- deny all;
- }
- location ^~ /data/upload/ {
- deny all;
- }
- location ^~ /application/ {
- deny all;
- }
- location ^~ /custom/ {
- deny all;
- }
- location ^~ /vendor/ {
- deny all;
- }
- location ~ /\.ht {
- deny all;
- }
-}
-```
-
-## Enable this server block
-
-Create a symbolic link:
-
-```
-sudo ln -s /etc/nginx/sites-available/espocrm.conf /etc/nginx/sites-enabled/
-````
-
-Run this command to check if everything is fine:
-
-```
-sudo nginx -t
-```
-
-And restart Nginx server:
-
-```
-sudo service nginx restart
-```
-
-## Configure your local hosts (optional, for a local domain only)
-
-If you added a local domain, you have to configure it on your local computer (not on the server). For Ubuntu, open the file `/etc/hosts` and add the line:
-
-```
-192.168.1.1 espocrm.local # specify the IP address of your Nginx server
-```
-
-For Windows, please follow these [instructions](http://support.microsoft.com/kb/923947).
diff --git a/i18n/tr_TR/administration/portal.md b/i18n/tr_TR/administration/portal.md
deleted file mode 100644
index d03647880..000000000
--- a/i18n/tr_TR/administration/portal.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Portal
-
-Portal, müşterileri ve ortakları için belirli CRM verisine ve işlevlerine erişme olanağı sağlar. Yönetici, birden fazla portal oluşturabilir. Her portal kendi ayarlarına, kumanda paneline, kullanıcı listesine, erişim kontrolü ayarlarına sahip olabilir.
-
-Portal oluşturmak için, Yönetim> Portallar'ı takip edin, Portal Oluştur butonuna tıklayınız.
-
-* `Is Active`. Değilse portal kimseye açık olmayacaktır.
-* `Is Default`. Bu, portalın daha kısa bir URL ile kullanıma sunulacağı anlamına gelir: http (s): // YOUR_ESPO_URL/portal..
-* `Roles`. Portala giriş yapan kullanıcılara uygulanacak bir veya birden fazla portal rolünü belirtiniz. Portal rolleri hakkında daha fazla bilgi aşağıda bulabilirsiniz.
-* `Tab List`. Navigasyon çubuğunda gösterilecek sekmeler.
-* `Dashboard Layout`. Portalın giriş sayfasında görüntülenen dashletleri belirtiniz. Portal kullanıcılarının gösterge tablosunu yapılandıramayacağını unutmayınız.
-* `URL`. Portala erişebileceğiniz bağlantıyı gösteren sadece okunabilen alandır.
-
-
-## Portal Kullanıcıları
-
-Yöneticiler portal kullanıcıları oluşturabilir.
-
-1. Yönetim>Kullanıcılar.
-2. Kullanıcı Oluştur'un yanındaki sağ açılır menüye tıklayınız.
-3. Portal Kullanıcısı Oluştur'a tıklayınız.
-4. Portal kullanıcısı ile iletişim kuracak olan bağlantıyı seçiniz.
-5. Formu doldurun ve Kaydet'e tıklayınız.
-
-Portal kullanıcısı, o portala erişebilmek için Portal kaydına bağlanmalıdır.
-
-## Portal Rolleri
-
-Portal rolleri, EspoCRM'deki normal rollere benzer ancak birkaç farklılığa sahiptir.
-
-* `not-set` seviyesinde bir erişimi reddeder.
-* `own` seviyesi, kayıtların kullanıcı tarafından oluşturulduğu anlamına gelir. Örneğin. portal kullanıcısı bazı durumlara katlandı ve bu durum, bu kullanıcıya aittir.
-* `account` düzeyinde kayıt, portal kullanıcısının ilişkili olduğu hesaba bağlı olduğu anlamına gelir.
-* `contact` seviyesi, kayıtların portal kullanıcısının ilgili bulunduğu kişiyle ilişkili olduğu anlamına gelir.
-
-Atanan Kullanıcının ve Takımların alanları, portal kullanıcıları için yalnızca okunurdur.
-
-### Örnek
-
-`Portal kullanıcıları, durumlar oluşturabilir, hesaplarıyla ilgili durumları görebilir; bilgi tabanını görebilmelidirler.`
-
-1. Portal Rolü Oluşturma formunu açınız (Yönetim> Portal Rolleri> Rol Oluştur).
-2. Durumlar'a erişimi etkinleştirin, ayarlayınız: `create - yes, read - account, edit - no, delete - no, stream - account`.
-3. Bilgi Tabanına erişimi etkinleştirin, ayarlayınız: `create - no, read - account, edit - no, delete - no`.
-4. Portal kaydınızı düzenleyiniz (Yönetim> Portallar). Roller alanında portal rolünü seçiniz ve sonra kaydediniz.
-
-
-## Portal'a Erişim
-
-Portal kayıtınızın 'URL' alanında portalınızdaki URL'yi bulabilirsiniz. Ayrıca farklı URL'ler ile erişebilmek için sunucu yapılandırma araçlarını da (mod_rewrite gibi) kullanmak mümkündür. Bu durumda, 'Özel URL' alanını doldurmanız gerekmektedir.
-
-### Apache sunucusu için Özel URL ile portala erişim
-
-Özel URL: my-portal-host-name.com.
-
-#### crm.portal.conf
-```
-
- DocumentRoot /path/to/espocrm/instance/
- ServerName my-portal-host-name.com
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Order allow,deny
- allow from all
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-
-ServerAlias my-portal-host-name.com
-
-```
-
-#### Mod yeniden yazma kuralları
-
-`{PORTAL_ID}` yerinde portal kayıt kimliğini belirtiniz. Portal kaydı kimliğini, portal kaydının ayrıntılı görünümünü açtığınızda web tarayıcınızın adres çubuğunda kullanılabilirdir. Gibi: https://my-espocrm-url.com/#Portal/16b9hm41c069e6j24. 16b9hm41c069e6j24 bir portal kaydı kimliğidir.
-
-```
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteRule ^client - [L]
-
- RewriteCond %{HTTP_HOST} ^portal-host-name.com$
- RewriteCond %{REQUEST_URI} !^/portal/{PORTAL_ID}/.*$
- RewriteRule ^(.*)$ /portal/{PORTAL_ID}/$1 [L]
-```
diff --git a/i18n/tr_TR/administration/roles-management.md b/i18n/tr_TR/administration/roles-management.md
deleted file mode 100644
index 05901f421..000000000
--- a/i18n/tr_TR/administration/roles-management.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Rol Yönetimi
-
-## Genel Bakış
-
-Bazı kullanıcıların erişimini kısıtlamak için Rolleri kullanmanız gerekmektedir. Yönetici, Yönetim panelindeki rolleri yönetebilir. Her rol, bu rolü kullanan kullanıcılara uygulanan belirli alanlara (kapsamlar) erişimi tanımlamaktadır.
-
-Bir kullanıcı birden çok role sahip olabilir. Bu roller, belirli bir kullanıcı için seçilebilir (Kullanıcı girdisinde 'Roller' alanı) ve/veya kullanıcının ait olduğu ekiplerden devralınabilir.
-
-Bir kullanıcının birden fazla rolü varsa, izin verilen kuralın daha yüksek önceliğe sahip olması için birleştirileceklerdir.Bu, yöneticinin erişim seviyesi denetimini kolay ve esnek bir şekilde yönetmesini sağlamaktadır.
-
-Kullanıcının ayrıntılı görünümünde 'Erişim' butonuna tıklayarak belirli bir kullanıcıya hangi izinlerin uygulandığını görmek mümkündür.
-
-
-
-## Örnek
-
-Örneğin, kullanıcı 'Satış' ekibine aittir. Bu ekibin tek bir "Satış elemanı" rolü vardır. Böylece bu takımdaki tüm kullanıcılar 'Satışçı' rolünü alacaklardır.
-
-'Satış elemanı' rolü şu şekilde tanımlanır:
-
-Rehber:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-İmkan:
-```
-create - yes
-read – team
-edit – own
-delete – no
-stream - team
-```
-
-Kullanıcılar, yalnızca 'Satış Departmanı' ekibine ('Takımlar' alanı) ait olan potansiyel satışları ve fırsatları okuyabilmektedir.
-Kullanıcı yalnızca atadığı fırsatları veya yarattığı fırsatları düzenleyebilir.Kullanıcılar potansiyel satışları veya fırsatları kaldıramaz.
-
-Şirkette satış yöneticisi pozisyonuna sahip belirli bir kullanıcıya daha fazla hak vermek istiyoruz. Bu çalışanın 'Satış' takımındaki tüm kayıtları okuma / düzenleme / silme becerisine sahip olması gerekmektedir. Kullanıcı, 'Satış' takımımıza ait olmalıdır. Ancak yeni rolü 'Satış Yöneticisi' oluşturmalıdır ve bu rolü bu kullanıcı için 'Roller' alanından seçmeliyiz.
-
-'Satış Müdürü' rolü şu şekilde tanımlanır:
-
-
-Rehber:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-İmkan:
-```
-create - yes
-read – team
-edit – team
-delete – team
-stream - team
-```
-
-Kullanıcılarımız 'Satış' ekibinden tüm olası pazarlama fırsatlarını yönetebilir.
-
-## Özel İzinler
-
-### Atama İzni
-
-Kayıtları başka bir kullanıcıya ve/veya takımlara yeniden atama yeteneğini sınırlandırmak için bu parametreyi ayarlayınız. Eğer 'Takım' belirtirseniz - yalnızca kendi takım(ları)ın kullanıcılarına atamak mümkün olacaktır.Eğer `hayır` ise - kullanıcılar yeniden atayamazlar.
-
-Ayrıca, kullanıcının başka kullanıcıların/takımların akışına yayın yapıp yapamayacağını tanımlar.
-
-### Kullanıcı İzinleri
-
-Kullanıcıların diğer kullanıcıların etkinliklerini, takvimlerini ve yayın akışlarını görüntüleme olanağını kısıtlamasına izin verir.
-
-### Portal İzni
-
-Portal bilgilerine erişim, portal kullanıcılarına mesaj gönderme becerisi tanımlamaktadır.
-
-### E-posta Grup Hesabı İzinleri
-
-Grup e-posta hesaplarına erişimi, SMTP grubundan e-posta gönderme becerisini tanımlamaktadır.
-
-### Dışarıya Aktarma İzinleri
-
-Kullanıcıların kayıtları dışa aktarma yeteneği olup olmadığını değerlendirir. (sürüm 4.9.0'dan beri)
-
-## Varsayılanlara Göre İzinler
-
-Varsayılan olarak kullanıcılar (herhangi bir uygulama yoksa) tüm kayıtları okuyabilirler ve düzenleyebilirler. Ancak, oluşturdukları ve bunlarla aynı anda atananların haricindeki herhangi bir şeyi silemezler.
-
-Varsayılan olarak uygulanan erişim, Yönetim>Ayarlar kısmında 'ACL Strict Mode' özelliğini etkinleştirerek kısıtlama olanağı sağlar.
-
-## Alan Seviyesinde Güvenlik
-
-Belirli bir alana erişimi kontrol etmeyi sağlar.
-
-Varsayılan kullanıcı olarak, kayıtları okuyabilirse tüm alanları okuyabilir. Alan Seviyesinde Güvenlik özelliğini kullanarak belirli alanlara erişimi kısıtlayabilirsiniz.
-
-Alan Seviyesi bölümündeki bir rol kaydının düzenleme görünümündeki, belirli kapsamın yanındaki artı simgesine tıklayınız ve ardından gerekli alanı seçiniz. Ardından, `read` ve` edit` eylemleri için erişim seviyesini belirleyebileceksiniz. Var olan seçenekler: `evet` ve `hayır`.
-
-
diff --git a/i18n/tr_TR/administration/server-configuration.md b/i18n/tr_TR/administration/server-configuration.md
deleted file mode 100644
index f80c94325..000000000
--- a/i18n/tr_TR/administration/server-configuration.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# EspoCRM için Sunucu Yapılandırması
-
-EspoCRM Apache'de ([talimatlar](apache-server-configuration.md)), Nginx'te ([talimatlar](nginx-server-configuration.md)), veya PHP sürüm 5.6 veya daha üstü ve MySQL sürüm 5.1 veya daha üstü desteklenen IIS sunucusu için kurulabilir.
-
-## Önerilen Yapılandırmalar
-
-### PHP Gereksinimleri
-
-EspoCRM, aşağıdaki uzantıların etkinleştirilmiş hali ile PHP 5.6 veya üst sürümünü gerektirir:
-
-* [PDO](http://php.net/manual/en/book.pdo.php) – PHP'de MySQL'e erişmek;
-* [JSON](http://php.net/manual/en/book.json.php) – kaynaklar bu formatı kullanır (meta veriler, düzen, diller ve diğerleri);
-* [GD](http://php.net/manual/en/book.image.php) – görüntüleri değiştirmek;
-* [OpenSSL](http://php.net/manual/en/book.openssl.php) – en yüksek korumayı sağlamak için;
-* [Zip](http://php.net/manual/en/book.zip.php) – EspoCRM sürümünü güncelleyip uzantıları yükleyebilmek;
-* [IMAP](http://php.net/manual/en/book.imap.php) – EspoCRM'deki posta kutularını izlemek için;
-* [mbstring](http://php.net/manual/en/book.mbstring.php);
-* [cURL](http://php.net/manual/en/book.curl.php).
-
-Ayrıca, [mailparse] (https://pecl.php.net/package/mailparse) pecl uzantısının kurulu olması önerilmektedir.E-postayı alma özelliğinin sorunsuz çalışması için gereklidir.
-
-
-php.ini ayarları:
-
-```
-max_execution_time = 180
-max_input_time = 180
-memory_limit = 256M
-post_max_size = 50M
-upload_max_filesize = 50M
-```
-
-
-### MySQL Gereksinimleri
-
-EspoCRM, MySQL sürüm 5.1 veya daha yeni sürümünü desteklemektedir.
-Hiçbir özel özellik yoktur.Tüm varsayılan ayarlar EspoCRM için iyidir.
-
-## Unix Tabanlı Sistemler için Gerekli İzinler
-
-Dosyalar ve dizinler aşağıdaki izinlere sahip olmalıdır:
-
-* `/data`, `/custom`, `/client/custom` – tüm dosyalar, dizinler ve alt dizinler (dosyalar için 664, dizinler için 775, tüm alt dizinler ve dosyalar da dahil olmak üzere) yazılabilir olmalıdır;
-* `/application/Espo/Modules`, `/client/modules` – geçerli dizin de (mevcut dizin için 775, dosyalar için 644, dizinler ve alt dizinler için 755) yazılabilir olmalıdır;
-* Diğer tüm dosyalar ve dizinler okunabilir olmalıdır (dosyalar için 644, dizinler için 755).
-
-İzinleri ayarlamak için terminaldeki şu komutları çalıştırınız:
-
-```
-cd
-find . -type d -exec chmod 755 {} + && find . -type f -exec chmod 644 {} +;
-find data custom -type d -exec chmod 775 {} + && find data custom -type f -exec chmod 664 {} +;
-```
-
-Tüm dosyalar, web sunucusu işlemleri tarafından sahip olunmalı ve gruba ait olmalıdır."Www-data", "daemon", "apache", "www" vb. Olabilirler.
-Not: Bitnami Yığınındaki, dosyaların "daemon" kullanıcısı tarafından sahibi olunduğu ve gruba ait olması gerekir.
-Not: Paylaşılan ana makinelerdeki dosyalar kullanıcı hesabınıza ait ve gruba ait olmalıdır.
-
-Sahibi ve grup sahibini ayarlamak için terminaldeki şu komutları çalıştırın:
-
-```
-cd
-chown -R : .;
-```
-
-## Bir crontab kurulumu
-
-Bir UNIX sisteminde bir crontab kurmak için aşağıdaki adımları izleyiniz:
-
-* 1. EspoCRM örneğinize yönetici olarak giriş yapınız.
-* 2. Yönetici panelindeki Zamanlanmış İşler bölümüne gidiniz (Menü>Yönetim>Zamanlanmış İşler) ve crontab için dizeyi kopyalayınız. Bu şuna benzemektedir:
-```
-* * * * * /usr/bin/php -f /var/www/html/espocrm/cron.php > /dev/null 2>&1
-```
-* 3. Bir terminal açın ve şu komutu çalıştırınız:
-```
-crontab -e -u WEBSERVER_USER
-```
-WEBSERVER_USER "www", "www-data", "apache" vb. Oolabilir(web sunucunuza bağlıdır).
-* 4. Kopyaladığınız dizeyi (2. adımdan) yapıştırın ve crontab dosyasını (nano düzenleyici için Ctrl + O, ardından Ctrl + X) kaydediniz.
-
-## Sunucunuza dayalı yapılandırma talimatları:
-
-* [Apache sunucu yapılandırması](apache-server-configuration.md).
-* [Nginx sunucu yapılandırması](nginx-server-configuration.md).
diff --git a/i18n/tr_TR/administration/troubleshooting.md b/i18n/tr_TR/administration/troubleshooting.md
deleted file mode 100644
index 19011a4aa..000000000
--- a/i18n/tr_TR/administration/troubleshooting.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# Sorun giderme
-
-## Günlükleri Kontrol et
-
-Sorunu bulmak için hata günlüğü dosyalarını kontrol etmeniz gerekmektedir.
-
-#### EspoCRM Hata Günlükleri
-
-EspoCRM günlükleri ` / logs / *. Log` bölümünde bulunur ve bazı hata bilgilerini içermektedir.
-
-#### Apache Hata Günlükleri
-
-Ubuntu sunucusu için bir apache hata günlüğü `/var /log /apache2 /error.log` dosyasında bulunur ve tüm hata bilgilerini içermektedir.Günlük dosyalarının konumu diğer sistemlerde farklı olabilir.
-
-## Hata ayıklama modunu etkinleştir
-
-Hata ayıklama modunu etkinleştirmek için, kurulu EspoCRM dizinine gidiniz, `data/config.php` dosyasını açın ve değeri değiştiriniz:
-
-```
-'logger' => [
- ...
- 'level' => 'WARNING',
- ...
-]
-```
-to
-```
-'logger' => [
- ...
- 'level' => 'DEBUG',
- ...
-]
-```
-
-## Zamanlanmış Görevler çalışmıyor
-
-#### #1. Sorun: Crontab'ınız yapılandırılmadı
-
-1. SSH ile sunucunuza giriş yapın.
-
-2. Aşağıdaki adımları uygulayarak crontab'ınızı yapılandırınız: https://www.espocrm.com/documentation/administration/server-configuration/#user-content-setup-a-crontab.
-
-Not: Crontab web sunucusu kullanıcısı altında yapılandırılmalıdır, Örneğin, `crontab -e -u www-data`.
-
-3. Bir süre bekleyin ve herhangi bir iş yürütülüp gerçekleştirildiğini görmek için Zamanlanmış işleri'i kontrol ediniz (bkz. Bir Günlük paneli).
-
-#### #2. Sorun: Crontab yapılandırıldı, ancak Zamanlanmış İşler çalışmıyor
-
-Cron çalışırken hata olmadığından emin olmak için bir terminalde cron komutunu çalıştırmayı deneyiniz:
-
-1. SSH ile sunucunuza giriş yapınız.
-
-2. EspoCRM'nin kurulu olduğu dizine gidiniz. Örneğin, `/var/www/html/espocrm` dizini için komut şu şekildedir:
-```bash
-cd /var/www/html/espocrm
-```
-
-3. Crontab komutunu çalıştırın:
-
-```bash
-php cron.php
-```
-
-Not: Bu web sunucusu kullanıcısı altında yürütülmelidir. root olarak oturum açtıysanız, komutun olması gerekir (ör. Ubuntu için):
-
-```bash
-sudo -u www-data php cron.php
-```
-
-Nerede `www-data` bir web-sunucusu kullanıcısıdır?
-
-4. Herhangi bir hata yoksa, herhangi bir işin yürütülüp yürütülmediğini görmek için Zamanlanmış İşler'e bakınz (bkz. Bir Günlük paneli).
-
-## EspoCRM, güncellemeden sonra yüklenmiyor
-
-Bu, bazen paylaşılan bazı barındırmalardan meydana gelebilir.
-
-Dosyaların izinlerini kontrol ediniz:
-/index.php
-/api/v1/index.php
-
-Bunların 644 olması gerekir. Bu dosyalardan herhangi birinin 664 iznine sahip olması durumunda dosyayı 644 olarak değiştirmeniz gerekmektedir. Barındırma kontrol panelini veya chmod komutunu kullanınız.
-
-```
-chmod 644 /path/to/file
-```
-Dosya izinleri hakkındaki daha fazla bilgi: [burada](server-configuration.md#required-permissions-for-unix-based-systems).
diff --git a/i18n/tr_TR/administration/upgrading.md b/i18n/tr_TR/administration/upgrading.md
deleted file mode 100644
index 43a2047d5..000000000
--- a/i18n/tr_TR/administration/upgrading.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# EspoCRM nasıl güncellenir?
-
-EspoCRM, aşağıdaki adımlarla en yeni sürüme yükseltilebilir:
-
-### 1. Adım Geçerli Sürümünüzü Kontrol Edin
-
-Geçerli sürümünüzü kontrol etmek için Yönetim> Güncelleme sayfasına gidin.
-
-### 2. Adım Gerekli Güncelleme Paketlerini indirin
-
-Yükseltme sayfasına https://www.espocrm.com/download/upgrades/ adresinden gidin ve doğru sürümünüze uygun olarak gereken paketleri indirin.
-
-### 3. Adım Yedek oluştur (isteğe bağlı)
-
-Yükseltmeden önce EspoCRM dosyalarınızın ve verilerinizin yedeğini oluşturun. İşlemi tamamlamak için [bu talimatları izleyin] (https://github.com/espocrm/documentation/blob/master/administration/backup-andrestrest.md).
-
-### 4. Adım Yükseltme işlemi
-
-Yönetim> Güncelle'ye gidin. Tek tek yükseltme paketleri yükleyin ve kurun.
-
-Menü>Hakkında bölümünde en son sürüme sahip olup olmadığınızı kontrol edebilirsiniz.
-
-## CLI üzerinden yükseltme
-
-Ayrıca, komut satırı arayüzü üzerinden yükseltmeyi çalıştırabilirsiniz. Aşağıdaki komutu EspoCRM kök dizininden çalıştırmanız gerekmektedir:
-
-```
-php upgrade.php /path/to/upgrade/package.zip
-```
diff --git a/i18n/tr_TR/administration/workflows.md b/i18n/tr_TR/administration/workflows.md
deleted file mode 100644
index fd44cd1d1..000000000
--- a/i18n/tr_TR/administration/workflows.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# İş Akışları
-
-İş akışları özelliği, [Gelişmiş Paket]'de mevcuttur (https://www.espocrm.com/extensions/advanced-pack/).
-
-İş akışları, işlemlerinizi kolay bir şekilde otomatikleştirir. Bunu Yönetim panelinde bulabilirsiniz. Bir iş akışı kuralı oluşturmak için şunları tanımlamanız gerekmektedir:
-
-* Hedef Varlık - hangi varlık türü iş akışına uygulanır;
-* Tetikleyici Türü - iş akışı tetiklendiğinde;
-* Koşullar - iş akışını tetiklemek için gerekli koşulların yerine getirilmesi gerekir;
-* Eylemler - iş akışı tetiklenirse ne yapılacak?
-
-
-## Tetikleyici Tipleri
-
-### Kayıt Oluşturulduktan sonra
-
-Yalnızca yeni bir kayıt oluşturulduğunda tetiklenmektedir. Belirtilen koşullar yerine getirilirse olaylar gerçekleştirilir.
-
-### Kayıt kaydedildikten sonra
-
-Yeni bir kayıt oluşturulduğunda veya mevcut bir kayıt güncellendiğinde başlatılır. Belirtilen koşullar yerine getirilirse olaylar gerçekleştirilir.
-
-Bu tür tetiklemeye sahip iş akışı kuralları için, bazı alanların 'değiştirildi' olup olmadığını kontrol eden bir koşul olması yaygın bir uygulamadır. Örneğin, Olayların durumu değişirse, bazı işlemleri gerçekleştiriniz.
-
-### Zamanlanmış
-
-Tanımlanan zamanlamaya göre başlatıldı. Her gün, her hafta, vb. çalıştırmak için kurulum yapabilirsiniz. Belirli bir liste raporu tarafından geri gönderilen kayıtlar için eylemler uygulanacaktır.Dolayısıyla bir liste raporu oluşturmanız gerekmektedir.
-
-Tarifeleme bir crontab notlarında belirtilmiştir.
-
-```
-* * * * * *
-| | | | | |
-| | | | | +-- Year (range: 1900-3000)
-| | | | +---- Day of the Week (range: 1-7, 1 standing for Monday)
-| | | +------ Month of the Year (range: 1-12)
-| | +-------- Day of the Month (range: 1-31)
-| +---------- Hour (range: 0-23)
-+------------ Minute (range: 0-59)
-```
-
-### Ardışık
-
-Nadiren kullanılırdı. Başka bir iş akışı tarafından çalıştırılması gerekiyordu.Bir karmaşık mantıksal yapma özelliğini sağlar.
-
-Not: Sıralı iş akışları için bir İş Akışı özelliği yerine [BPM aracı] (bpm.md) kullanmanız önerilir.
-
-## Koşullar
-
-İş akışını başlatmak için yerine getirilmesi gereken koşulları belirtebilirsiniz. Koşulların nasıl belirtileceğini göstermenin iki yolu vardır: UI koşul oluşturucu ve formüldür.
-
-### UI Koşul Oluşturucu
-
-Bazı mevcut koşul türleri:
-
-* _equals_ - alan belirli bir değere veya başka bir alanın değerine eşittir;
-* _was equal_ - iş akışı tetiklenmeden önce alan belirli bir değere eşittir;
-* _not equals_ - alan belirli bir değere veya başka bir alanın değerine eşit değildir;
-* _was not equal_ - iş akışı tetiklenmeden önce alan belirli bir değere eşit değildir;
-* _empty_ - alan değeri boştur;
-* _not empty_ - alan değeri boş değildir;
-* _changed_ - alan değiştirildi;
-* _not changed_ - alan değiştirilmedi.
-
-### Formül koşulları
-
-Förmül herhangi bir karmaşıklığın koşullarını tanımlama olanağı sağlamaktadır.Formül sözdizimini okumak için [Bu yazı] (formula.md) bölümüne bakınız.
-
-Not: Bir koşul belirlediğinde formül kodunda kullanılan `;` sınırlandırıcı olmamalıdır.
-
-## Eylemler
-
-### E-posta Göndermek
-
-Sistem belirtişmiş e-posta şablonunu kullanarak bir e-posta gönderir. Bir alıcının e-posta adresi, hedef kaydı, ilişkili herhangi bir kaydı, geçerli kullanıcıyı, takipçileri, takım üyelerinden veya belirtilenlerden alınabilir. E-posta hemen gönderilebilir veya belirli bir süre için gecikir.
-
-### Kayıt Oluşturma
-
-Sistem herhangi bir öğe türünün yeni kaydını oluşturacaktır. Hedef kayıt ile kayıt oluşturma arasında bir ilişki varsa, kayıtları ilişkilendirmek mümkündür.
-
-Alanları hesaplamak için formül tanımlama özelliği vardır.
-
-### İlgili Kayıt Oluşturma
-
-Sistem hedef kayıtla ilgili kayıt oluşturacaktır. Alanları hesaplamak için formülü tanımlamak mümkündür.
-
-### Hedef Kaydı Güncellemek
-
-Hedef kaydın belirli alanlarını değiştirmeye izin verirlir. Alanları hesaplamak için formülü tanımlamak mümkündür.
-
-Mevcut verileri kaybetmeden (örneğin, Takımlar) Çoklu-Bağlantı alanına yeni öğeler eklemeniz gerekiyorsa formül fonksiyonu entity\addLinkMultipleId kullanmanız gerekir. Örneğin: `entity\addLinkMultipleId('teams', 'teamId')`.
-
-### İlgili Kaydı Güncellemek
-
-İlgili kayıt veya kayıtların belirli alanlarının değiştirilmesine izin verirlir. Alanları hesaplamak için formülü tanımlamak mümkündür.
-
-### Başka Bir Kayıtla Bağlantı Kurmak
-
-Hedef varlığı başka bir belirli varlıkla ilişkilendirir. Örneğin, kayıta özel takım eklendi.
-
-### Başka Bir Kayıtla Bağlantı Koparmak
-
-Hedef birimi başka bir belirli varlıkla ilişkilendirmez. Örneğin, belli bir ekibi kayıtlardan kaldırır.
-
-### Görev Kuralı Atamak
-
-Hedef kaydı, dağılım kuralına göre kullanıcıya atayınız. İki geçerli kural vardır: Round-Robin ve Least-Busy.
-
-* Round-Robin - kullanıcılar bir listenin en üstünden en altına (takım) seçilir ve tekrar başlarlar.
-* Least-Busy - kayıtlı atama sayısı daha az olan kullanıcı görev için seçilecektir.
-
-_List Report_ - Least-Busy dağıtımında, hesapların atanmış kayıtlarının sayısını hesaplamak için nelerin dikkkate alınacağını belirler. Örneğin. Olaylar için yalnızca aktif durumdaki kayıtları almamız gerekmektedir.
-
-### Bildirim Oluşturmak
-
-Belirli kullanıcıları mesajla bilgilendir. Mesaj şablonunda yer belirleyicilerin kullanılması mümkündür: {entity}-hedef kayıt, {user}-geçerli kullanıcı.
-
-### Takip Et
-
-Belirli kullanıcıları hedef varlığı veya belirtilen ilgili bir varlığı izlemek için zorlar.
-
-### Başka Bir İş Akışını Tetiklemek
-
-Ardışık iş akışlarını oluşturmaya izin verir. İş akışını duruma göre şubelendirmek mümkündür: iş akışını, iş akışlarında tanımlanan farklı koşullarla iki iş akışını başlatacak şekilde ayarlayabilirsiniz.
-
-Sıralı iş akışının yürütülmesini geciktirmek mümkündür. Sıralı iş akışında, üst iş akışı _ Changed_ ve _Was Equal_ koşul türleri kullanılarak tetiklendiğinden dolayı, özel alanların değiştirilip değiştirilmediğini kontrol eden koşul tanımlayabilirsiniz.
-
-NNot: Sıralı iş akışları için bir İş Akışı özelliği yerine [BPM aracı] (bpm.md) kullanmanız önerilir.
-
-### Hizmet Eylemini Çalıştırmak
-
-Belirli hizmet komut dosyalarını çalıştırmaya izin verir. Varsayılan olarak aşağıdaki eylemleri kullanabilirsiniz:
-
-* Davetiyeleri Gönder - for Meetings/Calls;
-* Alıntı Ekle - for Quotes.
-
-Geliştiriciler kendi hizmet işlemlerini yazabilir. Bkz. [Ayrıntılı bilgi] (../ development / workflow-service-actions.md).
-
-## İşlemlerde Formül Kullanımı
-
-Kayıt Oluştur, Hedef Kaydı Güncelle, İlgili Kaydı Oluştur, İlgili Kayıtları Güncelle alanlarını hesaplamak için formül tanımlamak mümkündür. Son iki yılda, hedef varlığın özelliklerine erişmek için, `targetEntity \ attribute` işlevini kullanmalısınız. İş akışı tetiklenmeden önce belirlenen hedef öğenin özelliklerine erişmek için, `targetEntity \ attributeFetched` işlemini kullanınız.
-
-Örnek:
-```
-name = string\concatenate(targetEntity\attribute('name'), ' ', datetime\today());
-```
diff --git a/i18n/tr_TR/development/api.md b/i18n/tr_TR/development/api.md
deleted file mode 100644
index 28c505264..000000000
--- a/i18n/tr_TR/development/api.md
+++ /dev/null
@@ -1,223 +0,0 @@
-# REST Uygulaması(API)
-
-EspoCRM bir tek sayfa uygulamasıdır, bu nedenle bir ön uç, arka uçla bağlanmantılı olmak için REST API'yı kullanmaktadır.
-Programlama dilinizi kullanarak API çağrılarıyla uygulayabileceğiniz UI'yı kullanarak gerçekleştirdiğiniz tüm işlemlerdir.
-Tarayıcı konsolunuzdaki ağ sekmesinde neler olduğunu takip ederseniz API'nın nasıl çalıştığını öğrenebilirsiniz.
-
-Çoğu API fonksiyonları JSON'u döndürür. POST, PATCH çağrıları genelde yük altında, bazı JSON verilerine ihtiyaç duyarlar.
-
-EspoCRM API'sinin temel URL'si: `api/v1/`. Bu referans içindeki ifadelerle başa eklemeniz gerekmektedir. Örneğin:
-
-`GET http://your_domain/api/v1/Contact/55643ca033f7ab4c5`.
-
-## Yetkilendirme
-
-EspoCRM API'sı [Temel Kimlik Doğrulaması]nı (http://en.wikipedia.org/wiki/Basic_access_authentication) kullanır. Kullanıcı adı ve şifre/simge, base64'de kodlanmıştır 'Yetkilendirme' başlığı sayesinde geçirilir.
-
-`"Authorization: Basic " + base64Encode(username + ':' + password)`
-
-
-API ile çalışırken şifre yerine onay simgesi kullanmak daha iyidir. Bu durumda, `Espo-Yetkilendirme` başlığında kullanıcı adı ve şifre/simge girmeniz gerekecektir.
-```
-"Espo-Authorization: " + base64Encode(username + ':' + passwordOrToken)
-```
-
-1. `Espo-Yetkilendirme` başlığında elde edilen kullanıcı adı ve şifreyle `GET App/user` isteği ile erişim simgesini edininiz.
-2. Daha fazla istek için `Espo-Yetkilendirme` başlığındaki şifre yerine bu simgeyi kullanınız.
-3. Eğer İstek, 403 hatası döndürürse, kullanıcı adı/şifre yanlış veya simge artık geçerli değil demektir.
-
-#### Kimlik Doğrulama Simgesi/Kullanıcıya Özgü Veri
-
-`GET App/user`
-
-Sonuçlar:
-
-* `token` - kullanmak için erişim izni;
-* `acl` - kullanıcı erişimi hakkındaki bilgi;
-* `preferences` - Kullanıcı tercihleri;
-* `user` - kullanıcı kayıtlı özellikleri.
-
-
-## CRUD İşlemleri
-
-#### Listelenmiş Varlıklar
-
-`GET {entityType}`
-
-GET parametleri:
-
-* `offset` - (int) ofset;
-* `maxSize` - (int) maksimum boyut;
-* `where` - (array) filtreler;
-* `sortBy` - (string) sıralamak için alan;
-* `asc` - (bool) sıralama yönü.
-
-_Örnek_
-
-`GET Account?offset=0&maxSize=20`
-
-Sonuçlar:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Varlıkları Oku
-
-`GET {entityType}/{id}`
-
-JSON nesnesindeki öznitelikleri döndürür.
-
-_Örnek_
-
-`GET Account/5564764442a6d024c`
-
-#### Varlık Yarat
-
-`POST {entityType}`
-
-Payload: Varlık özniteliklerinin nesnesidir.
-
-JSON nesnesindeki öznitelikleri döndürür.
-
-_Örnek_
-
-`POST Account`
-
-Payload:
-```
-{
- "name": "Test",
- "assignedUserId": "1"
-}
-```
-
-#### Varlığı Güncelleme
-
-`PATCH {entityType}/{id}`
-
-veya
-
-`PUT {entityType}/{id}`
-
-Payload: Varlık özelliklerinin nesnesinin değiştirilmesi gereklidir.
-
-JSON nesnesindeki öznitelikleri döndürür.
-
-_Örnek_
-
-`PATCH Account/5564764442a6d024c`
-
-Payload:
-```
-{
- "assignedUserId": "1"
-}
-```
-
-#### Varlığı Silmek
-
-`DELETE {entityType}/{id}`
-
-_Örnek_
-
-`DELETE Account/5564764442a6d024c`
-
-
-## İlgili Varlıklar
-
-#### İlişkili Varlıkları Listele
-
-`GET {entityType}/{id}/{link}`
-
-* `offset` - (int) ofset;
-* `maxSize` - (int) maksimum boyut;
-* `where` - (array) filtreler;
-* `sortBy` - (string) sıralamak için alan;
-* `asc` - (bool) sıralama yönü.
-
-_Örnek_
-
-`GET Account/5564764442a6d024c/opportunities`
-
-Sonuçlar:
-```
-{
- "list": [... array of records...],
- "total": {totalCountOfRecords}
-}
-```
-
-#### Varlıkların Bağlantısı
-
-`POST {entityType}/{id}/{link}`
-
-Payload:
-
-1. `id` nitelik.
-2. `ids` dizi niteliği.
-3. `"massRelate": true` ve `"where": {...}` arama kriterlerine göre birden fazla kaydı ilişkilendirmek içindir.
-
-_Örnek_
-
-`POST Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-#### Varlığın Bağlantısını Kopartmak
-
-`DELETE {entityType}/{id}/{link}`
-
-Payload:
-
-1. JSON, `id` özniteliği ile birliktedir.
-2. JSON `ids` dizi özniteliği iledir.
-
-_Örnek_
-
-`DELETE Account/5564764442a6d024c/opportunities`
-
-Payload:
-```
-{
- "id": "55646fd85955c28c5"
-}
-```
-
-## Akış
-
-#### Varsayılan kullanıcı için akış girdilerini listelemek
-
-`GET Stream`
-
-Get parametleri:
-
-* `offset` - (int) ofset;
-* `maxSize` - (int) maksimum boyut;
-
-#### Belirli bir kayda ilişkin akış girdilerini listelemek
-
-`GET {entityType}/{id}/stream`
-
-Get parametleri:
-
-* `offset` - (int) ofset;
-* `maxSize` - (int) maksimum boyut;
-
-#### Kaydı takip et
-
-`PUT {entityType}/{id}/subscription`
-
-#### Kaydın takibini bırak
-
-`DELETE {entityType}/{id}/subscription`
-
-
-
diff --git a/i18n/tr_TR/development/custom-field-type.md b/i18n/tr_TR/development/custom-field-type.md
deleted file mode 100644
index a0740802a..000000000
--- a/i18n/tr_TR/development/custom-field-type.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# Özel Alan Türü Oluşturmak
-
-### Alan Tanımlaması
-
-Gerekli parametrelerle `/custom/Espo/Custom/Resources/metadata/fields/{field-type}.json` dosyasını oluşturunuz.
-
-```
-{
- "view": "custom:views/fields/{field-type}"`
-}
-```
-
-Kutudan çıkmış alan türlerini örnek olarak kullanımı: `/application/Espo/Resources/metadata/fields`.
-
-### Çeviri
-
-Etiket, Varlık Yöneticisi'nde, `fieldTypes` bölümündeki `custom/Espo/Custom/Resources/i18n/en_US/Admin.json` ayarında kullanılabilir.
-Başka bir dile çeviri eklemeniz gerekiyorsa, `en_US` yerine gerekli dili [dil kodu] kullanınız (https://en.wikipedia.org/wiki/ISO_639-1)_[ülke kodu](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). `LanguageList` bölümündeki` data/ config.php` bölümünde bulunan dillerin listesini bulabilirsiniz.
-
-### Görünüm
-
-`client/custom/src/views/fields/{field-type}.js` alanı için görünümü oluşturun ve şablonlarını tanımlayınız.
-```
-Espo.define('custom:views/fields/[field-type]', 'views/fields/base', function (Dep) {
-
- return Dep.extend({
-
- });
-});
-```
-
-Kutudan çıkmış alan türlerini örnek olarak kullanımı:
-- `/client/src/views/fields` - görünümler;
-- `/client/res/templates/fields` - şablonları.
-
-Sonra yeniden yönetim panelinde çalıştırmanız gerekmektedir.
diff --git a/i18n/tr_TR/development/custom-views.md b/i18n/tr_TR/development/custom-views.md
deleted file mode 100644
index 2f3235af9..000000000
--- a/i18n/tr_TR/development/custom-views.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Custom Views
-
-## Record Views
-
-EspoCRM framework provides flexible abilities to define custom views for certain entity types. They must be defined it `clientDefs` category of metadata.
-
-`custom/Espo/Custom/Resources/metadata/clientDefs/YourEntityType.json`
-
-```json
-{
- "views": {
- "list": "custom:views/your-entity-type/list",
- "detail": "custom:views/your-entity-type/detail",
- "edit": "custom:views/your-entity-type/edit"
- },
- "recordViews": {
- "list": "custom:views/your-entity-type/record/list",
- "detail": "custom:views/your-entity-type/record/detail",
- "edit": "custom:views/your-entity-type/record/edit"
- }
-}
-```
-
-`client/custom/src/views/your-entity-type/record/detail.js`
-
-Record/Detail view contains all panels with fields, relations and other data you can see on detail view. It doesn't contain header and buttons in the top-right corner.
-
-```javascript
-Espo.define('custom:views/your-entity-type/record/detail', 'views/record/detail', function (Dep) {
-
- return Dep.extend({
- template: 'custom:views/your-entity-type/record/detail', // Here is your custom template. Omit if you don't need it.
- middleView: 'custom:views/your-entity-type/record/detail-middle', // Here is your custom view. Omit if you don't need it.
- sideView: 'custom:views/your-entity-type/record/detail-side', // Here is your custom view. Omit if you don't need it.
- bottomView: 'custom:views/your-entity-type/record/detail-bottom', // Here is your custom view. Omit if you don't need it.
-
- setup: function () {
- Dep.prototype.setup.call(this);
-
- this.hideField('someField');
- this.showField('someField');
-
- // Custom initalization logic here. Like binding listening to model changes.
- this.listenTo(this.model, 'change:myField', function () {
- this.model.set('anotherField', this.model.get('myField') + ' Hello');
-
- this.hideField('someField');
- this.showField('someField');
- this.setFieldRequired('someField');
- this.setFieldNotRequired('someField');
-
- this.setFieldReadOnly('someField');
- this.setFieldNotReadOnly('someField');
-
- this.hidePanel('activities');
- this.showPanel('history');
- }, this);
- },
-
- afterRender: function () {
- Dep.prototype.afterRender.call(this);
-
- // Custom code to be invoked right after rendering, when DOM is avaiable.
- this.$el.find('label[data-name="myField"]').addClass('hidden');
- }
- });
-});
-
-```
-
-You are able to create a custom template with the following path:
-`client/custom/res/templates/your-entity-type/record/detail.tpl`
-
-
-
-`client/custom/src/views/your-entity-type/detail.js`
-
-Detail view contains Record/Detail view and Header.
-
-
-`client/custom/src/views/your-entity-type/edit.js`
-`client/custom/src/views/your-entity-type/record/edit.js`
-
-The same as detail but is used when record is being created or edited not in inline-edit mode.
-
-
-`client/custom/src/views/your-entity-type/list.js`
-
-List view contains Record/List view, Header and Search Form View.
-
-
-`client/custom/src/views/your-entity-type/record/list.js`
-
-List/Record view contains rows of records.
-
-
-It is worth being mentioned that you need to inherit your view class from specific class for your entity if one already exists.
-
-```javascript
-Espo.define('custom:views/email/record/detail', 'views/email/record/detail', function (Dep) {
-
-});
-```
-
-## Field Views
-
-Custom views for specific fields should be specified in entityDefs section of metadata.
-
-`custom/Espo/Custom/Resources/metadata/entityDefs/YourEntityType.json`
-
-
-
-```json
-{
- "fields": {
- "yourFieldName": {
- "view": "custom:views/your-entity-type/fields/your-field-name"
- }
- }
-}
-```
-
diff --git a/i18n/tr_TR/development/dynamic-forms.md b/i18n/tr_TR/development/dynamic-forms.md
deleted file mode 100644
index 5b6e09bc9..000000000
--- a/i18n/tr_TR/development/dynamic-forms.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Dinamik Formlar
-
-Not: 4.3.0 versiyonundan bu yana, Varlık Yöneticisi'ndeki yönetici arayüzü aracılığıyla dinamik formu tanımlamak mümkündür.
-
-EspoCRM'de form davranışını tanımlama yeteneği vardır.
-
-## Örnek
-
-> _nextStep_ alanını Fırsat Ayrıntısı görünümünde yalnızca Sahne Alanı 'Closed Won' olduğunda göstermeniz gerekmektedir.
->
-
-Dosya oluşturun `custom/Espo/Custom/Resources/metadata/clientDefs/Opportunity.json`.
-```json
-{
- "formDependency": {
- "stage": {
- "map": {
- "Closed Won" : [
- {
- "action": "show",
- "fields": ["nextStep"]
- }
- ]
- },
- "default": [
- {
- "action": "hide",
- "fields": ["nextStep"]
- }
- ]
- }
- }
-}
-```
-
-Bu, _nextStep_ alanı varsayılan olarak gizleneceğini ve sahne alanı 'Closed Won' ile aynı ise, gösterileceği anlamına gelmektedir.
-
-Kullanılabilir işlemlerin listesi: `show`, `hide`, `setRequired`, `setNotRequired`.
-
-Panelleri hide/show özelliği de vardır. `fields` ile aynı şekilde, `panels` içindeki panel adlarını belirtiniz.
-
diff --git a/i18n/tr_TR/development/extension-packages.md b/i18n/tr_TR/development/extension-packages.md
deleted file mode 100644
index 0e2dda1ba..000000000
--- a/i18n/tr_TR/development/extension-packages.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Uzantı Paketleri
-
-Uzantılar, EspoCRM'ye fazladan işlevsellik eklemenizi sağlarlar. Yönetici paneli tarafından `Customization` bölümü altında kurulabilirler.
-
-## Uzantı paketi nasıl oluşturulur?
-
-Bir paketin dosya yapısı:
-
-* `/manifest.json` – uzantı özellikleri içeren bir dosyadır;
-* `/files` – uzantı dosyalarını içeren bir dizindir;
-* `/scripts` – uzantı komut dosyalarını içerir.
-
-### Manifest
-```json
-{
- "name": "Extension Name",
- "version": "1.0.0",
- "acceptableVersions": [
- ">=3.7.2"
- ],
- "releaseDate": "2015-10-15",
- "author": "Your Name",
- "description": "Description of your extension",
- "delete": []
-}
-```
-
-* `version` ve `acceptableVersions` sözdizimi, http://semver.org'da bulunan v2.0.0 belirtilmesiyle tanımlanmıştır.
-* `delete` - silinmesi gereken temel dosyaların listesidir.Bu parametrenin kullanılması tavsiye edilmez. Atlayabilirsiniz.
-
-### Dosyalar
-
-Tüm uzantı dosyaları `files` dizinine yerleştirilmelidir. EspoCRM çekirdek dizinine kopyalanırlar.
-
-### Komut Dosyaları
-
-Farklı amaçlar için, EspoCRM aşağıdaki komut türlerini desteklemektedir. Hepsi "scripts" dizini içerisine yerleştirilmelidir.
-
-* `BeforeInstall.php` – bir yükleme işlemi öncesinde çalıştırılan bir komut dosyasıdır;
-* `AfterInstall.php` – kurulum işlemi tamamlandıktan sonra sonlanır;
-* `BeforeUninstall.php` – kaldırma işleminden önce yürütülendir;
-* `AfterUninstall.php` – kaldırma işlemi tamamlandıktan sonra gerçekleştirilir.
-
-Örnek:
-
-```php
-class AfterInstall
-{
- public function run($conatiner)
- {
- $config = $conatiner->get('config');
-
- $tabList = $config->get('tabList');
- if (!in_array('My Custom Entity', $tabList)) {
- $tabList[] = 'My Custom Entity';
- $config->set('tabList', $tabList);
- }
-
- $config->save();
- }
-}
-```
-
-### Paket
-
-Sonuç olarak, tüm bu dosyaları bir .zip arşivine yerleştirmeliyiz.
diff --git a/i18n/tr_TR/development/hooks.md b/i18n/tr_TR/development/hooks.md
deleted file mode 100644
index 118d659e8..000000000
--- a/i18n/tr_TR/development/hooks.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Hooks
-
-## Create a Hook
-To create a hook, you need to:
-- create a file `custom/Espo/Custom/Hooks/{EntityName}/{HookName}.php`;
-- declare hook type action;
-- clear Cache in Administration.
-
-## Hook Types
-
-The main hook types are:
-
-- beforeSave;
-- afterSave;
-- beforeRemove;
-- afterRemove;
-- afterRelate;
-- afterUnrelate;
-- afterMassRelate.
-
-### New Hook Type
-You can use your own hook type and trigger it with
-
-`$this->getEntityManager()->getHookManager()->process($entityType, $hookType, $entity, $options);`.
-
-## Hook Order
-If you have several hooks, related to one Entity Type and with the same hook type, and running order is important, you can set a `public static $order` property in an integer value.
-
-Ascending order - the hook with the smallest order number runs first.
-
-## Example
-This example sets Account Name for new Leads, if it is not set.
-
-`custom/Espo/Custom/Hooks/Lead/AccountName.php`
-
-```php
-namespace Espo\Custom\Hooks\Lead;
-
-use Espo\ORM\Entity;
-
-class AccountName extends \Espo\Core\Hooks\Base
-{
- public function beforeSave(Entity $entity, array $options = array())
- {
- if ($entity->isNew() && !$entity->get('accountName')) {
- $entity->set("accountName", "No Account");
- }
- }
-}
-```
-
-## Global Hooks
-If you need to apply a hook for all entities, you can use common hooks. To do this, put your hook class in Common directory, e.g. `custom/Espo/Custom/Hooks/Common/{HookName}.php`.
diff --git a/i18n/tr_TR/development/how-to-create-a-dashlet.md b/i18n/tr_TR/development/how-to-create-a-dashlet.md
deleted file mode 100644
index 7c99f1082..000000000
--- a/i18n/tr_TR/development/how-to-create-a-dashlet.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# How to create a dashlet
-
-Create a file `custom/Espo/Custom/Resources/metadata/dashlets/{DASHLET_NAME}.json` with your dashlet configuration.
-
-Here you need to define `"view"`, and you could set `"aclScope"`, `"entityType"`, and `"options"`.
-
-If it's typical list dashlet, use `"view":"views/dashlets/abstract/record-list"`, if not, create own view (https://github.com/espocrm/documentation/blob/master/development/custom-views.md).
-
-## Options
-By default in dashlet options you can set _Title_ and _Auto-refresh Interval_.
-
-Additional option fields you can set in `"options"` > `"fields"`.
-
-To define fields position set the layout in in `"options"` > `"layout"` > `"rows"`
-
-Also you can define other options, if your view needs more data.
-
-## Example
-
-`application/Espo/Modules/Crm/Resources/metadata/dashlets/Cases.json`
-
-```
-{
- "view":"views/dashlets/abstract/record-list",
- "aclScope": "Case",
- "entityType": "Case",
- "options": {
- "fields": {
- "title": {
- "type": "varchar",
- "required": true
- },
- "autorefreshInterval": {
- "type": "enumFloat",
- "options": [0, 0.5, 1, 2, 5, 10]
- },
- "displayRecords": {
- "type": "enumInt",
- "options": [3,4,5,10,15]
- },
- "expandedLayout": {
- "type": "base",
- "view": "views/dashlets/fields/records/expanded-layout"
- }
- },
- "defaults": {
- "sortBy": "createdAt",
- "asc": false,
- "displayRecords": 5,
- "expandedLayout": {
- "rows": [
- [
- {
- "name": "number"
- },
- {
- "name": "name",
- "link": true
- },
- {
- "name": "type"
- }
- ],
- [
- {
- "name": "status"
- },
- {
- "name": "priority"
- }
- ]
- ]
- },
- "searchData": {
- "bool": {
- "onlyMy": true
- },
- "primary": "open"
- }
- },
- "layout": [
- {
- "rows": [
- [
- {"name": "title"}
- ],
- [
- {"name": "displayRecords"},
- {"name": "autorefreshInterval"}
- ],
- [
- {"name": "expandedLayout"},
- false
- ]
- ]
- }
- ]
- }
-}
-```
-There you can see some examples `application/Espo/Modules/Crm/Resources/metadata/dashlets`.
-
-## Translation
-
-Translation to dashlet is in `Global` scope, in `"dashlets"` section.
-
-__After all don't forget to Clear Cache in Administration.__
diff --git a/i18n/tr_TR/development/link-multiple-with-primary.md b/i18n/tr_TR/development/link-multiple-with-primary.md
deleted file mode 100644
index 0a4b5b0c4..000000000
--- a/i18n/tr_TR/development/link-multiple-with-primary.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Link Multiple field with Primary
-
-~For EspoCRM 3.6.0 and greater.~
-
-Sometimes you have `hasMany` relationship and need to have an ability to select primary record among related ones. As example, `Contacts` field of Case entity.
-
->Need to create `contacts` linkMultiple field with a primary for our custom entity `Stock`.
->
-
-###Step 1
-`custom/Espo/Custom/Resources/metadata/entityDefs/Stock.json`
-```json
-{
- "fields": {
- ...
- "contacts": {
- "type": "linkMultiple",
- "view": "custom:views/stock/fields/contacts"
- },
- "contact": {
- "type": "link"
- },
- ...
- },
- "links": {
- ...
- "contact": {
- "type": "belongsTo",
- "entity": "Contact",
- "foreign": "stocksPrimary"
- },
- "contacts": {
- "type": "hasMany",
- "entity": "Contact",
- "foreign": "stocks",
- "layoutRelationshipsDisabled": true
- },
- ...
- }
-}
-```
-
-###Step 2
-`custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json`
-```json
-{
- "links": {
- ...
- "stocksPrimary": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contact",
- "layoutRelationshipsDisabled": true
- },
- "stocks": {
- "type": "hasMany",
- "entity": "Stock",
- "foreign": "contacts"
- }
- ...
- }
-}
-```
-
-###Step 3
-`custom/Espo/Custom/Repositories/Stock.php`
-```php
-handleAfterSaveContacts($entity, $options);
- return $result;
- }
- protected function handleAfterSaveContacts(Entity $entity, array $options)
- {
- $contactIdChanged = $entity->has('contactId') && $entity->get('contactId') != $entity->getFetched('contactId');
- if ($contactIdChanged) {
- $contactId = $entity->get('contactId');
- if (empty($contactId)) {
- $this->unrelate($entity, 'contacts', $entity->getFetched('contactId'));
- return;
- }
- }
- if ($contactIdChanged) {
- $pdo = $this->getEntityManager()->getPDO();
- $sql = "
- SELECT id FROM contact_stock
- WHERE
- contact_id = ".$pdo->quote($contactId)." AND
- stock_id = ".$pdo->quote($entity->id)." AND
- deleted = 0
- ";
- $sth = $pdo->prepare($sql);
- $sth->execute();
- if (!$sth->fetch()) {
- $this->relate($entity, 'contacts', $contactId);
- }
- }
- }
-}
-```
-
-###Step 4
-`client/custom/src/views/stock/fields/contacts.js`
-```js
-Espo.define('custom:views/stock/fields/contacts', 'views/fields/link-multiple-with-primary', function (Dep) {
- return Dep.extend({
- primaryLink: 'contact'
- });
-});
-```
-
-###Step 5
-Run Rebuild
-
-###Step 6
-Execute SQL query
-```sql
-UPDATE stock
-JOIN contact_stock
-ON contact_stock.stock_id = stock.id AND contact_stock.deleted = 0
-SET stock.contact_id = contact_stock.contact_id
-```
-
diff --git a/i18n/tr_TR/development/metadata.md b/i18n/tr_TR/development/metadata.md
deleted file mode 100644
index 3ef626960..000000000
--- a/i18n/tr_TR/development/metadata.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Metadata
-
-Metadata is intended for: storing system data such as entity's fields and relationships; specifying frontend controllers, views, panels; defining fields, dashlets; and other data needed for the application.
-
-
-## How to access
-
-#### Backend
-
-Metadata object of `Espo\Core\Utils\Metadata` class can be access from Container. Path to a needed parameter is specified using dots `.`.
-
-```php
-$metadata->get('entityDefs.Account.fields.name.type')
-```
-will return `'varchar'`.
-
-```php
-$metadata->get('entityDefs.Account.fields')
-```
-will return an associative array of all fields.
-
-#### Frontend
-
-Metadata object is accessible from all view objects by method `#getMetadata`. It works the same way as backend's one.
-
-```JavaScript
-this.getMetadata().get('entityDefs.Account.fields.name.type')
-```
-
-
-## How is it stored
-
-Metadata is stored in JSON files that can be located in different places:
-
-* application/Espo/Resources/metadata/
-* custom/Espo/Custom/Resources/metadata/
-* application/Espo/Modules/{MODULE_NAME}/Resources/metadata/
-
-When you access data by path `clientDefs.Account.views.edit` the first lexeme `clientDefs` corresponds to dir name, the second `Account` to file name `Account.json`. All following lexemes correspond to path in the JSON.
-```json
-{
- "views": {
- "edit": "crm:views/account/views/edit"
- }
-}
-```
-
-All JSON files from these directories get merged recursively into a single php array and stored in a cache file.
-
-
-## Extending
-
-Since metadata is merged recursively you can easily redefine json objects and arrays in _custom_ and in your _module_. Also you can append to existing arrays by using `__APPEND__` (since version 2.6.0) as the first element of array.
-
-`custom/Espo/Custom/Resources/Metadata/entityDefs/Account.json`
-
-```json
-{
- "fields": {
- "employeeCount": {
- "type": "int"
- },
- "type": {
- "options": ["__APPEND__", "Drug dealer", "Lawyer"]
- }
- }
-}
-```
diff --git a/i18n/tr_TR/development/new-function-in-formula.md b/i18n/tr_TR/development/new-function-in-formula.md
deleted file mode 100644
index 683a84693..000000000
--- a/i18n/tr_TR/development/new-function-in-formula.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Defining new funtions for Formula
-
-EspoCRM provides the possibility to create custom functions that can be used in formula.
-
-If your function is related to the one of groups like String, Logic, Date, create a file in __{GroupName}Group__ folder, named __{FunctionName}Type.php__ with __{FunctionName}Type__ class declaration. You need to define the method __'process'__.
-
-For example, let's create a new string function for checking if a string (HAYSTACK) contains another string (NEEDLE) with a possible offset (OFFSET).
-
-Create a file `application/Espo/Core/Formula/Functions/StringGroup/ContainsType.php` with the code:
-
-```
-namespace Espo\Core\Formula\Functions\StringGroup;
-
-use \Espo\Core\Exceptions\Error;
-
-class ContainsType extends \Espo\Core\Formula\Functions\Base
-{
- public function process(\StdClass $item)
- {
- if (!property_exists($item, 'value')) {
- throw new Error();
- }
-
- if (!is_array($item->value)) {
- throw new Error();
- }
-
- if (count($item->value) < 2) {
- throw new Error();
- }
-
- $haystack = $this->evaluate($item->value[0]);
- $needle = $this->evaluate($item->value[1]);
-
- if (count($item->value) > 2) {
- $offset = $this->evaluate($item->value[2]);
- return !(strpos($haystack, $needle, $offset) === false);
- } else {
- return !(strpos($haystack, $needle) === false);
- }
- }
-}
-```
-## Adding the function to the list
-
-In order to add the created function to the function list of formula, create a file `custom/Espo/Custom/Resources/metadata/app/formula.json` and add the code:
-```
-{
- "functionList": [
- {
- "name": "string\\contains",
- "insertText": "string\\contains(HAYSTACK, NEEDLE, OFFSET)"
- }
-}
-```
-
-__Clear cache__ and use this function in formula. You can type it `string\contains(HAYSTACK, NEEDLE, OFFSET)` or select from function list, if you add it.
-
diff --git a/i18n/tr_TR/development/orm.md b/i18n/tr_TR/development/orm.md
deleted file mode 100644
index 5321a42f8..000000000
--- a/i18n/tr_TR/development/orm.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# ORM (How to Manage Entities)
-
-EspoCRM has built-in own ORM (Object-relational mapping). It’s very simple to create, update, read, delete and search entities. All these operations available through EntityManager object. EntityManager is available in record Services by method `#getEntityManager()`.
-
-```php
-$entityManager = $this->getEntityManager();
-```
-
-#### Create new entity
-```php
-$account = $entityManager->getEntity('Account')
-```
-or
-```php
-$account = $entityManager->getRepository('Account')->get();
-```
-
-#### Fetch existing
-```php
-$account = $entityManager->getEntity('Account', $accountId);
-```
-or
-```php
-$account = $entityManager->getRepository('Account')->get($accountId);
-```
-
-#### Get value
-```php
-$fieldValue = $account->get('fieldName');
-```
-
-#### Has value
-```php
-$fieldNameIsSet = $account->has('fieldName'); // true or false
-```
-
-#### Set value
-```php
-$account->set('fieldName', 'Test Account');
-```
-
-```php
-$account->set(array(
- 'name' => 'Test Account',
- 'assignedUserId' => '1'
-));
-```
-
-#### Store
-```php
-$entityManager->saveEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->save($account);
-```
-
-#### Remove
-```php
-$entityManager->removeEntity($account);
-```
-or
-```php
-$entityManager->getRepository('Account')->remove($account);
-```
-
-#### Find
-```php
-$accountList = $entityManager->getRepository('Account')->where(array(
- 'type' => 'Customer',
-))->find();
-```
-
-Descending order:
-
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', true)->find();
-```
-
-Ascending order:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt')->find();
-```
-
-or:
-```php
-$accountList = $entityManager->getRepository('Account')->limit(0, 10)->order('createdAt', 'DESC')->find();
-```
-
-#### Find the first one
-```php
-$account = $entityManager->getRepository('Account')->where(array(
- 'type' => 'Customer',
-))->findOne();
-```
-
-#### Find related
-```php
-$opportunityList = $entityManager->getRepository('Account')->findRelated($account, 'opportunities');
-```
-
-#### Relate entities
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->relate($account, 'opportunities', $opportunityId);
-```
-
-#### Unrelate entities
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunity);
-```
-or
-```php
-$entityManager->getRepository('Account')->unrelate($account, 'opportunities', $opportunityId);
-```
-
diff --git a/i18n/tr_TR/development/scheduled-job.md b/i18n/tr_TR/development/scheduled-job.md
deleted file mode 100644
index 4b4327fbf..000000000
--- a/i18n/tr_TR/development/scheduled-job.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Creating Scheduled Job
-
-To define a custom Scheduled Job create a file `custom/Espo/Custom/Jobs/{JOB_NAME}.php` with the content.
-
-```
-namespace Espo\Custom\Jobs;
-
-class {JOB_NAME} extends \Espo\Core\Jobs\Base
-{
-
- public function run()
- {
- //all the logic needs to be defined in the method run
- }
-}
-```
-
-Also, you can set a label for your job (`custom/Espo/Custom/Resources/i18n/{language}/ScheduledJob.json`).
-```
-{
- "options": {
- "job": {
- "{JOB_NAME}": "{JOB_NAME_TRANSLATION}"
- }
- }
-}
-```
-
-To implement the changes, go to Administration panel and Clear Cache.
diff --git a/i18n/tr_TR/development/workflow-service-actions.md b/i18n/tr_TR/development/workflow-service-actions.md
deleted file mode 100644
index 0e8a98e54..000000000
--- a/i18n/tr_TR/development/workflow-service-actions.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# İş Akışı için özel hizmet işlemi eklemek
-
-İş akışları, özel hizmet eylemleri oluşturmanıza olanak tanımaktadır. Bu örnekte, bunun bir Arama öğesi için nasıl yapılacağı gösterilecektir.
-
-## 1. Adım: Hizmet Sınıfı Oluşturun
-
-```php
-Önbelleği Temizle. Artık, hizmet eylemi, Hizmet Çalıştırma İşlemi formunda İş Akışları için kullanılabilir.
diff --git a/i18n/tr_TR/user-guide/browser-support.md b/i18n/tr_TR/user-guide/browser-support.md
deleted file mode 100644
index 724e79d6b..000000000
--- a/i18n/tr_TR/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Tarayıcı desteği
-
-Google Chrome veya Mozilla Firefox'un en son versiyonlarının kullanılmasını tavsiye ederiz. EspoCRM en iyi bu tarayıcılarda çalışır. Bu tarayıcılarda tüm özellikleri düzenli olarak test ediyoruz.
-
-Microsoft Edge ve Safari de desteklenmektedir, fakat her şeyin düzgünce çalışacağına dair garanti daha azdır.
-
-Kesinlikle Internet Explorer 11 kullanılmasını tavsiye etmiyoruz.
diff --git a/i18n/tr_TR/user-guide/emails.md b/i18n/tr_TR/user-guide/emails.md
deleted file mode 100644
index 022c7affb..000000000
--- a/i18n/tr_TR/user-guide/emails.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Eposta Kullanım Önerileri
-
-EspoCRM epostaları IMAP kutusundan getirme yetisi sağlar ve bu EspoCRM'yi eposta işlemcisi olarak CRM'ye özel özelliklerle birlikte kullanmayı mümkün kılar.
-EspoCRM provides the ability to fetch emails from IMAP box. This makes possible to use EspoCRM as an email client along with CRM-specific features.
-
-## IMAP hesapları
-
-*Not: Almalısınız [cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) sisteminizde gelen mailleri çalışır durumda tutmak için düzgünce yapılandırılmıştır.*
-
-Kullanıcı IMAP hesabını Kişisel Eposta Hesapları sayfasından ayarlayabilir (Epostalar sekmesi > sağ-üst menü > Kişisel Eposta Hesapları).
-
-Gözlenen Dosyalar alanında yönetilecek dosyaların hangileri olduğunu belirtiniz. Varsayılan ayarlarda GELEN KUTUSU olarak ayarlanmıştır. Eğer epostalarınızı göndermek için dış eposta istemcileri kullanıyorsanız bu epostaları arşivleyerek Gönderilmişler dosyasına ekleyebilirsiniz.
-
-
-*Getirme Tarihi* epostaların hangi tarihten itibaren arşivlenmiş olacağını seçmenize izin verir. Eski epostaları arşivlemeye ihtiyacınız varsa tarihi bugünden önce herhangi bir zamana ayarlayın.
-
-Kişisel Eposta Hesabında *Dosta* belirleme yetisi vardır. Gelen epostalar bu dosyaya koyulacaktır.
-
-## SMTP Hesapları
-
-Kullanıcılar SMTP ayarlarını Kişisel Eposta Hesaplarında olduğu gibi Tercihler kısmından yapabilirler. Yönetici de SMTP sistemini kullanmaya izin verebilir (Paylaşımlı yapın).
-
-Kullanıcılar birden fazla SMTP hesabına sahip olabilirler (4.2.0 versiyonundan beri). Ama, burayı epostalarını göndermek için kullanan eposta adreslerinin kullanıcısı *Kullanıcı* kaydının eposta adreslerinden belirlenir.
-
-## Epostalarla Çalışmak
-
-Epostalar her birkaç dakikada bir(zaman aralığı Yönetici tarafından belirlenebilir) cron ile getirilir(arkaplanda). Epostalar sekmesinde bütün epostalarınızı görebilirsiniz. Sol tarafta Gelen Kutusu, Gönderilen, Taslak epostalar olarak standart dosyalar bulunmaktadır.
-
-
-*Durum* alanı. `Gönderildi` CRM'den gönderildiği anlamına gelir, `Arşivlendi` – IMAP hesabından getirilmiş veya elle arşivlenmiş, `Taslak` – epostanın taslak olarak yaratılmış olduğu anlamına gelir.
-
-Yeni bir eposta geldiği zaman sistem bu epostanın hangi kayda ait olduğunu tanımaya çalışır. Bu mail Hesap, Kılavuz, Fırsat, Durum(B2C moduyla etkileşim halindedir) vb. ile bağlantılı olabilir. Eğer mail tanınmazsa kullanıcı elle *Üst öğe* alanını doldurarak bağlantı kurabilir.
-
-Eğer eposta potansiyel yeni bir istemciden geliyorsa kullanıcı **Kılavuze çevirebilir** . Eposta öğesini açın ve sağ-üst menüden Kılavuz Yarat sekmesine tıklayın.
-
-Eposta kaydından **Durum veya Görev yaratmak** da mümkündür.
-
-Eğer bir email kaydındaki email adresleri (-dan, -a, cc) sistemce biliniyorsa, sistem ilgili olduğu kişiyi gösterecektir (Kişi, Kılavuz, Kullanıcı vb). Eğer bazı eposta adresleri yeniyse hemen oradan **kişi yaratabilirsiniz**.
-
-Bütün epostalar o kaydın Geçmiş panelinde gösterilen spesifik bir kayıtla ilgilidir. Örneğin, eğer bazı epostalar fırsatla ilgiliyse ama fırsatlar hesapla ilgiliyse, bu epostalar hem fırsatlarda hem de hesapta gösterilecektir.
-
-## Eposta Yollama
-
-Birkaç yolla yeni eposta oluşturabilirsiniz:
-* Eposta listesi görünümündeki *Eposta Oluştur* butonu ile;
-* bir başka maile cevap vererek;
-* bir kaydın bir eposta adresine tıklayarak;
-* Aktiviteler panelinden *Eposta Oluştur* işlemiyle.
-
-Epostanız için **şablon seçme** yetisi vardır.
-
-Tercihlerden **eposta imzanızı** ayarlayabilirsiniz.
-
-## Email Dosyaları
-
-Kullanıcılar kolaylık olsun diye bazı epostaları koymak için kendi eposta dosyalarını yaratabilirler. Uygun dosyaların listesi Epostalar sayfasının sol tarafında mevcuttur. Dosyaları yaratmak veya düzenlemek için Epostalar > sağ-üst köşedeki açılır liste > Dosyalar takip edilir. 'Bildirimleri Atla' belirli bir dosyaya düşen epostalar hakkında bildirim almayacağınız anlamına gelir. Eposta Filtrelerini kullanarak epostaları otomatik olarak spesifik bir kritere dayanarak dosyalara koymanız mümkündür.
-
-## Eposta Filtreleri
-
-Yönetici istenmeyen epostaları atlamak için global eposta filtreleri yaratabilir. Bu filtreler Yönetim > Eposta Filtreleri sekmesinde mevcuttur.
-
-Düzenli kullanıcılar kendi Kişisel Eposta Hesapları veya kendi gelen kutuları için eposta filtreleri yaratabilirler. Bu filtreler Epostalar > sağ-üst köşedeki açılır kapanır liste > Filtreler takip edilir.
-
-İki tip filtre mevcuttur:
-* Geç - email *Çöp*e koyulur veya filtre Kişisel Eposta Hesabıyla alakalıysa aktarılmayacaktır;
-* Dosyaya koy - aktarılmış epostalar otomatik olarak özelleştirilmiş kullanıcı dosyasına koyulacaktır.
-
-## Eposta Şablonları
-
-Epostalar > sağ-üst köşedeki açılır kapanır liste > Eposta Şablonları kısmında eposta şablonları mevcuttur. Hem toplu eposta gönderimlerinde, hem de normal epostalar için kullanılabilir. 'Tek seferlik' onay kutusu eposta şablonunun sadece tek bir sefer kullanılması gerektiği anlamına gelir ki bu eposta marketing için alışılmış bir durumdur.
-
-Eposta şablonunun gövde ve konusunda dosyaları kullanmak mümkündür örneğin {Hesap.adı}, {Kişi.epostaAdresi}. İlgili kayıtların değerleri onların yerine gelecektir.
-
-Ek mahfuz dosyaları şablon gövdesinde kullanabilirsiniz: {optOutUrl} ve {optOutLink}.
-```
-Unsubscribe
-```
-Bu toplu eposta için aboneliği kaldırma linkidir.
diff --git a/i18n/tr_TR/user-guide/markdown.md b/i18n/tr_TR/user-guide/markdown.md
deleted file mode 100644
index c17e283a5..000000000
--- a/i18n/tr_TR/user-guide/markdown.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Markdown syntax
-
-Text fields support markdown syntax.
-
-## Code
-```
-`some text`
-```
-
-`some text`
-
-## Multiline code
-
-```
-``` some text ```
-```
-
-```
-some text
-```
-
-## Strong text
-
-```
-**some text**
-```
-
-**some text**
-
-## Emphasized text
-
-```
-*some text*
-```
-
-*some text*
-
-## Deleted text
-
-```
-~~some text~~
-```
-
-~~some text~~
-
-## Blockquote
-
-```
-> some
-> test
-```
-
-> some
-> text
-
-## Link
-
-```
-[link text](https://www.espocrm.com)
-```
-[link text](https://www.espocrm.com)
-
-## Numbered list
-
-```
-1. Some item
-2. Another item
-```
-
-1. Some item
-2. Another item
-
-## Unnumbered list
-
-```
-* Some item
-* Another item
-```
-
-* Some item
-* Another item
-
-## Horizontal line
-
-```
-___
-```
-
diff --git a/i18n/tr_TR/user-guide/mass-email.md b/i18n/tr_TR/user-guide/mass-email.md
deleted file mode 100644
index 8ab57532b..000000000
--- a/i18n/tr_TR/user-guide/mass-email.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# Toplu Eposta
-
-## Nasıl toplu eposta gönderilir
-
-crmnizde en az hedef kayıtların olduğu bir Hedef Listesi ve Eposta Şablonu olmalıdır.
-
-1.`Eposta` or `Bülten` olarak yeni bir Kampanya yarat. `Hedef Listeleri` alanından bir veya daha fazla hedef listesi seç.
-2. Kampanya kaydı yaratıldıktan sonra bu kampanya için Toplu Eposta yarat: Toplu Eposta panelindeki artıya tıkla. Epostaların gönderilmesi gereken _Başlama tarihi_ belirle ve _Eposta Şablonu_ seç. _Durum_u `Beklenen` olarak ayarladığınıza emin olun.
-
-Her şey doğru ayarlandıysa epostalar gitmelidir. Epostalar her saat parçalar halinde gönderilmelidir (parça büyüklüğünü Yönetim > Giden Epostalar kısmından değiştirebilirsiniz). Yönetici `Programlama` alanından `Grup Eposta Hesaplarını Kontrol Et` Programlanmış İşi güncelleyerek değiştirebilir.
-
-Log panelinden epostaların gönderilip gönderilmediğini kontrol edebilirsiniz.
-
-## Alıcılara neyin gönderileceğini test et
-
-_Toplu Eposta_ panelinde toplu eposta sırasının sağ açılır listesine tıkla ve sonra _Test Gönder_e tıkla.
-
-## Log
-
-Log'da şunları görebilirsiniz:
-* Gönderilmiş eposta;
-* Alıcı tarafından açılmış eposta;
-* Alıcı tarafından tıklanmış linkler;
-* Ayrılan alıcılar;
-* Geri seken epostalar (alıcıya iletilmemiş).
-
-## Ayrılma Linki
-
-Sistem varsayılan olarak ayrılmayı tüm gönderilmiş epostalara ekleyecektir. Ama siz Eposta Şablonunuzda özel bir tane kullanabilirsiniz.
-
-Örnek:
-```html
-Mail listesinden çık.
-```
-
-Yönetici sistem tarafından eklenmiş zorunlu ayrılma linkini Yönetim > Giden Epostalar kısmından devre dışı bırakabilir.
-
-## URL İzleme
-
-Eğer alıcınızın epostadaki linki açtığını bilmek istiyorsanız, bir URL İzleme yaratmalısınız. Linkinizin gitmesi gereken herhangi bir _İsim_ ve _URL_ belirleyin. Sonra, Eposta Şablonunuza yaratılan kodu yapıştırmalısınız.
-
- Örnek:
- ```html
-Demomuzu deneyin
- ```
-
-## Hedef Listeler
-
-Hedef Listeler Hesap, Kişiler, Destekler ve Kullanıcıların kayıt listelerini içerir.
-
-Kullanıcılar Hedef Listesinin detaylı görünümüne denk düşen panelde _Seç_ eylemini kullanarak hedef listesini elle doldurabilirler. Filtreleme ve sonra aramanın tüm sonuçlarını seçme yetisi vardır.
-
-## Hedef listelerini raporlarla doldurmak
-
-[Reports](reports.md#syncing-with-target-lists) özelliği hedef listelerinin spesifik kriterlerle eşleşen kayıtlarla doldurulmasını sağlar.
-
-## Dışarda Tutulan Hedef Listeleri
-
-Toplu epostaları belli alıcılara göndermekten kaçınmak için Dışarda Tutulan Hedef Listelerini belirleyin. Eğer dışarıda tutulmuş bir eposta adresinin kaydıyla eşleşen bir eposta adresi kaydı varsa, ilk kayıt da dışarıda tutulacaktır.
-
-## Kampanya Logu
-
-Kampanya Logunda gönderilmiş epostaları, açılmış epostaları, geri sekmiş epostaları, ayrılanları ve epostadaki linke tıklayanları görebilirsiniz. Bu logu, logdaki kayıtları baz alarak bir Hedef Listesi (panelde sağ-üst köşedeki açılır liste) yaratarak kullanmak mümkündür. Örneğin, sadece linke tıklamış kişileri seçersiniz (URL izleme).
-
-## Sorun Giderme
-
-_Yöneticiler için_
-
-#### Epostalar gönderilmezse yapılacaklar
-
-1. _Test Gönder_ çalışıyor mu diye kontrol edin. Eğer çalışmıyorsa, SMTP sistem ayarlarının doğruluğunu kontrol edin.
-2. Sisteminiz için kurulum cronu olup olmadığını kontrol edin.
-3. `Toplu Eposta Gönder`de Planlanmış İş var mı kontrol edin ve `Aktif` olup olmadığına bakın (Yönetim > Planlanmış İşler > Toplu Eposta Gönder). Log'da bir şey olup olmadığını kontrol edin.
-
-
-#### What if Tracking URLs has wrong url that does not lead to your crm.
-
-Check 'siteUrl' parameter in `data/config.php` file. It must be set as URL of your EspoCRM accessible from the external world.
-
-#### Bounced emails are not being logged
-
-Bounced emails can be handled by group email account only. Make sure that you have a group email account that monitores the mailbox bounced emails are sent to.
-
-Also some mail server providers can deviate from standards, so bounced emails can be not distinguished.
diff --git a/i18n/tr_TR/user-guide/quotes.md b/i18n/tr_TR/user-guide/quotes.md
deleted file mode 100644
index 625fe70bc..000000000
--- a/i18n/tr_TR/user-guide/quotes.md
+++ /dev/null
@@ -1,110 +0,0 @@
-# Fiyatlandırma
-
-Fiyatların özelliği [Gelişmiş Paket] içerisinde mevcuttur.(https://www.espocrm.com/extensions/advanced-pack/).
-
-Fiyatlandırma, müşterilere teklif ettiğiniz miktar ve fiyatlarla belirli ürün veya hizmet grubudur.
-
-Fiyatlandırma fırsat ile bir ilişkilidir. Fırsatlar ayrıntısını fiyatlandırma paneline Yönetim> Düzen Yöneticisi> Fırsatlar> İlişkilere ekleyebilirsiniz.Bir fırsata bağlı yeni bir fiyat teklifi hazırlarken fırsat öğelerini fiyat teklifine aktarılır.
-
-İlgili teklifleri görebilmek için Hesapın detaylı görünümüne Fiyat panelini ekleyebilirsiniz. Bunu, Yönetim>Düzen Yöneticisi> Hesaplar> İlişkilerde de yapabilirsiniz.
-
-## Ürünlerin Fiyatandırması
-
-Fiyatlandırmanın bir ürün listesi vardır. Her bir madde, açıklama, miktar, vergi oranı, liste fiyatı ve birim fiyat alanlarıyla belli bir ürünü veya hizmeti temsil edebilir. Öğeleri manuel olarak sıralamak mümkündür.
-
-Varlık Yöneticisi'ni kullanarak Fiyat Elemanı varlığı için özel alanlar ekleme özelliği vardır.
-
-## Şablonlar
-
-Varsayılan olarak iki mevcut şablon vardır: Fiyat ve Fatura. Yeni şablonları (Quotes list view> top-right dropdown menu> Templates) oluşturabilir ve var olanları düzenleyebilirsiniz.
-
-Daha hassas düzenleme için Kod Görünümü modunu kullanmanız önerilir.
-
-Şablonunuzdaki yer tutucuları kullanarak Fiyatlandırma kayıt alanlarını ve ilgili kayıt alanlarını yazdırabilirsiniz.
-
-Örnekler:
-`{{accountName}}` – Hesap adı,
-
-`{{{billingAddressStreet}}}` – Soka,
-
-`{{account.type}}` – ilgili hesap türü,
-
-`{{assignedUser.lastName}}` – atanmış kullanıcının soyadı.
-
-Satır öğeniz bir ürünse, ürün alanlarını yazdırabilirsiniz.
-
-Örnekler:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Uzunluk ve renk, örneklerde Ürün varlığının özel alanlarıdır.
-
-Teklif ürünleriyle döngü:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-Resim alanlarını basmak mümkündür:
-
-```
-
-```
-Nerede `imageId` – Fiyat nesnesinde özel imaj alanının adını `ID` sonekiyle bitiştirilir.
-
-Ürün için üretim hattı:
-
-```
-
-```
-
-Virgüllü sayıları (örneğin miktar, birim fiyat vb.) Görüntülemek için kesirli kısmı (tam sayı olarak) aşağıdaki ifadeleri kullanınız (sürüm 4.8.3'ten beri):
-
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Para birimi değerleri için özel biçimlendirme (sürüm 4.8.3'ten beri):
-
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
- `10000.5` değeri `10 000,50` yazıcı olacaktır.
-
-Metin alanlarını görüntülemek için (çok satırlı) üçlü parantez kullanın: `{{{description}}}`.
-
-## PDF'ye yazdır
-
-Fiyatlandırmalar PDF'ye yazdırılabilir. Bu işlem teklifin ayrıntılı görünümü Düzenle düğmesinin yanında açılır menüde mevcuttur.Devamında Şablon'u seçmeniz istenecektir.
-
-
-## E-Postaya gönderilen fiyatlar
-
-Fiyatlandırmalar PDF e-postayla ek olarak gönderilebilir. Teklif kaydını açın, Düzenle butonunun yanındaki açılır listeye tıklayın ve E-posta PDF'e göndermeye tıklayın..
-
-## Otomatik numaralandırma
-
-Fiyatlandırmanın varlık türü için Varlık Yöneticisi aracılığıyla bir numara alanı oluşturabilirsiniz. Yönetim> Varlık Yönetimi> Fiyatlar> Alanlar> Alan Ekle> Numara. Ardından, Düzen Yöneticisi'ni kullanarak ayrıntılı görünümüne yerleştirmeniz gerekmektedir.
-
-Değer, her yeni teklif tarafından artırılacaktır. Önekin yanı sıra sonraki numarayı belirtme olanağı da vardır.
-
-## Varsayılan vergi
-
-EspoCRM 4.8.0'dan beri mevcut.
-
-1. Yönetim> Kuruluş Yöneticisi> Fiyatlar > Alanlar> Vergi> Varsayılan'da, varsayılan vergi kaydını belirtin.
-2. Varsayılan vergi oranını Yönetim> Kuruluş Yöneticisi> Fiyatlar> Alanlar> Vergi Oranı> Varsayılan değerlerinden belirleyin.
-
-## Faturalar
-
-Fiyatlandırma durumu `Onaylandığında` bir fatura olarak ele alınabilir.Ardından Faturalandırılmış Tarih, Fatura Numarası alanları görülür. Faturaları yazdırmak için farklı şablon kullanabilirsiniz.
-
diff --git a/i18n/tr_TR/user-guide/reports.md b/i18n/tr_TR/user-guide/reports.md
deleted file mode 100644
index 774f0bb3e..000000000
--- a/i18n/tr_TR/user-guide/reports.md
+++ /dev/null
@@ -1,91 +0,0 @@
-# Raporlar
-
-Raporların özelliği [Gelişmiş Paket](https://www.espocrm.com/extensions/advanced-pack/) adresinde mevcuttur.
-
-İki tür rapor vardır: Listeli ve Izgaralı.
-
-## Liste Raporları
-
-Rapor sonuçlarını, belirtilen kriterleri karşılayan kayıtların listesini yapınız.
-
-Yeni liste raporu oluşturmak için Raporlar sekmesini ve ardından Rapor Oluştur düğmesini tıklayınız. İstenilen Öğe Türü'nü seçiniz ve Liste Raporu bölümünde Oluştur düğmesini tıklayınız.
-
-_Sütunlar_ alanında görüntülemek istediğiniz alanları seçin. Aşağıda, her sütunun görüntü parametrelerini belirtebilirsiniz; örneğin: genişlik ve hizalamak.
-
-_Liste komutu_ alanını sıralamak için gerekli olanını seçiniz.
-
-_Filtreler_ bölümünde, raporunuzda hangi kayıtların listeleneceğini belirleyen ölçütleri belirtebilirsiniz. Buradaki mantıksal operatörlerin 'VEYA' ve 'VE' değerlerini kullanabilirsiniz.
-
-_Çalışma zamanlı filtreler_, raporu çalıştırmadan önce farklı filtreler belirlemenize izin verir.
-
-Excel ve CSV formatlarının listelenmiş rapor sonuçlarını __dışarıya aktarabilirsiniz__.
-
-## Izgara Raporları
-
-Izgara raporları, belirtilen alanlarla gruplandırılmış, özetlenmiş değerleri verir. Bu raporlar bir grafik olarak görüntülenebilirler.
-
-
-
-
-Yeni ızgara raporu oluşturmak için Raporlar sekmesine tıklayın ve ardından Rapor Oluştur butonuna tıklayınız. Gerekli Öğe Türü'nü seçin ve Izgara Raporu bölümünde Oluştur butonuna tıklayınız.
-
-_Grupla_ alanında, rapor verilerinizin gruplandırılmasını istediğiniz bir veya iki alanı seçiniz. Tarih alanlarına yıl, ay ve gün bazında gruplama yapmak mümkündür.Eğer iki alana da gruplarsanız, raporunuz üç boyutlu olarak kabul edilir.
-
-_Sütunlar_ kısmında, COUNT, SUM (toplam), MIN, MAX, AVG (ortalama) gibi bir veya daha fazla toplama işlevini seçiniz.
-
-_Gruplama_ alanı rapor verilerinin nasıl sıralanacağını tanımlar.
-
-_Filtreler_ bölümünde, raporunuzda hangi kayıtların kullanılacağını belirleyen ölçütleri belirtebilirsiniz. Buradaki mantıksal operatörlerin 'VEYA' ve 'VE' değerlerini kullanabilirsiniz.
-
-_Çalışma zamanlı filtreler_, raporu çalıştırmadan önce farklı filtreler belirlemenize izin verir.
-
-Izgara raporu, sonuçları grafik formunda görüntülemenize izin verir. Aşağıdaki _grafik türleri_ ardından şunlardır:Bar (Yatay), Bar (Dikey), Pie, Çizgi.
-
-Excel ve CSV formatlarının listelenmiş rapor sonuçlarını __dışarıya aktarabilirsiniz__.
-
-## Filtreler
-
-### Alan Filtresi
-
-Basit filtre türlerini kullanınız. Ayrıca, hedef varlığın alanlarını ve ilgili varlıkları da seçebilirsiniz.
-
-
-
-### VEYA grubu
-
-VEYA, gruptaki en az bir koşulun yerine getirilmesi gerektiği anlamına gelir.
-
-
-
-### VE grubu
-
-VE, gruptaki tüm koşulların yerine getirilmesi gerektiği anlamına gelir.
-
-### DEĞİL grubu
-
-Belirtilen kriterlere uymayan kayıtları filtreleme olanağı sağlar. Örneğin. Kapalı Kazanılan veya Kapatılı Kaybedilmiş Durumularıyla fırsat bulamayan hesapları listeleme.
-
-
-
-### Karmaşık İfade
-
-Daha gelişmiş kullanım içindir. Belli bir veritabanı sütunu için işlevi uygulayabilir ve [formül](../administration/formula.md) ifadesinin sonucuyla karşılaştırabilirsiniz.
-
-
-Not: Sadece basit bir dize değeri ile karşılaştırmanız gerekiyorsa ona, `'bazı dize'` tek tırnak işaretlerini koymalısınız.
-
-Not: Form kayıtları belirli kayıtlara uygulanmadığından varlık kaydı ile etkileşim kurmayı amaçlayan fonksiyonlar burada geçerli olmayacaktır.
-
-
-
-## Gösterge tablosunda gösteriliyor
-
-Gösterge tablosundaki herhangi bir raporu görüntüleyebilirsiniz. Bunun için Report dashlet'ni eklemeniz ve ardından dashlet seçeneklerinden gerekli raporu seçmeniz gerekmektedir.
-
-## E-posta Gönderme
-
-Belli zamana göre belirli kullanıcılara rapor sonuçlarını göndermek için sistemi düzenli olarak yapmak mümkündür. Bu, belirli raporlar için ayrı ayrı yapılandırılmalıdır.
-
-## Hedef Listelerle Senkronizasyon
-
-Liste raporlarının sonuçları ile senkronize edilmiş hedef listelerinin olması mümkündür. E-postalar yalnızca gönderim sırasındaki bazı ölçütleri karşılayan kişilere göndermek istediğinizde toplu e-posta için uygundur. Bu özellik, 'Raporlarla Senkronize Etme' panelindeki herhangi bir hedef listesinin ayrıntılı görünümünde bulunur.
diff --git a/i18n/tr_TR/user-guide/stream.md b/i18n/tr_TR/user-guide/stream.md
deleted file mode 100644
index a3cff4def..000000000
--- a/i18n/tr_TR/user-guide/stream.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Akış
-
-Kendi akışınıza ve (sürüm 3.8.0'dan bu yana) başka kullanıcıların akışına gönderim yapabilirsiniz. EspoCRM'de iki tür yayın bulunur: kayıt akışı ve kullanıcı akışı.
-
-Varsayılan olarak, aşağıdaki öğeler bir akışa sahiptir: Hesaplar, Kişiler, Müşteri Adayları, Fırsatlar, Olaylar. Yöneticiler, [Öğe Yöneticisi](../administration/entity-manager.md)'inden belirli bir öğe için akışı etkinleştirebilir veya devre dışı bırakabilir.
-
-## Kayıt Akışı
-
-Kayıt Akışı, belirli bir kaydın ayrıntılı görünümdeki Akış panelinde gösterilir. Gönderiler, güncellemeler ve mevcut kayıtla ilgili yeni ilaveler burada gösterilir.
-
-## Kullanıcı Akışı
-
-Kullanıcılar, Akış panelinde ve Akış sekmesi altında akışlarını görebilirler. Ayrıca, Rollerin `Kullanıcı İzinleri` alanıyla kontrol edilen bir erişimleri varsa, kullanıcıların detaylı görünümünde, başka kullanıcıların akışlarını da görebilirler.
-
-Kullanıcı akışında, kullanıcının takip ettiği kayıtlarla ilgili yeni ilaveler, güncellemeler ve gönderiler görebilirsiniz. Ayrıca, kullanıcıya gönderilen gönderileri görebilirsiniz. Bu girdiler herhangi bir kayıtla ilgili değildir.
-
-## Bildirimler
-
-Akışınıza, başka kullanıcıların neden olduğu yeni ilaveler hakkında bildirimler alacaksınız.
-
-## Gönderiler
-
-Belli bir kayıtla ilgili gönderi oluşturabilirsiniz. Ayrıca gönderinize birden fazla dosya ve resim ekleyebilirsiniz. Gönderinizde birisinden bahsetmek isterseniz sadece başına `@` sembole koymanız ve kullanıcının adını yazmanız yeterlidir. Mesajınızda bahsettiğiniz kullanıcıya bu konuda haber verilecektir.
-
-## Kullancılara gönderimler
-
-_Bu özellik, 3.8.0 sürümünden itibaren mevcuttur._
-
-Kullanıcılar; belirli kullanıcılara, belirli takımlara, tüm kullanıcılara ve kendine gönderi hazırlayabilir. Bu yetiye erişim, Rollerin `Atama İzinleri` alanıyla kontrol edilir.
-
-## Filtreleme
-
-Akışta görmek istediklerinizi filtreleyebilirsiniz: `Tümü`,`Gönderiler` veya `Güncellemeler`.
-
diff --git a/i18n/vi_VN/user-guide/browser-support.md b/i18n/vi_VN/user-guide/browser-support.md
deleted file mode 100644
index 384e4ceba..000000000
--- a/i18n/vi_VN/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Các trình duyệt được hỗ trợ
-
-Chúng tôi đề xuất sử dụng phiên bản mới nhất của Google Chrome hoặc Mozilla Firefox. EspoCRM hoạt động tốt nhất trên những trình duyệt này. Chúng tôi thường xuyên thử nghiệm tất cả tính năng mới trên những trình duyệt này.
-
-Microsoft Edge và Safari cũng được hỗ trợ, nhưng có ít sự đảm bảo rằng mọi chức năng sẽ hoạt động tốt trên những trình duyệt này.
-
-Chúng tôi cực kì không khuyến khích sử dụng Internet Explorer 11.
diff --git a/i18n/vi_VN/user-guide/emails.md b/i18n/vi_VN/user-guide/emails.md
deleted file mode 100644
index cf94bec2b..000000000
--- a/i18n/vi_VN/user-guide/emails.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Hướng dẫn sử dụng với thư điện tử
-
-EspoCRM cung cấp khả năng lấy thư từ hộp thư IMAP. Điều này cho phép EspoCRM hoạt động như phần mềm thư điện tử có các tính năng đặc trưng của CRM.
-
-## Tài khoản IMAP
-
-*Lưu ý: Bạn cần có [cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab) thiết lập đúng trong hệ thống để nhận được thư điện tử gửi đến.*
-
-Người dung có thể thiết lập tài khoản IMAP trong trang Tài Khoản Thư điện tử cá nhân (Tab Thư điện tử > trình đơn góc phải > Tài Khoản Thư điện tử cá nhân).
-
-Xác định thư mục nào cần theo dõi trong trường Các thư mục được theo. Mặc định, trường này được gán cho Hộp thư đến. Nếu bạn sử dụng các phần mềm thư điện tử ngoài để gửi thư thì bạn có thể thiết lập thư mục Đã gửi để lưu trữ lại những thư điện tử này.
-
-*Lấy từ lúc* cho phép bạn chọn ngày thư điện tử nên được lưu trữ. Thiết lập nó tới những ngày trong quá khứ nếu bạn muốn lưu trữ những thư điện tử cũ.
-
-Chương trình cũng có khả năng xác định *Thư mục* trong Tài khoản Thư điện tử cá nhận. Những thư điện tử gửi đến sẽ nằm trong thư mục này.
-
-## Tài khoản SMTP
-
-Người dùng có thể thiết lập cấu hình SMTP trong Ưa thích cũng như trong Tài khoản Thư điện tử cá nhân của. Quản trị viên cũng có khả năng cho phép sử dụng hệ thống SMTP (Bằng cách chia sẻ nó)
-
-Người dùng có thể có nhiều tài khoản SMTP (từ phiên bản 4.2.0 trở đi). Tuy nhiên những địa chỉ thư điện tử mà người dùng có thể sử dụng để gửi đi cần được xác định trong danh sách các địa chỉ thư điện tử của bản ghi *Người dùng*.
-
-## Làm việc với thư điện tử
-
-Thư điện tử được lấy về bằng tác vụ (chạy ngầm) mỗi phút (thời gian chính xác có thể được quy định bởi quản trị viên).
-Bạn có thể thấy tất cả thư điện tử trong tab Thư điện tử. Có những thư mục mặc định là Hộp thư đến, Thư đã gửi, Thư nháp nằm ở phía bên trái.
-
-Trường *Trạng thái*. `Đã gửi` nghĩa là thư được gửi từ CRM, `Lưu trữ` – thư được lấy từ tài khoản IMAP hoặc được lưu trữ thủ công, `Nháp` – nghĩa là thư được tạo như một bản nháp.
-
-Khi thư điện tử mới đến thì hệ thống sẽ cố gắng xác định thư này thuộc về bản ghi nào. Nó có thể liên kết với Tài khoản, Khách hàng tiềm năng, Cơ hội, Vụ việc (và Liên hệ khi ở chế độ B2C) etc. Nếu thư không được xác định thì người dùng có thể liên kết nó một cách thủ công bằng cách nhập vào trường “Nguồn gốc”.
-
-Nếu thư điện tử đến từ một khách hàng tiềm năng người dùng có thể **chuyển nó vào bản ghi Khách hàng tiềm năng** . Người dùng chỉ cần mở Thư điện tử và nhấp chọn Tạo khách hàng tiềm năng ở trình đơn góc trên bên phải.
-
-Bạn cũng có thể **tạo Tác vụ hoặc Vụ việc** từ một bản ghi thư điện tử.
-
-Nếu những địa chỉ thư điện tử (Gửi từ, gửi đến, cc) trong một bản ghi thư điện tử là những địa chỉ hệ thống đã ghi nhận thì thư điện tử này sẽ hiển thị thông tin những người liên quan(Liên hệ, Khách hàng tiềm năng, Người dùng, etc). Nếu những địa chỉ thư điện tử này là hoàn toàn mới thì bạn có thể **tạo liên hệ** trực tiếp từ đây.
-
-Mọi thư điện tử liên quan tới một bản ghi nhất định được hiển thị trong thanh Lịch sử của bản ghi đó. Ví dụ, nếu có thư điện tử liên quan tới một cơ hội mà cơ hội này lại liên quan tới một tài khoản, thì thư điện tử này sẽ hiển thị cả thông tin về cơ hội và tài khoản đó.
-
-## Gửi thư điện tử
-
-Bạn có thể soạn thư điện tử mới bằng một số cách sau đây:
-* Nhấn nút* *Soạn thư* trong khung nhìn danh sách thư;
-* phản hồi một thư điện tử;
-* nhấp chọn thư điện tử của bản ghi nào đó;
-* thực hiện hành động * *Soạn thư* trong thanh Các hoạt động.
-
-Bạn cũng có thể **Lựa chọn mẫu** cho thư điện tử của bạn.
-
-Bạn có thể thiết lập **chữ kí thư điện tử** trong mục Yêu thích.
-
-## Thư mục thư điện tử
-
-Người dùng có thể tạo thư mục thư điện tử của riêng họ để quản lý các loại thư điện tử một cách tiện lợi. Danh sách những thư mục khả dụng nằm ở phía bên trái trong trang Danh sách thư điện tử. Để tạo hoặc chỉnh sửa thư mục, người dùng cần vào Danh sách thư điện tử> trình đơn xổ xuống ở góc trên tùng bên phải > Danh sách thư mục. `Bỏ qua thông báo` nghĩa là bạn không muốn nhận được thông báo về các thư điện tử được gửi tới mà rơi vào một thư mục nào đó. Bằng cách tối ưu Bộc lọc thư, bạn có thể đặt Thư điện tử vào các thư mục một cách tự động dựa trên các tiêu chí nhất định.
-
-## Bộ lọc thư điện tử
-
-Quản trị viên có thể tạo bộ lọc thư toàn cục để bỏ qua các thư điện tử không được mong muốn. Cấu hình này nằm ở mục Quản trị > Bộ lọc thư điện tử.
-
-Người dùng thông thường có thể tạo bộ lọc cho Tài khoản thư điện tử cá nhân hoặc cho toàn bộ Hộp thư đến. Những cấu hình này nằm ở Danh sách thư điện tử > trình đơn xổ xuống ở góc trên cùng bên phải > Bộ lọc.
-
-Có hai loại Bộ lọc:
-* Bỏ qua – thư điện tử sẽ được đặt trong *Thùng rác* hoặc không được nhập vào nếu bộ lọc liên quan tới Tài khoản thư điện tử cá nhân;
-* Phân loại vào thư mục - nhập các thư điện tử vào các thư mục xác định của người dùng một cách tự động.
-
-## Mẫu thư điện tử
-
-Mẫu thư điện tử nằm ở Danh sách thư điện tử > trình đơn xổ xuống ở góc trên cùng bên phải > Mẫu thư điện tử. Chúng có thể được sử dụng cho cả việc gửi thư điện tử hàng loại và những thư điện tử thông thường. Checkbox `Một lần` nghĩa là mẫu thư điện tử được coi như là chỉ để dùng một lần, điều thường được sử dụng trong các chiến dịch quảng cáo bằng thư điện tử..
-
-Người dùng cũng có thể sử dụng các kí hiệu giữ chỗ trong nội dung và tiêu đề của mẫu thư điện tử, ví dụ {Account.name}, {Person.emailAddress}. Những kí hiệu giữ chỗ này sẽ được thay thế khi gửi đi bằng giá trị của các bản ghi liên quanThey will be replaced with values of related records.
-
-Bạn có thể sử dụng các kí hiệu giữ chỗ có sẵn trong mẫu nội dung như {optOutUrl} và {optOutLink}.
-```
-Unsubscribe
-```
-Đây là đường dẫn hủy đăng kí áp dụng trong việc gửi thư điện tử hàng loạt.
diff --git a/i18n/vi_VN/user-guide/markdown.md b/i18n/vi_VN/user-guide/markdown.md
deleted file mode 100644
index c17e283a5..000000000
--- a/i18n/vi_VN/user-guide/markdown.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Markdown syntax
-
-Text fields support markdown syntax.
-
-## Code
-```
-`some text`
-```
-
-`some text`
-
-## Multiline code
-
-```
-``` some text ```
-```
-
-```
-some text
-```
-
-## Strong text
-
-```
-**some text**
-```
-
-**some text**
-
-## Emphasized text
-
-```
-*some text*
-```
-
-*some text*
-
-## Deleted text
-
-```
-~~some text~~
-```
-
-~~some text~~
-
-## Blockquote
-
-```
-> some
-> test
-```
-
-> some
-> text
-
-## Link
-
-```
-[link text](https://www.espocrm.com)
-```
-[link text](https://www.espocrm.com)
-
-## Numbered list
-
-```
-1. Some item
-2. Another item
-```
-
-1. Some item
-2. Another item
-
-## Unnumbered list
-
-```
-* Some item
-* Another item
-```
-
-* Some item
-* Another item
-
-## Horizontal line
-
-```
-___
-```
-
diff --git a/i18n/vi_VN/user-guide/mass-email.md b/i18n/vi_VN/user-guide/mass-email.md
deleted file mode 100644
index 9a69036ed..000000000
--- a/i18n/vi_VN/user-guide/mass-email.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Mass Email
-
-## How to send mass email
-
-You need to have at least one Target List with target records and Email Template in your crm.
-
-1. Create new Campaign with a status `Email` or `Newsletter`. Select one or a few target lists in `Target Lists` field.
-2. After Campaign record is created create Mass Email for this campaign: click plus on Mass Email panel. Specify _Date Start_ - when emails should be sent, and select _Email Template_. Make sure _Status_ set as `Pending`.
-
-If everything is setup right emails should go out. They should be sent each hour with portions (you can change portion size in Administration > Outbound Emails). Administrator can change it by updating `Scheduling` field of `Check Group Email Accounts` Scheduled Job.
-
-You can check if emails are sent in Log panel.
-
-## Test what will be sent to recipients
-
-Click right dropdown on the mass email row in _Mass Email_ panel and then click _Send Test_.
-
-## Log
-
-In log you can see:
-* Sent email;
-* Emails opened by recipient;
-* Links clicked by recipient;
-* Recipients who opted out;
-* Bounced emails (not delivered to recipient).
-
-## Opt-out link
-
-By default the system will append opt-out to all sent emails. But you can use custom one in your Email Template.
-
-Example:
-```html
-Unsubscribe from the mailing list.
-```
-
-Administrator can disable mandatory opt-out link being added by system at Administration > Outbound Emails.
-
-## Tracking URL
-
-If you want to know that your recipient opened the link from your email, you need to create Tracking URL. Specify any _Name_
- and _URL_ where your link should lead to. Then you will need to paste generated code into your Email Template.
-
- Example:
- ```html
-Try our demo
- ```
-
-## Target Lists
-
-Target Lists contains the lists of Accounts, Contacts, Leads and Users records.
-
-Users can populate target lists manually using _Select_ action on the corresponding panel on Target List detail view. There is an ability to make filtering and then select all result of search.
-
-## Populating target lists with Reports
-
-[Reports](reports.md#syncing-with-target-lists) feature provides an ability to populate target lists with records matching specific criteria.
-
-## Excluding Target Lists
-
-Specify Excluding Target Lists to avoid sending mass email to certain recipients. If there is a record with the email address that matches the email address of any excluding record, the first record will be excluded as well.
-
-## Campaign Log
-
-At Campaign Log you can see emails that have been sent, opened emails, bounced emails, who opted out, and who clicked the link in the email. It's possible to utilize this log by creating Target List (dropdown in the top-right corner on panel) based on records from log. For example, you pick only contacts that clicked on the link (tracking url).
-
-## Troubleshooting
-
-_For Administrators_
-
-#### What to do if emails are not sent out.
-
-1. Check if _Send Test_ works. If does't work, then check if system SMTP settings are correct.
-2. Check if you have setup cron for your system.
-3. Check if you have `Send Mass Emails` Scheduled Job and it's `Active` (Administration > Scheduled Jobs > Send Mass Emails). Check if there is something in Log.
-
-
-#### What if Tracking URLs has wrong url that does not lead to your crm.
-
-Check 'siteUrl' parameter in `data/config.php` file. It must be set as URL of your EspoCRM accessible from the external world.
-
-#### Bounced emails are not being logged
-
-Bounced emails can be handled by group email account only. Make sure that you have a group email account that monitores the mailbox bounced emails are sent to.
-
-Also some mail server providers can deviate from standards, so bounced emails can be not distinguished.
diff --git a/i18n/vi_VN/user-guide/printing-to-pdf.md b/i18n/vi_VN/user-guide/printing-to-pdf.md
deleted file mode 100644
index fcfa78bee..000000000
--- a/i18n/vi_VN/user-guide/printing-to-pdf.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# In thành tập tin PDF
-
-Lưu ý: Tính năng này chỉ khả dụng từ phiên bản EspoCRM 5.0.5.
-
-Tính năng in thành tập tin PDF cho phép tạo ra tập tin PDF với dữ liệu của một bản ghi. Nội dung của tài liệu được định nghĩa bằng các mẫu có sẵn.
-
-
-1. Bạn cần có ít nhất một mẫu có sẵn cho loại thực thể của bản ghi mà bạn muốn in.
-2. 'In thành PDF' sẽ khả dụng khi xem chi tiết ở thanh xổ xuống gần nút 'Chỉnh sửa'.
-
-## Các mẫu có sẵn
-
-Tab các mẫu có sẵn mặc định được ẩn đi. Quản trị viên có thể thêm nó trong Quản trị > Giao diện người dùng.
-
-Để chỉnh sửa một cách chính xác nhất thì bạn được đề xuất sử dụng chế độ góc nhìn mã chương trình.
-
-Bạn có thể in các trường chi tiết của bản ghi cũng như các trường của các bản ghi liên quan bằng cách tối ưu các kí hiệu giữ chỗ trong mẫu có sẵn.
-
-Ví dụ:
-
-* `{{name}}` – Tên của bản ghi;
-* `{{assignedUserName}}` – Người dùng được chỉ định;
-* `{{account.name}}` – Tên của tài khoản liên quan.
-
-Bạn cũng có thể in trường hình ảnhIt's possible to print image fields:
-```
-
-```
-
-ở `imageId` – là tên của trường hình ảnh tùy biến, được nối với hậu tố `Id`.
-
-Để hiển thị số thực dấu phẩy động mà không có phần thập phân (như số nguyên) sử dụng cách biểu hiện sau:
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Tùy chỉnh định dang cho các giá trị tiền tệ
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-
-Giá trị `10000.5` sẽ được in ra là `10 000,50`.
-
-Để hiện thị các trường văn bản (nhiều dòng) sử dungj dấu ngoặc ba lần liên tiếp: ```{{{description}}}```.
diff --git a/i18n/vi_VN/user-guide/quotes.md b/i18n/vi_VN/user-guide/quotes.md
deleted file mode 100644
index d845954c4..000000000
--- a/i18n/vi_VN/user-guide/quotes.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Quotes
-
-Quotes feature is available in [Advanced Pack](https://www.espocrm.com/extensions/advanced-pack/).
-
-Quotes are specific group of products or services with their quantities and prices that you quote to customers.
-
-Quotes has a relationship with Opportunity. You can add Quotes panel to Opportunity detail view at Administration > Layout Manager > Opportunities > Relationships. When creating a new quote linked to an opportunity it transfers opportunity items to the quote.
-
-You can add Quotes panel to Accunt's detail view to be able to see related quotes. You can do it at Administration > Layout Manager > Accounts > Relationships.
-
-## Quote Items
-
-Quote has a list of items. Each item can represent a certain product or a service with description, quantity, tax rate, list price and unit price fields. It's possible to sort items manually.
-
-There is an ability to add custon fields for Quote Item entity using Entity Manager.
-
-## Templates
-
-By default there are two available templates: Quote and Invoice. You can create new templates (Quotes list view > top-right dropdown menu > Templates) as well as edit existing ones.
-
-For more precise editing it's recommended to use Code View mode.
-
-You can print fields of Quote record as well as fields of related records by utilizing placeholders in your template.
-
-Examples:
-`{{accountName}}` – Account name,
-
-`{{{billingAddressStreet}}}` – street,
-
-`{{account.type}}` – type of related Account,
-
-`{{assignedUser.lastName}}` – last name of the assigned user.
-
-If your line item is a product you can print product’s fields.
-
-Examples:
-`{{product.length}}`,
-
-`{{product.color}}`.
-
-Length and color are custom fields of Product entity in examples.
-
-Looping through quote items:
-
-```
-
-
{{order}}
-
{{name}}
-
{{quantity}}
-
{{product.weight}}
-
{{listPrice}}
-
{{unitPrice}}
-
{{amount}}
-
-```
-
-It's possible to print image fields:
-
-```
-
-```
-where `imageId` – the name of custom image field in Quote entity concatenated with the suffix `Id`.
-
-For product line item:
-```
-
-```
-
-To display float numbers (like quantity, unitPrice etc.) w/o fractional part (as integer) use following expressions (since version 4.8.3):
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-Custom formatting for currency values (since version 4.8.3):
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-Value `10000.5` will be printer as `10 000,50`.
-
-To display text fileds (multiline) use triple braces: `{{{description}}}`.
-
-## Print to PDF
-
-Quotes can be printed to PDF. This action is available in dropdown next to Edit button on the quote’s detail view. Then you will be prompted to select Template.
-
-## Email Quote
-
-Quote PDF can be send in email as an attachment. Open quote record, click dropdown next to Edit button and the click Email PDF.
-
-## Automatic numbering
-
-You can create a Number field via Entity Manager for Quote entity type. Administration > Entity Manager > Quote > Fields > Add Filed > Number. Then you need to place it in on detail view using Layout Manager.
-
-The value will be incremented by every new quote. There is an ability to specify the next number as well as prefix.
-
-## Default tax
-
-Available since EspoCRM 4.8.0.
-
-1. Specify default Tax record at Administration > Entity Manager > Quotes > fields > Tax > Default.
-2. Specify default tax rate at Administration > Entity Manager > Quotes > fields > Tax Rate > Default.
-
-## Invoices
-
-Quote can be treated as an invoice if its status became `Approved`. Then _Date Invoiced_, _Invoice Number_ fields show up. You can use different template for invoices for printing.
diff --git a/i18n/vi_VN/user-guide/reports.md b/i18n/vi_VN/user-guide/reports.md
deleted file mode 100644
index dcfa9e9c4..000000000
--- a/i18n/vi_VN/user-guide/reports.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Báo cáo
-
-Tính năng báo cáo chỉ khả dụng ở [Bản Mở Rộng](https://www.espocrm.com/extensions/advanced-pack/).
-
-Có hai loại báo cáo: Danh sách và Lưới.
-
-## Báo Cáo Danh sách
-
-Kết quả của báo cáo danh sách là danh sách các bản ghi phù hợp với các tiêu chí nhất định.
-
-Để tạo báo cách danh sách mới thì nhấp chuột vào tab báo cáo rồi nhấp vào nút Tạo báo cáo. Chọn loại đối tượng cần thiết rồi nhấp vào nút Tạo ở khu vực báo cáo danh sách.
-
-Ở trường _Cột_ chọn những trường mà bạn muốn hiển thị. Bạn cũng có thể chọn các biến hiển thị cho từng cột, ví dụ độ rộng và căn lề.
-
-Chọn thứ tự sắp xếp cần thiết ở trường _Thứ tự danh sách_.
-
-Ở khu vực _Bộ lọc_ bạn có thể xác định tiêu chí định hình nên bản ghi sẽ được liệt kê trong danh sách của bạn. Bạn có thể sử dụng toán tử luận lý như 'OR' hoặc 'AND' ở đây.
-
-_Bộ lọc Runtime_ cho phép bạn xác định các bộ lọc khác nhau trước khi bạn chạy báo cáo.
-
-Bạn có thể __xuất__ kết quả của báo cáo danh sách thành định dạng excel và csv.
-
-## Báo cáo lưới
-
-Kết quả của báo cáo lưới tóm tắt các giá trị được gộp thành nhóm dựa trên các trường xác định. Những báo cáo này có thể được hiển thị thành một biểu đồ.
-
-
-
-Để tạo báo cách danh sách mới thì nhấp chuột vào tab báo cáo rồi nhấp vào nút Tạo báo cáo. Chọn loại đối tượng cần thiết rồi nhấp vào nút Tạo ở khu vực báo cáo lưới.
-
-Ở trường _Nhóm theo_ bạn chọn một hoặc hai trường mà bạn muốn dữ liệu báo cáo được nhóm theo. Có thể chọn nhóm theo năm, tháng, ngày cho những trường về ngày tháng. Nếu bạn nhóm theo hai trường thì báo cáo của bạn sẽ được xem như báo cáo ba chiều.
-
-Ở trường _Cột_ có thể chọn một hoặc nhiều chức năng tổng hợp như COUNT, SUM(tính tổng), MIN, MAX, AVG (tính trung bình).
-
-Trường _Xếp theo_ xác định dữ liệu báo cáo sẽ được sắp xếp như thế nào.
-
-Ở khu vực _Bộ lọc_ bạn có thể xác định tiêu chí định hình nên bản ghi sẽ được liệt kê trong báo cáo của bạn. Bạn có thể sử dụng toán tử luận lý như 'OR' hoặc 'AND' ở đây.
-
-_Bộ lọc Runtime_ cho phép bạn xác định các bộ lọc khác nhau trước khi bạn chạy báo cáo.
-
-Báo cáo lưới cho phép hiển thị kết quả ở dạng biểu đồ. Có _các loại biểu đồ_ sau : Cột (Ngang), Cột (Dọc), Tròn, đường.
-
-Bạn có thể __xuất__ kết quả của báo cáo danh sách thành định dạng excel và csv.
-
-## Bộ lọc
-
-### Bộ lọc theo trường
-
-Các loại bộ lọc có thể sử dụng một cách rất dễ dàng. Bạn cũng có thể chọn các trường cho thực thể cần cũng như các thực thể liên quan.
-
-
-
-### Nhóm theo toán tử OR
-
-Toán tử OR hay toán tử hoặc nghĩa là các phần tử của nhóm phải thỏa mãn ít nhất một điều kiện.
-
-
-
-### Nhóm theo toán tử AND
-
-Toán tử AND hay toán tử và nghĩa là các phần tử của nhóm phải thỏa mãn tất cả các điều kiệnt.
-
-### Nhóm theo toán tử NOT
-
-Cung cấp khả năng lọc các bản ghi không phù hợp các tiêu chí nhất định. Ví dụ liệt kê danh sách các tài khoản không có tiềm năng nào có trạng thái Thành công đã đóng hoặc Mất đã đóng.
-
-
-
-### Ngôn ngữ biểu hiện
-
-Đối với các nhu cầu sử dụng nâng cao. Bạn có thể áp dụng hàm cho các cột dữ liệu nhất định và so sánh nó với kết quả của [công thức](../administration/formula.md) hiển thị.
-
-Lưu ý: Nếu bạn cần so sánh chỉ với một giá trị chuỗi đơn giản thì bạn nên đặt nó vào ngoặc đơn `'chuỗi nào đó'`.
-
-Lưu ý: Các hàm có mục đích tương tác với bản ghi thực thể sẽ không thể chạy ở đây bởi vì hàm không được áp dụng với bản ghi nhất định.
-
-
-
-## Hiển thị trên bảng điều khiển
-
-Bạn có thể hiển thị bất kì báo cáo nào trên bảng điều khiển. Để làm được điều này bạn cần thêm dashlet Báo cáo và chọn báo cáo cần hiển thị trong các lựa chọn của dashlet.
-
-## Gửi thư điện tử
-
-Bạn có thể thiết lập hệ thống gửi kết quả báo cáo tới các người dùng nhất định theo một lịch thường xuyên vào một khoảng thời gian nhất định. Thiết lập này phải được thực hiện với từng báo cáo một cách độc lập.
-
-## Đồng bộ với các danh sách mục tiêu
-
-Bạn có thể có các danh sách mục tiêu được đồng bộ với các kết quả của danh sách báo cáo. Điều này tiện cho việc gửi thư điện tử hàng loạt khi bạn chỉ muốn gửi thư tới các liên hệ thỏa mãn vài tiêu chí tại thời điểm thư điện tử được gửi đi. Tính năng này có sẵn khi bạn xem chi tiết của bất kì danh sách mục tiêu nào tại thanh 'Đồng bộ với Báo cáo'.
diff --git a/i18n/vi_VN/user-guide/stream.md b/i18n/vi_VN/user-guide/stream.md
deleted file mode 100644
index da6adab84..000000000
--- a/i18n/vi_VN/user-guide/stream.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Stream
-
-Stream trong EspoCRM là một bảng tin nơi bạn có thể theo dõi các cập nhật và bổ sung cho bản ghi mà bạn đang theo dõi. Bạn cũng có thể đăng lên stream của riêng bạn và lên stream của những người dùng khác (từ phiên bản 3.8.0 trở đi). Có hai loại stream trong Espo CRM: stream bản ghi và stream người dùng.
-
-Mặc định thì những thực thể sau có một stream: Tài khoản, Danh bạ, Khách hàng tiềm năng, Cơ hội, Vụ việc. Quản trị viên có thể kích hoạt hoặc vô hiệu hóa stream cho một thực thể nhất định trong [Entity Manager](../administration/entity-manager.md).
-
-## Stream Bản Ghi
-
-Steam Bản Ghi được hiển thị trong một bảng điều khiển Stream của một bản ghi nhất định khi xem chi tiết. Các bài viết, cập nhật và những bổ sung mới liên quan tới bản ghi hiện tại cũng được hiển thị ở đây.
-
-## Stream Người Dùng
-
-Người dùng có thể xem stream của họ trong Stream dashlet cũng như dưới tab Stream. Người dùng cũng có thể thấy stream của người dùng khác trong xem chi tiết người dùng, nếu họ có quyền truy cập được kiểm soát bởi trường `Quyền Người Dùng` của Danh sách Quyền.
-
-Trong luồng người dùng bạn có thể xem bài viết, cập nhật và bổ sung mới liên quan tới các bản ghi mà người dùng đang theo dõi. Bạn cũng có thể xem các bài viết được gửi cho người dùng. Những bài viết này không liên quan tới bất kì bản ghi nào.
-
-## Thông báo
-
-Bạn sẽ nhận được thông báo về những bổ sung mới tới stream của bạn khi những thay đổi này được thực hiện bởi 1 người dùng khác.
-
-## Bài viết
-
-Bạn có thể tạo bài viết liên quan tới một bản ghi nhất định. Bạn cũng có thể đính kèm nhiều tập tin và hình ảnh vào bài viết của bạn. Nếu bạn muốn đề cập tới ai đó trong vài viết của mình bạn cần nhập kí hiệu `@` và bắt đầu nhập tên của người dùng đó. Người dùng mà bạn đề cập trong bài viết sẽ được thông báo về nó.
-
-## Bài viết tới người dùng
-
-_Tính năng này khả dụng từ phiên bản 3.8.0._
-
-Người dùng có thể tạo bài viết tới một người dùng nhất định, tới những nhóm nhất định, tới mọi người dùng và tới bản thân. Quyền truy xuất tới khả năng này được kiểm soát bởi trường `Quyền Được Cấp` của Danh sách Quyền.
-
-
-## Bộ Lọc
-
-Bạn có thể lọc những gì muốn xem trong một stream: `Tất cả`, `Bài Viết` hoặc `Cập nhật`.
diff --git a/i18n/zh_CN/administration/backup-and-restore.md b/i18n/zh_CN/administration/backup-and-restore.md
deleted file mode 100644
index 2ecf1cc05..000000000
--- a/i18n/zh_CN/administration/backup-and-restore.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# 备份和恢复
-
-## 如何对EspoCRM进行手动备份
-
-EspoCRM系统由文件和数据库数据组成。所有的这两种数据对于创建一份完整的EspoCRM备份来说都是必要的。以下内容是在Ubuntu服务器上配合MySQL数据库创建备份的操作指南。
-
-### 第一步,对文件进行备份
-
-创建一个存档,它包含整个EspoCRM目录的内容。对于Ubuntu系统,默认路径是`/var/www/html`。以下是操作命令:
-
-```bash
-tar -czf "files.tar.gz" -C /var/www/html .
-```
-
-### 第二步,对数据库进行备份
-
-要进行备份操作,必须要知道数据库名称和访问凭证。数据库的名称在`database`部分的配置文件`/ESPOCRM_DIRECTORY/data/config.php`中。备份数据库的命令如下:
-
-```bash
-mysqldump --user=YOUR_USER --password=YOUR_PASSWORD YOUR_DATABASE_NAME > "db.sql"
-```
-
-### 第三步,对备份进行复制
-
-就这样完成了。接下来需要把已创建的备份文件复制到安全的地方。
-
-
-## 使用脚本对EspoCRM进行备份
-
-可以使用脚本来备份所需的数据。使用SSH方式进行登录,然后运行相关命令(在Ubuntu上测试通过)。
-
-### 下载脚本
-
-```bash
-wget https://raw.githubusercontent.com/espocrm/documentation/master/_static/scripts/backup.sh
-```
-
-### 运行脚本
-
-```bash
-bash ./backup.sh PATH_TO_ESPOCRM BACKUP_PATH
-```
-其中
-* `PATH_TO_ESPOCRM`是EspoCRM的安装目录。
-* `BACKUP_PATH`是备份目录。
-
-对于Ubuntu系统的服务器,这个脚本是:
-
-```bash
-bash ./backup.sh /var/www/html /opt/backups
-```
-
-注:如果你的某位MySQL用户没有所需的转储数据库的权限,系统会提示你输入另外一位MySQL用户的凭据。
-
-创建成功之后,你会知道刚建备份的路径。
-
-## 使用备份文件还原EspoCRM
-
-上文中创建的备份文件可用来还原EspoCRM。
-
-### 第一步,解压备份文件
-
-可以用“归档管理器”或运行以下命令对备份文件进行解压:事先要把文件放到Web服务器的某个目录下。
-
-```bash
-tar -xzf "files.tar.gz" -C /var/www/html
-```
-其中:
-* `/var/www/html` 是Web服务器的目录。
-
-### 第二步,设置必要的权限
-
-文件须归Web服务器用户所有,并且权限设置妥当。请按以下说明对必要的权限进行设置:[www.espocrm.com/documentation/i18n/zh_CN/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems](https://www.espocrm.com/documentation/i18n/zh_CN/administration/server-configuration/#user-content-required-permissions-for-unix-based-systems)。
-
-### 第三步,导入数据库转储文件
-
-应把数据库转储文件导入到用户凭据相同的数据库,否则需要对配置文件`ESPOCRM_DIRECTORY/data/config.php`进行更正。在终端运行以下命令可以导入你的数据库转储文件:
-
-```bash
-mysql --user=YOUR_DATABASE_USER --password=YOUR_DATABASE_PASSWORD YOUR_DATABASE_NAME < db.sql
-```
-
-### 第四步,查看或配置计划任务
-
-检查一下你的计划任务是不是配置妥当。运行以下命令,检查指向EspoCRM的路径是否正确:
-
-```bash
-sudo crontab -l -u www-data
-```
-其中:
- * `www-data`是Web服务器的用户。
-
-如果需要进行更改,请用以下命令:
-
-```bash
-sudo crontab -l -u www-data
-```
-
-有关EspoCRM计划任务配置的详情,请访问:[www.espocrm.com/documentation/i18n/zh_CN/administration/server-configuration/#user-content-setup-a-crontab](https://www.espocrm.com/documentation/i18n/zh_CN/administration/server-configuration/#user-content-setup-a-crontab)。
-
diff --git a/i18n/zh_CN/administration/emails.md b/i18n/zh_CN/administration/emails.md
deleted file mode 100644
index ee377b4eb..000000000
--- a/i18n/zh_CN/administration/emails.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# 邮件
-
-> 重要说明:你需要正确配置好你系统里的[cron](https://github.com/espocrm/documentation/blob/master/i18n/zh_CN/administration/server-configuration.md#setup-a-crontab),才可以正常收取电子邮件。你可以在EspoCRM的“管理”>“已安排工作”中查看相关信息。
-
-## 概览
-
-EspoCRM可以监视IMAP邮箱账户。归档电子邮件有两种方式:“群组邮件账户”和“个人邮件账户”。“群组收件账户”用于群组邮箱,比如最常见的客户支持邮箱。而“个人邮件账户”则对应为用户的个人邮箱。
-
-收到邮件时,系统试着将它与合适的记录(“账户”、“潜在客户”、“机会”、“案例”)相关联。即使不是某封邮件的收件人或抄送人,用户关注了某项记录就会收到有新邮件的系统通知。
-
-## 群组邮件账户
-
-只有管理员才可以创建“群组邮件账户”。“群组邮件账户”既可以用于接收邮件,也可以用于发送邮件。自4.9.0版开始,群组账户可以发送邮件。
-
-入站邮件会被指派给哪个团队取决于“团队”字段的设置。
-
-如果群组邮件账户有SMTP功能,而且设为共享,那么它的访问权就由“群组邮件账户”所许可的“角色”来控制。如果权限级别为“团队”,那么就用“团队”字段。
-
-可以让系统对入站邮件进行自动回复。
-
-## 从邮件生成“案例”
-
-你可以让系统创建来自于入站群组邮件的案例。
-这项功能是为客户支持团队而设的。
-将案例派发给指定团队的成员用户有几种方式:
-`direct assignment`、`round-robin`和`less-busy`。
-对于一个话题,只有第一封邮件才会生成一个新案例。
-随后的每封邮件则会关联到已有的案例记录,并在它的“流”面板上显示出来。
-
-如果用户要发邮件回复客户,请确保把案例选为待发邮件的父级。这样,客户的回复邮件就发到群组邮箱,而不是用户自己的邮箱。
-
-## 个人邮件账户
-
-用户可以设立自己的监视邮件账户。操作为:“邮件”>右上角的下拉菜单>“个人邮件账户”。管理员也可以对用户的邮件账户进行管理。
-
-## 邮件过滤器
-
-邮件过滤器可以按照指定的标准来筛选入站邮件。例如,当你不希望EspoCRM导入一些程序发来的通知信息时,你可以创建过滤器,让EspoCRM忽略这些邮件。
-
-管理员可以创建(适用于全部邮件账户的)全局性过滤器。用户则可以为自己的个人邮件账户或整个收件箱创建过滤器。
-
diff --git a/i18n/zh_CN/administration/extensions.md b/i18n/zh_CN/administration/extensions.md
deleted file mode 100644
index a623eed5e..000000000
--- a/i18n/zh_CN/administration/extensions.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# 对扩展进行管理
-
-## 怎样安装扩展
-
-安装EspoCRM扩展(如“高级工具包”、“VoIP集成”)的操作步骤为:
-
-1. 以管理员身份登录。
-2. 前往“管理”>“扩展”。
-3. 上传你的扩展程序包(ZIP文件)。
-4. 点击“安装”按钮。
-
-
-## 怎样升级扩展
-
-对已有的扩展(如“高级工具包”、“VoIP集成”)进行版本升级的操作步骤为:
-
-1. 下载新版本的扩展程序。
-2. 以管理员身份登录。
-3. 前往“管理”>“扩展”。
-4. 上传新的扩展程序包(ZIP文件)——无需卸载原有的版本。
-5. 点击“安装”按钮。
-
-
-## 怎样卸载扩展
-
-卸载扩展程序的操作步骤为:
-
-1. 以管理员身份登录。
-2. 前往“管理”>“扩展”。
-3. 在可得扩展的列表中找到所需的扩展程序。
-4. 点击“卸载”按钮。
-
-
-## 怎样删除扩展
-
-扩展程序卸载后仍会存留在系统中。你可以把它完全删除。删除扩展程序的操作步骤:
-
-1. 以管理员身份登录。
-2. 前往“管理”>“扩展”。
-3. 在可得扩展的列表中到这款扩展程序。
-4. 点击“移除”按钮。
-
diff --git a/i18n/zh_CN/administration/layout-manager.md b/i18n/zh_CN/administration/layout-manager.md
deleted file mode 100644
index 5e81f7b65..000000000
--- a/i18n/zh_CN/administration/layout-manager.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# 布局管理器
-
-“布局管理器”位于管理面板。用它可以对细节视图、编辑视图、列表视图、搜索筛选器、批量更新表单字段的外观进行自定义。
-
-## 列表
-
-列表视图的基本布局如下图所示。在这里可以对栏及其参数进行设置。
-
-
-
-下面列出一些可用的与栏相关的参数。
-
-### 宽度(%)
-
-宽度值用百分比来表示,留空则表示自动宽度。
-
-### 链接
-
-如果选中,那么这个字段会显示为一个指向某个记录的细节视图的链接。这个参数通常用在名称字段。
-
-### 不进行排序
-
-不对栏进行排序。
-
-### 对齐方式
-
-栏的对齐方式有左对齐和右对齐。
-
-## 细节
-
-下图为细节视图和编辑视图的基本布局。在这里可以对面板、行和单元格进行定义。单元格包含若干个字段。
-
-一行可以是两个单元格,也可以是占满整个行宽的单个单元格。添加充满单元格的行,先添加新行,再在任一单元格上点击“-”的标志。
-
-
-
-## (小型)列表布局
-
-这种列表布局主要用在关系面板中。但也可以用在别的地方,只要列表适合用较窄的视图来显示。
-
-## (小型)细节布局
-
-这种细节视图用于快速创建、快速查看和快速编辑表单。
-
-## 搜索筛选器
-
-字段列表位于进行搜索操作时所使用的列表视图中。
-
-## 批量更新
-
-这个字段列表在“批量更新”表单处。
-
-## 关系面板
-
-关系列表面板位于细节视图的底部。你可以对面板进行自行排序。你可以使用“样式”参数对面板的颜色进行设置。
-
-## 侧面板
-
-侧面板用在“细节”、“编辑”、“小型细节”、“小型编辑”表单这些布局中。你可以隐藏侧面板,或者对“活动”、“历史”、“任务”等面板列表进行重新排序。你使用“样式”参数可以为面板设置不同的颜色。
-
-## 其它的布局类型
-
-有些实体类型有其它的布局类型,比如“转化为潜在顾客”、“账户列表”等。
-
diff --git a/i18n/zh_CN/user-guide/browser-support.md b/i18n/zh_CN/user-guide/browser-support.md
deleted file mode 100644
index 9d4b768ef..000000000
--- a/i18n/zh_CN/user-guide/browser-support.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# 浏览器的支持情况
-
-我们推荐使用最新版本的谷歌Chrome或Mozilla火狐浏览器。在这些浏览器里,EspoCRM表现最佳。我们定期在这些浏览器中测试所有功能的运作情况。
-
-微软Edge浏览器和Safari浏览器也支持,但不太能保证所有的功能都能够运作良好。
-
-我们严重不推荐使用IE 11。
diff --git a/i18n/zh_CN/user-guide/emails.md b/i18n/zh_CN/user-guide/emails.md
deleted file mode 100644
index 74cdae3fe..000000000
--- a/i18n/zh_CN/user-guide/emails.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# 电子邮件使用指南
-
-EspoCRM能从IMAP服务器接收电子邮件。这样,与它特定的CRM功能相结合,EspoCRM就可以用作电子邮件客户端。
-
-## IMAP账户
-
-*注意:你需要正确配置好你系统里的[cron](https://github.com/espocrm/documentation/blob/master/administration/server-configuration.md#setup-a-crontab),才可以正常收取电子邮件。*
-
-用户可以在“个人邮件账户”页面(“邮件”选项卡>右上角的菜单>“个人邮件账户”)对IMAP账户进行设置。
-
-在“监视文件夹”字段中指定你要监视的文件夹。默认的设置是“收件箱”。如果你是使用一些外部电邮客户端来发送邮件,你可以添加一个名为“已发送”的文件夹来对这些邮件进行归档。
-
-*收取自*字段表明邮件归档的开始日期。如果你需要对旧邮件进行归档,这个归档开始日期必须早于今天。
-
-你可以在“个人邮件账户”中指定一个*文件夹*。这样,收到的电子邮件就会放到这个文件夹中。
-
-## SMTP账户
-
-用户可以在“首选项”对SMTP进行设置,也可以在“个人邮件账户”中设置。管理员也可以允许用户使用系统SMTP(设为“已共享”)。
-
-(从4.2.0版开始)用户可以使用多个SMTP账户。但是,用户发送邮件能用的邮箱地址是在*用户*记录中设定的邮箱地址。
-
-## 使用电子邮件
-
-电子邮件是(在后台)通过cron来收取的,每隔几分钟接收一次(这个间隔时间可由管理员设定)。
-在“邮件”选项卡你可以看到全部的邮件。在页面左侧有多个标准的文件夹:收件箱、发件箱、草稿箱。
-
-*状态*字段。`已发送`表示邮件是从CRM发出的,`已归档`表示邮件收取自IMAP账户或邮件已经过手动归档,`草稿`表示邮件在创建后处在草稿状态。
-
-当有新邮件进来时,系统会尝试识别邮件所属的记录。系统可以将邮件与“账户”、“潜在客户”、“机会”、“案例”(和B2C模式下的“联系人”)等相联系。如果系统不能识别,那么用户可以手动将这封邮件与特定的记录进行关联,在*父级*字段中填写这个记录即可。
-
-如果邮件来自是一位有望成交的客户发过来的,你可以将它**转换为“潜在客户”**。打开“邮件”条目,在右上角的菜单中点击“创建潜在客户”。
-
-你也可以在一条邮件记录中**创建“任务”或“案例”**。
-
-如果在一个邮件记录的邮箱地址(发自、发往、转发)是系统已知的,那么,相关的人(“联系人”、“潜在客户”、“用户”等)就会显示出来。如果邮箱地址是新的,你可以直接在那里**新建联系人**。
-
-与特定记录相关的全部邮件都会在这个记录的“历史”面板中显示出来。例如,一些邮件与“机会”相关联,而“机会”与“账户”相关联,那么,这些邮件就会同时出现在“机会”和“账户”中。
-
-## 发送电子邮件
-
-写新邮件有几种方法:
-* 点击“邮件列表”视图中的*写邮件*按钮;
-* 对一封邮件进行回复;
-* 点击邮件记录中的某个邮箱地址;
-* “活动”面板中点击*写邮件*这项操作
-
-你可以为你的邮件**选择模板**。
-
-你可以在“首选项”中设置**邮件签名**。
-
-## 邮件文件夹
-
-用户可以创建自己的邮件文件夹,有时候把一些邮件放进特定的文件夹是很方便的做法。你可以在“电子邮件”页面的左侧看到可用文件夹的列表。要创建或编辑文件夹,选择“邮件”>右上角的下拉菜单>“文件夹”。`跳过通知`表示,属于某个文件夹的邮件进来时,你不会收到通知。设置“邮件过滤器”后,邮件可自动地按特定的标准放入文件夹。
-
-## 邮件过滤器
-
-管理员可以创建全局的邮件过滤器,过滤掉不需要的邮件。这可以在“管理”>“邮件过滤器”中找到。
-
-普通用户可以为他们的“个人邮件账户”或整个收件箱创建邮件过滤器。可以在“邮件”>右上角的下拉菜单>过滤器中设置。
-
-过滤器有两种类型:
-* “跳过”:如果过滤器与“个人邮件账户”关联,邮件就会放入*垃圾箱*,或者不会导入。
-* “放入文件夹”:导入的邮件会自动放入用户的特定的文件夹。
-
-## 邮件模板
-
-你可以在“邮件”>右上角的下拉菜单>“邮件模板”中找到邮件模板。邮件模板可以用于群发和定期发送。`一次性`复选框选中则表示邮件模板只使用一次,这通常用于邮件营销。
-
-在邮件模板的正文和主题处可以使用占位符,例如{Account.name}、{Person.emailAddress}。邮件发出时,占位符会被相应记录的值所取代。
-
-在模板的正文,你可以用其它保留占位符,例如:{optOutUrl}和{optOutLink}。
-```
-不再订阅
-```
-这个链接表示不再订阅群发邮件。
-
diff --git a/i18n/zh_CN/user-guide/markdown.md b/i18n/zh_CN/user-guide/markdown.md
deleted file mode 100644
index 2bcc5128d..000000000
--- a/i18n/zh_CN/user-guide/markdown.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# Markdown语法
-
-各种文本字段是支持markdown语法的。
-
-## 代码
-```
-`一些文本`
-```
-
-`一些文本`
-
-## 多行代码
-
-```
-``` 一些文本 ```
-```
-
-```
-一些文本
-```
-
-## 表示强调的文本
-
-```
-**一些文本**
-```
-
-**一些文本**
-
-## 对文本进行强调
-
-```
-*一些文本*
-```
-
-*一些文本*
-
-## 带删除线的文本
-
-```
-~~一些文本~~
-```
-
-~~一些文本~~
-
-## 多行引用
-
-```
-> 一些
-> 文本
-```
-
-> 一些
-> 文本
-
-## 链接
-
-```
-[链接文本](https://www.espocrm.com)
-```
-[链接文本](https://www.espocrm.com)
-
-## 有序列表
-
-```
-1. 某个列表项
-2. 另一个列表项
-```
-
-1. 某个列表项
-2. 另一个列表项
-
-## 无序列表
-
-```
-* 某个列表项
-* 另一个列表项
-```
-
-* 某个列表项
-* 另一个列表项
-
-## 水平分隔线
-
-```
-___
-```
-
diff --git a/i18n/zh_CN/user-guide/mass-email.md b/i18n/zh_CN/user-guide/mass-email.md
deleted file mode 100644
index b616b4dcd..000000000
--- a/i18n/zh_CN/user-guide/mass-email.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# 群发邮件
-
-## 如何群发邮件
-
-在你的CRM中要有至少一张带有目标记录的“目标列表”,还要有“邮件模板”。
-
-1. 创建状态为`邮件`或`通讯`的新“活动”(Campaign)。在`目标列表`字段中选择一份或者若干份目标清单。
-2. “活动”记录创建之后,为这项活动创建“群发邮件”:在“群发邮件”面板点击“+”。指定 _开始日期_ ,即邮件发送的日期,然后选择 _邮件模板_ 。确保 _状态_ 设置为`待定`。
-
-如果全部设置妥当,邮件应该可以顺利发送。邮件应该是每小时发送一部分(每个小时的发送量可以在“管理”>“发送邮件”中进行设置。)管理员可以更新`查看群邮件账户`中的`安排`字段,安排邮件工作。
-
-在“日志”面板,可以检查邮件是否已正常发送。
-
-## 测试收件人会收到什么样的邮件
-
-点击 _群发邮件_ 面板里“群发邮件”行右边的下拉菜单,然后点击 _发送测试_ 。
-
-## 日志
-
-在日志部分,你可以看到:
-* 已发送的邮件;
-* 收件人打开过的邮件;
-* 收件人点击过的链接;
-* 不再订阅的收件人;
-* 被退回的邮件(Bounced emails)(没有发送到收件人)。
-
-## 退订链接
-
-系统默认会在全部发出的邮件中加上退订链接。在“邮件模板”中,你也可以对这种链接进行自定义。
-
-这是一个代码示例:
-```html
-在邮件列表中取消订阅。
-```
-
-默认情况下系统强制性地添加退订链接,管理员可以停用这一设置,在“管理”>“发送邮件”处设置即可。
-
-## 跟踪链接
-
-如果你想知道收件人有没有打开邮件中的链接,你需要创建“跟踪链接”。指定 _名称_
-和你的链接指向的 _URL_ 。然后把生成的代码粘贴到邮件模板中。
-
-这是一个代码示例:
-```html
-看看我们的演示
-```
-
-## 目标列表
-
-“目标列表”包含“账户”列表、“联系人”列表、“潜在客户”列表和“用户”记录。
-
-使用“目标列表”细节视图中相应面板上的 _选择_ 操作,用户就可以手动填写目标列表中的一些内容。你可以进行筛选,然后选择全部搜索结果。
-
-## 用报告填写目标列表
-
-[报告](reports.md#syncing-with-target-lists)功能能将与特定标准相配的记录填入目标列表中。
-
-## 排除式目标列表
-
-指定“排除式目标列表”可以避免把群发邮件发送到某些收件人那里。如果一条记录带有与任何排除式记录中的邮箱地址相匹配的邮箱地址,那么这条记录也会被排除。
-
-## 活动日志
-
-在“活动日志”中,你可以看到已发送的邮件、已阅邮件、退回的邮件、取消订阅的人和点击了邮件中链接的人。你可以这样利用这份日志:用基于来自日志的记录来创建“目标列表”(面板右上角的下拉菜单)。例如,单单挑选出那些点击了链接(跟踪链接)的联系人。
-
-## 疑难解答
-
- _写给管理员_
-
-#### 邮件没有发出时如何处理
-
-1. 检查 _发送测试_ 是否正常运作。如果不正常,继续检查系统SMTP设置是否正确。
-2. 检查有没有为你的系统设置cron。
-3. 检查`发送群发邮件`是否已经设置为“已安排工作”以及它是否处在`已启用`状态(“管理”>“已安排工作”>“发送群发邮件”)。检查日志中有没有什么记录。
-
-
-#### 假如跟踪链接的URL不正确,连接不到你的CRM时如何处理
-
-检查`data/config.php`文件中的“siteUrl”参数。它必须设为你的EspoCRM可从外部访问的URL。
-
-#### 被退回的邮件没有记录在日志中
-
-退回邮件只可以由群组邮件账户处理。确保你有一个监视着退信接收的邮箱的群组邮件账户。
-
-一些邮件服务器提供商也可能会偏离标准,所以,是不是真的退信可能无法区分。
diff --git a/i18n/zh_CN/user-guide/printing-to-pdf.md b/i18n/zh_CN/user-guide/printing-to-pdf.md
deleted file mode 100644
index f57bf7af1..000000000
--- a/i18n/zh_CN/user-guide/printing-to-pdf.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# 打印成PDF文档
-
-注:这项功能始于EspoCRM 5.0.5版。
-
-“打印成PDF”是生成一份包含记录数据的PDF文档。文档的内容由“模板”定义。
-
-
-1. 对于你想打印的记录,它的实体类型必须至少要有一个“模板”。
-2. “打印成PDF”这项功能在细节视图上邻近“编辑”按钮的下拉菜单中。
-
-## 模板
-
-“模板”选项卡在默认情况下是隐藏着的。管理员可以在“管理”>“用户界面”中添加模板。
-
-如果你要进行更精确的编辑工作,推荐采用“代码视图”模式。
-
-在模板中使用占位符,可以打印记录字段与相关记录字段。
-
-如:
-
-* `{{name}}`——记录名;
-* `{{assignedUserName}}`——指派的用户;
-* `{{account.name}}`——相关账户的名称。
-
-可以打印图片字段:
-```
-
-```
-
-其中的`imageId`是自定义图像字段的名称,它带有后缀`Id`。
-
-要显示没有小数部分的浮点数字(如整数),使用下列的表达式:
-```
-{{numberFormat quantity_RAW decimals=0}}
-```
-
-对货币数值的格式进行自定义:
-```
-{{numberFormat unitPrice_RAW decimals=2 decimalPoint=',' thousandsSeparator=' '}}
-```
-
-值`10000.5`会被打印为`10 000,50`(千分位后有空格,小数点用英文逗号表示)。
-
-显示多行的文本字段,要使用三层大括号包围它:`{{{description}}}`。
-
diff --git a/i18n/zh_CN/user-guide/quotes.md b/i18n/zh_CN/user-guide/quotes.md
deleted file mode 100644
index bed877678..000000000
--- a/i18n/zh_CN/user-guide/quotes.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# 报价
-
-报价功能在[高级工具包](https://www.espocrm.com/extensions/advanced-pack/)里提供。
-
-报价是指你就一定数量的、具体的产品组合或服务组合向客户报出的价格。
-
-报价与“机会”有关。你可以在“管理”>“布局管理器”>“机会”>“关系”中将“报价”面板添加至“机会”细节视图。新建一份与一个机会相联系的报价就是将机会项目转移到这份报价上。
-
-你可以将“报价”面板添加到“账户”的细节视图中,这样就可以看到相关的报价情况。你可以在“管理”>“布局管理器”>“账户”>“关系”中进行操作。
-
-## 报价项目
-
-报价包括一系列项目。一个项目可以表示一种特定产品或一项服务及其描述、数量、税率、定价和单价这些字段。你可以手动对多个项目进行排序。
-
-你也可以用“实体管理器”为“报价项目”实体添加自定义字段。
-
-## 模板
-
-默认的情况下,有两套模板可以使用:“报价”模板和“发票”模板。对于模板,你可以新建模板(“报价”列表视图>右上角的下拉菜单>“模板”),也可以对现有的模板进行编辑。
-
-如果你要进行更精确的编辑工作,推荐采用“代码视图”模式。
-
-在模板中使用占位符,可以打印“报价”记录字段与相关记录字段。
-
-如:
-`{{accountName}}`——账户名,
-
-`{{{billingAddressStreet}}}`——街道,
-
-`{{account.type}}`——相关账户的类型,
-
-`{{assignedUser.lastName}}`——指派用户的姓氏。
-
-如果单个项目是一件产品,你可以对产品的字段进行打印。
-
-如:
-`{{product.length}}`、
-
-`{{product.color}}`。
-
-在上面的两个例子中,长度(length)和颜色(color)是“产品”实体的自定义字段。
-
-报价项目的循环:
-
-```
-
-