snapshot of https://github.com/frappe/crm.git (develop, 2026-09-18; blobs > 131072B omitted)
Some checks failed
Frontend / Unit Tests & Coverage (push) Has been skipped
Server / Tests (frappe ${{ matrix.frappe-branch }}) (push) Has been skipped
Server / Resolve frappe matrix (push) Failing after 1s
Frontend / Lint (push) Failing after 1s
Frontend / Production Build (push) Failing after 1s
Server / Coverage Wrap Up (push) Has been skipped
Frontend / Coverage Wrap Up (push) Has been skipped
Regenerate POT file (translatable strings) / Regenerate POT file (develop) (push) Failing after 1s
Regenerate POT file (translatable strings) / Regenerate POT file (main-hotfix) (push) Failing after 1s
Some checks failed
Frontend / Unit Tests & Coverage (push) Has been skipped
Server / Tests (frappe ${{ matrix.frappe-branch }}) (push) Has been skipped
Server / Resolve frappe matrix (push) Failing after 1s
Frontend / Lint (push) Failing after 1s
Frontend / Production Build (push) Failing after 1s
Server / Coverage Wrap Up (push) Has been skipped
Frontend / Coverage Wrap Up (push) Has been skipped
Regenerate POT file (translatable strings) / Regenerate POT file (develop) (push) Failing after 1s
Regenerate POT file (translatable strings) / Regenerate POT file (main-hotfix) (push) Failing after 1s
This commit is contained in:
117
crm/www/crm.py
Normal file
117
crm/www/crm.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# GNU GPLv3 License. See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe import _, get_installed_apps
|
||||
from frappe.integrations.frappe_providers.frappecloud_billing import is_fc_site
|
||||
from frappe.translate import get_messages_for_boot, get_translated_doctypes
|
||||
from frappe.utils import cint, get_system_timezone
|
||||
from frappe.utils.telemetry import capture
|
||||
|
||||
no_cache = 1
|
||||
|
||||
|
||||
def get_context():
|
||||
from crm.api import check_app_permission
|
||||
|
||||
if not check_app_permission():
|
||||
frappe.throw(_("You do not have permission to access Frappe CRM"), frappe.PermissionError)
|
||||
|
||||
redirect_to_set_password()
|
||||
|
||||
frappe.db.commit()
|
||||
context = frappe._dict()
|
||||
context.boot = get_boot()
|
||||
if frappe.session.user != "Guest":
|
||||
capture("active_site", "crm")
|
||||
return context
|
||||
|
||||
|
||||
def redirect_to_set_password():
|
||||
"""Send users who have no password of their own to the set password page.
|
||||
|
||||
The Frappe Cloud site owner arrives on a session handed over by the
|
||||
dashboard and never sets a password, so they cannot get back in once it
|
||||
expires. Invited users are already routed here by `accept_invitation`; this
|
||||
covers everyone else, on the same page.
|
||||
"""
|
||||
from crm.api.user import needs_password_setup
|
||||
|
||||
if not needs_password_setup():
|
||||
return
|
||||
|
||||
user = frappe.get_doc("User", frappe.session.user)
|
||||
link = user._reset_password()
|
||||
|
||||
# this is a GET request, which is rolled back unless a commit is requested
|
||||
frappe.local.flags.commit = True
|
||||
|
||||
frappe.local.flags.redirect_location = link
|
||||
|
||||
# 302, not the 301 default: v16+ lets the browser cache a permanent redirect,
|
||||
# which would keep sending the user to a spent key long after they set a
|
||||
# password. Set on the instance — v15's `Redirect` takes no constructor arg.
|
||||
redirect = frappe.Redirect()
|
||||
redirect.http_status_code = 302
|
||||
raise redirect
|
||||
|
||||
|
||||
@frappe.whitelist(methods=["POST"], allow_guest=True)
|
||||
def get_context_for_dev():
|
||||
if not frappe.conf.developer_mode:
|
||||
frappe.throw(_("This method is only meant for developer mode"))
|
||||
return get_boot()
|
||||
|
||||
|
||||
def get_boot():
|
||||
return frappe._dict(
|
||||
{
|
||||
"frappe_version": frappe.__version__,
|
||||
"default_route": get_default_route(),
|
||||
"site_name": frappe.local.site,
|
||||
"socketio_port": frappe.conf.socketio_port,
|
||||
"read_only_mode": frappe.flags.read_only,
|
||||
"csrf_token": frappe.sessions.get_csrf_token(),
|
||||
"setup_complete": cint(frappe.get_system_settings("setup_complete")),
|
||||
"sysdefaults": frappe.defaults.get_defaults(),
|
||||
"is_demo_site": frappe.conf.get("is_demo_site"),
|
||||
"demo_data_created": frappe.db.get_default("crm_demo_data_created") == "1",
|
||||
"is_fc_site": is_fc_site(),
|
||||
"translated_doctypes": get_translated_doctypes(),
|
||||
"translated_messages": get_messages_for_boot(),
|
||||
"timezone": {
|
||||
"system": get_system_timezone(),
|
||||
"user": frappe.db.get_value("User", frappe.session.user, "time_zone")
|
||||
or get_system_timezone(),
|
||||
},
|
||||
"state_options": get_state_options(),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def get_state_options() -> dict[str, list[str]]:
|
||||
"""Country -> list of states, so the frontend can render a state dropdown.
|
||||
|
||||
Sourced from India Compliance's own constant when that app is installed, so the
|
||||
options stay in sync with the desk. Returns an empty map (state field stays free
|
||||
text) on any failure.
|
||||
|
||||
This runs inside ``get_boot``, so it must never raise — a failure here would break
|
||||
the whole CRM page load. ``get_installed_apps`` can return `[]` or raise in
|
||||
unauthenticated/boot contexts (notably on v15), so the lookup is wrapped defensively.
|
||||
"""
|
||||
try:
|
||||
if "india_compliance" not in get_installed_apps():
|
||||
return {}
|
||||
|
||||
from india_compliance.gst_india.constants import INDIAN_STATES
|
||||
|
||||
return {"India": list(INDIAN_STATES)}
|
||||
except Exception:
|
||||
# Degrade silently to free-text: this runs in boot, so the except branch
|
||||
# must not do anything that can itself raise (e.g. logging to a missing dir).
|
||||
return {}
|
||||
|
||||
|
||||
def get_default_route():
|
||||
return "/crm"
|
||||
Reference in New Issue
Block a user