Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
bf54160
Enhancements
Altrix-One Nov 7, 2025
d3ba1b2
Update features for auto update fields
Altrix-One Nov 7, 2025
b147a19
Update form validations
Altrix-One Nov 7, 2025
da099ff
Whitelist
Altrix-One Nov 7, 2025
66e7adf
Update form settings
Altrix-One Nov 7, 2025
5a4cdc3
Update form view
Altrix-One Nov 7, 2025
de0c40e
Fix preview
Altrix-One Nov 7, 2025
56d3044
Update styling
Altrix-One Nov 7, 2025
2e2c16b
Image
Altrix-One Nov 7, 2025
3068cf4
logo
Altrix-One Nov 8, 2025
0e48458
Fixed calendar view
Altrix-One Nov 8, 2025
173afdd
additional Field options
Altrix-One Nov 8, 2025
22375f4
Update available fields
Altrix-One Nov 8, 2025
7bd7d4d
Update Routes
Altrix-One Nov 8, 2025
d4cdd50
Chadcn
Altrix-One Nov 8, 2025
40b1c03
Update chadcn components
Altrix-One Nov 8, 2025
e63922c
Dashboard
Altrix-One Nov 8, 2025
89c0d08
Frontend Changes
Altrix-One Nov 8, 2025
bbfe81d
Update mobile view
Altrix-One Nov 8, 2025
7a0303f
Update form
Altrix-One Nov 8, 2025
775b177
Update guest user
Altrix-One Nov 8, 2025
b4006dd
Cache
Altrix-One Nov 8, 2025
40b0562
Update frontend
Altrix-One Nov 8, 2025
fb010e2
Signature
Altrix-One Nov 8, 2025
fb508fb
Update catergories
Altrix-One Nov 8, 2025
8dbcff6
Update categories
Altrix-One Nov 8, 2025
a3425e9
form List
Altrix-One Nov 8, 2025
6afd2b5
Update File Uploader
Altrix-One Nov 8, 2025
6a4ca8e
Update siganture
Altrix-One Nov 8, 2025
7e444c0
Fixed Signature
Altrix-One Nov 8, 2025
e01f7c2
Update fields
Altrix-One Nov 8, 2025
f7d7b55
Update Forms
Altrix-One Nov 8, 2025
7fde4c2
Update validations
Altrix-One Nov 8, 2025
2b3cb7b
Update
Altrix-One Nov 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions forms_pro/api/category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Copyright (c) 2025, harsh@buildwithhussain.com and contributors
# For license information, please see license.txt

import frappe
from frappe import _


@frappe.whitelist()
def get_categories() -> list[dict]:
"""Get all categories with form counts"""
categories = frappe.get_all(
"Form Category",
fields=["name", "title", "description", "color", "order"],
order_by="COALESCE(`order`, 999999), title ASC"
)

# Get form counts for each category
for category in categories:
form_count = frappe.db.count("Form", {"category": category.name})
category["form_count"] = form_count

return categories


@frappe.whitelist()
def create_category(title: str, description: str = None, color: str = None, order: int = None) -> dict:
"""Create a new category"""
category = frappe.get_doc({
"doctype": "Form Category",
"title": title,
"description": description,
"color": color,
"order": order,
})
category.insert()
return {
"name": category.name,
"title": category.title,
"description": category.description,
"color": category.color,
"order": category.order,
}


@frappe.whitelist()
def update_category(category_id: str, title: str = None, description: str = None, color: str = None, order: int = None) -> dict:
"""Update an existing category"""
category = frappe.get_doc("Form Category", category_id)

if title is not None:
category.title = title
if description is not None:
category.description = description
if color is not None:
category.color = color
if order is not None:
category.order = order

category.save()
return {
"name": category.name,
"title": category.title,
"description": category.description,
"color": category.color,
"order": category.order,
}


@frappe.whitelist()
def delete_category(category_id: str) -> dict:
"""Delete a category"""
# Check if any forms are using this category
form_count = frappe.db.count("Form", {"category": category_id})
if form_count > 0:
frappe.throw(
_("Cannot delete category. {0} form(s) are using this category.").format(form_count),
frappe.ValidationError
)

category = frappe.get_doc("Form Category", category_id)
category.delete()
return {"success": True}


@frappe.whitelist()
def get_forms_by_category(category_id: str = None) -> list[dict]:
"""Get forms grouped by category, or forms for a specific category"""
if category_id:
# Get forms for a specific category
forms = frappe.get_all(
"Form",
filters={"category": category_id, "owner": frappe.session.user},
fields=["name", "title", "is_published", "route", "creation", "modified"],
order_by="modified DESC"
)
return forms
else:
# Get all categories with their forms
categories = get_categories()
result = []

for category in categories:
forms = frappe.get_all(
"Form",
filters={"category": category.name, "owner": frappe.session.user},
fields=["name", "title", "is_published", "route", "creation", "modified"],
order_by="modified DESC"
)
result.append({
**category,
"forms": forms
})

# Also get uncategorized forms
uncategorized_forms = frappe.get_all(
"Form",
filters={"category": ["in", ["", None]], "owner": frappe.session.user},
fields=["name", "title", "is_published", "route", "creation", "modified"],
order_by="modified DESC"
)

if uncategorized_forms:
result.append({
"name": None,
"title": "Uncategorized",
"description": None,
"color": None,
"order": 999999,
"form_count": len(uncategorized_forms),
"forms": uncategorized_forms
})

return result

Loading