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
Regenerate POT file (translatable strings) / Regenerate POT file (develop) (push) Failing after 1m13s
Regenerate POT file (translatable strings) / Regenerate POT file (main-hotfix) (push) Failing after 6s
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
Some checks failed
Frontend / Unit Tests & Coverage (push) Has been skipped
Regenerate POT file (translatable strings) / Regenerate POT file (develop) (push) Failing after 1m13s
Regenerate POT file (translatable strings) / Regenerate POT file (main-hotfix) (push) Failing after 6s
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
This commit is contained in:
179
crm/api/__init__.py
Normal file
179
crm/api/__init__.py
Normal file
@@ -0,0 +1,179 @@
|
||||
import frappe
|
||||
from bs4 import BeautifulSoup
|
||||
from frappe import _
|
||||
from frappe.core.api.file import get_max_file_size
|
||||
from frappe.rate_limiter import rate_limit
|
||||
from frappe.translate import get_all_translations
|
||||
from frappe.utils import cstr, split_emails, validate_email_address
|
||||
|
||||
from crm.utils import is_frappe_version
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def get_translations():
|
||||
if frappe.session.user != "Guest":
|
||||
language = frappe.db.get_value("User", frappe.session.user, "language")
|
||||
else:
|
||||
language = frappe.db.get_single_value("System Settings", "language")
|
||||
|
||||
return get_all_translations(language)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_user_signature():
|
||||
user = frappe.session.user
|
||||
user_email_signature = (
|
||||
frappe.db.get_value(
|
||||
"User",
|
||||
user,
|
||||
"email_signature",
|
||||
)
|
||||
if user
|
||||
else None
|
||||
)
|
||||
|
||||
signature = user_email_signature or frappe.db.get_value(
|
||||
"Email Account",
|
||||
{"default_outgoing": 1, "add_signature": 1},
|
||||
"signature",
|
||||
)
|
||||
|
||||
if not signature:
|
||||
return
|
||||
|
||||
soup = BeautifulSoup(signature, "html.parser")
|
||||
html_signature = soup.find("div", {"class": "ql-editor read-mode"})
|
||||
_signature = None
|
||||
if html_signature:
|
||||
_signature = html_signature.renderContents()
|
||||
content = ""
|
||||
if cstr(_signature) or signature:
|
||||
content = f'<br><p class="signature">{signature}</p>'
|
||||
return content
|
||||
|
||||
|
||||
def check_app_permission():
|
||||
if frappe.session.user == "Administrator":
|
||||
return True
|
||||
|
||||
allowed_modules = []
|
||||
|
||||
if is_frappe_version("15"):
|
||||
allowed_modules = frappe.config.get_modules_from_all_apps_for_user()
|
||||
elif is_frappe_version("16", above=True):
|
||||
from frappe.utils.modules import get_modules_from_all_apps_for_user
|
||||
|
||||
allowed_modules = get_modules_from_all_apps_for_user()
|
||||
|
||||
allowed_modules = [x["module_name"] for x in allowed_modules]
|
||||
if "FCRM" not in allowed_modules:
|
||||
return False
|
||||
|
||||
roles = frappe.get_roles()
|
||||
if any(role in ["System Manager", "Sales User", "Sales Manager"] for role in roles):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(limit=10, seconds=60 * 60)
|
||||
def accept_invitation(key: str | None = None):
|
||||
if not key:
|
||||
frappe.throw(_("Invalid or expired key"))
|
||||
|
||||
result = frappe.db.get_all("CRM Invitation", filters={"key": key}, pluck="name")
|
||||
if not result:
|
||||
frappe.throw(_("Invalid or expired key"))
|
||||
invitation = frappe.get_doc("CRM Invitation", result[0])
|
||||
is_new_user = invitation.accept()
|
||||
invitation.reload()
|
||||
|
||||
# this is a GET request, which is rolled back unless a commit is requested
|
||||
frappe.local.flags.commit = True
|
||||
|
||||
if invitation.status == "Accepted":
|
||||
frappe.local.response["type"] = "redirect"
|
||||
if is_new_user:
|
||||
# a new user has no password yet, send them to the set password page
|
||||
# which logs them in and redirects to /crm once the password is set
|
||||
user = frappe.get_doc("User", invitation.email)
|
||||
frappe.local.response["location"] = user._reset_password()
|
||||
else:
|
||||
frappe.local.login_manager.login_as(invitation.email)
|
||||
frappe.local.response["location"] = "/crm"
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def invite_by_email(emails: str, role: str):
|
||||
frappe.only_for(["Sales Manager", "System Manager"], True)
|
||||
|
||||
user_roles = frappe.get_roles(frappe.session.user)
|
||||
|
||||
if role == "System Manager" and "System Manager" not in user_roles:
|
||||
frappe.throw(_("You are not allowed to invite System Managers"), frappe.PermissionError)
|
||||
|
||||
if role == "Sales Manager" and "System Manager" not in user_roles:
|
||||
frappe.throw(_("You are not allowed to invite Sales Managers"), frappe.PermissionError)
|
||||
|
||||
if role not in ["System Manager", "Sales Manager", "Sales User"]:
|
||||
frappe.throw(_("Cannot invite for this role"), frappe.PermissionError)
|
||||
|
||||
if not emails:
|
||||
return
|
||||
|
||||
email_string = validate_email_address(emails, throw=False)
|
||||
email_list = split_emails(email_string)
|
||||
if not email_list:
|
||||
return
|
||||
existing_members = frappe.db.get_all("User", filters={"email": ["in", email_list]}, pluck="email")
|
||||
existing_invites = frappe.db.get_all(
|
||||
"CRM Invitation",
|
||||
filters={
|
||||
"email": ["in", email_list],
|
||||
"role": ["in", ["System Manager", "Sales Manager", "Sales User"]],
|
||||
},
|
||||
pluck="email",
|
||||
)
|
||||
|
||||
to_invite = list(set(email_list) - set(existing_members) - set(existing_invites))
|
||||
|
||||
for email in to_invite:
|
||||
frappe.get_doc(doctype="CRM Invitation", email=email, role=role).insert(ignore_permissions=True)
|
||||
|
||||
return {
|
||||
"existing_members": existing_members,
|
||||
"existing_invites": existing_invites,
|
||||
"to_invite": to_invite,
|
||||
}
|
||||
|
||||
|
||||
@frappe.whitelist(methods=["DELETE", "POST"])
|
||||
def delete_attachment(doctype: str, docname: str, file_url: str):
|
||||
if not frappe.has_permission(doctype, doc=docname, ptype="write"):
|
||||
frappe.throw(_("You don't have permission to delete this attachment"), frappe.PermissionError)
|
||||
|
||||
file_name = frappe.db.get_value(
|
||||
"File",
|
||||
{"file_url": file_url, "attached_to_doctype": doctype, "attached_to_name": docname},
|
||||
"name",
|
||||
)
|
||||
if file_name:
|
||||
frappe.delete_doc("File", file_name)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_file_uploader_defaults(doctype: str):
|
||||
max_number_of_files = None
|
||||
make_attachments_public = False
|
||||
if doctype:
|
||||
meta = frappe.get_meta(doctype)
|
||||
max_number_of_files = meta.get("max_attachments")
|
||||
make_attachments_public = meta.get("make_attachments_public")
|
||||
|
||||
return {
|
||||
"allowed_file_types": frappe.get_system_settings("allowed_file_extensions"),
|
||||
"max_file_size": get_max_file_size(),
|
||||
"max_number_of_files": max_number_of_files,
|
||||
"make_attachments_public": bool(make_attachments_public),
|
||||
}
|
||||
Reference in New Issue
Block a user