Root cause of recurring 'Password not found for Email Account Performance West Outgoing': the account was shipped as a fixture with awaiting_password=1 and no password. Email Account SMTP passwords are encrypted per-site and cannot live in a fixture, so every `bench migrate` reimported the fixture and re-broke outgoing mail (login notifications, password resets, welcome emails). - Remove the Email Account fixture (it cannot carry the encrypted secret). - Add email_account_sync.sync_outgoing_password: idempotent, exception-safe upsert that reconciles the account + password from SMTP_* env and clears awaiting_password. - Wire it to after_migrate (repairs at end of every deploy/migrate, right after fixtures import) and the daily scheduler (heals out-of-band restore/restart drift). - Pass SMTP_* into the erpnext + erpnext-scheduler containers so the sync has the secret (they previously had no SMTP env).
68 lines
3 KiB
Python
68 lines
3 KiB
Python
app_name = "performancewest_erpnext"
|
|
app_title = "Performance West ERPNext"
|
|
app_publisher = "Performance West Inc."
|
|
app_description = "Custom payment gateways, surcharge hooks, and identity verification for Performance West"
|
|
app_email = "support@performancewest.net"
|
|
app_license = "MIT"
|
|
|
|
# Fixtures to import on bench migrate
|
|
fixtures = [
|
|
{"dt": "Custom Field", "filters": [["dt", "in", ["Sales Order", "Sales Invoice", "Payment Request"]]]},
|
|
{"dt": "Notification", "filters": [["name", "like", "CRTC%"]]},
|
|
{"dt": "Notification", "filters": [["name", "like", "Admin %"]]},
|
|
# NB: the "Performance West Outgoing" Email Account is intentionally NOT a
|
|
# fixture. Its SMTP password is stored encrypted (per-site encryption_key)
|
|
# and cannot be carried in a fixture, so reimporting it on `bench migrate`
|
|
# would set awaiting_password=1 and an empty password — breaking all
|
|
# outgoing mail ("Password not found for Email Account ..."). The account is
|
|
# created/repaired idempotently from the SMTP_* env via
|
|
# email_account_sync.sync_outgoing_password (after_migrate + scheduler).
|
|
# Subscription plans for recurring renewals (RA, annual report, CRTC maintenance,
|
|
# formation maintenance bundles). Pricing updated per go-live-todo.md:37, 261.
|
|
{"dt": "Subscription Plan"},
|
|
# Service Items referenced by renewal_worker._compliance_type_to_item —
|
|
# CRTC-MAINT-ANNUAL, MAILBOX-RENEWAL, BC-ANNUAL-REPORT, DOMAIN-RENEWAL-CA,
|
|
# and the COMPLIANCE-OTHER catch-all.
|
|
{"dt": "Item", "filters": [["item_code", "in", [
|
|
"CRTC-MAINT-ANNUAL", "MAILBOX-RENEWAL", "BC-ANNUAL-REPORT",
|
|
"DOMAIN-RENEWAL-CA", "COMPLIANCE-OTHER",
|
|
]]]},
|
|
]
|
|
|
|
# Portal menu items — adds "My Orders" to the ERPNext portal sidebar
|
|
portal_menu_items = [
|
|
{"title": "My Orders", "route": "/orders", "reference_doctype": "Sales Order", "role": "Customer"},
|
|
]
|
|
|
|
# Document event hooks
|
|
doc_events = {
|
|
"Payment Request": {
|
|
"before_insert": "performancewest_erpnext.payments.surcharge.inject_surcharge",
|
|
},
|
|
"Sales Order": {
|
|
"before_submit": "performancewest_erpnext.payments.identity_gate.check_identity",
|
|
},
|
|
}
|
|
|
|
# pw_stripe_checkout is served from www/pw_stripe_checkout.py automatically
|
|
|
|
# Exempt Stripe webhook from CSRF — Stripe uses signature verification instead
|
|
csrf_ignore_methods = [
|
|
"performancewest_erpnext.api.stripe_webhook",
|
|
]
|
|
|
|
# Reconcile the outgoing Email Account password from the SMTP_* environment at
|
|
# the end of every migrate (fixtures import just before this, and cannot carry
|
|
# the encrypted password). Keeps "Password not found for Email Account ..." from
|
|
# recurring after a deploy.
|
|
after_migrate = [
|
|
"performancewest_erpnext.email_account_sync.sync_outgoing_password",
|
|
]
|
|
|
|
# Daily self-heal: catches drift from out-of-band restarts / DB restores that
|
|
# wipe the encrypted password without going through migrate.
|
|
scheduler_events = {
|
|
"daily": [
|
|
"performancewest_erpnext.email_account_sync.sync_outgoing_password",
|
|
],
|
|
}
|