diff --git a/.github/semantic.yml b/.github/semantic.yml deleted file mode 100644 index fa15046b4a..0000000000 --- a/.github/semantic.yml +++ /dev/null @@ -1,30 +0,0 @@ -# Always validate the PR title AND all the commits -titleAndCommits: true - -# Allow use of Merge commits (eg on github: "Merge branch 'master' into feature/ride-unicorns") -# this is only relevant when using commitsOnly: true (or titleAndCommits: true) -allowMergeCommits: true - -# Allow use of Revert commits (eg on github: "Revert "feat: ride unicorns"") -# this is only relevant when using commitsOnly: true (or titleAndCommits: true) -allowRevertCommits: true - -# For allowed PR types: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json -# Tool Reference: https://github.com/zeke/semantic-pull-requests - -# By default types specified in commitizen/conventional-commit-types is used. -# See: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json -# You can override the valid types -types: - - BREAKING CHANGE - - feat - - fix - - docs - - style - - refactor - - perf - - test - - build - - ci - - chore - - revert diff --git a/.github/workflows/semantic-commits.yml b/.github/workflows/semantic-commits.yml new file mode 100644 index 0000000000..a3536d5019 --- /dev/null +++ b/.github/workflows/semantic-commits.yml @@ -0,0 +1,30 @@ +name: Semantic Commits + +on: + pull_request: {} + +permissions: + contents: read + +concurrency: + group: commitcheck-frappe-${{ github.event.number }} + cancel-in-progress: true + +jobs: + commitlint: + name: Check Commit Titles + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 200 + + - uses: actions/setup-node@v3 + with: + node-version: 14 + check-latest: true + + - name: Check commit titles + run: | + npm install @commitlint/cli @commitlint/config-conventional + npx commitlint --verbose --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} diff --git a/.mergify.yml b/.mergify.yml index d9896df921..a863ee67dd 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -21,6 +21,7 @@ pull_request_rules: - name: Automatic merge on CI success and review conditions: - status-success=Sider + - status-success=Check Commit Titles - status-success=Python Unit Tests (MariaDB) (1) - status-success=Python Unit Tests (MariaDB) (2) - status-success=Python Unit Tests (Postgres) (1) diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000000..8847564e53 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,25 @@ +module.exports = { + parserPreset: 'conventional-changelog-conventionalcommits', + rules: { + 'subject-empty': [2, 'never'], + 'type-case': [2, 'always', 'lower-case'], + 'type-empty': [2, 'never'], + 'type-enum': [ + 2, + 'always', + [ + 'build', + 'chore', + 'ci', + 'docs', + 'feat', + 'fix', + 'perf', + 'refactor', + 'revert', + 'style', + 'test', + ], + ], + }, +}; diff --git a/frappe/client.py b/frappe/client.py index 6ed40f8344..0b097909ca 100644 --- a/frappe/client.py +++ b/frappe/client.py @@ -274,13 +274,6 @@ def delete(doctype, name): frappe.delete_doc(doctype, name, ignore_missing=False) -@frappe.whitelist(methods=["POST", "PUT"]) -def set_default(key, value, parent=None): - """set a user default value""" - frappe.db.set_default(key, value, parent or frappe.session.user) - frappe.clear_cache(user=frappe.session.user) - - @frappe.whitelist(methods=["POST", "PUT"]) def bulk_update(docs): """Bulk update documents diff --git a/frappe/email/doctype/email_queue/email_queue.py b/frappe/email/doctype/email_queue/email_queue.py index eb07be0b38..3c020eea39 100644 --- a/frappe/email/doctype/email_queue/email_queue.py +++ b/frappe/email/doctype/email_queue/email_queue.py @@ -27,6 +27,7 @@ from frappe.utils import ( get_hook_method, get_string_between, nowdate, + sbool, split_emails, ) @@ -110,8 +111,11 @@ class EmailQueue(Document): return self.status in ["Not Sent", "Partially Sent"] def can_send_now(self): - hold_queue = cint(frappe.defaults.get_defaults().get("hold_queue")) == 1 - if frappe.are_emails_muted() or not self.is_to_be_sent() or hold_queue: + if ( + frappe.are_emails_muted() + or not self.is_to_be_sent() + or cint(frappe.db.get_default("suspend_email_queue")) == 1 + ): return False return True @@ -359,6 +363,8 @@ class SendMailContext: @frappe.whitelist() def retry_sending(name): doc = frappe.get_doc("Email Queue", name) + doc.check_permission() + if doc and (doc.status == "Error" or doc.status == "Partially Errored"): doc.status = "Not Sent" for d in doc.recipients: @@ -371,9 +377,16 @@ def retry_sending(name): def send_now(name): record = EmailQueue.find(name) if record: + record.check_permission() record.send() +@frappe.whitelist() +def toggle_sending(enable): + frappe.only_for("System Manager") + frappe.db.set_default("suspend_email_queue", 0 if sbool(enable) else 1) + + def on_doctype_update(): """Add index in `tabCommunication` for `(reference_doctype, reference_name)`""" frappe.db.add_index( diff --git a/frappe/email/doctype/email_queue/email_queue_list.js b/frappe/email/doctype/email_queue/email_queue_list.js index edc6250714..ab2a1b9a45 100644 --- a/frappe/email/doctype/email_queue/email_queue_list.js +++ b/frappe/email/doctype/email_queue/email_queue_list.js @@ -3,27 +3,37 @@ frappe.listview_settings['Email Queue'] = { var colour = {'Sent': 'green', 'Sending': 'blue', 'Not Sent': 'grey', 'Error': 'red', 'Expired': 'orange'}; return [__(doc.status), colour[doc.status], "status,=," + doc.status]; }, - refresh: function(doclist){ - if (has_common(frappe.user_roles, ["Administrator", "System Manager"])){ - if (cint(frappe.defaults.get_default("hold_queue"))){ - doclist.page.clear_inner_toolbar() - doclist.page.add_inner_button(__("Resume Sending"), function() { - frappe.defaults.set_default("hold_queue", 0); - cur_list.refresh(); - }) - } else { - doclist.page.clear_inner_toolbar() - doclist.page.add_inner_button(__("Suspend Sending"), function() { - frappe.defaults.set_default("hold_queue", 1) - cur_list.refresh(); - }) - } - } - }, - - onload: function(listview) { + refresh: show_toggle_sending_button, + onload: function(list_view) { frappe.require("logtypes.bundle.js", () => { - frappe.utils.logtypes.show_log_retention_message(cur_list.doctype); + frappe.utils.logtypes.show_log_retention_message(list_view.doctype); }) } -} +}; + +function show_toggle_sending_button(list_view) { + if (!has_common(frappe.user_roles, ["Administrator", "System Manager"])) + return; + + const sending_disabled = cint(frappe.sys_defaults.suspend_email_queue); + const label = sending_disabled ? __("Resume Sending") : __("Suspend Sending"); + + list_view.page.add_inner_button( + label, + async () => { + await frappe.xcall( + "frappe.email.doctype.email_queue.email_queue.toggle_sending", + + // enable if disabled + {enable: sending_disabled} + ); + + // set new value for suspend_email_queue in sys_defaults + frappe.sys_defaults.suspend_email_queue = sending_disabled ? 0 : 1; + + // clear the button and show one with the opposite label + list_view.page.remove_inner_button(label); + show_toggle_sending_button(list_view); + } + ); +} \ No newline at end of file diff --git a/frappe/email/queue.py b/frappe/email/queue.py index 2c3e0ee011..bc02c6be32 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -148,7 +148,7 @@ def flush(from_test=False): msgprint(_("Emails are muted")) from_test = True - if cint(frappe.defaults.get_defaults().get("hold_queue")) == 1: + if cint(frappe.db.get_default("suspend_email_queue")) == 1: return for row in get_queue(): diff --git a/frappe/patches.txt b/frappe/patches.txt index d9b827931c..437648bf9e 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -183,6 +183,7 @@ frappe.patches.v13_0.queryreport_columns frappe.patches.v13_0.jinja_hook frappe.patches.v13_0.update_notification_channel_if_empty frappe.patches.v13_0.set_first_day_of_the_week +frappe.patches.v13_0.encrypt_2fa_secrets execute:frappe.reload_doc('custom', 'doctype', 'custom_field') frappe.patches.v14_0.update_workspace2 # 20.09.2021 frappe.patches.v14_0.save_ratings_in_fraction #23-12-2021 @@ -205,3 +206,4 @@ frappe.patches.v14_0.update_auto_account_deletion_duration frappe.patches.v14_0.update_integration_request frappe.patches.v14_0.set_document_expiry_default frappe.patches.v14_0.delete_data_migration_tool +frappe.patches.v14_0.set_suspend_email_queue_default \ No newline at end of file diff --git a/frappe/patches/v13_0/encrypt_2fa_secrets.py b/frappe/patches/v13_0/encrypt_2fa_secrets.py new file mode 100644 index 0000000000..3b220f485f --- /dev/null +++ b/frappe/patches/v13_0/encrypt_2fa_secrets.py @@ -0,0 +1,44 @@ +import frappe +import frappe.defaults +from frappe.cache_manager import clear_defaults_cache +from frappe.twofactor import PARENT_FOR_DEFAULTS +from frappe.utils.password import encrypt + +DOCTYPE = "DefaultValue" +OLD_PARENT = "__default" + + +def execute(): + table = frappe.qb.DocType(DOCTYPE) + + # set parent for `*_otplogin` + ( + frappe.qb.update(table) + .set(table.parent, PARENT_FOR_DEFAULTS) + .where(table.parent == OLD_PARENT) + .where(table.defkey.like("%_otplogin")) + ).run() + + # update records for `*_otpsecret` + secrets = { + key: value + for key, value in frappe.defaults.get_defaults_for(parent=OLD_PARENT).items() + if key.endswith("_otpsecret") + } + + if not secrets: + return + + defvalue_cases = frappe.qb.terms.Case() + + for key, value in secrets.items(): + defvalue_cases.when(table.defkey == key, encrypt(value)) + + ( + frappe.qb.update(table) + .set(table.parent, PARENT_FOR_DEFAULTS) + .set(table.defvalue, defvalue_cases) + .where(table.parent == OLD_PARENT) + ).run() + + clear_defaults_cache() diff --git a/frappe/patches/v14_0/set_suspend_email_queue_default.py b/frappe/patches/v14_0/set_suspend_email_queue_default.py new file mode 100644 index 0000000000..8cdb05a177 --- /dev/null +++ b/frappe/patches/v14_0/set_suspend_email_queue_default.py @@ -0,0 +1,13 @@ +import frappe +from frappe.cache_manager import clear_defaults_cache + + +def execute(): + frappe.db.set_default( + "suspend_email_queue", + frappe.db.get_default("hold_queue", "Administrator") or 0, + parent="__default", + ) + + frappe.db.delete("DefaultValue", {"defkey": "hold_queue"}) + clear_defaults_cache() diff --git a/frappe/public/js/frappe/defaults.js b/frappe/public/js/frappe/defaults.js index 6115afb784..858880df01 100644 --- a/frappe/public/js/frappe/defaults.js +++ b/frappe/public/js/frappe/defaults.js @@ -47,20 +47,6 @@ frappe.defaults = { if(!$.isArray(d)) d = [d]; return d; }, - set_default: function(key, value, callback) { - if(typeof value!=="string") - value = JSON.stringify(value); - - frappe.boot.user.defaults[key] = value; - return frappe.call({ - method: "frappe.client.set_default", - args: { - key: key, - value: value - }, - callback: callback || function(r) {} - }); - }, set_user_default_local: function(key, value) { frappe.boot.user.defaults[key] = value; }, diff --git a/frappe/public/js/frappe/form/controls/datepicker_i18n.js b/frappe/public/js/frappe/form/controls/datepicker_i18n.js index f010325c2e..a5b825072d 100644 --- a/frappe/public/js/frappe/form/controls/datepicker_i18n.js +++ b/frappe/public/js/frappe/form/controls/datepicker_i18n.js @@ -22,10 +22,10 @@ import "air-datepicker/dist/js/i18n/datepicker.zh.js"; months: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'اكتوبر', 'نوفمبر', 'ديسمبر'], monthsShort: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'اكتوبر', 'نوفمبر', 'ديسمبر'], today: 'اليوم', - clear: 'Clear', + clear: 'حذف', dateFormat: 'dd/mm/yyyy', timeFormat: 'hh:ii aa', - firstDay: 0 + firstDay: 6 }; })(jQuery); diff --git a/frappe/public/js/frappe/form/dashboard.js b/frappe/public/js/frappe/form/dashboard.js index c057903a63..5c1b5d392f 100644 --- a/frappe/public/js/frappe/form/dashboard.js +++ b/frappe/public/js/frappe/form/dashboard.js @@ -554,7 +554,8 @@ frappe.ui.form.Dashboard = class FormDashboard { colors: ['green'], truncateLegends: 1, axisOptions: { - shortenYAxisNumbers: 1 + shortenYAxisNumbers: 1, + numberFormatter: frappe.utils.format_chart_axis_number, } }); this.show(); diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js index 877add95bf..78c9859b35 100644 --- a/frappe/public/js/frappe/utils/utils.js +++ b/frappe/public/js/frappe/utils/utils.js @@ -1145,7 +1145,12 @@ Object.assign(frappe.utils, { { divisor: 1.0e+5, symbol: 'Lakh' - }], + }, + { + divisor: 1.0e+3, + symbol: 'K', + } + ], '': [{ divisor: 1.0e+12, @@ -1205,7 +1210,8 @@ Object.assign(frappe.utils, { axisOptions: { xIsSeries: 1, shortenYAxisNumbers: 1, - xAxisMode: 'tick' + xAxisMode: 'tick', + numberFormatter: frappe.utils.format_chart_axis_number, } }; @@ -1220,6 +1226,11 @@ Object.assign(frappe.utils, { return new frappe.Chart(wrapper, chart_args); }, + format_chart_axis_number(label, country) { + const default_country = frappe.sys_defaults.country; + return frappe.utils.shorten_number(label, country || default_country, 3); + }, + generate_route(item) { const type = item.type.toLowerCase(); if (type === "doctype") { diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index e15cc339ae..525bc5af4b 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -944,10 +944,10 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { }; } options.axisOptions = { - shortenYAxisNumbers: 1 + shortenYAxisNumbers: 1, + numberFormatter: frappe.utils.format_chart_axis_number, }; options.height = 280; - return options; } diff --git a/frappe/public/js/frappe/views/reports/report_utils.js b/frappe/public/js/frappe/views/reports/report_utils.js index f458a4daf6..35c8d132c8 100644 --- a/frappe/public/js/frappe/views/reports/report_utils.js +++ b/frappe/public/js/frappe/views/reports/report_utils.js @@ -30,7 +30,8 @@ frappe.report_utils = { colors: colors, axisOptions: { shortenYAxisNumbers: 1, - xAxisMode: 'tick' + xAxisMode: 'tick', + numberFormatter: frappe.utils.format_chart_axis_number, } }; diff --git a/frappe/public/js/frappe/views/reports/report_view.js b/frappe/public/js/frappe/views/reports/report_view.js index 6880d472d3..2ea780c13d 100644 --- a/frappe/public/js/frappe/views/reports/report_view.js +++ b/frappe/public/js/frappe/views/reports/report_view.js @@ -529,7 +529,8 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView { truncateLegends: 1, colors: ['#70E078', 'light-blue', 'orange', 'red'], axisOptions: { - shortenYAxisNumbers: 1 + shortenYAxisNumbers: 1, + numberFormatter: frappe.utils.format_chart_axis_number, }, tooltipOptions: { formatTooltipY: value => frappe.format(value, get_df(this.chart_args.y_axes[0]), { always_show_decimals: true, inline: true }, get_doc(value.doc)) diff --git a/frappe/public/scss/desk/global.scss b/frappe/public/scss/desk/global.scss index 7466bdc874..1e68f374c4 100644 --- a/frappe/public/scss/desk/global.scss +++ b/frappe/public/scss/desk/global.scss @@ -589,6 +589,10 @@ details > summary:focus { background-color: var(--diff-removed); } +.chart-wrapper { + padding: 1em; +} + // REDESIGN TODO: Handling of broken images? // img.no-image:before { // .img-background(); diff --git a/frappe/templates/includes/comments/comments.py b/frappe/templates/includes/comments/comments.py index c316db37fd..44963051ca 100644 --- a/frappe/templates/includes/comments/comments.py +++ b/frappe/templates/includes/comments/comments.py @@ -3,7 +3,7 @@ import re import frappe -from frappe import _ +from frappe import _, scrub from frappe.rate_limiter import rate_limit from frappe.utils.html_utils import clean_html from frappe.website.doctype.blog_settings.blog_settings import get_comment_limit @@ -41,8 +41,13 @@ def add_comment(comment, comment_email, comment_by, reference_doctype, reference if route: clear_cache(route) - content = comment.content + "
".format( - frappe.utils.get_request_site_address(), doc.route, comment.name, _("View Comment") + if doc.get("route"): + url = f"{frappe.utils.get_request_site_address()}/{doc.route}#{comment.name}" + else: + url = f"{frappe.utils.get_request_site_address()}/app/{scrub(doc.doctype)}/{doc.name}#comment-{comment.name}" + + content = comment.content + "".format( + url, _("View Comment") ) if doc.doctype == "Blog Post" and not doc.enable_email_notification: diff --git a/frappe/tests/test_twofactor.py b/frappe/tests/test_twofactor.py index d9bf982cd2..b04cb6a91d 100644 --- a/frappe/tests/test_twofactor.py +++ b/frappe/tests/test_twofactor.py @@ -12,6 +12,7 @@ from frappe.twofactor import ( authenticate_for_2factor, confirm_otp_token, get_cached_user_pass, + get_default, get_otpsecret_for_, get_verification_obj, should_run_2fa, @@ -111,7 +112,7 @@ class TestTwoFactor(unittest.TestCase): def test_get_otpsecret_for_user(self): """OTP secret should be set for user.""" self.assertTrue(get_otpsecret_for_(self.user)) - self.assertTrue(frappe.db.get_default(self.user + "_otpsecret")) + self.assertTrue(get_default(self.user + "_otpsecret")) def test_confirm_otp_token(self): """Ensure otp is confirmed""" diff --git a/frappe/translations/ru.csv b/frappe/translations/ru.csv index 5e333c8e9d..bcd02baf93 100644 --- a/frappe/translations/ru.csv +++ b/frappe/translations/ru.csv @@ -107,7 +107,7 @@ Hourly,Почасовой, Hub Sync ID,Идентификатор синхронизации концентратора, IP Address,IP адрес, Image,Изображение, -Image View,Просмотр изображения, +Image View,Просмотр изображений, Import Data,Импорт данных, Import Log,Лог импорта, Inactive,Неактивный, @@ -246,7 +246,7 @@ Start Import,Начать импорт, State,Состояние, Stopped,Приостановлено, Subject,Тема, -Submit,Провести, +Submit,Подписать, Successful,Успешно, Summary,Резюме, Sunday,Воскресенье, @@ -445,7 +445,7 @@ Append To can be one of {0},Добавить к может быть одним Append To is mandatory for incoming mails,Добавить к является обязательным для входящих сообщений, "Append as communication against this DocType (must have fields, ""Status"", ""Subject"")","Добавить как коммуникацию для этого DocType (должен иметь поля, ""Статус"", ""Тема"")", Applicable Document Types,Применимые типы документов, -Apply,Подать заявление, +Apply,Применить, Apply Strict User Permissions,Применение строгих пользовательских разрешений, Apply To All Document Types,Применить ко всем типам документов, Apply this rule if the User is the Owner,"Применить это правило, если пользователь является владелец", @@ -679,8 +679,8 @@ Client Information,Информация о клиенте, Client Script,Скрипт клиента, Client URLs,URL-адреса клиентов, Client side script extensions in Javascript,Расширения клиентский сценарий в Javascript, -Collapsible,Складной, -Collapsible Depends On,Складные Зависит от, +Collapsible,Сворачиваемый, +Collapsible Depends On,Сворачиваемый - зависит от, Column,Колонка, Column {0} already exist.,Столбец {0} уже существует., Column Break,Разрыв столбца, @@ -706,7 +706,8 @@ Compiled Successfully,Успешно скомпилировано, Complete By,Завершить до, Complete Registration,Полная регистрация, Complete Setup,Завершение установки, -Completed By,Завершено, +Completed By,Завершил(а), +Completed On,Завершено, Compose Email,Написать письмо, Condition Detail,Детализация условий, Conditions,Условия, @@ -755,8 +756,6 @@ Created Custom Field {0} in {1},Дата создания настраиваем Created On,Дата создания, Criticism,Критика, Criticize,Критиковать, -Ctrl + Down,Ctrl + Down, -Ctrl + Up,Ctrl + Up, Ctrl+Enter to add comment,"Ctrl+Enter, чтобы добавить комментарий", Currency Name,Название валюты, Currency Precision,Точность валюты, @@ -879,7 +878,7 @@ Disable SMTP server authentication,Отключить аутентификаци Disable Sidebar Stats,Отключить статистику боковой панели, Disable Signup,Отключение Регистрация, Disable Standard Email Footer,Отключить стандартный нижний колонтитул электронной почты, -Discard,Отбросить, +Discard,Отменить, Display,Показать, Display Depends On,Показание зависит от, Do not allow user to change after set the first time,Не позволяйте пользователю изменять после установить в первый раз, @@ -1120,11 +1119,11 @@ First Transaction,Первая сделка, First data column must be blank.,Первая колонка данных должна быть пустой., First set the name and save the record.,Сначала задайте имя и сохраните запись., Flag,Флаг, -Float,Сплавы, -Float Precision,Float Precision, -Fold,Сложить, -Fold can not be at the end of the form,Fold не может быть в конце виде, -Fold must come before a Section Break,Сложите должны прийти до перерыва раздел, +Float,Дробное, +Float Precision,Плавающая точность, +Fold,Сворачиваемое, +Fold can not be at the end of the form,Сворачиваемое поле не может быть в конце формы, +Fold must come before a Section Break,Сворачиваемое должно идти до разрыва раздел, Folder,Папка, Folder name should not include '/' (slash),Имя папки не должно включать «/» (косая черта), Folder {0} is not empty,Папка {0} не пуста, @@ -1240,15 +1239,12 @@ Home Settings,Домашние настройки, Home/Test Folder 1,Главная/Тестовая Папка 1, Home/Test Folder 1/Test Folder 3,Главная/Тестовая Папка 1/Тестовая Папка 3, Home/Test Folder 2,Главная/Тестовая Папка 2, -Host,Host, -Hostname,Hostname, "How should this currency be formatted? If not set, will use system defaults","Как следует отображать числа в этой валюте? Если не указано, то будут использоваться системные значения", -I found these: ,Я нашел следующее:, +I found these: ,Я нашел это: , ID,ID, ID (name) of the entity whose property is to be set,"ID (имя) лица, имущество которого должно быть установлено", Icon will appear on the button,Иконка появится на кнопке, Identity Details,Сведения о личности, -Idx,Idx, "If Apply Strict User Permission is checked and User Permission is defined for a DocType for a User, then all the documents where value of the link is blank, will not be shown to that User","Если флажок Apply Strict User Permission установлен, а для пользователя DocType для пользователя задано разрешение пользователя, тогда все документы, где значение ссылки пустым, не будут показаны этому пользователю", If Checked workflow status will not override status in list view,"Если установлен флажок, статус процесса не будет отменять статус в журнале", If Owner,Если владелец, @@ -1303,7 +1299,7 @@ In Filter,В фильтрe, In Global Search,В глобальном поиске, In Grid View,В табличном виде, In Hours,В час, -In List View,В виде списка, +In List View,Отображать в списке, In Preview,В предварительном просмотре, In Reply To,В ответ на, In Standard Filter,В стандартный фильтр, @@ -1322,7 +1318,7 @@ Index,Индекс, Indicator,Индикатор, Info,Информация, Info:,Информация:, -Initial Sync Count,Первоначальная синхронизация Count, +Initial Sync Count,Первоначальная синхронизация, InnoDB,InnoDB, Insert Above,Вставить сверху, Insert After,Вставить после, @@ -1333,7 +1329,7 @@ Insert Column Before {0},Вставить столбец до {0}, Insert Style,Вставьте стиль, Insert new records,Вставить новые записи, Instructions Emailed,Инструкции отправлены по электронной почте, -Insufficient Permission for {0},Недостаточное разрешение для {0}, +Insufficient Permission for {0},Недостаточно прав для {0}, Int,Интервал, Integration Request,Интеграция заявки, Integration Request Service,Интеграция заявки на обслуживание, @@ -1374,33 +1370,30 @@ Invalid recipient address,Неверный адрес получателя, Invalid {0} condition,Недопустимое условие {0}, Inverse,Обратный, Is,Является, -Is Attachments Folder,Является папкой вложений, -Is Child Table,Является дочерней таблицей, +Is Attachments Folder,Это папка для вложений, +Is Child Table,Это дочерняя таблицей, Is Custom Field,Это нестандартное поле, Is First Startup,Первый запуск, -Is Folder,Папка, +Is Folder,Это папка, Is Global,Является глобальным, Is Globally Pinned,Глобально закреплено, Is Home Folder,Является корневой папкой, Is Mandatory Field,Является обязательным полем, Is Pinned,Прикреплено, -Is Primary Contact,Основной контакт, +Is Primary Contact,Это основной контакт, Is Private,Является приватным, -Is Published Field,Есть Опубликовано поле, -Is Published Field must be a valid fieldname,Опубликовано Поле должно быть действительным имя_полем, +Is Published Field,Это опубликованое поле, +Is Published Field must be a valid fieldname,Опубликованое роле должно быть допустимым именем поля, Is Single,Единственный, -Is Spam,Спам, -Is Standard,Стандартный отчёт, +Is Spam,Это спам, +Is Standard,Это стандартный отчёт, Is Submittable,Подлежит исполнению, Is Table,Является таблицей, Is Your Company Address,Является адресом вашей компании, It is risky to delete this file: {0}. Please contact your System Manager.,"Рискованно удалять этот файл: {0}. Пожалуйста, обратитесь к менеджеру системы.", Item cannot be added to its own descendents,Продукт не может быть добавлен к своим подпродуктам, -JS,JS, -JSON,JSON, JavaScript Format: frappe.query_reports['REPORTNAME'] = {},Формат JavaScript: frappe.query_reports ['REPORTNAME'] = {}, Javascript to append to the head section of the page.,Javascript для добавления к головной части страницы., -Jinja,Jinja, John Doe,Джон Доу, Kanban,Канбан, Kanban Board Column,Колонка канбан-доски, @@ -1480,7 +1473,7 @@ List,Список, List Filter,Фильтр списка, List View Setting,Настройка просмотра списка, List a document type,Перечислите тип документа, -"List as [{""label"": _(""Jobs""), ""route"":""jobs""}]","Список как [{""Ярлык"": _(""Работы""), ""маршруты"":""работы""}]", +"List as [{""label"": _(""Jobs""), ""route"":""jobs""}]","Список как [{""Метка"": _(""Работы""), ""маршруты"":""работы""}]", List of backups available for download,"Список резервных копий, доступных для загрузки", List of patches executed,Список выполненных патчей, List of themes for Website.,Список тем для сайта., @@ -1513,7 +1506,7 @@ Long Text,Длинный текст, Looks like something is wrong with this site's Paypal configuration.,"Похоже, что что-то не так с конфигурацией Paypal этого сайта.", Looks like something is wrong with this site's payment gateway configuration. No payment has been made.,"Похоже, что-то не так с конфигурацией платежного шлюза этого сайта. Платеж не был выполнен.", "Looks like something went wrong during the transaction. Since we haven't confirmed the payment, Paypal will automatically refund you this amount. If it doesn't, please send us an email and mention the Correlation ID: {0}.","Похоже, что-то пошло не так во время транзакции. Поскольку мы не подтвердили платеж, Paypal автоматически вернет вам эту сумму. Если это не так, отправьте нам электронное письмо и укажите идентификатор корреляции: {0}.", -Madam,Госпожа, +Madam,Мадам, Main Section,Основной раздел, "Make ""name"" searchable in Global Search","Индексировать ""name"" для глобального поиска", Make use of longer keyboard patterns,Используйте более длинных моделей клавиатуры, @@ -1540,7 +1533,7 @@ Max Value,Макс. значение, Max width for type Currency is 100px in row {0},Макс. ширина для типа валюты 100px в строке {0}, Maximum Attachment Limit for this record reached.,Достигнут предел вложений для этой записи., Maximum {0} rows allowed,Макс. {0} строк разрешено, -"Meaning of Submit, Cancel, Amend","Значение Провести, Отменить, Изменить", +"Meaning of Submit, Cancel, Amend","Значение Подписать, Отменить, Изменить", Mention transaction completion page URL,URL-ссылка на страницу-упоминание о завершении транзакции, Mentions,Упоминания, Menu,Меню, @@ -1606,14 +1599,14 @@ New Chat,Новый чат, New Comment on {0}: {1},Новый комментарий к {0}: {1}, New Connection,Новое соединение, New Custom Print Format,Новый пользовательский печатный бланк, -New Email,Новая электронная почта, +New Email,Новое письмо, New Email Account,Новый аккаунт электронной почты, New Event,Новое событие, New Folder,Новая папка, New Kanban Board,Новая панель канбан, New Message from Website Contact Page,Новое сообщение с формы обратной связи на сайте, New Name,Новое имя, -New Newsletter,Новый бюллетень, +New Newsletter,Новая новость, New Password,Новый пароль, New Password Required.,Требуется новый пароль., New Print Format Name,Название нового печатного бланка, @@ -1672,8 +1665,8 @@ No template found at path: {0},Нет шаблона по адресу: {0}, No {0} found,{0} не найдено, No {0} mail,Нет {0} почта, No {0} permission,Нет {0} разрешение, -None: End of Workflow,Ни один: Конец потока, -Not Allowed: Disabled User,Не разрешено: отключен пользователь, +None: End of Workflow,Нет: конец рабочего процесса, +Not Allowed: Disabled User,Не разрешено: пользователь отключен, Not Ancestors Of,Не предки, Not Descendants Of,Не потомки, Not Equals,Не равно, @@ -1688,7 +1681,7 @@ Not a valid Comma Separated Value (CSV File),"Не является допуст Not a valid User Image.,Недействительный изображение пользователя., Not a valid Workflow Action,Недоступное действие рабочего-процесса, Not a valid user,Не является действительным пользователем, -Not a zip file,Не zip файл, +Not a zip file,Не является zip файлом, Not allowed for {0}: {1},Не разрешено для {0}: {1}, Not allowed for {0}: {1} in Row {2}. Restricted field: {3},Недопустимо для {0}: {1} в строке {2}. Запрещенное поле: {3}, Not allowed for {0}: {1}. Restricted field: {2},Не допускается для {0}: {1}. Запрещенное поле: {2}, @@ -1732,11 +1725,11 @@ OTP Secret has been reset. Re-registration will be required on next login.,OTP S OTP secret can only be reset by the Administrator.,Секрет OTP может быть сброшен администратором., Office,Офис, Office 365,Офис 365, -Old Password,Старый Пароль, -Old Password Required.,Требуется старый пароль., +Old Password,Старый пароль, +Old Password Required.,Старый пароль обязателен., Older backups will be automatically deleted,Более старые резервные копии будут автоматически удалены, "On {0}, {1} wrote:","На {0}, {1} писал:", -"Once submitted, submittable documents cannot be changed. They can only be Cancelled and Amended.",После отправки поданные документы не могут быть изменены. Они могут быть только отменены и исправлены., +"Once submitted, submittable documents cannot be changed. They can only be Cancelled and Amended.",После отправки подписанные документы не могут быть изменены. Они могут быть только отменены и исправлены., "Once you have set this, the users will only be able access documents (eg. Blog Post) where the link exists (eg. Blogger).","После такой установки, пользователи получат доступ только к документам (например, сообщениям в блоге), связанным с этими разрешениями пользователя (например, блоггера).", One Last Step,Последний шаг, One Time Password (OTP) Registration Code from {},Одноразовый пароль (OTP) Регистрационный код от {}, @@ -1760,7 +1753,7 @@ Open a dialog with mandatory fields to create a new record quickly,"Открой Open a module or tool,Открыть модуль или инструмент, Open your authentication app on your mobile phone.,Откройте приложение для проверки подлинности на своем мобильном телефоне., Open {0},Открыть {0}, -Opened,Открыт, +Opened,Открыть, Operator must be one of {0},Оператор должен быть одним из {0}, Option 1,Опция 1, Option 2,Опция 2, @@ -1778,9 +1771,7 @@ Org History Heading,Org История Заголовок, Orientation,Ориентация, Original Value,Первоначальная стоимость, Outgoing email account not correct,Исходящая учетная запись электронной почты не верна, -Outlook.com,Outlook.com, Output,Вывод, -PDF,PDF, PDF Page Size,Размер PDF страницы, PDF Settings,Настройки PDF, PDF generation failed,Не удалось сгенерировать PDF-файл, @@ -1790,17 +1781,17 @@ Page HTML,Страница HTML, Page Length,Длина страницы, Page Name,Имя страницы, Page Settings,Настройки страницы, -Page has expired!,Страница просрочена!, +Page has expired!,Срок действия страницы истек!, Page not found,Страница не найдена, Page to show on the website\n,Страница для показа на сайте, Pages in Desk (place holders),Страницы-заглушки, Parent,Родитель, Parent Error Snapshot,Родитель снимка ошибки, Parent Label,Родительская метка, -Parent Table,Родитель Таблица, +Parent Table,Родительская таблица, Parent is required to get child table data,Родитель обязан получать данные дочерней таблицы, Parent is the name of the document to which the data will get added to.,"Родитель - это имя документа, к которому будут добавлены данные.", -Partial Success,Частичный успех, +Partial Success,Выполнено не полностью, Partially Successful,Частично успешный, Participants,Участники, Passive,Пассивный, @@ -1903,14 +1894,14 @@ Please specify which date field must be checked,"Просьба уточнить Please specify which value field must be checked,"Просьба уточнить, какие значения поля должны быть проверены", Please try again,"Пожалуйста, попробуйте еще раз", Please verify your Email Address,"Пожалуйста, подтвердите свой адрес электронной почты", -Point Allocation Periodicity,Периодичность распределения точек, +Point Allocation Periodicity,Периодичность распределения баллов, Points,Баллы, Points Given,Баллы засчитаны, Port,Порт, Portal Menu,Меню портала, -Portal Menu Item,Портал Пункт меню, +Portal Menu Item,Пункт меню портала, Post,Опубликовать, -Post Comment,Оставьте комментарий, +Post Comment,Оставить комментарий, Postal,Почтовый, Postal Code,Почтовый индекс, Postprocess Method,Метод постпроцесса, @@ -1966,15 +1957,6 @@ Provider Name,Имя поставщика, Public Key,Открытый ключ, Publishable Key,Ключ для публикации, Published On,Опубликовано на, -Pull,Тянуть, -Pull Failed,Не удалось выполнить Pull, -Pull Insert,Вставить вкладыш, -Pull Update,Pull Update, -Push,От себя, -Push Delete,Нажмите Удалить, -Push Failed,Ошибка отправки, -Push Insert,Push Insert, -Push Update,Push Update, Python Module,Модуль Python, Pyver,Pyver, QR Code,QR код, @@ -1986,7 +1968,7 @@ Query,Запрос, Query Report,Отчёт-выборка, Query must be a SELECT,Запрос должен быть ВЫБОР, Queue should be one of {0},Очередь должна быть одной из {0}, -Queued for backup. It may take a few minutes to an hour.,Queued для резервного копирования. Это может занять несколько минут до часа., +Queued for backup. It may take a few minutes to an hour.,В очереди для резервного копирования. Это может занять от несколько минут до часа., Queued for backup. You will receive an email with the download link,Очередь для резервного копирования. Вы получите электронное письмо с ссылкой для загрузки, Quick Help for Setting Permissions,Быстрая помощь при настройки прав доступа, Rating: ,Рейтинг: , @@ -2091,8 +2073,8 @@ Retake,пересдавать, Retry,Повторить, Return to the Verification screen and enter the code displayed by your authentication app,"Вернитесь на экран проверки и введите код, отображаемый приложением для аутентификации.", Reverse Icon Color,Обратный цвет значка, -Revert,Вернуть, -Revert Of,Вернуть из, +Revert,Возврат, +Revert Of,Возвращенно из, Reverted,Отменено, Review Level,Уровень обзора, Review Levels,Уровни обзора, @@ -2101,9 +2083,8 @@ Reviews,Отзывы, Revoke,Аннулировать, Revoked,Аннулировано, Rich Text,Форматированный текст, -Robots.txt,Robots.txt, -Role Name,Имя роли, -Role Permission for Page and Report,Роль Разрешение на страницу и отчет, +Role Name,Название роли, +Role Permission for Page and Report,Разрешение роли для страницы и отчета, Role Permissions,Разрешения роли, Role Profile,Профиль ролей, Role and Level,Роль и уровень, @@ -2198,7 +2179,7 @@ Select Print Format,Выберите бланк для печати, Select Print Format to Edit,Выберите печатный бланк для редактирования, Select Role,Выберите роль, Select Table Columns for {0},Выберите столбцы таблицы для {0}, -Select Your Region,Выберите регион, +Select Your Region,Выберите ваш регион, Select a Brand Image first.,Выберите бренд изображение в первую очередь., Select a DocType to make a new format,"Выберите DOCTYPE, чтобы сделать новый бланк", Select a chat to start messaging.,"Выберите чат, чтобы начать обмен сообщениями.", @@ -2234,7 +2215,6 @@ Send only if there is any data,"Отправить только если ест Send unsubscribe message in email,Отправить сообщение об отказе от подписки на электронную почту, Sender,Отправитель, Sender Email,Электронная почта отправителя, -Sendgrid,Sendgrid, Sent Read Receipt,Отправлять уведомление о прочтении, Sent or Received,Отправлено или получено, Sent/Received Email,Отправлено/Получено письмо, @@ -2279,8 +2259,8 @@ Setup Reports to be emailed at regular intervals,Настройка регуля Share,Поделиться, Share URL,Поделиться URL, Share With,Поделиться с, -Share this document with,Поделитесь этот документ с, -Share {0} with,Поделиться {0}, +Share this document with,Поделиться этим документом с, +Share {0} with,Поделиться {0} с, Shared,Общий, Shared With,Совместно с, Shared with everyone,Общий для всех, @@ -2325,8 +2305,6 @@ Single Post (article).,Один пост(статья)., Single Types have only one record no tables associated. Values are stored in tabSingles,"Холост Типы нет только одна запись не таблицы, связанные. Значения сохраняются в tabSingles", Skip Authorization,Пропустить авторизацию, Skip rows with errors,Пропустить строки с ошибками, -Skype,Skype, -Slack,Slack, Slack Channel,Slack канал, Slack Webhook Error,Slack Webhook ошибка, Slack Webhook URL,Неверный URL веб-хостинга, @@ -2350,14 +2328,13 @@ Something went wrong while generating dropbox access token. Please check error l Sorry! I could not find what you were looking for.,"Извините! Я не мог найти то, что вы ищете.", Sorry! Sharing with Website User is prohibited.,Извините! Поделиться с сайта Пользователю запрещается., Sorry! User should have complete access to their own record.,Извините! Пользователь должен иметь полный доступ к своей записи., -Sorry! You are not permitted to view this page.,Извините! Вам не разрешается для просмотра этой страницы., +Sorry! You are not permitted to view this page.,Извините! У вас нет разрешений для просмотра этой страницы., "Sorry, you're not authorized.","Извините, вы не авторизованы.", Sort Field,Сортировать поле, Sort Order,Порядок сортировки, Sort field {0} must be a valid fieldname,Сортировка поля {0} должен быть действительным имя_поля, Source Text,Исходный текст, Spam,Спам, -SparkPost,SparkPost, Special Characters are not allowed,Спецсимволы не допустимы, "Standard DocType cannot have default print format, use Customize Form","Стандартный DocType не может иметь формат печати по умолчанию, используйте Настроить форму", Standard Print Format cannot be updated,Стандартный печатный бланк не может быть обновлен, @@ -2371,12 +2348,11 @@ Start Date Field,Поле начальной даты, Start a conversation.,Начните разговор., Start entering data below this line,Начните вводить данные ниже этой линии, Start new Format,Начать новую Формат, -StartTLS,StartTLS, Started,Начал, Starting Frappe ...,Запуск Frappé ..., Starts on,Начало, -States,Статусы, -"States for workflow (e.g. Draft, Approved, Cancelled).","Статусы бизнес-процесса (например: черновик, утверждён, отменён).", +States,Состояния, +"States for workflow (e.g. Draft, Approved, Cancelled).","Состояния рабочего-процесса (например: черновик, утверждён, отменён).", Static Parameters,Статические параметры, Stats based on last month's performance (from {0} to {1}),Статистика на основе результатов прошлого месяца (от {0} до {1}), Stats based on last week's performance (from {0} to {1}),Статистика на основе результатов прошлой недели (от {0} до {1}), @@ -2396,7 +2372,7 @@ Subdomain,Субдомен, Subject Field,Поле темы, Submit after importing,Отправить после импорта, Submit an Issue,Отправить вопрос, -Submit this document to confirm,Провести этот документ для подтверждения, +Submit this document to confirm,Подписать этот документ для подтверждения, Submit {0} documents?,Отправить {0} документы?, Submitting {0},Помещение {0}, Submitted Document cannot be converted back to draft. Transition row {0},Проведенный Документ не может быть преобразован обратно в проект. Переходная строка {0}, @@ -2437,8 +2413,6 @@ Team Members,Члены команды, Team Members Heading,Члены команды Возглавлять, Temporarily Disabled,Временно отключен, Test Email Address,Проверить адрес электронной почты, -Test Runner,Тест Runner, -Test_Folder,Test_Folder, Text,Текст, Text Align,Выравнивание текста, Text Color,Цвет текста, @@ -2463,8 +2437,8 @@ The system provides many pre-defined roles. You can add new roles to set finer p The user from this field will be rewarded points,Пользователь из этого поля будет вознагражден баллами, Theme,Тема, Theme URL,URL темы, -There can be only one Fold in a form,Там может быть только один Fold в виде, -There is an error in your Address Template {0},Существует ошибка в адресной Шаблон {0}, +There can be only one Fold in a form,В форме может быть только один Fold, +There is an error in your Address Template {0},Ошибка в вашем шаблоне адреса {0}, There is no data to be exported,Нет данных для экспорта, There is some problem with the file url: {0},Существует некоторая проблема с файловой URL: {0}, There must be atleast one permission rule.,Там должно быть по крайней мере один правило разрешения., @@ -2502,7 +2476,7 @@ This is similar to a commonly used password.,Это похоже на обычн This is the template file generated with only the rows having some error. You should use this file for correction and import.,"Это файл шаблона, сгенерированный только строками с некоторой ошибкой. Вы должны использовать этот файл для исправления и импорта.", This link has already been activated for verification.,Эта ссылка уже была активирована для проверки., This link is invalid or expired. Please make sure you have pasted correctly.,"Эта ссылка является недействительным или истек. Пожалуйста, убедитесь, что вы вставили правильно.", -This may get printed on multiple pages,Это может быть напечатано на нескольких страницах, +This may get printed on multiple pages,Это будет напечатано на нескольких страницах, This month,Этот месяц, This query style is discontinued,Этот стиль запроса прекращен, This report was generated on {0},Этот отчет был создан в {0}, @@ -2511,7 +2485,6 @@ This request has not yet been approved by the user.,Этот запрос еще This role update User Permissions for a user,Эта роль обновляет разрешения пользователя для пользователя, This will log out {0} from all other devices,Это выведет {0} из всех других устройств, This will permanently remove your data.,Это навсегда удалит ваши данные., -Throttled,Throttled, Thumbnail URL,Миниатюра URL, Time Interval,Интервал времени, Time Series,Временные ряды, @@ -2529,7 +2502,7 @@ Timeseries,Временные ряды, Timestamp,Временная отметка, Title Case,Название дела, Title Field,Название поля, -Title Prefix,Название Приставка, +Title Prefix,Название приставки, Title field must be a valid fieldname,Название поля должно быть допустимым имя_поля, To Date Field,Поле даты, To Do,Список дел, @@ -2589,7 +2562,7 @@ Type:,Тип:, UID,UID, UIDNEXT,UIDNEXT, UIDVALIDITY,UIDVALIDITY, -UNSEEN,НЕПРОЧИТАННО, +UNSEEN,НЕПРОЧИТАННЫЕ, UPPER CASE,ВЕРХНИЙ РЕГИСТР, "URIs for receiving authorization code once the user allows access, as well as failure responses. Typically a REST endpoint exposed by the Client App.\n