# Copyright (c) 2013, FinByz Tech Pvt. Ltd. and contributors # For license information, please see license.txt 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("supply_type", "Outward") row.setdefault("sub_type", "Supply") row.setdefault("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_all( "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_all( "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