# Copyright (c) 2013, FinByz Tech Pvt. Ltd. and contributors # For license information, please see license.txt from __future__ import unicode_literals import json import re import frappe from frappe import _ from frappe.utils import nowdate def execute(filters=None): if not filters: filters.setdefault('posting_date', [nowdate(), nowdate()]) columns, data = [], [] columns = get_columns() data = get_data(filters) return columns, data def get_data(filters): conditions = get_conditions(filters) data = frappe.db.sql(""" SELECT dn.name as dn_id, dn.posting_date, dn.company, dn.company_gstin, dn.customer, dn.customer_gstin, dni.item_code, dni.item_name, dni.description, dni.gst_hsn_code, dni.uom, dni.qty, dni.amount, dn.mode_of_transport, dn.distance, dn.transporter_name, dn.gst_transporter_id, dn.lr_no, dn.lr_date, dn.vehicle_no, dn.gst_vehicle_type, dn.company_address, dn.shipping_address_name FROM `tabDelivery Note` AS dn join `tabDelivery Note Item` AS dni on (dni.parent = dn.name) WHERE dn.docstatus < 2 %s """ % conditions, as_dict=1) unit = { 'Bag': "BAGS", 'Bottle': "BOTTLES", 'Kg': "KILOGRAMS", 'Liter': "LITERS", 'Meter': "METERS", 'Nos': "NUMBERS", 'PKT': "PACKS", 'Roll': "ROLLS", 'Set': "SETS" } # Regular expression set to remove all the special characters special_characters = r"[$%^*()+\\[\]{};':\"\\|<>.?]" for row in data: set_defaults(row) set_taxes(row, filters) set_address_details(row, special_characters) # Eway Bill accepts date as dd/mm/yyyy and not dd-mm-yyyy row.posting_date = '/'.join(str(row.posting_date).replace("-", "/").split('/')[::-1]) row.lr_date = '/'.join(str(row.lr_date).replace("-", "/").split('/')[::-1]) if row.gst_vehicle_type == 'Over Dimensional Cargo (ODC)': row.gst_vehicle_type = 'ODC' row.item_name = re.sub(special_characters, " ", row.item_name) row.description = row.item_name row.uom = unit.get(row.uom, row.uom) # For removing special charactes and numbers from customer. row.customer = re.sub(special_characters[:-1] + "&0-9" + "]", "", row.customer) return data def get_conditions(filters): conditions = "" conditions += filters.get('company') and " AND dn.company = '%s' " % filters.get('company') or "" conditions += filters.get('posting_date') and " AND dn.posting_date >= '%s' AND dn.posting_date <= '%s' " % (filters.get('posting_date')[0], filters.get('posting_date')[1]) or "" conditions += filters.get('delivery_note') and " AND dn.name = '%s' " % filters.get('delivery_note') or "" conditions += filters.get('customer') and " AND dn.customer = '%s' " % filters.get('customer').replace("'", "\'") or "" return conditions def set_defaults(row): row.setdefault(u'supply_type', "Outward") row.setdefault(u'sub_type', "Supply") row.setdefault(u'doc_type', "Delivery Challan") def set_address_details(row, special_characters): if row.get('company_address'): address_line1, address_line2, city, pincode, state = frappe.db.get_value("Address", row.get('company_address'), ['address_line1', 'address_line2', 'city', 'pincode', 'state']) row.update({'from_address_1': re.sub(special_characters, "", address_line1 or '')}) row.update({'from_address_2': re.sub(special_characters, "", address_line2 or '')}) row.update({'from_place': city and city.upper() or ''}) row.update({'from_pin_code': pincode and pincode.replace(" ", "") or ''}) row.update({'from_state': state and state.upper() or ''}) row.update({'dispatch_state': row.from_state}) if row.get('shipping_address_name'): address_line1, address_line2, city, pincode, state = frappe.db.get_value("Address", row.get('shipping_address_name'), ['address_line1', 'address_line2', 'city', 'pincode', 'state']) row.update({'to_address_1': re.sub(special_characters, "", address_line1 or '')}) row.update({'to_address_2': re.sub(special_characters, "", address_line2 or '')}) row.update({'to_place': city and city.upper() or ''}) row.update({'to_pin_code': pincode and pincode.replace(" ", "") or ''}) row.update({'to_state': state and state.upper() or ''}) row.update({'ship_to_state': row.to_state}) def set_taxes(row, filters): taxes = frappe.get_list("Sales Taxes and Charges", filters={ 'parent': row.dn_id }, fields=('item_wise_tax_detail', 'account_head')) account_list = ["cgst_account", "sgst_account", "igst_account", "cess_account"] taxes_list = frappe.get_list("GST Account", filters={ "parent": "GST Settings", "company": filters.company }, fields=account_list) if not taxes_list: frappe.throw(_("Please set GST Accounts in GST Settings")) item_tax_rate = {} for tax in taxes: item_wise_tax = json.loads(tax.item_wise_tax_detail) item_tax_rate[tax.account_head] = item_wise_tax.get(row.item_code) tax_rate = [] tax = taxes_list[0] for key in account_list: if tax[key] not in item_tax_rate.keys(): item_tax_rate[tax[key]] = [0.0, 0.0] tax_rate.append(str(item_tax_rate[tax[key]][0])) row.update({key[:5] + "amount": round(item_tax_rate.get(tax[key], 0.0)[1], 2)}) item_tax_rate.pop(tax[key]) row.amount = float(row.amount) + sum(i[1] for i in item_tax_rate.values()) row.update({'tax_rate': '+'.join(tax_rate)}) def get_columns(): columns = [ { "fieldname": "supply_type", "label": _("Supply Type"), "fieldtype": "Data", "width": 100 }, { "fieldname": "sub_type", "label": _("Sub Type"), "fieldtype": "Data", "width": 100 }, { "fieldname": "doc_type", "label": _("Doc Type"), "fieldtype": "Data", "width": 100 }, { "fieldname": "dn_id", "label": _("Doc Name"), "fieldtype": "Link", "options": "Delivery Note", "width": 140 }, { "fieldname": "posting_date", "label": _("Doc Date"), "fieldtype": "Data", "width": 100 }, { "fieldname": "company", "label": _("From Party Name"), "fieldtype": "Link", "options": "Company", "width": 120 }, { "fieldname": "company_gstin", "label": _("From GSTIN"), "fieldtype": "Data", "width": 100 }, { "fieldname": "from_address_1", "label": _("From Address 1"), "fieldtype": "Data", "width": 120 }, { "fieldname": "from_address_2", "label": _("From Address 2"), "fieldtype": "Data", "width": 120 }, { "fieldname": "from_place", "label": _("From Place"), "fieldtype": "Data", "width": 80 }, { "fieldname": "from_pin_code", "label": _("From Pin Code"), "fieldtype": "Data", "width": 80 }, { "fieldname": "from_state", "label": _("From State"), "fieldtype": "Data", "width": 80 }, { "fieldname": "dispatch_state", "label": _("Dispatch State"), "fieldtype": "Data", "width": 100 }, { "fieldname": "customer", "label": _("To Party Name"), "fieldtype": "Data", "width": 120 }, { "fieldname": "customer_gstin", "label": _("To GSTIN"), "fieldtype": "Data", "width": 120 }, { "fieldname": "to_address_1", "label": _("To Address 1"), "fieldtype": "Data", "width": 120 }, { "fieldname": "to_address_2", "label": _("To Address 2"), "fieldtype": "Data", "width": 120 }, { "fieldname": "to_place", "label": _("To Place"), "fieldtype": "Data", "width": 80 }, { "fieldname": "to_pin_code", "label": _("To Pin Code"), "fieldtype": "Data", "width": 80 }, { "fieldname": "to_state", "label": _("To State"), "fieldtype": "Data", "width": 80 }, { "fieldname": "ship_to_state", "label": _("Ship To State"), "fieldtype": "Data", "width": 100 }, { "fieldname": "item_name", "label": _("Product"), "fieldtype": "Link", "options": "Item", "width": 120 }, { "fieldname": "description", "label": _("Description"), "fieldtype": "Data", "width": 100 }, { "fieldname": "gst_hsn_code", "label": _("HSN"), "fieldtype": "Data", "width": 120 }, { "fieldname": "uom", "label": _("Unit"), "fieldtype": "Data", "width": 100 }, { "fieldname": "qty", "label": _("Qty"), "fieldtype": "Float", "width": 100 }, { "fieldname": "amount", "label": _("Accessable Value"), "fieldtype": "Float", "width": 120 }, { "fieldname": "tax_rate", "label": _("Tax Rate"), "fieldtype": "Data", "width": 100 }, { "fieldname": "cgst_amount", "label": _("CGST Amount"), "fieldtype": "Data", "width": 100 }, { "fieldname": "sgst_amount", "label": _("SGST Amount"), "fieldtype": "Data", "width": 100 }, { "fieldname": "igst_amount", "label": _("IGST Amount"), "fieldtype": "Data", "width": 100 }, { "fieldname": "cess_amount", "label": _("CESS Amount"), "fieldtype": "Data", "width": 100 }, { "fieldname": "mode_of_transport", "label": _("Mode of Transport"), "fieldtype": "Data", "width": 100 }, { "fieldname": "distance", "label": _("Distance"), "fieldtype": "Data", "width": 100 }, { "fieldname": "transporter_name", "label": _("Transporter Name"), "fieldtype": "Data", "width": 120 }, { "fieldname": "gst_transporter_id", "label": _("Transporter ID"), "fieldtype": "Data", "width": 100 }, { "fieldname": "lr_no", "label": _("Transport Receipt No"), "fieldtype": "Data", "width": 120 }, { "fieldname": "lr_date", "label": _("Transport Receipt Date"), "fieldtype": "Data", "width": 120 }, { "fieldname": "vehicle_no", "label": _("Vehicle No"), "fieldtype": "Data", "width": 100 }, { "fieldname": "gst_vehicle_type", "label": _("Vehicle Type"), "fieldtype": "Data", "width": 100 }, ] return columns