From 748f8145b66489c010074dfbb887029535342666 Mon Sep 17 00:00:00 2001 From: Saqib Date: Thu, 14 Jan 2021 19:53:51 +0530 Subject: [PATCH] feat: show transporter address in sales invoice (#23731) * feat: show transporter address in sales invoice * feat: multiple transporter address * fix: update all eway-bill fields * fix: travis * fix: travis * fix: travis * fix: travis * fix: travis Co-authored-by: Nabin Hait --- .../doctype/sales_invoice/regional/india.js | 10 ++ erpnext/hooks.py | 3 +- erpnext/patches.txt | 1 + .../v12_0/add_transporter_address_field.py | 150 ++++++++++++++++++ erpnext/regional/india/party.js | 2 +- erpnext/regional/india/setup.py | 30 +++- erpnext/regional/india/utils.py | 25 +++ 7 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 erpnext/patches/v12_0/add_transporter_address_field.py diff --git a/erpnext/accounts/doctype/sales_invoice/regional/india.js b/erpnext/accounts/doctype/sales_invoice/regional/india.js index ba672c9368d..ca15626e19c 100644 --- a/erpnext/accounts/doctype/sales_invoice/regional/india.js +++ b/erpnext/accounts/doctype/sales_invoice/regional/india.js @@ -14,6 +14,16 @@ frappe.ui.form.on("Sales Invoice", { }; }); + frm.set_query('transporter_address', function (doc) { + return { + query: 'frappe.contacts.doctype.address.address.address_query', + filters: { + link_doctype: 'Supplier', + link_name: doc.transporter + } + } + }); + frm.set_query('driver', function(doc) { return { filters: { diff --git a/erpnext/hooks.py b/erpnext/hooks.py index bf81805833b..219e426d782 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -245,7 +245,8 @@ doc_events = { "Sales Invoice": { "on_submit": ["erpnext.regional.create_transaction_log", "erpnext.regional.italy.utils.sales_invoice_on_submit"], "on_cancel": "erpnext.regional.italy.utils.sales_invoice_on_cancel", - "on_trash": "erpnext.regional.check_deletion_permission" + "on_trash": "erpnext.regional.check_deletion_permission", + "validate": "erpnext.regional.india.utils.set_transporter_address" }, "Purchase Invoice": { "validate": "erpnext.regional.india.utils.update_grand_total_for_rcm" diff --git a/erpnext/patches.txt b/erpnext/patches.txt index e6066a9fead..08eda7e2c43 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -678,4 +678,5 @@ erpnext.patches.v12_0.update_state_code_for_daman_and_diu erpnext.patches.v12_0.rename_lost_reason_detail erpnext.patches.v12_0.update_leave_application_status erpnext.patches.v12_0.update_payment_entry_status +erpnext.patches.v12_0.add_transporter_address_field #2020-10-27 erpnext.patches.v12_0.setup_einvoice_fields #2020-12-02 diff --git a/erpnext/patches/v12_0/add_transporter_address_field.py b/erpnext/patches/v12_0/add_transporter_address_field.py new file mode 100644 index 00000000000..78da58f4e03 --- /dev/null +++ b/erpnext/patches/v12_0/add_transporter_address_field.py @@ -0,0 +1,150 @@ +from __future__ import unicode_literals +import frappe +from frappe.custom.doctype.custom_field.custom_field import create_custom_fields + +def execute(): + company = frappe.get_all('Company', filters = {'country': 'India'}) + if not company: + return + + fields = [ + { + 'fieldname': 'transporter_info', + 'label': 'Transporter Info', + 'fieldtype': 'Section Break', + 'insert_after': 'terms', + 'collapsible': 1, + 'collapsible_depends_on': 'transporter', + 'print_hide': 1 + }, + { + 'fieldname': 'transporter', + 'label': 'Transporter', + 'fieldtype': 'Link', + 'insert_after': 'transporter_info', + 'options': 'Supplier', + 'print_hide': 1 + }, + { + 'fieldname': 'transporter_name', + 'label': 'Transporter Name', + 'fieldtype': 'Data', + 'insert_after': 'transporter', + 'fetch_from': 'transporter.name', + 'read_only': 1, + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'gst_transporter_id', + 'label': 'GST Transporter ID', + 'fieldtype': 'Data', + 'insert_after': 'transporter_name', + 'fetch_from': 'transporter.gst_transporter_id', + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'driver', + 'label': 'Driver', + 'fieldtype': 'Link', + 'insert_after': 'gst_transporter_id', + 'options': 'Driver', + 'print_hide': 1 + }, + { + 'fieldname': 'lr_no', + 'label': 'Transport Receipt No', + 'fieldtype': 'Data', + 'insert_after': 'driver', + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'vehicle_no', + 'label': 'Vehicle No', + 'fieldtype': 'Data', + 'insert_after': 'lr_no', + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'distance', + 'label': 'Distance (in km)', + 'fieldtype': 'Float', + 'insert_after': 'vehicle_no', + 'print_hide': 1 + }, + { + 'fieldname': 'transporter_col_break', + 'fieldtype': 'Column Break', + 'insert_after': 'distance' + }, + { + 'fieldname': 'transporter_address', + 'label': 'Transporter Address Name', + 'fieldtype': 'Link', + 'insert_after': 'transporter_col_break', + 'options': 'Address', + 'print_hide': 1 + }, + { + 'fieldname': 'transporter_address_display', + 'label': 'Transporter Address Preview', + 'fieldtype': 'Small Text', + 'insert_after': 'transporter_address', + 'read_only': 1, + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'mode_of_transport', + 'label': 'Mode of Transport', + 'fieldtype': 'Select', + 'options': '\nRoad\nAir\nRail\nShip', + 'default': 'Road', + 'insert_after': 'transporter_address_display', + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'driver_name', + 'label': 'Driver Name', + 'fieldtype': 'Data', + 'insert_after': 'mode_of_transport', + 'fetch_from': 'driver.full_name', + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'lr_date', + 'label': 'Transport Receipt Date', + 'fieldtype': 'Date', + 'insert_after': 'driver_name', + 'default': 'Today', + 'print_hide': 1 + }, + { + 'fieldname': 'gst_vehicle_type', + 'label': 'GST Vehicle Type', + 'fieldtype': 'Select', + 'options': 'Regular\nOver Dimensional Cargo (ODC)', + 'depends_on': 'eval:(doc.mode_of_transport === "Road")', + 'default': 'Regular', + 'insert_after': 'lr_date', + 'print_hide': 1, + 'translatable': 0 + }, + { + 'fieldname': 'ewaybill', + 'label': 'e-Way Bill No.', + 'fieldtype': 'Data', + 'depends_on': 'eval:(doc.docstatus === 1)', + 'allow_on_submit': 1, + 'insert_after': 'tax_id', + 'translatable': 0 + } + ] + + create_custom_fields({ 'Sales Invoice': fields }, update=True) + frappe.reload_doctype('Sales Invoice') \ No newline at end of file diff --git a/erpnext/regional/india/party.js b/erpnext/regional/india/party.js index 402a387c4a1..8e9c9a5f94e 100644 --- a/erpnext/regional/india/party.js +++ b/erpnext/regional/india/party.js @@ -22,4 +22,4 @@ erpnext.setup_gst_reminder_button = (doctype) => { } } }); -}; +}; \ No newline at end of file diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 8f2137a87aa..4954b3438dc 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -273,11 +273,21 @@ def make_custom_fields(update=True): 'options': 'Supplier', 'print_hide': 1 }, + { + 'fieldname': 'transporter_name', + 'label': 'Transporter Name', + 'fieldtype': 'Data', + 'insert_after': 'transporter', + 'fetch_from': 'transporter.name', + 'read_only': 1, + 'print_hide': 1, + 'translatable': 0 + }, { 'fieldname': 'gst_transporter_id', 'label': 'GST Transporter ID', 'fieldtype': 'Data', - 'insert_after': 'transporter', + 'insert_after': 'transporter_name', 'fetch_from': 'transporter.gst_transporter_id', 'print_hide': 1, 'translatable': 0 @@ -319,11 +329,18 @@ def make_custom_fields(update=True): 'insert_after': 'distance' }, { - 'fieldname': 'transporter_name', - 'label': 'Transporter Name', - 'fieldtype': 'Data', + 'fieldname': 'transporter_address', + 'label': 'Transporter Address Name', + 'fieldtype': 'Link', 'insert_after': 'transporter_col_break', - 'fetch_from': 'transporter.name', + 'options': 'Address', + 'print_hide': 1 + }, + { + 'fieldname': 'transporter_address_display', + 'label': 'Transporter Address Preview', + 'fieldtype': 'Small Text', + 'insert_after': 'transporter_address', 'read_only': 1, 'print_hide': 1, 'translatable': 0 @@ -333,7 +350,8 @@ def make_custom_fields(update=True): 'label': 'Mode of Transport', 'fieldtype': 'Select', 'options': '\nRoad\nAir\nRail\nShip', - 'insert_after': 'transporter_name', + 'default': 'Road', + 'insert_after': 'transporter_address_display', 'print_hide': 1, 'translatable': 0 }, diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 2b6eedec3f8..89677433392 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -12,6 +12,7 @@ from erpnext.regional.india import number_state_mapping from six import string_types from erpnext.accounts.general_ledger import make_gl_entries from erpnext.accounts.utils import get_account_currency +from frappe.contacts.doctype.address.address import get_address_display from frappe.model.utils import get_fetch_values def validate_gstin_for_india(doc, method): @@ -137,6 +138,30 @@ def get_itemised_tax_breakup_data(doc, account_wise=False): def set_place_of_supply(doc, method=None): doc.place_of_supply = get_place_of_supply(doc, doc.doctype) +def set_transporter_address(doc, method=None): + country = frappe.get_cached_value('Company', doc.company, 'country') + if country != 'India': + return + + if doc.get("transporter_address"): + # once supplier is set, address can be selected from multiple transporter addresses + doc.transporter_address_display = get_address_display(doc.get("transporter_address")) + return + + transporter_address = frappe.db.get_value("Dynamic Link", { + 'link_doctype': 'Supplier', + 'link_name': doc.get('transporter'), + 'parenttype': 'Address' + }, "parent") + + if not transporter_address: + doc.transporter_address = "" + doc.transporter_address_display = "" + return + + doc.transporter_address = transporter_address + doc.transporter_address_display = get_address_display(transporter_address) + # don't remove this function it is used in tests def test_method(): '''test function'''