fix: Frappe/ERPNext v16 compatibility (missing dependency declaration, broken hooks, broken link queries) - #26
Open
rjonesbsink wants to merge 3 commits into
Conversation
pyproject.toml had no [tool.bench.frappe-dependencies] table -- the mechanism bench's validate_app_dependencies() actually uses to check an app against the installed Frappe/ERPNext version. The only version hint was a commented-out, stale "frappe~=15.0.0" line. Declares frappe/erpnext >=16.0.0,<17.0.0. Verified working against Frappe 16.28.0 / ERPNext 16.29.0.
- required_apps was commented out despite this app adding custom fields and doc_events to Sales Invoice, Purchase Order, Purchase Receipt, Purchase Invoice, Delivery Note, and Stock Entry -- all ERPNext doctypes. Installing on a bare Frappe site (no ERPNext) would fail partway through without this declared. - add_to_apps_screen was commented out and pointed has_permission at beveren_fsm.api.permission.has_app_permission, a module/function that doesn't exist anywhere in this app, so even uncommenting it as-is would silently fail to register a Desk "Apps" tile (the exception is swallowed and logged by frappe.apps.get_apps()). Enabled without has_permission (optional; defaults to always visible) and pointed the logo at the app's existing schedule favicon instead of the never-added logo.png.
…query/contact_query
The customer_address and customer_contact (service_address in
Service Quotation) link-field queries in Service Request, Service
Order, and Service Quotation filtered directly on
{link_doctype, link_name} against the Address/Contact doctypes.
Neither doctype has those fields directly -- they live on the child
"Dynamic Link" table referenced via Address/Contact's "links" field.
Without an explicit query pointing at a handler that understands this
(as ERPNext core does everywhere it queries Address/Contact by dynamic
link), Frappe's default list query tries to resolve link_doctype as a
literal column on Address/Contact, which doesn't exist, surfacing as:
You do not have permission to access field: Address.link_doctype
You do not have permission to access field: Contact.link_doctype
Fixed by adding the same query methods ERPNext core uses for this
exact pattern: frappe.contacts.doctype.address.address.address_query
and frappe.contacts.doctype.contact.contact.contact_query.
maniamartial
self-requested a review
July 24, 2026 13:13
Contributor
|
I will review |
Author
|
Heads up on the CI failures, in case it helps triage — both look pre-existing/environmental rather than caused by this PR:
Let me know if you'd like anything adjusted. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
While setting up this app on a fresh Frappe v16 / ERPNext v16 site, I ran into three separate bugs that needed fixing before it was usable. Filing them together since they were found (and fixed) in the same pass.
No
[tool.bench.frappe-dependencies]inpyproject.toml— this is whatbenchactually uses to validate an app against the installed Frappe/ERPNext version (validate_app_dependencies()). The only version hint present was a commented-out, stalefrappe~=15.0.0line, so bench has no way to tell whether this app is compatible with whatever it's being installed on. Addedfrappe/erpnext>=16.0.0,<17.0.0, verified against Frappe 16.28.0 / ERPNext 16.29.0.required_appscommented out — this app adds custom fields anddoc_eventsto Sales Invoice, Purchase Order, Purchase Receipt, Purchase Invoice, Delivery Note, and Stock Entry, all ERPNext doctypes. Installing on a bare Frappe site (no ERPNext) fails partway through without this declared.add_to_apps_screencommented out, and broken as written — it pointshas_permissionatbeveren_fsm.api.permission.has_app_permission, which doesn't exist anywhere in the app.frappe.apps.get_apps()callsfrappe.get_attr()on that path, catches the resulting exception, and just logs it — so even uncommenting the block as-is silently fails to register a Desk "Apps" tile. Enabled it withouthas_permission(it's optional) and pointed the logo at the app's existing schedule favicon sincelogo.pngwas never added.customer_address/customer_contact(service_addressin Service Quotation) link-field queries inservice_request.js,service_order.js,service_quotation.jsfilter directly on{link_doctype, link_name}against theAddress/Contactdoctypes. Neither doctype has those fields directly — they live on the childDynamic Linktable via thelinksfield. Without an explicitquerypointing at a handler that understands this, Frappe's default list query tries to resolvelink_doctypeas a literal column onAddress/Contact, which doesn't exist, and surfaces as:Fixed by routing through
frappe.contacts.doctype.address.address.address_queryandfrappe.contacts.doctype.contact.contact.contact_query, the same functions ERPNext core uses for this exact pattern elsewhere (e.g.warranty_claim.js,opportunity.js,payment_entry.js).Testing
All four fixes verified on a local Docker deployment: Frappe 16.28.0, ERPNext 16.29.0, MariaDB 11.8. Confirmed the Desk "Apps" tile renders and routes correctly, and that both
address_query/contact_querycalls return results instead of throwing, via directfrappe.callinvocations matching what the form scripts trigger.