diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 8c18d14d29f..0c20dbd73e2 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -566,3 +566,4 @@ erpnext.patches.v11_0.redesign_healthcare_billing_work_flow erpnext.patches.v10_0.delete_hub_documents # 12-08-2018 erpnext.patches.v11_0.rename_healthcare_fields erpnext.patches.v11_0.remove_land_unit_icon +erpnext.patches.v11_0.add_default_dispatch_notification_template diff --git a/erpnext/patches/v11_0/add_default_dispatch_notification_template.py b/erpnext/patches/v11_0/add_default_dispatch_notification_template.py new file mode 100644 index 00000000000..08006ad01b1 --- /dev/null +++ b/erpnext/patches/v11_0/add_default_dispatch_notification_template.py @@ -0,0 +1,25 @@ +import os + +import frappe +from frappe import _ + + +def execute(): + frappe.reload_doc("email", "doctype", "email_template") + frappe.reload_doc("stock", "doctype", "delivery_settings") + + if not frappe.db.exists("Email Template", _("Dispatch Notification")): + base_path = frappe.get_app_path("erpnext", "stock", "doctype") + response = frappe.read_file(os.path.join(base_path, "delivery_trip/dispatch_notification_template.html")) + + frappe.get_doc({ + "doctype": "Email Template", + "name": _("Dispatch Notification"), + "response": response, + "subject": _("Your order is out for delivery!"), + "owner": frappe.session.user, + }).insert(ignore_permissions=True) + + delivery_settings = frappe.get_doc("Delivery Settings") + delivery_settings.dispatch_template = _("Dispatch Notification") + delivery_settings.save() diff --git a/erpnext/setup/setup_wizard/operations/defaults_setup.py b/erpnext/setup/setup_wizard/operations/defaults_setup.py index 657905d184b..ff8dd75eeef 100644 --- a/erpnext/setup/setup_wizard/operations/defaults_setup.py +++ b/erpnext/setup/setup_wizard/operations/defaults_setup.py @@ -55,6 +55,10 @@ def set_default_settings(args): buying_settings.allow_multiple_items = 1 buying_settings.save() + delivery_settings = frappe.get_doc("Delivery Settings") + delivery_settings.dispatch_template = _("Dispatch Notification") + delivery_settings.save() + hr_settings = frappe.get_doc("HR Settings") hr_settings.emp_created_by = "Naming Series" hr_settings.leave_approval_notification_template = _("Leave Approval Notification") diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index 59e65771ef6..194e0dda6b3 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -250,6 +250,12 @@ def install(country=None): records += [{'doctype': 'Email Template', 'name': _("Leave Status Notification"), 'response': response,\ 'subject': _("Leave Status Notification"), 'owner': frappe.session.user}] + base_path = frappe.get_app_path("erpnext", "stock", "doctype") + response = frappe.read_file(os.path.join(base_path, "delivery_trip/dispatch_notification_template.html")) + + records += [{'doctype': 'Email Template', 'name': _("Dispatch Notification"), 'response': response,\ + 'subject': _("Your order is out for delivery!"), 'owner': frappe.session.user}] + # Records for the Supplier Scorecard from erpnext.buying.doctype.supplier_scorecard.supplier_scorecard import make_default_records make_default_records() diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 6e45273f994..6fec6121c8c 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -460,6 +460,7 @@ def make_delivery_trip(source_name, target_doc=None): target_doc.customer_address = source_parent.shipping_address target_doc.contact = source_parent.contact_person target_doc.customer_contact = source_parent.contact_display + target_doc.grand_total = source_parent.grand_total # Append unique Delivery Notes in Delivery Trip delivery_notes.append(target_doc.delivery_note) diff --git a/erpnext/stock/doctype/delivery_settings/__init__.py b/erpnext/stock/doctype/delivery_settings/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/stock/doctype/delivery_settings/delivery_settings.js b/erpnext/stock/doctype/delivery_settings/delivery_settings.js new file mode 100644 index 00000000000..03aa1922ff5 --- /dev/null +++ b/erpnext/stock/doctype/delivery_settings/delivery_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Delivery Settings', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/stock/doctype/delivery_settings/delivery_settings.json b/erpnext/stock/doctype/delivery_settings/delivery_settings.json new file mode 100644 index 00000000000..b70d74d1a6f --- /dev/null +++ b/erpnext/stock/doctype/delivery_settings/delivery_settings.json @@ -0,0 +1,194 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-09-04 23:01:34.458550", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "sb_dispatch", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Dispatch Settings", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "dispatch_template", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Dispatch Notification Template", + "length": 0, + "no_copy": 0, + "options": "Email Template", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "send_with_attachment", + "description": "Leave blank to use the standard Delivery Note format", + "fieldname": "dispatch_attachment", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Dispatch Notification Attachment", + "length": 0, + "no_copy": 0, + "options": "Print Format", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "send_with_attachment", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Send with Attachment", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2018-09-05 00:16:23.569855", + "modified_by": "Administrator", + "module": "Stock", + "name": "Delivery Settings", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 0, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0, + "track_views": 0 +} \ No newline at end of file diff --git a/erpnext/stock/doctype/delivery_settings/delivery_settings.py b/erpnext/stock/doctype/delivery_settings/delivery_settings.py new file mode 100644 index 00000000000..909efda856f --- /dev/null +++ b/erpnext/stock/doctype/delivery_settings/delivery_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class DeliverySettings(Document): + pass diff --git a/erpnext/stock/doctype/delivery_settings/test_delivery_settings.js b/erpnext/stock/doctype/delivery_settings/test_delivery_settings.js new file mode 100644 index 00000000000..22977c08f75 --- /dev/null +++ b/erpnext/stock/doctype/delivery_settings/test_delivery_settings.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Delivery Settings", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Delivery Settings + () => frappe.tests.make('Delivery Settings', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/stock/doctype/delivery_settings/test_delivery_settings.py b/erpnext/stock/doctype/delivery_settings/test_delivery_settings.py new file mode 100644 index 00000000000..4395d266287 --- /dev/null +++ b/erpnext/stock/doctype/delivery_settings/test_delivery_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestDeliverySettings(unittest.TestCase): + pass diff --git a/erpnext/stock/doctype/delivery_stop/delivery_stop.json b/erpnext/stock/doctype/delivery_stop/delivery_stop.json index 4fe4102180f..023e34de085 100644 --- a/erpnext/stock/doctype/delivery_stop/delivery_stop.json +++ b/erpnext/stock/doctype/delivery_stop/delivery_stop.json @@ -18,7 +18,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "columns": 0, + "columns": 2, "fieldname": "customer", "fieldtype": "Link", "hidden": 0, @@ -78,6 +78,38 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "lock", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Lock", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -148,7 +180,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "section_break_7", + "fieldname": "order_information_section", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -157,6 +189,135 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Order Information", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "delivery_note", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Delivery Note", + "length": 0, + "no_copy": 1, + "options": "Delivery Note", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "cb_order", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "grand_total", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Grand Total", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_7", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Contact Information", "length": 0, "no_copy": 0, "permlevel": 0, @@ -186,7 +347,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 0, "label": "Contact Name", "length": 0, @@ -205,6 +366,38 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "email_sent_to", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Email sent to", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -284,6 +477,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Dispatch Information", "length": 0, "no_copy": 0, "permlevel": 0, @@ -362,196 +556,6 @@ "set_only_once": 0, "translatable": 0, "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_12", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "delivery_note", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Delivery Note", - "length": 0, - "no_copy": 1, - "options": "Delivery Note", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_14", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 1, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "notified_by_email", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Notified by Email", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_18", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "email_sent_to", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Email sent to", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 } ], "has_web_view": 0, @@ -564,7 +568,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-08-21 22:25:53.276548", + "modified": "2018-09-05 00:51:55.275009", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Stop", diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.js b/erpnext/stock/doctype/delivery_trip/delivery_trip.js index f3c0f752fd9..9c31e05f474 100755 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.js +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.js @@ -2,8 +2,8 @@ // For license information, please see license.txt frappe.ui.form.on('Delivery Trip', { - setup: function(frm) { - frm.set_query("driver", function() { + setup: function (frm) { + frm.set_query("driver", function () { return { filters: { "status": "Active" @@ -11,7 +11,7 @@ frappe.ui.form.on('Delivery Trip', { }; }); - frm.set_query("address", "delivery_stops", function(doc, cdt, cdn) { + frm.set_query("address", "delivery_stops", function (doc, cdt, cdn) { var row = locals[cdt][cdn]; if (row.customer) { return { @@ -24,7 +24,7 @@ frappe.ui.form.on('Delivery Trip', { } }) - frm.set_query("contact", "delivery_stops", function(doc, cdt, cdn) { + frm.set_query("contact", "delivery_stops", function (doc, cdt, cdn) { var row = locals[cdt][cdn]; if (row.customer) { return { @@ -45,7 +45,7 @@ frappe.ui.form.on('Delivery Trip', { }); } - if (frm.doc.docstatus===0) { + if (frm.doc.docstatus === 0) { frm.add_custom_button(__('Delivery Note'), () => { erpnext.utils.map_current_doc({ method: "erpnext.stock.doctype.delivery_note.delivery_note.make_delivery_trip", @@ -93,12 +93,8 @@ frappe.ui.form.on('Delivery Trip', { }, notify_customers: function (frm) { - var owner_email = frm.doc.owner == "Administrator" - ? frappe.user_info("Administrator").email - : frm.doc.owner; - $.each(frm.doc.delivery_stops || [], function (i, delivery_stop) { - if (!delivery_stop.delivery_notes) { + if (!delivery_stop.delivery_note) { frappe.msgprint({ "message": __("No Delivery Note selected for Customer {}", [delivery_stop.customer]), "title": __("Warning"), @@ -107,34 +103,37 @@ frappe.ui.form.on('Delivery Trip', { }); } }); - frappe.confirm(__("Do you want to notify all the customers by email?"), function () { - frappe.call({ - method: "erpnext.stock.doctype.delivery_trip.delivery_trip.notify_customers", - args: { - "docname": frm.doc.name, - "date": frm.doc.date, - "driver": frm.doc.driver, - "vehicle": frm.doc.vehicle, - "sender_email": owner_email, - "sender_name": frappe.user.full_name(owner_email), - "delivery_notification": frm.doc.delivery_notification - } - }); - frm.doc.email_notification_sent = true; - frm.refresh_field('email_notification_sent'); + + frappe.db.get_value("Delivery Settings", { name: "Delivery Settings" }, "dispatch_template", (r) => { + if (!r.dispatch_template) { + frappe.throw(__("Missing email template for dispatch. Please set one in Delivery Settings.")); + } else { + frappe.confirm(__("Do you want to notify all the customers by email?"), function () { + frappe.call({ + method: "erpnext.stock.doctype.delivery_trip.delivery_trip.notify_customers", + args: { + "delivery_trip": frm.doc.name + }, + callback: function (r) { + if (!r.exc) { + frm.doc.email_notification_sent = true; + frm.refresh_field('email_notification_sent'); + } + } + }); + }); + } }); } }); - - frappe.ui.form.on('Delivery Stop', { customer: function (frm, cdt, cdn) { var row = locals[cdt][cdn]; - if(row.customer) { + if (row.customer) { frappe.call({ method: "erpnext.stock.doctype.delivery_trip.delivery_trip.get_contact_and_address", - args: {"name": row.customer}, + args: { "name": row.customer }, callback: function (r) { if (r.message) { if (r.message["shipping_address"]) { @@ -158,12 +157,13 @@ frappe.ui.form.on('Delivery Stop', { }); } }, + address: function (frm, cdt, cdn) { var row = locals[cdt][cdn]; - if(row.address) { + if (row.address) { frappe.call({ method: "frappe.contacts.doctype.address.address.get_address_display", - args: {"address_dict": row.address}, + args: { "address_dict": row.address }, callback: function (r) { if (r.message) { frappe.model.set_value(cdt, cdn, "customer_address", r.message); @@ -177,10 +177,10 @@ frappe.ui.form.on('Delivery Stop', { contact: function (frm, cdt, cdn) { var row = locals[cdt][cdn]; - if(row.contact) { + if (row.contact) { frappe.call({ method: "erpnext.stock.doctype.delivery_trip.delivery_trip.get_contact_display", - args: {"contact": row.contact}, + args: { "contact": row.contact }, callback: function (r) { if (r.message) { frappe.model.set_value(cdt, cdn, "customer_contact", r.message); diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.json b/erpnext/stock/doctype/delivery_trip/delivery_trip.json index 364bc6b13cd..3cb19af0f29 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.json +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.json @@ -114,7 +114,7 @@ { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, - "allow_on_submit": 0, + "allow_on_submit": 1, "bold": 0, "collapsible": 0, "columns": 0, @@ -437,7 +437,7 @@ { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, - "allow_on_submit": 1, + "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, @@ -507,7 +507,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "section_break_13", + "fieldname": "section_break_15", "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, @@ -531,40 +531,6 @@ "translatable": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "", - "fieldname": "delivery_notification", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Delivery Notification", - "length": 0, - "no_copy": 0, - "options": "Email Template", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -608,7 +574,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-08-30 02:31:49.400138", + "modified": "2018-09-05 01:20:34.165834", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Trip", diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index 5f291c3342d..e932b1414f4 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -10,8 +10,7 @@ import frappe from frappe import _ from frappe.contacts.doctype.address.address import get_address_display from frappe.model.document import Document -from frappe.utils import cstr, get_datetime, getdate, get_link_to_form -from frappe.utils.user import get_user_fullname +from frappe.utils import get_datetime, get_link_to_form class DeliveryTrip(Document): @@ -169,59 +168,50 @@ def get_arrival_times(name): @frappe.whitelist() -def notify_customers(docname, date, driver, vehicle, sender_email, delivery_notification): - sender_name = get_user_fullname(sender_email) - attachments = [] +def notify_customers(delivery_trip): + delivery_trip = frappe.get_doc("Delivery Trip", delivery_trip) - parent_doc = frappe.get_doc('Delivery Trip', docname) - args = parent_doc.as_dict() + context = delivery_trip.as_dict() - for delivery_stop in parent_doc.delivery_stops: - contact_info = frappe.db.get_value("Contact", delivery_stop.contact, - ["first_name", "last_name", "email_id", "gender"], as_dict=1) + if delivery_trip.driver: + context.update(frappe.db.get_value("Driver", delivery_trip.driver, "cell_number", as_dict=1)) - args.update(delivery_stop.as_dict()) - args.update(contact_info) + email_recipients = [] - if delivery_stop.delivery_note: - default_print_format = frappe.get_meta('Delivery Note').default_print_format - attachments = frappe.attach_print('Delivery Note', - delivery_stop.delivery_note, - file_name="Delivery Note", - print_format=default_print_format or "Standard") + for stop in delivery_trip.delivery_stops: + contact_info = frappe.db.get_value("Contact", stop.contact, + ["first_name", "last_name", "email_id", "gender"], as_dict=1) - if not delivery_stop.notified_by_email and contact_info.email_id: - driver_info = frappe.db.get_value("Driver", driver, ["full_name", "cell_number"], as_dict=1) - sender_designation = frappe.db.get_value("Employee", sender_email, ["designation"]) + if contact_info and contact_info.email_id: + context.update(stop.as_dict()) + context.update(contact_info) - estimated_arrival = cstr(delivery_stop.estimated_arrival)[:-3] - email_template = frappe.get_doc("Email Template", delivery_notification) - message = frappe.render_template(email_template.response, args) + dispatch_template_name = frappe.db.get_single_value("Delivery Settings", "dispatch_template") + dispatch_template = frappe.get_doc("Email Template", dispatch_template_name) - frappe.sendmail( - recipients=contact_info.email_id, - sender=sender_email, - message=message, - attachments=attachments, - subject=_(email_template.subject).format(getdate(date).strftime('%d.%m.%y'), - estimated_arrival)) + frappe.sendmail(recipients=contact_info.email_id, + subject=dispatch_template.subject, + message=frappe.render_template(dispatch_template.response, context), + attachments=get_attachments(stop)) - frappe.db.set_value("Delivery Stop", delivery_stop.name, "notified_by_email", 1) - frappe.db.set_value("Delivery Stop", delivery_stop.name, - "email_sent_to", contact_info.email_id) - frappe.msgprint(_("Email sent to {0}").format(contact_info.email_id)) + stop.db_set("email_sent_to", contact_info.email_id) + email_recipients.append(contact_info.email_id) -def round_timedelta(td, period): - """Round timedelta""" - period_seconds = period.total_seconds() - half_period_seconds = period_seconds / 2 - remainder = td.total_seconds() % period_seconds - if remainder >= half_period_seconds: - return datetime.timedelta(seconds=td.total_seconds() + (period_seconds - remainder)) + if email_recipients: + frappe.msgprint(_("Email sent to {0}").format(", ".join(email_recipients))) + delivery_trip.db_set("email_notification_sent", True) else: - return datetime.timedelta(seconds=td.total_seconds() - remainder) + frappe.msgprint(_("No contacts with email IDs found.")) -def format_address(address): - """Customer Address format """ - address = frappe.get_doc('Address', address) - return '{}, {}, {}, {}'.format(address.address_line1, address.city, address.pincode, address.country) + +def get_attachments(delivery_stop): + if not (frappe.db.get_single_value("Delivery Settings", "send_with_attachment") and delivery_stop.delivery_note): + return [] + + dispatch_attachment = frappe.db.get_single_value("Delivery Settings", "dispatch_attachment") + attachments = frappe.attach_print("Delivery Note", + delivery_stop.delivery_note, + file_name="Delivery Note", + print_format=dispatch_attachment) + + return [attachments] diff --git a/erpnext/stock/doctype/delivery_trip/dispatch_notification_template.html b/erpnext/stock/doctype/delivery_trip/dispatch_notification_template.html new file mode 100644 index 00000000000..90a5c50eb1a --- /dev/null +++ b/erpnext/stock/doctype/delivery_trip/dispatch_notification_template.html @@ -0,0 +1,50 @@ +

Dispatch Notification

+

Details:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Customer's Name{{ customer }}
Contact's Name{{ first_name }} {{ last_name }}
Address Name{{ address }}
Address Details{{ customer_address }}
Order Number{{ delivery_note }}
Order Total{{ grand_total }}
Departure Time{{ cstr(departure_time) }}
Estimated Arrival{{ cstr(estimated_arrival) }}
Driver's Name{{ driver_name }}
Driver's Number{{ cell_number }}
Vehicle Number{{ vehicle }}
\ No newline at end of file diff --git a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py b/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py index aad36c14df7..4f7fcd8e58f 100644 --- a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/test_delivery_trip.py @@ -3,60 +3,70 @@ # See license.txt from __future__ import unicode_literals -import frappe -import erpnext import unittest -from frappe.utils import nowdate, add_days + +import erpnext +import frappe +from erpnext.stock.doctype.delivery_trip.delivery_trip import get_contact_and_address, notify_customers from erpnext.tests.utils import create_test_contact_and_address -from erpnext.stock.doctype.delivery_trip.delivery_trip import notify_customers, get_contact_and_address +from frappe.utils import add_days, now_datetime + class TestDeliveryTrip(unittest.TestCase): def setUp(self): create_driver() create_vehicle() - create_delivery_notfication() + create_delivery_notification() create_test_contact_and_address() def test_delivery_trip(self): contact = get_contact_and_address("_Test Customer") if not frappe.db.exists("Delivery Trip", "TOUR-00000"): - delivery_trip = frappe.new_doc("Delivery Trip") - delivery_trip.company = erpnext.get_default_company() - delivery_trip.date = add_days(nowdate(), 5) - delivery_trip.driver = "DRIVER-00001" - delivery_trip.vehicle = "JB 007" - delivery_trip.append("delivery_stops", { - "customer": "_Test Customer", - "address": contact.shipping_address.parent, - "contact": contact.contact_person.parent + delivery_trip = frappe.get_doc({ + "doctype": "Delivery Trip", + "company": erpnext.get_default_company(), + "departure_time": add_days(now_datetime(), 5), + "driver": "DRIVER-00001", + "vehicle": "JB 007", + "delivery_stops": [{ + "customer": "_Test Customer", + "address": contact.shipping_address.parent, + "contact": contact.contact_person.parent + }] }) - delivery_trip.delivery_notification = 'Delivery Notification' delivery_trip.insert() - sender_email = frappe.db.get_value("User", frappe.session.user, "email") - notify_customers(docname=delivery_trip.name, date=delivery_trip.date, driver=delivery_trip.driver, - vehicle=delivery_trip.vehicle, - sender_email=sender_email, delivery_notification=delivery_trip.delivery_notification) - self.assertEqual(delivery_trip.get("delivery_stops")[0].notified_by_email, 0) + notify_customers(delivery_trip=delivery_trip.name) + delivery_trip.load_from_db() + self.assertEqual(delivery_trip.email_notification_sent, 1) + def create_driver(): if not frappe.db.exists("Driver", "Newton Scmander"): - driver = frappe.new_doc("Driver") - driver.full_name = "Newton Scmander" - driver.cell_number = "98343424242" - driver.license_number = "B809" + driver = frappe.get_doc({ + "doctype": "Driver", + "full_name": "Newton Scmander", + "cell_number": "98343424242", + "license_number": "B809" + }) driver.insert() -def create_delivery_notfication(): + +def create_delivery_notification(): if not frappe.db.exists("Email Template", "Delivery Notification"): - frappe.get_doc({ + dispatch_template = frappe.get_doc({ 'doctype': 'Email Template', 'name': 'Delivery Notification', 'response': 'Test Delivery Trip', 'subject': 'Test Subject', 'owner': frappe.session.user - }).insert() + }) + dispatch_template.insert() + + delivery_settings = frappe.get_single("Delivery Settings") + delivery_settings.dispatch_template = 'Delivery Notification' + def create_vehicle(): if not frappe.db.exists("Vehicle", "JB 007"):