diff --git a/crm/fcrm/doctype/crm_deal/crm_deal.js b/crm/fcrm/doctype/crm_deal/crm_deal.js index 944ac6d4..3526767a 100644 --- a/crm/fcrm/doctype/crm_deal/crm_deal.js +++ b/crm/fcrm/doctype/crm_deal/crm_deal.js @@ -5,4 +5,68 @@ frappe.ui.form.on("CRM Deal", { refresh(frm) { frm.add_web_link(`/crm/deals/${frm.doc.name}`, __("Open in Portal")); }, + update_total: function (frm) { + let total = 0; + let total_qty = 0; + let net_total = 0; + frm.doc.products.forEach((d) => { + total += d.amount; + total_qty += d.qty; + net_total += d.net_amount; + }); + + frappe.model.set_value(frm.doctype, frm.docname, "total", total); + frappe.model.set_value( + frm.doctype, + frm.docname, + "net_total", + net_total || total + ); + } +}); + +frappe.ui.form.on("CRM Products", { + products_add: function (frm, cdt, cdn) { + frm.trigger("update_total"); + }, + products_remove: function (frm, cdt, cdn) { + frm.trigger("update_total"); + }, + product_code: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + frappe.model.set_value(cdt, cdn, "product_name", d.product_code); + }, + rate: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + if (d.rate && d.qty) { + frappe.model.set_value(cdt, cdn, "amount", d.rate * d.qty); + } + frm.trigger("update_total"); + }, + qty: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + if (d.rate && d.qty) { + frappe.model.set_value(cdt, cdn, "amount", d.rate * d.qty); + } + frm.trigger("update_total"); + }, + discount_percentage: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + if (d.discount_percentage && d.amount) { + discount_amount = (d.discount_percentage / 100) * d.amount; + frappe.model.set_value( + cdt, + cdn, + "discount_amount", + discount_amount + ); + frappe.model.set_value( + cdt, + cdn, + "net_amount", + d.amount - discount_amount + ); + } + frm.trigger("update_total"); + } }); diff --git a/crm/fcrm/doctype/crm_deal/crm_deal.json b/crm/fcrm/doctype/crm_deal/crm_deal.json index 133630ce..67f441c3 100644 --- a/crm/fcrm/doctype/crm_deal/crm_deal.json +++ b/crm/fcrm/doctype/crm_deal/crm_deal.json @@ -43,6 +43,12 @@ "mobile_no", "phone", "gender", + "products_tab", + "products", + "section_break_ccbj", + "total", + "column_break_udbq", + "net_total", "sla_tab", "sla", "sla_creation", @@ -334,11 +340,46 @@ "fieldtype": "Link", "label": "Currency", "options": "Currency" + }, + { + "fieldname": "products_tab", + "fieldtype": "Tab Break", + "label": "Products" + }, + { + "fieldname": "products", + "fieldtype": "Table", + "label": "Products", + "options": "CRM Products" + }, + { + "fieldname": "section_break_ccbj", + "fieldtype": "Section Break" + }, + { + "fieldname": "column_break_udbq", + "fieldtype": "Column Break" + }, + { + "fieldname": "total", + "fieldtype": "Currency", + "label": "Total", + "options": "currency", + "read_only": 1 + }, + { + "description": "Total after discount", + "fieldname": "net_total", + "fieldtype": "Currency", + "label": "Net Total", + "options": "currency", + "read_only": 1 } ], + "grid_page_length": 50, "index_web_pages_for_search": 1, "links": [], - "modified": "2024-12-11 14:31:41.058895", + "modified": "2025-05-12 12:30:55.415282", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Deal", @@ -370,10 +411,11 @@ "write": 1 } ], + "row_format": "Dynamic", "show_title_field_in_link": 1, "sort_field": "modified", "sort_order": "DESC", "states": [], "title_field": "organization", "track_changes": 1 -} \ No newline at end of file +} diff --git a/crm/fcrm/doctype/crm_fields_layout/crm_fields_layout.py b/crm/fcrm/doctype/crm_fields_layout/crm_fields_layout.py index e44e3e20..1fd85824 100644 --- a/crm/fcrm/doctype/crm_fields_layout/crm_fields_layout.py +++ b/crm/fcrm/doctype/crm_fields_layout/crm_fields_layout.py @@ -27,7 +27,9 @@ def get_fields_layout(doctype: str, type: str, parent_doctype: str | None = None if not tabs and type != "Required Fields": tabs = get_default_layout(doctype) - has_tabs = tabs[0].get("sections") if tabs and tabs[0] else False + has_tabs = False + if isinstance(tabs, list) and len(tabs) > 0 and isinstance(tabs[0], dict): + has_tabs = any("sections" in tab for tab in tabs) if not has_tabs: tabs = [{"name": "first_tab", "sections": tabs}] @@ -47,7 +49,10 @@ def get_fields_layout(doctype: str, type: str, parent_doctype: str | None = None for tab in tabs: for section in tab.get("sections"): + if section.get("columns"): + section["columns"] = [column for column in section.get("columns") if column] for column in section.get("columns") if section.get("columns") else []: + column["fields"] = [field for field in column.get("fields") if field] for field in column.get("fields") if column.get("fields") else []: field = next((f for f in fields if f.fieldname == field), None) if field: diff --git a/crm/fcrm/doctype/crm_lead/crm_lead.js b/crm/fcrm/doctype/crm_lead/crm_lead.js index 0a9d57e1..af944f40 100644 --- a/crm/fcrm/doctype/crm_lead/crm_lead.js +++ b/crm/fcrm/doctype/crm_lead/crm_lead.js @@ -5,4 +5,68 @@ frappe.ui.form.on("CRM Lead", { refresh(frm) { frm.add_web_link(`/crm/leads/${frm.doc.name}`, __("Open in Portal")); }, + update_total: function (frm) { + let total = 0; + let total_qty = 0; + let net_total = 0; + frm.doc.products.forEach((d) => { + total += d.amount; + total_qty += d.qty; + net_total += d.net_amount; + }); + + frappe.model.set_value(frm.doctype, frm.docname, "total", total); + frappe.model.set_value( + frm.doctype, + frm.docname, + "net_total", + net_total || total + ); + } }); + +frappe.ui.form.on("CRM Products", { + products_add: function (frm, cdt, cdn) { + frm.trigger("update_total"); + }, + products_remove: function (frm, cdt, cdn) { + frm.trigger("update_total"); + }, + product_code: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + frappe.model.set_value(cdt, cdn, "product_name", d.product_code); + }, + rate: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + if (d.rate && d.qty) { + frappe.model.set_value(cdt, cdn, "amount", d.rate * d.qty); + } + frm.trigger("update_total"); + }, + qty: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + if (d.rate && d.qty) { + frappe.model.set_value(cdt, cdn, "amount", d.rate * d.qty); + } + frm.trigger("update_total"); + }, + discount_percentage: function (frm, cdt, cdn) { + let d = frappe.get_doc(cdt, cdn); + if (d.discount_percentage && d.amount) { + discount_amount = (d.discount_percentage / 100) * d.amount; + frappe.model.set_value( + cdt, + cdn, + "discount_amount", + discount_amount + ); + frappe.model.set_value( + cdt, + cdn, + "net_amount", + d.amount - discount_amount + ); + } + frm.trigger("update_total"); + } +}); \ No newline at end of file diff --git a/crm/fcrm/doctype/crm_lead/crm_lead.json b/crm/fcrm/doctype/crm_lead/crm_lead.json index e39af407..a9c25416 100644 --- a/crm/fcrm/doctype/crm_lead/crm_lead.json +++ b/crm/fcrm/doctype/crm_lead/crm_lead.json @@ -37,6 +37,12 @@ "annual_revenue", "image", "converted", + "products_tab", + "products", + "section_break_ggwh", + "total", + "column_break_uisv", + "net_total", "sla_tab", "sla", "sla_creation", @@ -285,12 +291,47 @@ "fieldtype": "Table", "label": "Status Change Log", "options": "CRM Status Change Log" + }, + { + "fieldname": "products_tab", + "fieldtype": "Tab Break", + "label": "Products" + }, + { + "fieldname": "products", + "fieldtype": "Table", + "label": "Products", + "options": "CRM Products" + }, + { + "fieldname": "section_break_ggwh", + "fieldtype": "Section Break" + }, + { + "fieldname": "total", + "fieldtype": "Currency", + "label": "Total", + "options": "currency", + "read_only": 1 + }, + { + "fieldname": "column_break_uisv", + "fieldtype": "Column Break" + }, + { + "description": "Total after discount", + "fieldname": "net_total", + "fieldtype": "Currency", + "label": "Net Total", + "options": "currency", + "read_only": 1 } ], + "grid_page_length": 50, "image_field": "image", "index_web_pages_for_search": 1, "links": [], - "modified": "2025-01-02 22:14:01.991054", + "modified": "2025-05-14 19:51:06.184569", "modified_by": "Administrator", "module": "FCRM", "name": "CRM Lead", @@ -331,6 +372,7 @@ "share": 1 } ], + "row_format": "Dynamic", "sender_field": "email", "sender_name_field": "first_name", "show_title_field_in_link": 1, @@ -339,4 +381,4 @@ "states": [], "title_field": "lead_name", "track_changes": 1 -} \ No newline at end of file +} diff --git a/crm/fcrm/doctype/crm_product/__init__.py b/crm/fcrm/doctype/crm_product/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/crm/fcrm/doctype/crm_product/crm_product.js b/crm/fcrm/doctype/crm_product/crm_product.js new file mode 100644 index 00000000..66925f81 --- /dev/null +++ b/crm/fcrm/doctype/crm_product/crm_product.js @@ -0,0 +1,9 @@ +// Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on("CRM Product", { + product_code: function (frm) { + if (!frm.doc.product_name) + frm.set_value("product_name", frm.doc.product_code); + } +}); diff --git a/crm/fcrm/doctype/crm_product/crm_product.json b/crm/fcrm/doctype/crm_product/crm_product.json new file mode 100644 index 00000000..18ed3466 --- /dev/null +++ b/crm/fcrm/doctype/crm_product/crm_product.json @@ -0,0 +1,105 @@ +{ + "actions": [], + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:product_code", + "creation": "2025-04-28 11:45:09.309636", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "naming_series", + "product_code", + "product_name", + "column_break_bpdj", + "disabled", + "standard_rate", + "image", + "section_break_rtwm", + "description" + ], + "fields": [ + { + "fieldname": "naming_series", + "fieldtype": "Select", + "label": "Naming Series", + "options": "CRM-PROD-.YYYY.-" + }, + { + "fieldname": "product_code", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Product Code", + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "product_name", + "fieldtype": "Data", + "label": "Product Name" + }, + { + "fieldname": "column_break_bpdj", + "fieldtype": "Column Break" + }, + { + "default": "0", + "fieldname": "disabled", + "fieldtype": "Check", + "label": "Disabled" + }, + { + "fieldname": "image", + "fieldtype": "Attach Image", + "label": "Image" + }, + { + "fieldname": "section_break_rtwm", + "fieldtype": "Section Break" + }, + { + "fieldname": "description", + "fieldtype": "Text Editor", + "label": "Description" + }, + { + "fieldname": "standard_rate", + "fieldtype": "Currency", + "label": "Standard Selling Rate" + } + ], + "grid_page_length": 50, + "image_field": "image", + "index_web_pages_for_search": 1, + "links": [], + "make_attachments_public": 1, + "modified": "2025-04-28 12:47:25.087957", + "modified_by": "Administrator", + "module": "FCRM", + "name": "CRM Product", + "naming_rule": "By fieldname", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "row_format": "Dynamic", + "search_fields": "product_name,description", + "show_name_in_global_search": 1, + "show_preview_popup": 1, + "sort_field": "creation", + "sort_order": "DESC", + "states": [], + "title_field": "product_name", + "track_changes": 1 +} diff --git a/crm/fcrm/doctype/crm_product/crm_product.py b/crm/fcrm/doctype/crm_product/crm_product.py new file mode 100644 index 00000000..a04845e1 --- /dev/null +++ b/crm/fcrm/doctype/crm_product/crm_product.py @@ -0,0 +1,16 @@ +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document + + +class CRMProduct(Document): + def validate(self): + self.set_product_name() + + def set_product_name(self): + if not self.product_name: + self.product_name = self.product_code + else: + self.product_name = self.product_name.strip() diff --git a/crm/fcrm/doctype/crm_product/test_crm_product.py b/crm/fcrm/doctype/crm_product/test_crm_product.py new file mode 100644 index 00000000..c6c8b1fb --- /dev/null +++ b/crm/fcrm/doctype/crm_product/test_crm_product.py @@ -0,0 +1,29 @@ +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests import IntegrationTestCase, UnitTestCase + +# On IntegrationTestCase, the doctype test records and all +# link-field test record dependencies are recursively loaded +# Use these module variables to add/remove to/from that list +EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] +IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] + + +class UnitTestCRMProduct(UnitTestCase): + """ + Unit tests for CRMProduct. + Use this class for testing individual functions and methods. + """ + + pass + + +class IntegrationTestCRMProduct(IntegrationTestCase): + """ + Integration tests for CRMProduct. + Use this class for testing interactions between multiple components. + """ + + pass diff --git a/crm/fcrm/doctype/crm_products/__init__.py b/crm/fcrm/doctype/crm_products/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/crm/fcrm/doctype/crm_products/crm_products.json b/crm/fcrm/doctype/crm_products/crm_products.json new file mode 100644 index 00000000..2d96656b --- /dev/null +++ b/crm/fcrm/doctype/crm_products/crm_products.json @@ -0,0 +1,136 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2025-04-28 12:50:49.812915", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "product_code", + "column_break_gvbc", + "product_name", + "section_break_fnvf", + "qty", + "column_break_ajac", + "rate", + "section_break_olqb", + "discount_percentage", + "column_break_uvra", + "discount_amount", + "section_break_cnpb", + "column_break_pozr", + "amount", + "column_break_ejqw", + "net_amount" + ], + "fields": [ + { + "fieldname": "column_break_gvbc", + "fieldtype": "Column Break" + }, + { + "fieldname": "product_name", + "fieldtype": "Data", + "label": "Product Name", + "reqd": 1 + }, + { + "fieldname": "section_break_fnvf", + "fieldtype": "Section Break" + }, + { + "fieldname": "section_break_olqb", + "fieldtype": "Section Break" + }, + { + "bold": 1, + "fieldname": "discount_percentage", + "fieldtype": "Percent", + "label": "Discount %" + }, + { + "fieldname": "discount_amount", + "fieldtype": "Currency", + "label": "Discount Amount", + "options": "currency", + "read_only": 1 + }, + { + "fieldname": "section_break_cnpb", + "fieldtype": "Section Break" + }, + { + "fieldname": "column_break_pozr", + "fieldtype": "Column Break" + }, + { + "bold": 1, + "fieldname": "rate", + "fieldtype": "Currency", + "in_list_view": 1, + "label": "Rate", + "options": "currency", + "reqd": 1 + }, + { + "bold": 1, + "fieldname": "amount", + "fieldtype": "Currency", + "label": "Amount", + "options": "currency", + "read_only": 1 + }, + { + "bold": 1, + "depends_on": "discount_percentage", + "description": "Amount after discount", + "fieldname": "net_amount", + "fieldtype": "Currency", + "label": "Net Amount", + "options": "currency", + "read_only": 1 + }, + { + "bold": 1, + "columns": 5, + "fieldname": "product_code", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Product", + "options": "CRM Product" + }, + { + "bold": 1, + "default": "1", + "fieldname": "qty", + "fieldtype": "Float", + "label": "Quantity" + }, + { + "fieldname": "column_break_ajac", + "fieldtype": "Column Break" + }, + { + "fieldname": "column_break_uvra", + "fieldtype": "Column Break" + }, + { + "fieldname": "column_break_ejqw", + "fieldtype": "Column Break" + } + ], + "grid_page_length": 50, + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2025-05-14 18:52:26.183306", + "modified_by": "Administrator", + "module": "FCRM", + "name": "CRM Products", + "owner": "Administrator", + "permissions": [], + "row_format": "Dynamic", + "sort_field": "creation", + "sort_order": "DESC", + "states": [] +} diff --git a/crm/fcrm/doctype/crm_products/crm_products.py b/crm/fcrm/doctype/crm_products/crm_products.py new file mode 100644 index 00000000..59f28e5c --- /dev/null +++ b/crm/fcrm/doctype/crm_products/crm_products.py @@ -0,0 +1,110 @@ +# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document + + +class CRMProducts(Document): + pass + + +def create_product_details_script(doctype): + if not frappe.db.exists("CRM Form Script", "Product Details Script for " + doctype): + script = get_product_details_script(doctype) + frappe.get_doc( + { + "doctype": "CRM Form Script", + "name": "Product Details Script for " + doctype, + "dt": doctype, + "view": "Form", + "script": script, + "enabled": 1, + "is_standard": 1, + } + ).insert() + + +def get_product_details_script(doctype): + doctype_class = "class " + doctype.replace(" ", "") + + return ( + doctype_class + + " {" + + """ + update_total() { + let total = 0 + let total_qty = 0 + let net_total = 0 + let discount_applied = false + + this.doc.products.forEach((d) => { + total += d.amount + net_total += d.net_amount + if (d.discount_percentage > 0) { + discount_applied = true + } + }) + + this.doc.total = total + this.doc.net_total = net_total || total + + if (!net_total && discount_applied) { + this.doc.net_total = net_total + } + } +} + +class CRMProducts { + products_add() { + let row = this.doc.getRow('products') + row.trigger('qty') + this.doc.trigger('update_total') + } + + products_remove() { + this.doc.trigger('update_total') + } + + async product_code(idx) { + let row = this.doc.getRow('products', idx) + + let a = await call("frappe.client.get_value", { + doctype: "CRM Product", + filters: { name: row.product_code }, + fieldname: ["product_name", "standard_rate"], + }) + + row.product_name = a.product_name + if (a.standard_rate && !row.rate) { + row.rate = a.standard_rate + row.trigger("rate") + } + } + + qty(idx) { + let row = this.doc.getRow('products', idx) + row.amount = row.qty * row.rate + row.trigger('discount_percentage', idx) + } + + rate() { + let row = this.doc.getRow('products') + row.amount = row.qty * row.rate + row.trigger('discount_percentage') + } + + discount_percentage(idx) { + let row = this.doc.getRow('products', idx) + if (!row.discount_percentage) { + row.net_amount = row.amount + row.discount_amount = 0 + } + if (row.discount_percentage && row.amount) { + row.discount_amount = (row.discount_percentage / 100) * row.amount + row.net_amount = row.amount - row.discount_amount + } + this.doc.trigger('update_total') + } +}""" + ) diff --git a/crm/install.py b/crm/install.py index 1e0d816f..5f25e7d0 100644 --- a/crm/install.py +++ b/crm/install.py @@ -4,6 +4,8 @@ import click import frappe from frappe.custom.doctype.custom_field.custom_field import create_custom_fields +from crm.fcrm.doctype.crm_products.crm_products import create_product_details_script + def before_install(): pass @@ -19,6 +21,7 @@ def after_install(force=False): add_default_industries() add_default_lead_sources() add_standard_dropdown_items() + add_default_scripts() frappe.db.commit() @@ -353,3 +356,8 @@ def add_standard_dropdown_items(): crm_settings.append("dropdown_items", item) crm_settings.save() + + +def add_default_scripts(): + for doctype in ["CRM Lead", "CRM Deal"]: + create_product_details_script(doctype) diff --git a/crm/locale/main.pot b/crm/locale/main.pot index 499aeadb..2685876b 100644 --- a/crm/locale/main.pot +++ b/crm/locale/main.pot @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: Frappe CRM VERSION\n" "Report-Msgid-Bugs-To: shariq@frappe.io\n" -"POT-Creation-Date: 2025-04-20 09:35+0000\n" -"PO-Revision-Date: 2025-04-20 09:35+0000\n" +"POT-Creation-Date: 2025-05-04 09:35+0000\n" +"PO-Revision-Date: 2025-05-04 09:35+0000\n" "Last-Translator: shariq@frappe.io\n" "Language-Team: shariq@frappe.io\n" "MIME-Version: 1.0\n" @@ -121,6 +121,10 @@ msgstr "" msgid "API Key" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:179 +msgid "API Key is required" +msgstr "" + #. Label of the api_secret (Password) field in DocType 'CRM Twilio Settings' #. Label of the api_secret (Password) field in DocType 'ERPNext CRM Settings' #: crm/fcrm/doctype/crm_twilio_settings/crm_twilio_settings.json @@ -151,6 +155,10 @@ msgstr "" msgid "Accepted At" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:13 +msgid "Account Name" +msgstr "" + #. Label of the account_sid (Data) field in DocType 'CRM Exotel Settings' #. Label of the account_sid (Data) field in DocType 'CRM Twilio Settings' #: crm/fcrm/doctype/crm_exotel_settings/crm_exotel_settings.json @@ -158,17 +166,25 @@ msgstr "" msgid "Account SID" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:165 +msgid "Account name is required" +msgstr "" + #: frontend/src/components/CustomActions.vue:73 #: frontend/src/components/ViewControls.vue:682 #: frontend/src/components/ViewControls.vue:1111 msgid "Actions" msgstr "" -#: frontend/src/pages/Deal.vue:542 frontend/src/pages/Lead.vue:528 +#: frontend/src/pages/Deal.vue:546 frontend/src/pages/Lead.vue:532 #: frontend/src/pages/MobileDeal.vue:441 frontend/src/pages/MobileLead.vue:344 msgid "Activity" msgstr "" +#: frontend/src/components/Settings/EmailAccountList.vue:9 +msgid "Add Account" +msgstr "" + #: frontend/src/components/ColumnSettings.vue:65 #: frontend/src/components/Kanban/KanbanView.vue:157 msgid "Add Column" @@ -266,9 +282,9 @@ msgstr "" msgid "All" msgstr "" -#: frontend/src/pages/Contact.vue:629 frontend/src/pages/MobileContact.vue:607 +#: frontend/src/pages/Contact.vue:633 frontend/src/pages/MobileContact.vue:607 #: frontend/src/pages/MobileOrganization.vue:493 -#: frontend/src/pages/Organization.vue:528 +#: frontend/src/pages/Organization.vue:532 msgid "Amount" msgstr "" @@ -331,12 +347,12 @@ msgstr "" msgid "Are you sure you want to delete this attachment?" msgstr "" -#: frontend/src/pages/Contact.vue:317 frontend/src/pages/MobileContact.vue:292 +#: frontend/src/pages/Contact.vue:321 frontend/src/pages/MobileContact.vue:292 msgid "Are you sure you want to delete this contact?" msgstr "" #: frontend/src/pages/MobileOrganization.vue:286 -#: frontend/src/pages/Organization.vue:324 +#: frontend/src/pages/Organization.vue:328 msgid "Are you sure you want to delete this organization?" msgstr "" @@ -397,7 +413,7 @@ msgstr "" msgid "Attach a file" msgstr "" -#: frontend/src/pages/Deal.vue:577 frontend/src/pages/Lead.vue:563 +#: frontend/src/pages/Deal.vue:581 frontend/src/pages/Lead.vue:567 #: frontend/src/pages/MobileDeal.vue:477 frontend/src/pages/MobileLead.vue:380 msgid "Attachments" msgstr "" @@ -414,6 +430,7 @@ msgid "BCC" msgstr "" #: frontend/src/components/FilesUploader/FilesUploader.vue:31 +#: frontend/src/components/Settings/EmailEdit.vue:67 msgid "Back" msgstr "" @@ -650,7 +667,7 @@ msgstr "" msgid "Calling..." msgstr "" -#: frontend/src/pages/Deal.vue:562 frontend/src/pages/Lead.vue:548 +#: frontend/src/pages/Deal.vue:566 frontend/src/pages/Lead.vue:552 #: frontend/src/pages/MobileDeal.vue:461 frontend/src/pages/MobileLead.vue:364 msgid "Calls" msgstr "" @@ -706,7 +723,7 @@ msgstr "" msgid "Change image" msgstr "" -#: frontend/src/pages/Lead.vue:241 frontend/src/pages/Lead.vue:267 +#: frontend/src/pages/Lead.vue:245 frontend/src/pages/Lead.vue:271 #: frontend/src/pages/MobileLead.vue:110 frontend/src/pages/MobileLead.vue:137 msgid "Choose Existing" msgstr "" @@ -719,6 +736,10 @@ msgstr "" msgid "Choose Existing Organization" msgstr "" +#: frontend/src/components/Settings/EmailAdd.vue:9 +msgid "Choose the email service provider you want to configure." +msgstr "" + #: frontend/src/components/Controls/Link.vue:60 msgid "Clear" msgstr "" @@ -790,7 +811,7 @@ msgstr "" msgid "Comment" msgstr "" -#: frontend/src/pages/Deal.vue:552 frontend/src/pages/Lead.vue:538 +#: frontend/src/pages/Deal.vue:556 frontend/src/pages/Lead.vue:542 #: frontend/src/pages/MobileDeal.vue:451 frontend/src/pages/MobileLead.vue:354 msgid "Comments" msgstr "" @@ -840,7 +861,7 @@ msgstr "" #: crm/fcrm/doctype/crm_contacts/crm_contacts.json #: crm/fcrm/doctype/crm_deal/crm_deal.json #: frontend/src/components/Layouts/AppSidebar.vue:509 -#: frontend/src/pages/Lead.vue:263 frontend/src/pages/MobileLead.vue:133 +#: frontend/src/pages/Lead.vue:267 frontend/src/pages/MobileLead.vue:133 msgid "Contact" msgstr "" @@ -852,11 +873,11 @@ msgstr "" msgid "Contact Us" msgstr "" -#: frontend/src/pages/Deal.vue:661 frontend/src/pages/MobileDeal.vue:560 +#: frontend/src/pages/Deal.vue:665 frontend/src/pages/MobileDeal.vue:560 msgid "Contact added" msgstr "" -#: frontend/src/pages/Deal.vue:647 frontend/src/pages/MobileDeal.vue:546 +#: frontend/src/pages/Deal.vue:651 frontend/src/pages/MobileDeal.vue:546 msgid "Contact already added" msgstr "" @@ -868,7 +889,7 @@ msgstr "" msgid "Contact not found" msgstr "" -#: frontend/src/pages/Deal.vue:676 frontend/src/pages/MobileDeal.vue:575 +#: frontend/src/pages/Deal.vue:680 frontend/src/pages/MobileDeal.vue:575 msgid "Contact removed" msgstr "" @@ -877,7 +898,7 @@ msgstr "" #. Label of a shortcut in the Frappe CRM Workspace #: crm/fcrm/doctype/crm_deal/crm_deal.json #: crm/fcrm/workspace/frappe_crm/frappe_crm.json -#: frontend/src/pages/Contact.vue:261 frontend/src/pages/MobileContact.vue:236 +#: frontend/src/pages/Contact.vue:265 frontend/src/pages/MobileContact.vue:236 #: frontend/src/pages/MobileOrganization.vue:373 msgid "Contacts" msgstr "" @@ -896,7 +917,7 @@ msgstr "" #: frontend/src/components/Layouts/AppSidebar.vue:351 #: frontend/src/components/ListBulkActions.vue:70 -#: frontend/src/pages/Lead.vue:201 frontend/src/pages/MobileLead.vue:49 +#: frontend/src/pages/Lead.vue:205 frontend/src/pages/MobileLead.vue:49 #: frontend/src/pages/MobileLead.vue:96 msgid "Convert" msgstr "" @@ -908,7 +929,7 @@ msgstr "" #: frontend/src/components/ListBulkActions.vue:62 #: frontend/src/components/ListBulkActions.vue:204 -#: frontend/src/pages/Lead.vue:38 frontend/src/pages/Lead.vue:212 +#: frontend/src/pages/Lead.vue:38 frontend/src/pages/Lead.vue:216 #: frontend/src/pages/MobileLead.vue:92 msgid "Convert to Deal" msgstr "" @@ -1032,7 +1053,7 @@ msgstr "" msgid "Custom statuses" msgstr "" -#: frontend/src/pages/Deal.vue:430 +#: frontend/src/pages/Deal.vue:434 msgid "Customer created successfully" msgstr "" @@ -1046,7 +1067,7 @@ msgstr "" #: frontend/src/components/Activities/DataFields.vue:6 #: frontend/src/components/Layouts/AppSidebar.vue:539 -#: frontend/src/pages/Deal.vue:557 frontend/src/pages/Lead.vue:543 +#: frontend/src/pages/Deal.vue:561 frontend/src/pages/Lead.vue:547 #: frontend/src/pages/MobileDeal.vue:456 frontend/src/pages/MobileLead.vue:359 msgid "Data" msgstr "" @@ -1082,19 +1103,19 @@ msgstr "" msgid "Deal Statuses" msgstr "" -#: frontend/src/pages/Contact.vue:650 frontend/src/pages/MobileContact.vue:628 +#: frontend/src/pages/Contact.vue:654 frontend/src/pages/MobileContact.vue:628 #: frontend/src/pages/MobileOrganization.vue:514 -#: frontend/src/pages/Organization.vue:549 +#: frontend/src/pages/Organization.vue:553 msgid "Deal owner" msgstr "" -#: frontend/src/pages/Deal.vue:470 frontend/src/pages/MobileDeal.vue:363 +#: frontend/src/pages/Deal.vue:474 frontend/src/pages/MobileDeal.vue:363 msgid "Deal updated" msgstr "" #. Label of a shortcut in the Frappe CRM Workspace #: crm/fcrm/workspace/frappe_crm/frappe_crm.json -#: frontend/src/pages/Deal.vue:502 frontend/src/pages/MobileContact.vue:320 +#: frontend/src/pages/Deal.vue:506 frontend/src/pages/MobileContact.vue:320 #: frontend/src/pages/MobileDeal.vue:395 #: frontend/src/pages/MobileOrganization.vue:367 msgid "Deals" @@ -1109,17 +1130,37 @@ msgstr "" msgid "Default" msgstr "" +#: frontend/src/components/Settings/EmailAccountCard.vue:41 +msgid "Default Inbox" +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:44 +msgid "Default Incoming" +msgstr "" + #. Label of the default_medium (Select) field in DocType 'CRM Telephony Agent' #: crm/fcrm/doctype/crm_telephony_agent/crm_telephony_agent.json msgid "Default Medium" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:52 +msgid "Default Outgoing" +msgstr "" + #. Label of the default_priority (Check) field in DocType 'CRM Service Level #. Priority' #: crm/fcrm/doctype/crm_service_level_priority/crm_service_level_priority.json msgid "Default Priority" msgstr "" +#: frontend/src/components/Settings/EmailAccountCard.vue:43 +msgid "Default Sending" +msgstr "" + +#: frontend/src/components/Settings/EmailAccountCard.vue:39 +msgid "Default Sending and Inbox" +msgstr "" + #: crm/fcrm/doctype/crm_service_level_agreement/crm_service_level_agreement.py:33 msgid "Default Service Level Agreement already exists for {0}" msgstr "" @@ -1157,14 +1198,14 @@ msgstr "" #: frontend/src/components/ListBulkActions.vue:186 #: frontend/src/components/ViewControls.vue:1163 #: frontend/src/components/ViewControls.vue:1174 -#: frontend/src/pages/Contact.vue:105 frontend/src/pages/Contact.vue:320 +#: frontend/src/pages/Contact.vue:105 frontend/src/pages/Contact.vue:324 #: frontend/src/pages/MobileContact.vue:81 #: frontend/src/pages/MobileContact.vue:295 #: frontend/src/pages/MobileDeal.vue:526 #: frontend/src/pages/MobileOrganization.vue:72 #: frontend/src/pages/MobileOrganization.vue:289 #: frontend/src/pages/Notes.vue:40 frontend/src/pages/Organization.vue:83 -#: frontend/src/pages/Organization.vue:327 frontend/src/pages/Tasks.vue:368 +#: frontend/src/pages/Organization.vue:331 frontend/src/pages/Tasks.vue:368 msgid "Delete" msgstr "" @@ -1186,12 +1227,12 @@ msgstr "" msgid "Delete attachment" msgstr "" -#: frontend/src/pages/Contact.vue:316 frontend/src/pages/MobileContact.vue:291 +#: frontend/src/pages/Contact.vue:320 frontend/src/pages/MobileContact.vue:291 msgid "Delete contact" msgstr "" #: frontend/src/pages/MobileOrganization.vue:285 -#: frontend/src/pages/Organization.vue:323 +#: frontend/src/pages/Organization.vue:327 msgid "Delete organization" msgstr "" @@ -1357,6 +1398,10 @@ msgstr "" msgid "Edit Data Fields Layout" msgstr "" +#: frontend/src/components/Settings/EmailEdit.vue:6 +msgid "Edit Email" +msgstr "" + #: frontend/src/components/Modals/SidePanelModal.vue:7 msgid "Edit Field Layout" msgstr "" @@ -1409,19 +1454,24 @@ msgstr "" #: crm/fcrm/doctype/crm_contacts/crm_contacts.json #: crm/fcrm/doctype/crm_deal/crm_deal.json #: crm/fcrm/doctype/crm_invitation/crm_invitation.json -#: crm/fcrm/doctype/crm_lead/crm_lead.json frontend/src/pages/Contact.vue:640 +#: crm/fcrm/doctype/crm_lead/crm_lead.json frontend/src/pages/Contact.vue:644 #: frontend/src/pages/MobileContact.vue:618 #: frontend/src/pages/MobileOrganization.vue:504 #: frontend/src/pages/MobileOrganization.vue:532 -#: frontend/src/pages/Organization.vue:539 -#: frontend/src/pages/Organization.vue:567 +#: frontend/src/pages/Organization.vue:543 +#: frontend/src/pages/Organization.vue:571 msgid "Email" msgstr "" +#: frontend/src/components/Settings/EmailAccountList.vue:6 #: frontend/src/components/Settings/Settings.vue:107 msgid "Email Accounts" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:168 +msgid "Email ID is required" +msgstr "" + #. Label of the email_sent_at (Datetime) field in DocType 'CRM Invitation' #: crm/fcrm/doctype/crm_invitation/crm_invitation.json msgid "Email Sent At" @@ -1431,6 +1481,14 @@ msgstr "" msgid "Email Templates" msgstr "" +#: frontend/src/components/Settings/EmailAdd.vue:143 +msgid "Email account created successfully" +msgstr "" + +#: frontend/src/components/Settings/EmailEdit.vue:214 +msgid "Email account updated successfully" +msgstr "" + #: frontend/src/components/Layouts/AppSidebar.vue:537 msgid "Email communication" msgstr "" @@ -1443,7 +1501,7 @@ msgstr "" msgid "Email template" msgstr "" -#: frontend/src/pages/Deal.vue:547 frontend/src/pages/Lead.vue:533 +#: frontend/src/pages/Deal.vue:551 frontend/src/pages/Lead.vue:537 #: frontend/src/pages/MobileDeal.vue:446 frontend/src/pages/MobileLead.vue:349 msgid "Emails" msgstr "" @@ -1464,6 +1522,14 @@ msgstr "" msgid "Enable" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:28 +msgid "Enable Incoming" +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:36 +msgid "Enable Outgoing" +msgstr "" + #. Label of the enabled (Check) field in DocType 'CRM Exotel Settings' #. Label of the enabled (Check) field in DocType 'CRM Form Script' #. Label of the enabled (Check) field in DocType 'CRM Service Level Agreement' @@ -1508,28 +1574,28 @@ msgstr "" #: frontend/src/components/Settings/SettingsPage.vue:91 #: frontend/src/components/Settings/TelephonySettings.vue:131 #: frontend/src/components/Settings/TelephonySettings.vue:156 -#: frontend/src/pages/Lead.vue:629 frontend/src/pages/Lead.vue:639 +#: frontend/src/pages/Lead.vue:633 frontend/src/pages/Lead.vue:643 #: frontend/src/pages/MobileLead.vue:438 frontend/src/pages/MobileLead.vue:448 msgid "Error" msgstr "" -#: frontend/src/pages/Deal.vue:491 frontend/src/pages/MobileDeal.vue:384 +#: frontend/src/pages/Deal.vue:495 frontend/src/pages/MobileDeal.vue:384 msgid "Error Updating Deal" msgstr "" -#: frontend/src/pages/Lead.vue:477 frontend/src/pages/MobileLead.vue:287 +#: frontend/src/pages/Lead.vue:481 frontend/src/pages/MobileLead.vue:287 msgid "Error Updating Lead" msgstr "" -#: frontend/src/pages/Lead.vue:662 +#: frontend/src/pages/Lead.vue:666 msgid "Error converting to deal" msgstr "" -#: frontend/src/pages/Deal.vue:478 frontend/src/pages/MobileDeal.vue:371 +#: frontend/src/pages/Deal.vue:482 frontend/src/pages/MobileDeal.vue:371 msgid "Error updating deal" msgstr "" -#: frontend/src/pages/Lead.vue:464 frontend/src/pages/MobileLead.vue:274 +#: frontend/src/pages/Lead.vue:468 frontend/src/pages/MobileLead.vue:274 msgid "Error updating lead" msgstr "" @@ -1632,10 +1698,18 @@ msgstr "" msgid "Failed to capture Twilio recording" msgstr "" +#: frontend/src/components/Settings/EmailAdd.vue:150 +msgid "Failed to create email account, Invalid credentials" +msgstr "" + #: crm/integrations/twilio/api.py:152 msgid "Failed to update Twilio call status" msgstr "" +#: frontend/src/components/Settings/EmailEdit.vue:222 +msgid "Failed to update email account, Invalid credentials" +msgstr "" + #. Label of the favicon (Attach) field in DocType 'FCRM Settings' #: crm/fcrm/doctype/fcrm_settings/fcrm_settings.json #: frontend/src/components/Settings/GeneralSettings.vue:62 @@ -1888,6 +1962,22 @@ msgstr "" msgid "Icon" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:55 +msgid "If enabled, all outgoing emails will be sent from this account. Note: Only one account can be default outgoing." +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:47 +msgid "If enabled, all replies to your company (eg: replies@yourcomany.com) will come to this account. Note: Only one account can be default incoming." +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:39 +msgid "If enabled, outgoing emails can be sent from this account." +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:31 +msgid "If enabled, records can be created from the incoming emails on this account." +msgstr "" + #. Label of the image (Attach Image) field in DocType 'CRM Lead' #: crm/fcrm/doctype/crm_lead/crm_lead.json msgid "Image" @@ -1916,6 +2006,10 @@ msgstr "" msgid "Inbound Call" msgstr "" +#: frontend/src/components/Settings/EmailAccountCard.vue:45 +msgid "Inbox" +msgstr "" + #. Option for the 'Type' (Select) field in DocType 'CRM Call Log' #: crm/fcrm/doctype/crm_call_log/crm_call_log.json msgid "Incoming" @@ -1984,6 +2078,10 @@ msgstr "" msgid "Invalid credentials" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:172 +msgid "Invalid email ID" +msgstr "" + #: frontend/src/components/Settings/Settings.vue:101 msgid "Invite Members" msgstr "" @@ -2138,11 +2236,11 @@ msgstr "" msgid "Last Year" msgstr "" -#: frontend/src/pages/Contact.vue:655 frontend/src/pages/MobileContact.vue:633 +#: frontend/src/pages/Contact.vue:659 frontend/src/pages/MobileContact.vue:633 #: frontend/src/pages/MobileOrganization.vue:519 #: frontend/src/pages/MobileOrganization.vue:547 -#: frontend/src/pages/Organization.vue:554 -#: frontend/src/pages/Organization.vue:582 +#: frontend/src/pages/Organization.vue:558 +#: frontend/src/pages/Organization.vue:586 msgid "Last modified" msgstr "" @@ -2188,13 +2286,13 @@ msgstr "" msgid "Lead Statuses" msgstr "" -#: frontend/src/pages/Lead.vue:456 frontend/src/pages/MobileLead.vue:266 +#: frontend/src/pages/Lead.vue:460 frontend/src/pages/MobileLead.vue:266 msgid "Lead updated" msgstr "" #. Label of a shortcut in the Frappe CRM Workspace #: crm/fcrm/workspace/frappe_crm/frappe_crm.json -#: frontend/src/pages/Lead.vue:488 frontend/src/pages/MobileLead.vue:298 +#: frontend/src/pages/Lead.vue:492 frontend/src/pages/MobileLead.vue:298 msgid "Leads" msgstr "" @@ -2395,9 +2493,9 @@ msgstr "" msgid "Mobile app installation" msgstr "" -#: frontend/src/pages/Contact.vue:645 frontend/src/pages/MobileContact.vue:623 +#: frontend/src/pages/Contact.vue:649 frontend/src/pages/MobileContact.vue:623 #: frontend/src/pages/MobileOrganization.vue:509 -#: frontend/src/pages/Organization.vue:544 +#: frontend/src/pages/Organization.vue:548 msgid "Mobile no" msgstr "" @@ -2435,7 +2533,7 @@ msgstr "" #: frontend/src/components/Modals/EmailTemplateModal.vue:24 #: frontend/src/components/ViewControls.vue:781 #: frontend/src/pages/MobileOrganization.vue:527 -#: frontend/src/pages/Organization.vue:562 +#: frontend/src/pages/Organization.vue:566 msgid "Name" msgstr "" @@ -2506,11 +2604,11 @@ msgstr "" msgid "New WhatsApp Message" msgstr "" -#: frontend/src/pages/Lead.vue:279 frontend/src/pages/MobileLead.vue:150 +#: frontend/src/pages/Lead.vue:283 frontend/src/pages/MobileLead.vue:150 msgid "New contact will be created based on the person's details" msgstr "" -#: frontend/src/pages/Lead.vue:254 frontend/src/pages/MobileLead.vue:124 +#: frontend/src/pages/Lead.vue:258 frontend/src/pages/MobileLead.vue:124 msgid "New organization will be created based on the data in details section" msgstr "" @@ -2558,6 +2656,10 @@ msgstr "" msgid "No Title" msgstr "" +#: frontend/src/components/Settings/EmailEdit.vue:152 +msgid "No changes made" +msgstr "" + #: frontend/src/components/Modals/SidePanelModal.vue:51 #: frontend/src/pages/Deal.vue:262 frontend/src/pages/MobileDeal.vue:199 msgid "No contacts added" @@ -2571,7 +2673,7 @@ msgstr "" msgid "No label" msgstr "" -#: frontend/src/pages/Deal.vue:722 +#: frontend/src/pages/Deal.vue:726 msgid "No mobile number set" msgstr "" @@ -2584,7 +2686,7 @@ msgstr "" msgid "No phone number set" msgstr "" -#: frontend/src/pages/Deal.vue:717 +#: frontend/src/pages/Deal.vue:721 msgid "No primary contact set" msgstr "" @@ -2675,8 +2777,8 @@ msgstr "" msgid "Not allowed to set primary contact for Deal" msgstr "" -#: frontend/src/pages/Contact.vue:252 frontend/src/pages/Deal.vue:414 -#: frontend/src/pages/Lead.vue:422 frontend/src/pages/Organization.vue:241 +#: frontend/src/pages/Contact.vue:256 frontend/src/pages/Deal.vue:418 +#: frontend/src/pages/Lead.vue:426 frontend/src/pages/Organization.vue:245 msgid "Not permitted" msgstr "" @@ -2686,7 +2788,7 @@ msgstr "" msgid "Note" msgstr "" -#: frontend/src/pages/Deal.vue:572 frontend/src/pages/Lead.vue:558 +#: frontend/src/pages/Deal.vue:576 frontend/src/pages/Lead.vue:562 #: frontend/src/pages/MobileDeal.vue:472 frontend/src/pages/MobileLead.vue:375 msgid "Notes" msgstr "" @@ -2734,10 +2836,10 @@ msgstr "" msgid "Old Parent" msgstr "" -#: frontend/src/pages/Contact.vue:300 frontend/src/pages/Lead.vue:592 +#: frontend/src/pages/Contact.vue:304 frontend/src/pages/Lead.vue:596 #: frontend/src/pages/MobileContact.vue:275 #: frontend/src/pages/MobileOrganization.vue:269 -#: frontend/src/pages/Organization.vue:307 +#: frontend/src/pages/Organization.vue:311 msgid "Only PNG and JPG images are allowed" msgstr "" @@ -2792,13 +2894,13 @@ msgstr "" #: crm/fcrm/doctype/crm_deal/crm_deal.json #: crm/fcrm/doctype/crm_lead/crm_lead.json #: frontend/src/components/Layouts/AppSidebar.vue:510 -#: frontend/src/pages/Contact.vue:624 frontend/src/pages/Lead.vue:237 +#: frontend/src/pages/Contact.vue:628 frontend/src/pages/Lead.vue:241 #: frontend/src/pages/MobileContact.vue:602 #: frontend/src/pages/MobileLead.vue:106 #: frontend/src/pages/MobileOrganization.vue:488 #: frontend/src/pages/MobileOrganization.vue:542 -#: frontend/src/pages/Organization.vue:523 -#: frontend/src/pages/Organization.vue:577 +#: frontend/src/pages/Organization.vue:527 +#: frontend/src/pages/Organization.vue:581 msgid "Organization" msgstr "" @@ -2826,14 +2928,14 @@ msgid "Organization logo" msgstr "" #: frontend/src/pages/MobileOrganization.vue:216 -#: frontend/src/pages/Organization.vue:254 +#: frontend/src/pages/Organization.vue:258 msgid "Organization updated" msgstr "" #. Label of a shortcut in the Frappe CRM Workspace #: crm/fcrm/workspace/frappe_crm/frappe_crm.json #: frontend/src/pages/MobileOrganization.vue:223 -#: frontend/src/pages/Organization.vue:261 +#: frontend/src/pages/Organization.vue:265 msgid "Organizations" msgstr "" @@ -2865,10 +2967,18 @@ msgstr "" msgid "Parent CRM Territory" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:64 +msgid "Password" +msgstr "" + #: crm/api/demo.py:21 crm/api/demo.py:29 msgid "Password cannot be reset by Demo User {}" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:175 +msgid "Password is required" +msgstr "" + #: frontend/src/components/Modals/EmailTemplateModal.vue:23 #: frontend/src/components/Modals/EmailTemplateSelectorModal.vue:11 msgid "Payment Reminder" @@ -2903,7 +3013,7 @@ msgstr "" #: crm/fcrm/doctype/crm_lead/crm_lead.json #: crm/fcrm/doctype/crm_telephony_agent/crm_telephony_agent.json #: frontend/src/pages/MobileOrganization.vue:537 -#: frontend/src/pages/Organization.vue:572 +#: frontend/src/pages/Organization.vue:576 msgid "Phone" msgstr "" @@ -2933,6 +3043,10 @@ msgstr "" msgid "Playback speed" msgstr "" +#: frontend/src/components/Settings/EmailAccountList.vue:34 +msgid "Please add an email account to continue." +msgstr "" + #: crm/integrations/twilio/twilio_handler.py:119 msgid "Please enable twilio settings before making a call." msgstr "" @@ -2941,11 +3055,11 @@ msgstr "" msgid "Please enter a valid URL" msgstr "" -#: frontend/src/pages/Lead.vue:630 frontend/src/pages/MobileLead.vue:439 +#: frontend/src/pages/Lead.vue:634 frontend/src/pages/MobileLead.vue:439 msgid "Please select an existing contact" msgstr "" -#: frontend/src/pages/Lead.vue:640 frontend/src/pages/MobileLead.vue:449 +#: frontend/src/pages/Lead.vue:644 frontend/src/pages/MobileLead.vue:449 msgid "Please select an existing organization" msgstr "" @@ -2964,7 +3078,7 @@ msgstr "" msgid "Primary" msgstr "" -#: frontend/src/pages/Deal.vue:691 frontend/src/pages/MobileDeal.vue:590 +#: frontend/src/pages/Deal.vue:695 frontend/src/pages/MobileDeal.vue:590 msgid "Primary contact set" msgstr "" @@ -3099,7 +3213,7 @@ msgstr "" msgid "Reject" msgstr "" -#: frontend/src/pages/Deal.vue:627 +#: frontend/src/pages/Deal.vue:631 msgid "Remove" msgstr "" @@ -3433,7 +3547,7 @@ msgstr "" msgid "Set an organization" msgstr "" -#: frontend/src/pages/Deal.vue:635 frontend/src/pages/MobileDeal.vue:534 +#: frontend/src/pages/Deal.vue:639 frontend/src/pages/MobileDeal.vue:534 msgid "Set as Primary Contact" msgstr "" @@ -3449,12 +3563,56 @@ msgstr "" msgid "Setting up" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:145 +msgid "Setting up Frappe Mail requires you to have an API key and API Secret of your email account. Read more " +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:97 +msgid "" +"Setting up GMail requires you to enable two factor authentication\n" +"\t\t and app specific passwords. Read more" +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:105 +msgid "" +"Setting up Outlook requires you to enable two factor authentication\n" +"\t\t and app specific passwords. Read more" +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:113 +msgid "" +"Setting up Sendgrid requires you to enable two factor authentication\n" +"\t\t and app specific passwords. Read more " +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:121 +msgid "" +"Setting up SparkPost requires you to enable two factor authentication\n" +"\t\t and app specific passwords. Read more " +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:129 +msgid "" +"Setting up Yahoo requires you to enable two factor authentication\n" +"\t\t and app specific passwords. Read more " +msgstr "" + +#: frontend/src/components/Settings/emailConfig.js:137 +msgid "" +"Setting up Yandex requires you to enable two factor authentication\n" +"\t\t and app specific passwords. Read more " +msgstr "" + #: frontend/src/components/Layouts/AppSidebar.vue:494 #: frontend/src/components/Settings/Settings.vue:11 #: frontend/src/components/Settings/Settings.vue:81 msgid "Settings" msgstr "" +#: frontend/src/components/Settings/EmailAdd.vue:6 +msgid "Setup Email" +msgstr "" + #: frontend/src/components/Activities/Activities.vue:230 msgid "Show" msgstr "" @@ -3550,10 +3708,10 @@ msgstr "" #: crm/fcrm/doctype/crm_invitation/crm_invitation.json #: crm/fcrm/doctype/crm_lead/crm_lead.json #: crm/fcrm/doctype/crm_lead_status/crm_lead_status.json -#: crm/fcrm/doctype/crm_task/crm_task.json frontend/src/pages/Contact.vue:635 +#: crm/fcrm/doctype/crm_task/crm_task.json frontend/src/pages/Contact.vue:639 #: frontend/src/pages/MobileContact.vue:613 #: frontend/src/pages/MobileOrganization.vue:499 -#: frontend/src/pages/Organization.vue:534 +#: frontend/src/pages/Organization.vue:538 msgid "Status" msgstr "" @@ -3596,6 +3754,10 @@ msgstr "" msgid "Sunday" msgstr "" +#: frontend/src/components/Settings/emailConfig.js:16 +msgid "Support / Sales" +msgstr "" + #: frontend/src/components/FilesUploader/FilesUploader.vue:49 msgid "Switch camera" msgstr "" @@ -3631,7 +3793,7 @@ msgstr "" msgid "Task" msgstr "" -#: frontend/src/pages/Deal.vue:567 frontend/src/pages/Lead.vue:553 +#: frontend/src/pages/Deal.vue:571 frontend/src/pages/Lead.vue:557 #: frontend/src/pages/MobileDeal.vue:467 frontend/src/pages/MobileLead.vue:370 msgid "Tasks" msgstr "" @@ -3751,6 +3913,10 @@ msgstr "" msgid "To User" msgstr "" +#: frontend/src/components/Settings/EmailEdit.vue:119 +msgid "To know more about setting up email accounts, click" +msgstr "" + #: frontend/src/components/Filter.vue:619 msgid "Today" msgstr "" @@ -3882,6 +4048,10 @@ msgstr "" msgid "Update" msgstr "" +#: frontend/src/components/Settings/EmailEdit.vue:74 +msgid "Update Account" +msgstr "" + #: frontend/src/components/Modals/EditValueModal.vue:30 msgid "Update {0} Records" msgstr "" @@ -3965,7 +4135,7 @@ msgid "Website" msgstr "" #: frontend/src/pages/MobileOrganization.vue:308 -#: frontend/src/pages/Organization.vue:350 +#: frontend/src/pages/Organization.vue:354 msgid "Website not found" msgstr "" @@ -3995,7 +4165,7 @@ msgstr "" #: crm/fcrm/doctype/crm_notification/crm_notification.json #: frontend/src/components/Layouts/AppSidebar.vue:562 #: frontend/src/components/Settings/Settings.vue:124 -#: frontend/src/pages/Deal.vue:582 frontend/src/pages/Lead.vue:568 +#: frontend/src/pages/Deal.vue:586 frontend/src/pages/Lead.vue:572 #: frontend/src/pages/MobileDeal.vue:482 frontend/src/pages/MobileLead.vue:385 msgid "WhatsApp" msgstr "" @@ -4146,6 +4316,10 @@ msgstr "" msgid "has reached out" msgstr "" +#: frontend/src/components/Settings/EmailEdit.vue:25 +msgid "here" +msgstr "" + #: frontend/src/components/Settings/InviteMemberPage.vue:17 msgid "john@doe.com" msgstr "" @@ -4247,7 +4421,7 @@ msgstr "" msgid "{0} assigned a {1} {2} to you" msgstr "" -#: frontend/src/pages/Deal.vue:492 frontend/src/pages/Lead.vue:478 +#: frontend/src/pages/Deal.vue:496 frontend/src/pages/Lead.vue:482 #: frontend/src/pages/MobileDeal.vue:385 frontend/src/pages/MobileLead.vue:288 msgid "{0} is a required field" msgstr "" diff --git a/crm/patches.txt b/crm/patches.txt index f602b2bc..59f37bfb 100644 --- a/crm/patches.txt +++ b/crm/patches.txt @@ -11,4 +11,5 @@ crm.patches.v1_0.create_default_fields_layout #22/01/2025 crm.patches.v1_0.create_default_sidebar_fields_layout crm.patches.v1_0.update_deal_quick_entry_layout crm.patches.v1_0.update_layouts_to_new_format -crm.patches.v1_0.move_twilio_agent_to_telephony_agent \ No newline at end of file +crm.patches.v1_0.move_twilio_agent_to_telephony_agent +crm.patches.v1_0.create_default_scripts \ No newline at end of file diff --git a/crm/patches/v1_0/create_default_scripts.py b/crm/patches/v1_0/create_default_scripts.py new file mode 100644 index 00000000..37e3b0d1 --- /dev/null +++ b/crm/patches/v1_0/create_default_scripts.py @@ -0,0 +1,5 @@ +from crm.install import add_default_scripts + + +def execute(): + add_default_scripts() diff --git a/crm/uninstall.py b/crm/uninstall.py index 34622d0b..a186c79f 100644 --- a/crm/uninstall.py +++ b/crm/uninstall.py @@ -1,12 +1,13 @@ # Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -from __future__ import unicode_literals import click import frappe + def before_uninstall(): delete_email_template_custom_fields() + def delete_email_template_custom_fields(): if frappe.get_meta("Email Template").has_field("enabled"): click.secho("* Uninstalling Custom Fields from Email Template") @@ -19,4 +20,4 @@ def delete_email_template_custom_fields(): for fieldname in fieldnames: frappe.db.delete("Custom Field", {"name": "Email Template-" + fieldname}) - frappe.clear_cache(doctype="Email Template") \ No newline at end of file + frappe.clear_cache(doctype="Email Template") diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 82afdb19..99bd28e3 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -53,6 +53,7 @@ declare module 'vue' { ContactsListView: typeof import('./src/components/ListViews/ContactsListView.vue')['default'] ConvertIcon: typeof import('./src/components/Icons/ConvertIcon.vue')['default'] CountUpTimer: typeof import('./src/components/CountUpTimer.vue')['default'] + CreateDocumentModal: typeof import('./src/components/Modals/CreateDocumentModal.vue')['default'] CRMLogo: typeof import('./src/components/Icons/CRMLogo.vue')['default'] CustomActions: typeof import('./src/components/CustomActions.vue')['default'] DashboardIcon: typeof import('./src/components/Icons/DashboardIcon.vue')['default'] @@ -113,9 +114,11 @@ declare module 'vue' { FileVideoIcon: typeof import('./src/components/Icons/FileVideoIcon.vue')['default'] Filter: typeof import('./src/components/Filter.vue')['default'] FilterIcon: typeof import('./src/components/Icons/FilterIcon.vue')['default'] + FormattedInput: typeof import('./src/components/Controls/FormattedInput.vue')['default'] FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default'] GenderIcon: typeof import('./src/components/Icons/GenderIcon.vue')['default'] GeneralSettings: typeof import('./src/components/Settings/GeneralSettings.vue')['default'] + GlobalModals: typeof import('./src/components/Modals/GlobalModals.vue')['default'] GoogleIcon: typeof import('./src/components/Icons/GoogleIcon.vue')['default'] Grid: typeof import('./src/components/Controls/Grid.vue')['default'] GridFieldsEditorModal: typeof import('./src/components/Controls/GridFieldsEditorModal.vue')['default'] diff --git a/frontend/src/components/Activities/DataFields.vue b/frontend/src/components/Activities/DataFields.vue index e73fb891..f572bbc0 100644 --- a/frontend/src/components/Activities/DataFields.vue +++ b/frontend/src/components/Activities/DataFields.vue @@ -5,7 +5,7 @@
+ {{ attrs.description }} +
+