Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: validate if doctype exists before syncing customisations #20598

Merged
merged 2 commits into from
Apr 11, 2023

Conversation

saurabh6790
Copy link
Member

@saurabh6790 saurabh6790 commented Apr 6, 2023

Before Fix

frappetech@Saurabhs-MacBook-Pro frappe % bench --site test.erpnext migrate
Migrating test.erpnext
Updating DocTypes for frappe        : [========================================] 100%
Updating DocTypes for erpnext       : [========================================] 100%
Updating DocTypes for journeys      : [========================================] 100%
Updating DocTypes for ********       : [========================================] 100%
Updating Dashboard for frappe
Updating Dashboard for erpnext
Updating Dashboard for journeys
Updating Dashboard for *******
Updating customizations for Address
Updating customizations for Contact
Updating customizations for Employee Benefit Claim
Queued rebuilding of search index for test.erpnext

Traceback with variables (most recent call last):
  File "/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
      mod_name = 'frappe.utils.bench_helper'
      alter_argv = True
      mod_spec = ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x10bf7b280>, origin='/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py')
      code = <code object <module> at 0x10fedd2c0, file "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py", line 1>
      main_globals = {'__name__': '__main__', '__doc__': None, '__package__': 'frappe.utils', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10bf7b280>, '__spec__': ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x10bf7b280>, origin='/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py'), '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py', '__cached__': '/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/__pycache__/bench_helper.cpython-310.pyc', 'importlib': <module 'importlib' from '/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/importlib/__init__.py'>, 'json': <module 'json' from '/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/json/__init__.py'>, 'os': <module 'os' from '/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/os.py'>, 'traceback'...
  File "/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
      code = <code object <module> at 0x10fedd2c0, file "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py", line 1>
      run_globals = {'__name__': '__main__', '__doc__': None, '__package__': 'frappe.utils', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10bf7b280>, '__spec__': ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x10bf7b280>, origin='/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py'), '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py', '__cached__': '/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/__pycache__/bench_helper.cpython-310.pyc', 'importlib': <module 'importlib' from '/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/importlib/__init__.py'>, 'json': <module 'json' from '/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/json/__init__.py'>, 'os': <module 'os' from '/Users/frappetech/.pyenv/versions/3.10.0/lib/python3.10/os.py'>, 'traceback'...
      init_globals = None
      mod_name = '__main__'
      mod_spec = ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x10bf7b280>, origin='/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py')
      pkg_name = 'frappe.utils'
      script_name = None
      loader = <_frozen_importlib_external.SourceFileLoader object at 0x10bf7b280>
      fname = '/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py'
      cached = '/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/__pycache__/bench_helper.cpython-310.pyc'
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py", line 104, in <module>
    main()
      ...skipped... 26 vars
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/utils/bench_helper.py", line 19, in main
    click.Group(commands=commands)(prog_name="bench")
      commands = {'frappe': <Group frappe>, 'get-frappe-commands': <Command get-frappe-commands>, 'get-frappe-help': <Command get-frappe-help>}
  File "/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
      self = <Group None>
      args = ()
      kwargs = {'prog_name': 'bench'}
  File "/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
      self = <Group None>
      args = ['frappe', '--site', 'kartoza.erpnext', 'migrate']
      prog_name = 'bench'
      complete_var = None
      standalone_mode = True
      windows_expand_args = True
      extra = {}
      ctx = <click.core.Context object at 0x10ff9a470>
  File "/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
      _process_result = <function MultiCommand.invoke.<locals>._process_result at 0x1101b75b0>
      args = ['migrate']
      cmd_name = 'frappe'
      cmd = <Group frappe>
      sub_ctx = <click.core.Context object at 0x11040fe80>
      ctx = <click.core.Context object at 0x10ff9a470>
      self = <Group None>
      __class__ = <class 'click.core.MultiCommand'>
  File "/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
      _process_result = <function MultiCommand.invoke.<locals>._process_result at 0x10fee57e0>
      args = []
      cmd_name = 'migrate'
      cmd = <Command migrate>
      sub_ctx = <click.core.Context object at 0x11238d120>
      ctx = <click.core.Context object at 0x11040fe80>
      self = <Group frappe>
      __class__ = <class 'click.core.MultiCommand'>
  File "/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
      self = <Command migrate>
      ctx = <click.core.Context object at 0x11238d120>
  File "/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
      _Context__self = <click.core.Context object at 0x11238d120>
      _Context__callback = <function migrate at 0x10ff420e0>
      args = ()
      kwargs = {'skip_failing': False, 'skip_search_index': False}
      ctx = <click.core.Context object at 0x11238d120>
  File "/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
      args = ()
      kwargs = {'skip_failing': False, 'skip_search_index': False}
      f = <function migrate at 0x10ff41ea0>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/commands/__init__.py", line 29, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
      ctx = <click.core.Context object at 0x11238d120>
      args = ()
      kwargs = {'skip_failing': False, 'skip_search_index': False}
      profile = False
      f = <function migrate at 0x10ff41e10>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/commands/site.py", line 605, in migrate
    SiteMigration(
      context = {'sites': ['kartoza.erpnext'], 'force': False, 'verbose': False, 'profile': False}
      skip_failing = False
      skip_search_index = False
      activate_by_import = <module 'traceback_with_variables.activate_by_import' from '/Users/frappetech/Workdesk/develop-bench/env/lib/python3.10/site-packages/traceback_with_variables/activate_by_import.py'>
      SiteMigration = <class 'frappe.migrate.SiteMigration'>
      site = 'kartoza.erpnext'
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/migrate.py", line 179, in run
    self.post_schema_updates()
      self = <frappe.migrate.SiteMigration object at 0x11238d1e0>
      site = 'kartoza.erpnext'
      filelock = <function filelock at 0x10ff07130>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/migrate.py", line 41, in wrapper
    ret = method(*args, **kwargs)
      args = (<frappe.migrate.SiteMigration object at 0x11238d1e0>,)
      kwargs = {}
      method = <function SiteMigration.post_schema_updates at 0x113b5e050>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/migrate.py", line 135, in post_schema_updates
    sync_customizations()
      self = <frappe.migrate.SiteMigration object at 0x11238d1e0>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/modules/utils.py", line 117, in sync_customizations
    sync_customizations_for_doctype(data, folder)
      app = None
      apps = ['frappe', 'erpnext', 'journeys', 'kartoza']
      app_name = 'kartoza'
      module_name = 'kartoza'
      folder = '/Users/frappetech/Workdesk/develop-bench/apps/kartoza/kartoza/kartoza/custom'
      fname = 'employee_benefit_claim.json'
      f = <_io.TextIOWrapper name='/Users/frappetech/Workdesk/develop-bench/apps/kartoza/kartoza/kartoza/custom/employee_benefit_claim.json' mode='r' encoding='UTF-8'>
      data = {'custom_fields': [{'_assign': None, '_comments': None, '_liked_by': None, '_user_tags': None, 'allow_in_quick_entry': 0, 'allow_on_submit': 0, 'bold': 0, 'collapsible': 0, 'collapsible_depends_on': None, 'columns': 0, 'creation': '2022-08-18 10:41:57.128390', 'default': None, 'depends_on': None, 'description': None, 'docstatus': 0, 'dt': 'Employee Benefit Claim', 'fetch_from': None, 'fetch_if_empty': 0, 'fieldname': 'kilometer', 'fieldtype': 'Float', 'hidden': 0, 'hide_border': 0, 'hide_days': 0, 'hide_seconds': 0, 'idx': 12, 'ignore_user_permissions': 0, 'ignore_xss_filter': 0, 'in_global_search': 0, 'in_list_view': 0, 'in_preview': 0, 'in_standard_filter': 0, 'insert_after': 'pay_against_benefit_claim', 'label': 'Kilometer', 'length': 0, 'mandatory_depends_on': None, 'modified': '2022-08-18 10:41:57.128390', 'modified_by': 'Administrator', 'name': 'Employee Benefit Claim-kilometer', 'no_copy': 0, 'non_negative': 0, 'options': None, 'owner': 'Administrator', 'parent': None, 'parentfi...
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/modules/utils.py", line 172, in sync_customizations_for_doctype
    validate_fields_for_doctype(doctype)
      validate_fields_for_doctype = <function validate_fields_for_doctype at 0x11403b760>
      update_schema = True
      sync = <function sync_customizations_for_doctype.<locals>.sync at 0x116042ef0>
      data = {'custom_fields': [{'_assign': None, '_comments': None, '_liked_by': None, '_user_tags': None, 'allow_in_quick_entry': 0, 'allow_on_submit': 0, 'bold': 0, 'collapsible': 0, 'collapsible_depends_on': None, 'columns': 0, 'creation': '2022-08-18 10:41:57.128390', 'default': None, 'depends_on': None, 'description': None, 'docstatus': 0, 'dt': 'Employee Benefit Claim', 'fetch_from': None, 'fetch_if_empty': 0, 'fieldname': 'kilometer', 'fieldtype': 'Float', 'hidden': 0, 'hide_border': 0, 'hide_days': 0, 'hide_seconds': 0, 'idx': 12, 'ignore_user_permissions': 0, 'ignore_xss_filter': 0, 'in_global_search': 0, 'in_list_view': 0, 'in_preview': 0, 'in_standard_filter': 0, 'insert_after': 'pay_against_benefit_claim', 'label': 'Kilometer', 'length': 0, 'mandatory_depends_on': None, 'modified': '2022-08-18 10:41:57.128390', 'modified_by': 'Administrator', 'name': 'Employee Benefit Claim-kilometer', 'no_copy': 0, 'non_negative': 0, 'options': None, 'owner': 'Administrator', 'parent': None, 'parentfi...
      doctype = 'Employee Benefit Claim'
      folder = '/Users/frappetech/Workdesk/develop-bench/apps/kartoza/kartoza/kartoza/custom'
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/core/doctype/doctype/doctype.py", line 1040, in validate_fields_for_doctype
    meta = frappe.get_meta(doctype, cached=False)
      doctype = 'Employee Benefit Claim'
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/__init__.py", line 1195, in get_meta
    return frappe.model.meta.get_meta(doctype, cached=cached)
      doctype = 'Employee Benefit Claim'
      cached = False
      frappe = <module 'frappe' from '/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/__init__.py'>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/model/meta.py", line 60, in get_meta
    return Meta(doctype)
      doctype = 'Employee Benefit Claim'
      cached = False
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/model/meta.py", line 117, in __init__
    super().__init__("DocType", doctype)
      self = <Meta: Employee Benefit Claim>
      doctype = 'Employee Benefit Claim'
      __class__ = <class 'frappe.model.meta.Meta'>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/model/document.py", line 107, in __init__
    self.load_from_db()
      self = <Meta: Employee Benefit Claim>
      args = ('DocType', 'Employee Benefit Claim')
      kwargs = {}
      __class__ = <class 'frappe.model.document.Document'>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/model/meta.py", line 123, in load_from_db
    super().load_from_db()
      self = <Meta: Employee Benefit Claim>
      __class__ = <class 'frappe.model.meta.Meta'>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/model/document.py", line 159, in load_from_db
    frappe.throw(
      self = <Meta: Employee Benefit Claim>
      get_value_kwargs = {'for_update': None, 'as_dict': True, 'order_by': None}
      d = None
      __class__ = <class 'frappe.model.document.Document'>
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/__init__.py", line 523, in throw
    msgprint(
      msg = 'DocType Employee Benefit Claim not found'
      exc = <class 'frappe.exceptions.DoesNotExistError'>
      title = None
      is_minimizable = False
      wide = False
      as_list = False
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/__init__.py", line 491, in msgprint
    _raise_exception()
      title = None
      as_table = False
      as_list = False
      indicator = 'red'
      alert = False
      primary_action = None
      is_minimizable = False
      wide = False
      sys = <module 'sys' (built-in)>
      out = {'message': 'DocType Employee Benefit Claim not found', 'title': 'Message', 'indicator': 'red', 'raise_exception': 1}
      _raise_exception = <function msgprint.<locals>._raise_exception at 0x116043f40>
      _strip_html_tags = <functools._lru_cache_wrapper object at 0x1160ece00>
      msg = 'DocType Employee Benefit Claim not found'
      raise_exception = <class 'frappe.exceptions.DoesNotExistError'>
      strip_html_tags = <function strip_html_tags at 0x10d523d00>
      ...skipped... 1 vars
  File "/Users/frappetech/Workdesk/develop-bench/apps/frappe/frappe/__init__.py", line 440, in _raise_exception
    raise raise_exception(msg)
      msg = 'DocType Employee Benefit Claim not found'
      raise_exception = <class 'frappe.exceptions.DoesNotExistError'>
      ...skipped... 1 vars
frappe.exceptions.DoesNotExistError: DocType Employee Benefit Claim not found

After fix

Screenshot 2023-04-10 at 11 15 47 AM

@saurabh6790 saurabh6790 requested review from a team and phot0n and removed request for a team April 6, 2023 09:03
@github-actions github-actions bot added the add-test-cases Add test case to validate fix or enhancement label Apr 6, 2023
@codecov
Copy link

codecov bot commented Apr 6, 2023

Codecov Report

Merging #20598 (6e0d70b) into develop (1c3cb63) will decrease coverage by 0.01%.
The diff coverage is 33.33%.

❗ Current head 6e0d70b differs from pull request most recent head e14fc2c. Consider uploading reports for the commit e14fc2c to get more accurate results

Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #20598      +/-   ##
===========================================
- Coverage    63.75%   63.74%   -0.01%     
===========================================
  Files          758      758              
  Lines        68709    68918     +209     
  Branches      6196     6196              
===========================================
+ Hits         43803    43934     +131     
- Misses       21269    21347      +78     
  Partials      3637     3637              
Flag Coverage Δ
server 68.81% <33.33%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

@saurabh6790 saurabh6790 requested review from surajshetty3416 and removed request for phot0n April 6, 2023 10:03
@ankush ankush changed the title chore: validate if doctype exists before syncing customisations fix: validate if doctype exists before syncing customisations Apr 6, 2023
@ankush ankush removed the add-test-cases Add test case to validate fix or enhancement label Apr 6, 2023
@ankush
Copy link
Member

ankush commented Apr 6, 2023

@saurabh6790 any change to production code should not be chore:

frappe/modules/utils.py Outdated Show resolved Hide resolved
@saurabh6790
Copy link
Member Author

@ankush pushed a fix

@ankush ankush added Skip CI Doesn't run Ci for this PR. backport version-13-hotfix backport version-14-hotfix backport to version 14 labels Apr 11, 2023
@ankush ankush merged commit 26e7320 into frappe:develop Apr 11, 2023
mergify bot pushed a commit that referenced this pull request Apr 11, 2023
* fix: validate if doctype exists before syncing customisations

* refactor: rename and add default

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
(cherry picked from commit 26e7320)

# Conflicts:
#	frappe/modules/utils.py
ankush pushed a commit that referenced this pull request Apr 11, 2023
* fix: validate if doctype exists before syncing customisations

* refactor: rename and add default

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
(cherry picked from commit 26e7320)
ankush pushed a commit that referenced this pull request Apr 11, 2023
#20644)

* fix: validate if doctype exists before syncing customisations

* refactor: rename and add default

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
(cherry picked from commit 26e7320)

Co-authored-by: Saurabh <saurabh6790@gmail.com>
ankush added a commit that referenced this pull request Apr 11, 2023
#20598) (#20645)

* fix: validate if doctype exists before syncing customisations (#20598)

* fix: validate if doctype exists before syncing customisations

* refactor: rename and add default

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
(cherry picked from commit 26e7320)

# Conflicts:
#	frappe/modules/utils.py

* chore: conflicts

---------

Co-authored-by: Saurabh <saurabh6790@gmail.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
frappe-pr-bot pushed a commit that referenced this pull request Apr 11, 2023
# [14.32.0](v14.31.0...v14.32.0) (2023-04-11)

### Bug Fixes

* also build jsx files ([#20624](#20624)) ([#20628](#20628)) ([01f4c38](01f4c38))
* better permission error for query_report ([#20643](#20643)) ([#20647](#20647)) ([33be129](33be129))
* change z-index of freeze component to make it appear above all components ([f6ebae9](f6ebae9)), closes [#20538](#20538)
* child row form should be above freeze screen ([8d4402e](8d4402e))
* Consider global default in user perm ([87e1aee](87e1aee))
* Consider user perimission default in get_user_default function ([24f6931](24f6931))
* dont create communication for auto repeat notification ([#20606](#20606)) ([#20611](#20611)) ([e9fc2ae](e9fc2ae))
* german translation of workflow state ([#20609](#20609)) ([#20616](#20616)) ([4d7a080](4d7a080))
* **grid row:** fix prettier hook check ([583e1d4](583e1d4))
* **grid row:** fix update_docfield_property function not updating grid row ([a2e9cc0](a2e9cc0))
* improved validation in `add_comment` ([#20520](#20520)) ([4d920fa](4d920fa))
* **ListView:** Evaluate sort_field sort_order within listviews based on DocTypes Definition ([#20482](#20482)) ([b560ccd](b560ccd))
* log requests even if no response ([#20638](#20638)) ([#20640](#20640)) ([a43c11e](a43c11e))
* minor oauth doctypes enhancements ([#20613](#20613)) ([75300f7](75300f7))
* **pretty-date:** plural form when the value is 1 ([#20619](#20619)) ([#20642](#20642)) ([7f6a557](7f6a557))
* track workspace changes ([#20649](#20649)) ([#20650](#20650)) ([5f54325](5f54325))
* validate if doctype exists before syncing customisations (backport [#20598](#20598)) ([#20645](#20645)) ([9a39bf8](9a39bf8))

### Features

* make report name translatable ([#20608](#20608)) ([#20618](#20618)) ([ed49e83](ed49e83))

### Performance Improvements

* Don't re-initate sessions in realtime.py ([#20577](#20577)) ([7480b86](7480b86))
frappe-pr-bot pushed a commit that referenced this pull request Apr 11, 2023
# [13.53.0](v13.52.0...v13.53.0) (2023-04-11)

### Bug Fixes

* allow `reset_otp_secret` only if Two Factor Auth is enabled (backport [#20506](#20506)) ([#20560](#20560)) ([e8025a4](e8025a4))
* better permission error for query_report ([#20643](#20643)) ([#20646](#20646)) ([d972af8](d972af8))
* change z-index of freeze component to make it appear above all components ([1878b87](1878b87)), closes [#20538](#20538)
* child row form should be above freeze screen ([9201e84](9201e84))
* client script add to instead of replace ([0c7ac16](0c7ac16))
* client_script default value ([9ed7851](9ed7851))
* german translation of workflow state ([#20609](#20609)) ([#20615](#20615)) ([3769bdf](3769bdf))
* **grid row:** fix prettier hook check ([9309687](9309687))
* **grid row:** fix update_docfield_property function not updating grid row ([558f908](558f908))
* **ListView:** Evaluate sort_field sort_order within listviews based on DocTypes Definition ([#20482](#20482)) ([ba3cf84](ba3cf84))
* log requests even if no response ([#20638](#20638)) ([#20639](#20639)) ([ae4f7dd](ae4f7dd))
* no optional chaining in v13 ([d08627b](d08627b))
* **pretty-date:** plural form when the value is 1 ([#20619](#20619)) ([#20641](#20641)) ([4d6b776](4d6b776))
* validate if doctype exists before syncing customisations ([#20598](#20598)) ([#20644](#20644)) ([32ba65f](32ba65f))

### Features

* add context to confirm dailog ([0e21299](0e21299))
* add context to prompt dialog ([1bbf9c9](1bbf9c9))
* make report name translatable (backport [#20608](#20608)) ([#20617](#20617)) ([a92e69e](a92e69e))
* **minor:** log datetime in worker log (backport [#20414](#20414)) ([#20569](#20569)) ([dccb6af](dccb6af))
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
backport version-14-hotfix backport to version 14 Skip CI Doesn't run Ci for this PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants