From 3b7d4db9840256330302146e83dfac665551b17f Mon Sep 17 00:00:00 2001 From: Sabu Siyad Date: Wed, 2 Aug 2023 20:41:17 +0530 Subject: [PATCH 01/20] refactor: custom fields --- desk/src/components/EmptyMessage.vue | 4 +- desk/src/pages/portal/TicketNew.vue | 146 +++++++++--------- .../doctype/hd_ticket_template/api.py | 48 ++++++ .../hd_ticket_template.json | 23 ++- .../hd_ticket_template/hd_ticket_template.py | 34 ++-- .../hd_ticket_template_field/__init__.py | 0 .../hd_ticket_template_field.js | 8 + .../hd_ticket_template_field.json | 55 +++++++ .../hd_ticket_template_field.py | 9 ++ .../test_hd_ticket_template_field.py | 9 ++ 10 files changed, 239 insertions(+), 97 deletions(-) create mode 100644 helpdesk/helpdesk/doctype/hd_ticket_template/api.py create mode 100644 helpdesk/helpdesk/doctype/hd_ticket_template_field/__init__.py create mode 100644 helpdesk/helpdesk/doctype/hd_ticket_template_field/hd_ticket_template_field.js create mode 100644 helpdesk/helpdesk/doctype/hd_ticket_template_field/hd_ticket_template_field.json create mode 100644 helpdesk/helpdesk/doctype/hd_ticket_template_field/hd_ticket_template_field.py create mode 100644 helpdesk/helpdesk/doctype/hd_ticket_template_field/test_hd_ticket_template_field.py diff --git a/desk/src/components/EmptyMessage.vue b/desk/src/components/EmptyMessage.vue index 24daab63b..f01bfe08e 100644 --- a/desk/src/components/EmptyMessage.vue +++ b/desk/src/components/EmptyMessage.vue @@ -1,6 +1,6 @@ + + diff --git a/desk/src/pages/portal/TicketNew.vue b/desk/src/pages/portal/TicketNew.vue index a0c8a8bb4..0db8e8882 100644 --- a/desk/src/pages/portal/TicketNew.vue +++ b/desk/src/pages/portal/TicketNew.vue @@ -8,43 +8,13 @@ v-html="sanitize(template.data.about)" />
-
-
{{ field.label }}
-
- -
-
- -
-
- -
-
- -
-
+ :field="field" + :value="customFields[field.fieldname]" + @change="customFields[field.fieldname] = $event.value" + />
@@ -102,14 +72,7 @@ diff --git a/desk/src/types.ts b/desk/src/types.ts index 4e2b4821b..01d2fe113 100644 --- a/desk/src/types.ts +++ b/desk/src/types.ts @@ -66,12 +66,11 @@ export interface Ticket { subject: string; ticket_type: string; via_customer_portal: string; - template: string; contact: Contact; comments: Comment[]; communications: Communication[]; history: Activity[]; - custom_fields: CustomField[]; + template: Template; views: ViewLog[]; } @@ -89,3 +88,20 @@ export interface Filter { operator: string; value: boolean | number | string; } + +export interface Field { + fieldname: string; + fieldtype: string; + hide_from_customer: 0 | 1; + label: string; + options: string; + required: 0 | 1; + description?: null; + documentation_url?: null; + url_method?: string; +} + +export interface Template { + about: string; + fields: Field[]; +} diff --git a/helpdesk/helpdesk/doctype/hd_ticket/api.py b/helpdesk/helpdesk/doctype/hd_ticket/api.py index f65274852..3b739c2d2 100644 --- a/helpdesk/helpdesk/doctype/hd_ticket/api.py +++ b/helpdesk/helpdesk/doctype/hd_ticket/api.py @@ -3,7 +3,17 @@ from frappe.utils.caching import redis_cache from pypika import Criterion, Order -from helpdesk.utils import get_customer, is_agent, check_permissions +from helpdesk.helpdesk.doctype.hd_ticket_template.api import get_one as get_template +from helpdesk.utils import check_permissions, get_customer, is_agent + + +@frappe.whitelist() +def new(doc, attachments=[]): + doc["doctype"] = "HD Ticket" + doc["via_customer_portal"] = bool(frappe.session.user) + d = frappe.get_doc(doc).insert() + d.create_communication_via_contact(d.description, attachments) + return d @frappe.whitelist() @@ -13,7 +23,6 @@ def get_one(name): QBComment = frappe.qb.DocType("HD Ticket Comment") QBCommunication = frappe.qb.DocType("Communication") QBContact = frappe.qb.DocType("Contact") - QBCustomField = frappe.qb.DocType("HD Ticket Custom Field") QBTicket = frappe.qb.DocType("HD Ticket") QBViewLog = frappe.qb.DocType("View Log") @@ -21,23 +30,7 @@ def get_one(name): query = ( frappe.qb.from_(QBTicket) - .select( - QBTicket._assign, - QBTicket.agent_group, - QBTicket.contact, - QBTicket.customer, - QBTicket.modified, - QBTicket.name, - QBTicket.priority, - QBTicket.raised_by, - QBTicket.resolution_by, - QBTicket.response_by, - QBTicket.status, - QBTicket.subject, - QBTicket.ticket_type, - QBTicket.via_customer_portal, - QBTicket.template, - ) + .select(QBTicket.star) .where(QBTicket.name == name) .limit(1) ) @@ -116,25 +109,26 @@ def get_one(name): .where(QBViewLog.reference_name == name) .orderby(QBViewLog.creation, order=Order.desc) ) - custom_fields = ( - frappe.qb.from_(QBCustomField) - .select( - QBCustomField.fieldname, - QBCustomField.label, - QBCustomField.value, - QBCustomField.route, - ) - .where(QBCustomField.parent == name) - .where(QBCustomField.parentfield == "custom_fields") - .where(QBCustomField.parenttype == "HD Ticket") - .run(as_dict=True) - ) + # custom_fields = ( + # frappe.qb.from_(QBCustomField) + # .select( + # QBCustomField.fieldname, + # QBCustomField.label, + # QBCustomField.value, + # QBCustomField.route, + # ) + # .where(QBCustomField.parent == name) + # .where(QBCustomField.parentfield == "custom_fields") + # .where(QBCustomField.parenttype == "HD Ticket") + # .run(as_dict=True) + # ) return { **ticket, "communications": communications, "contact": contact, - "custom_fields": custom_fields, + # "custom_fields": custom_fields, + "template": get_template(ticket.template) if ticket.template else None, "comments": comments.run(as_dict=True) if _is_agent else [], "history": history.run(as_dict=True) if _is_agent else [], "views": views.run(as_dict=True) if _is_agent else [], From 921d85e87ee5efd0675477e2852f3f76491e799c Mon Sep 17 00:00:00 2001 From: Sabu Siyad Date: Fri, 4 Aug 2023 00:33:08 +0530 Subject: [PATCH 03/20] fix: fetch from custom docfield table --- desk/src/types.ts | 1 - helpdesk/helpdesk/doctype/hd_ticket_template/api.py | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/desk/src/types.ts b/desk/src/types.ts index 01d2fe113..c627445aa 100644 --- a/desk/src/types.ts +++ b/desk/src/types.ts @@ -97,7 +97,6 @@ export interface Field { options: string; required: 0 | 1; description?: null; - documentation_url?: null; url_method?: string; } diff --git a/helpdesk/helpdesk/doctype/hd_ticket_template/api.py b/helpdesk/helpdesk/doctype/hd_ticket_template/api.py index 6bbe7bbf8..ebfde1c6a 100644 --- a/helpdesk/helpdesk/doctype/hd_ticket_template/api.py +++ b/helpdesk/helpdesk/doctype/hd_ticket_template/api.py @@ -15,7 +15,7 @@ def get_one(name: str): if not found: frappe.throw(_("Template not found"), frappe.DoesNotExistError) QBField = frappe.qb.DocType(DOCTYPE_TEMPLATE_FIELD) - QBDocField = frappe.qb.DocType("DocField") + QBDocField = frappe.qb.DocType("Custom Field") fields = ( frappe.qb.from_(QBField) .select(QBField.star) @@ -27,7 +27,6 @@ def get_one(name: str): frappe.qb.from_(fields) .select( QBDocField.description, - QBDocField.documentation_url, QBDocField.fieldtype, QBDocField.label, QBDocField.options, @@ -38,7 +37,7 @@ def get_one(name: str): ) .join(QBDocField, JoinType.inner) .on(QBDocField.fieldname == fields.fieldname) - .where(QBDocField.parent == "HD Ticket") + .where(QBDocField.dt == "HD Ticket") .run(as_dict=True) ) From 0db0ba6d9e702143d68825cf24a129551942b282 Mon Sep 17 00:00:00 2001 From: Sabu Siyad Date: Fri, 4 Aug 2023 00:43:24 +0530 Subject: [PATCH 04/20] fix: component selection logic --- desk/src/components/UniInput.vue | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/desk/src/components/UniInput.vue b/desk/src/components/UniInput.vue index eed3b30da..c0bc07215 100644 --- a/desk/src/components/UniInput.vue +++ b/desk/src/components/UniInput.vue @@ -6,8 +6,6 @@
- - From 5c78785077a1d9f18b18051c7c07a496e7575c16 Mon Sep 17 00:00:00 2001 From: Sabu Siyad Date: Fri, 4 Aug 2023 01:46:38 +0530 Subject: [PATCH 08/20] feat: template: verify if fields exist --- .../hd_ticket_template/hd_ticket_template.py | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py b/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py index fd3e4a64e..c36bef047 100644 --- a/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py +++ b/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py @@ -2,25 +2,22 @@ # For license information, please see license.txt import frappe +from frappe import _ from frappe.model.document import Document -from frappe.website.utils import cleanup_page_name class HDTicketTemplate(Document): - # def validate(self): - # allowed_field_types = [ - # "Link", - # "Select", - # ] - # - # for field in self.fields: - # if field.fieldtype not in allowed_field_types: - # frappe.throw( - # f"Type {field.fieldtype} not allowed, should be in {allowed_field_types}" - # ) - # if not field.fieldname: - # field.fieldname = cleanup_page_name(field.label) - # - # if field.fieldname == "description" and field.fieldtype != "Text Editor": - # frappe.throw("field type for description field should be Text Editor") - pass + def validate(self): + self.verify_field_exists() + + def verify_field_exists(self): + for f in self.fields: + docfield_exits = frappe.db.exists( + {"doctype": "DocField", "fieldname": f.fieldname, "parent": "HD Ticket"} + ) + custom_field_exists = frappe.db.exists( + {"doctype": "Custom Field", "fieldname": f.fieldname, "dt": "HD Ticket"} + ) + if not docfield_exits and not custom_field_exists: + text = _(f"Field `{f.fieldname}` does not exist in Ticket") + frappe.throw(text, frappe.DoesNotExistError) From 302cf82ca572cfd0368f2c837f2a4b5bb7619969 Mon Sep 17 00:00:00 2001 From: Sabu Siyad Date: Fri, 4 Aug 2023 01:50:45 +0530 Subject: [PATCH 09/20] fix: translate string arg https://frappeframework.com/docs/user/en/translations#2-variables --- .../helpdesk/doctype/hd_ticket_template/hd_ticket_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py b/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py index c36bef047..f0bb7dbfc 100644 --- a/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py +++ b/helpdesk/helpdesk/doctype/hd_ticket_template/hd_ticket_template.py @@ -19,5 +19,5 @@ def verify_field_exists(self): {"doctype": "Custom Field", "fieldname": f.fieldname, "dt": "HD Ticket"} ) if not docfield_exits and not custom_field_exists: - text = _(f"Field `{f.fieldname}` does not exist in Ticket") + text = _("Field `{0}` does not exist in Ticket").format(f.fieldname) frappe.throw(text, frappe.DoesNotExistError) From d76562120559ef92428e24f0991147de5fb0f1eb Mon Sep 17 00:00:00 2001 From: Sabu Siyad Date: Fri, 4 Aug 2023 02:03:03 +0530 Subject: [PATCH 10/20] chore: remove dead code --- desk/src/pages/desk/ticket/TicketDetails.vue | 15 ------------ helpdesk/helpdesk/doctype/hd_ticket/api.py | 24 -------------------- 2 files changed, 39 deletions(-) diff --git a/desk/src/pages/desk/ticket/TicketDetails.vue b/desk/src/pages/desk/ticket/TicketDetails.vue index db47f8ba0..788093bb4 100644 --- a/desk/src/pages/desk/ticket/TicketDetails.vue +++ b/desk/src/pages/desk/ticket/TicketDetails.vue @@ -176,21 +176,6 @@ function update(fieldname: string, value: string) { }, }); } - -function updateCustomField({ fieldname, value }) { - call("helpdesk.helpdesk.doctype.hd_ticket.api.update_custom_field", { - ticket_name: data.value.name, - fieldname, - value, - }).then(() => { - emitter.emit("update:ticket"); - createToast({ - title: "Ticket updated", - icon: "check", - iconClasses: "text-green-600", - }); - }); -}