* ci: re-fetch before push to avoid force-push on translations_hotfix
If upstream/translations_hotfix moved forward while the script was
running (e.g., a concurrent run or manual push), git push would fail
with "behind remote". Re-fetch right before pushing and merge any new
remote commits with -X ours so our .po changes and the main.pot from
${HOTFIX_BRANCH} (set by the initial -X theirs merge) are preserved
without needing a force-push.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: define HOTFIX_BRANCH once as job env; pass it to sync script
version-16-hotfix is now declared as env.HOTFIX_BRANCH at the job level
so the checkout ref and the script argument both derive from the same
value. Quoting the GITHUB_WORKSPACE path guards against spaces on
self-hosted runners.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: define HOTFIX_BRANCH as job env and pass to sync script via env
Declares version-16-hotfix once as env.HOTFIX_BRANCH at the job level
so the checkout ref and the script both derive from the same value.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: read HOTFIX_BRANCH from env instead of hardcoding in script
Removes the hardcoded branch name from the script; reads it from the
HOTFIX_BRANCH env var set by the workflow. Fails immediately with a
clear message if the var is not set.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: use ls-remote to check branch existence instead of swallowing fetch errors
Replace `git fetch ... 2>/dev/null || true` + `git rev-parse --verify`
with `git ls-remote --exit-code --heads upstream translations_hotfix`.
ls-remote queries the remote directly so the check is never based on
stale local state, and real failures (auth, network) propagate through
set -e instead of being silently ignored. Applied to both the initial
branch setup and the pre-push re-fetch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: rewrite orchestrator to dispatch runner per hotfix branch via matrix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: add per-branch runner workflow for hotfix translation sync
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: generalise sync script to use APP_NAME and GITHUB_REPOSITORY
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: remove push trigger from runner workflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: rename working branch to sync_translations_{hotfix_branch}
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Separates all make_*/create_* document-creation functions from the
SalesOrder controller into a dedicated mapper.py for better separation
of concerns. Re-exports from sales_order.py preserve backward compat.
Semgrep rule frappe-modifying-but-not-comitting-other-method flags
setting self.ignore_linked_doctypes inside make_gl_entries() instead
of in the calling on_cancel method. Follows the same pattern used by
AssetCapitalization.
accounts/services/child_item_update.py:
- ChildItemUpdater class with update() entry point encapsulating all
the logic from the old update_child_qty_rate free function; nested
closures (check_doc_permissions, validate_workflow_conditions,
validate_quantity_and_rate, validate_fg_item_for_subcontracting)
become private methods on the class
- update_child_qty_rate kept as @frappe.whitelist() thin wrapper;
re-exported from accounts_controller.py so the JS whitelist path
"erpnext.controllers.accounts_controller.update_child_qty_rate"
and test imports continue to work
- Free functions: set_order_defaults, validate_child_on_delete,
update_bin_on_delete, validate_and_delete_children, get_allow_zero_qty,
get_child_item_change_state, is_child_item_unchanged,
update_child_item_rate_and_discount, update_child_item_uom_and_weight,
check_if_child_table_updated
accounts_controller.py drops from ~2356 to ~1796 lines.
- accounts/services/party_validation.py: PartyValidator class with
single validate() entry point covering party frozen/disabled check,
party accounts, currency, party account currency, address/contact,
and company-linked addresses. AccountsController.get_party() kept
as a shim (called by advances and payment_schedule services).
- accounts/services/internal_transfer.py: InternalTransferService
class with validate() (reference + transaction rate + pricing/tax
disablers), set_account() for unrealized P&L, is_internal_transfer(),
process_common_party_accounting(), and get_common_party_link().
Shims retained on AccountsController for the three methods called
by selling/buying/stock controllers and GL composers.
accounts_controller.py drops from ~2722 to ~2356 lines.