[gst] adde reports + docs
This commit is contained in:
parent
b3c8f44b3e
commit
919a74ad88
@ -502,8 +502,20 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
frm.set_query('company_address', function(doc) {
|
||||
if(!doc.company) {
|
||||
frappe.throw(_('Please set Company'));
|
||||
}
|
||||
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.address.address.address_query',
|
||||
filters: {
|
||||
link_doctype: 'Company',
|
||||
link_name: doc.company
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
project: function(frm){
|
||||
|
@ -940,22 +940,22 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fieldname": "customer_group",
|
||||
"fieldname": "company_address",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"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": "Customer Group",
|
||||
"label": "Company Address",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer Group",
|
||||
"options": "Address",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@ -3489,6 +3489,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Customer Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer Group",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@ -4596,7 +4627,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-16 17:07:55.483734",
|
||||
"modified": "2017-06-22 14:45:35.257640",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
@ -7,11 +7,12 @@ import frappe
|
||||
import datetime
|
||||
from frappe import _, msgprint, scrub
|
||||
from frappe.defaults import get_user_permissions
|
||||
from frappe.model.utils import get_fetch_values
|
||||
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff, \
|
||||
add_years, get_timestamp, nowdate, flt
|
||||
from frappe.contacts.doctype.address.address import get_address_display, get_default_address
|
||||
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
|
||||
from erpnext.exceptions import PartyFrozen, InvalidCurrency, PartyDisabled, InvalidAccountCurrency
|
||||
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext import get_default_currency
|
||||
|
||||
@ -42,7 +43,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
||||
|
||||
party = frappe.get_doc(party_type, party)
|
||||
|
||||
set_address_details(out, party, party_type)
|
||||
set_address_details(out, party, party_type, doctype, company)
|
||||
set_contact_details(out, party, party_type)
|
||||
set_other_values(out, party, party_type)
|
||||
set_price_list(out, party, party_type, price_list)
|
||||
@ -60,10 +61,11 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
||||
|
||||
return out
|
||||
|
||||
def set_address_details(out, party, party_type):
|
||||
def set_address_details(out, party, party_type, doctype=None, company=None):
|
||||
billing_address_field = "customer_address" if party_type == "Lead" \
|
||||
else party_type.lower() + "_address"
|
||||
out[billing_address_field] = get_default_address(party_type, party.name)
|
||||
out.update(get_fetch_values(doctype, billing_address_field, out[billing_address_field]))
|
||||
|
||||
# address display
|
||||
out.address_display = get_address_display(out[billing_address_field])
|
||||
@ -72,6 +74,11 @@ def set_address_details(out, party, party_type):
|
||||
if party_type in ["Customer", "Lead"]:
|
||||
out.shipping_address_name = get_default_address(party_type, party.name, 'is_shipping_address')
|
||||
out.shipping_address = get_address_display(out["shipping_address_name"])
|
||||
out.update(get_fetch_values(doctype, 'shipping_address_name', out.shipping_address_name))
|
||||
|
||||
if doctype and doctype in ['Sales Invoice']:
|
||||
out.company_address = get_default_address('Company', company)
|
||||
out.update(get_fetch_values(doctype, 'company_address', out.company_address))
|
||||
|
||||
def set_contact_details(out, party, party_type):
|
||||
out.contact_person = get_default_contact(party_type, party.name)
|
||||
@ -363,28 +370,28 @@ def get_timeline_data(doctype, name):
|
||||
out.update({ timestamp: count })
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def get_dashboard_info(party_type, party):
|
||||
current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True)
|
||||
company = frappe.db.get_default("company") or frappe.get_all("Company")[0].name
|
||||
party_account_currency = get_party_account_currency(party_type, party, company)
|
||||
company_default_currency = get_default_currency() \
|
||||
or frappe.db.get_value('Company', company, 'default_currency')
|
||||
|
||||
|
||||
if party_account_currency==company_default_currency:
|
||||
total_field = "base_grand_total"
|
||||
else:
|
||||
total_field = "grand_total"
|
||||
|
||||
|
||||
doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice"
|
||||
|
||||
|
||||
billing_this_year = frappe.db.sql("""
|
||||
select sum({0})
|
||||
from `tab{1}`
|
||||
where {2}=%s and docstatus=1 and posting_date between %s and %s
|
||||
""".format(total_field, doctype, party_type.lower()),
|
||||
""".format(total_field, doctype, party_type.lower()),
|
||||
(party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))
|
||||
|
||||
|
||||
total_unpaid = frappe.db.sql("""
|
||||
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
|
||||
from `tabGL Entry`
|
||||
@ -396,5 +403,5 @@ def get_dashboard_info(party_type, party):
|
||||
info["total_unpaid"] = flt(total_unpaid[0][0]) if total_unpaid else 0
|
||||
if party_type == "Supplier":
|
||||
info["total_unpaid"] = -1 * info["total_unpaid"]
|
||||
|
||||
|
||||
return info
|
||||
|
@ -7,11 +7,14 @@ from frappe import _
|
||||
from frappe.utils import flt
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
|
||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = {}
|
||||
columns = get_columns()
|
||||
columns = get_columns(additional_table_columns)
|
||||
last_col = len(columns)
|
||||
|
||||
item_list = get_items(filters)
|
||||
item_list = get_items(filters, additional_query_columns)
|
||||
aii_account_map = get_aii_accounts()
|
||||
if item_list:
|
||||
item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
||||
@ -23,7 +26,7 @@ def execute(filters=None):
|
||||
"width": 80
|
||||
})
|
||||
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
|
||||
|
||||
|
||||
data = []
|
||||
for d in item_list:
|
||||
purchase_receipt = None
|
||||
@ -35,8 +38,16 @@ def execute(filters=None):
|
||||
|
||||
expense_account = d.expense_account or aii_account_map.get(d.company)
|
||||
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.supplier,
|
||||
d.supplier_name, d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
|
||||
purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount]
|
||||
d.supplier_name]
|
||||
|
||||
if additional_query_columns:
|
||||
for col in additional_query_columns:
|
||||
row.append(d.get(col))
|
||||
|
||||
row += [
|
||||
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
|
||||
purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount
|
||||
]
|
||||
|
||||
for tax in tax_accounts:
|
||||
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
|
||||
@ -49,17 +60,27 @@ def execute(filters=None):
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_columns():
|
||||
return [_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
|
||||
def get_columns(additional_table_columns):
|
||||
columns = [
|
||||
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
|
||||
_("Item Group") + ":Link/Item Group:100", _("Invoice") + ":Link/Purchase Invoice:120",
|
||||
_("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120",
|
||||
"Supplier Name::120", "Payable Account:Link/Account:120",
|
||||
"Supplier Name::120"
|
||||
]
|
||||
|
||||
if additional_table_columns:
|
||||
columns += additional_table_columns
|
||||
|
||||
columns += [
|
||||
"Payable Account:Link/Account:120",
|
||||
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
|
||||
_("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100",
|
||||
_("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140",
|
||||
_("Qty") + ":Float:120", _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
|
||||
]
|
||||
|
||||
return columns
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
@ -74,21 +95,23 @@ def get_conditions(filters):
|
||||
|
||||
return conditions
|
||||
|
||||
def get_items(filters):
|
||||
def get_items(filters, additional_query_columns):
|
||||
conditions = get_conditions(filters)
|
||||
match_conditions = frappe.build_match_conditions("Purchase Invoice")
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
select
|
||||
pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
|
||||
pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
|
||||
pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
|
||||
pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate,
|
||||
pi_item.base_net_amount, pi.supplier_name, pi.mode_of_payment
|
||||
pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
|
||||
pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
|
||||
pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate,
|
||||
pi_item.base_net_amount, pi.supplier_name, pi.mode_of_payment {0}
|
||||
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
|
||||
where pi.name = pi_item.parent and pi.docstatus = 1 %s %s
|
||||
order by pi.posting_date desc, pi_item.item_code desc
|
||||
""" % (conditions, match_conditions), filters, as_dict=1)
|
||||
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
|
||||
|
||||
def get_aii_accounts():
|
||||
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
|
||||
@ -104,11 +127,11 @@ def get_tax_accounts(item_list, columns):
|
||||
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
|
||||
|
||||
tax_details = frappe.db.sql("""
|
||||
select
|
||||
select
|
||||
parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
|
||||
from `tabPurchase Taxes and Charges`
|
||||
where parenttype = 'Purchase Invoice' and docstatus = 1
|
||||
and (account_head is not null and account_head != '')
|
||||
from `tabPurchase Taxes and Charges`
|
||||
where parenttype = 'Purchase Invoice' and docstatus = 1
|
||||
and (account_head is not null and account_head != '')
|
||||
and category in ('Total', 'Valuation and Total')
|
||||
and parent in (%s)
|
||||
""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
|
||||
@ -120,17 +143,17 @@ def get_tax_accounts(item_list, columns):
|
||||
if item_wise_tax_detail:
|
||||
try:
|
||||
item_wise_tax_detail = json.loads(item_wise_tax_detail)
|
||||
|
||||
|
||||
for item_code, tax_amount in item_wise_tax_detail.items():
|
||||
tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
|
||||
|
||||
item_net_amount = sum([flt(d.base_net_amount)
|
||||
|
||||
item_net_amount = sum([flt(d.base_net_amount)
|
||||
for d in item_row_map.get(parent, {}).get(item_code, [])])
|
||||
|
||||
|
||||
for d in item_row_map.get(parent, {}).get(item_code, []):
|
||||
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
|
||||
item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
|
||||
|
||||
|
||||
except ValueError:
|
||||
continue
|
||||
elif charge_type == "Actual" and tax_amount:
|
||||
|
@ -8,11 +8,14 @@ from frappe.utils import flt
|
||||
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
|
||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = {}
|
||||
columns = get_columns()
|
||||
columns = get_columns(additional_table_columns)
|
||||
last_col = len(columns)
|
||||
|
||||
item_list = get_items(filters)
|
||||
item_list = get_items(filters, additional_query_columns)
|
||||
if item_list:
|
||||
item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
||||
columns.append({
|
||||
@ -35,10 +38,17 @@ def execute(filters=None):
|
||||
if not delivery_note and d.update_stock:
|
||||
delivery_note = d.parent
|
||||
|
||||
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.customer, d.customer_name,
|
||||
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
|
||||
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.customer, d.customer_name]
|
||||
|
||||
if additional_query_columns:
|
||||
for col in additional_query_columns:
|
||||
row.append(d.get(col))
|
||||
|
||||
row += [
|
||||
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
|
||||
d.territory, d.project, d.company, d.sales_order,
|
||||
delivery_note, d.income_account, d.cost_center, d.qty, d.base_net_rate, d.base_net_amount]
|
||||
delivery_note, d.income_account, d.cost_center, d.qty, d.base_net_rate, d.base_net_amount
|
||||
]
|
||||
|
||||
for tax in tax_accounts:
|
||||
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
|
||||
@ -50,12 +60,18 @@ def execute(filters=None):
|
||||
|
||||
return columns, data
|
||||
|
||||
def get_columns():
|
||||
return [
|
||||
def get_columns(additional_table_columns):
|
||||
columns = [
|
||||
_("Item Code") + ":Link/Item:120", _("Item Name") + "::120",
|
||||
_("Item Group") + ":Link/Item Group:100", _("Invoice") + ":Link/Sales Invoice:120",
|
||||
_("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120",
|
||||
_("Customer Name") + "::120", _("Customer Group") + ":Link/Customer Group:120",
|
||||
_("Customer Name") + "::120"]
|
||||
|
||||
if additional_table_columns:
|
||||
columns += additional_table_columns
|
||||
|
||||
columns += [
|
||||
_("Customer Group") + ":Link/Customer Group:120",
|
||||
_("Receivable Account") + ":Link/Account:120",
|
||||
_("Mode of Payment") + "::120", _("Territory") + ":Link/Territory:80",
|
||||
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
|
||||
@ -66,6 +82,8 @@ def get_columns():
|
||||
_("Amount") + ":Currency/currency:120"
|
||||
]
|
||||
|
||||
return columns
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
@ -76,15 +94,18 @@ def get_conditions(filters):
|
||||
("to_date", " and si.posting_date<=%(to_date)s")):
|
||||
if filters.get(opts[0]):
|
||||
conditions += opts[1]
|
||||
|
||||
|
||||
if filters.get("mode_of_payment"):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Payment`
|
||||
where parent=si.name
|
||||
where parent=si.name
|
||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||
|
||||
return conditions
|
||||
|
||||
def get_items(filters):
|
||||
def get_items(filters, additional_query_columns):
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
@ -93,10 +114,11 @@ def get_items(filters):
|
||||
si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order,
|
||||
si_item.delivery_note, si_item.income_account, si_item.cost_center, si_item.qty,
|
||||
si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
|
||||
si.customer_group, si_item.so_detail, si.update_stock
|
||||
si.customer_group, si_item.so_detail, si.update_stock {0}
|
||||
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
|
||||
where si.name = si_item.parent and si.docstatus = 1 %s
|
||||
order by si.posting_date desc, si_item.item_code desc""" % conditions, filters, as_dict=1)
|
||||
order by si.posting_date desc, si_item.item_code desc
|
||||
""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
|
||||
|
||||
def get_tax_accounts(item_list, columns):
|
||||
import json
|
||||
|
@ -7,10 +7,13 @@ from frappe.utils import flt
|
||||
from frappe import msgprint, _
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
|
||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
invoice_list = get_invoices(filters)
|
||||
columns, expense_accounts, tax_accounts = get_columns(invoice_list)
|
||||
invoice_list = get_invoices(filters, additional_query_columns)
|
||||
columns, expense_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns)
|
||||
|
||||
if not invoice_list:
|
||||
msgprint(_("No record found"))
|
||||
@ -20,8 +23,9 @@ def execute(filters=None):
|
||||
invoice_expense_map, invoice_tax_map = get_invoice_tax_map(invoice_list,
|
||||
invoice_expense_map, expense_accounts)
|
||||
invoice_po_pr_map = get_invoice_po_pr_map(invoice_list)
|
||||
supplier_details = get_supplier_details(invoice_list)
|
||||
|
||||
suppliers = list(set([d.supplier for d in invoice_list]))
|
||||
supplier_details = get_supplier_details(suppliers)
|
||||
|
||||
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
|
||||
|
||||
data = []
|
||||
@ -31,10 +35,18 @@ def execute(filters=None):
|
||||
purchase_receipt = list(set(invoice_po_pr_map.get(inv.name, {}).get("purchase_receipt", [])))
|
||||
project = list(set(invoice_po_pr_map.get(inv.name, {}).get("project", [])))
|
||||
|
||||
row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name,
|
||||
supplier_details.get(inv.supplier),
|
||||
inv.credit_to, inv.mode_of_payment, ", ".join(project), inv.bill_no, inv.bill_date, inv.remarks,
|
||||
", ".join(purchase_order), ", ".join(purchase_receipt), company_currency]
|
||||
row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name]
|
||||
|
||||
if additional_query_columns:
|
||||
for col in additional_query_columns:
|
||||
row.append(inv.get(col))
|
||||
|
||||
row += [
|
||||
supplier_details.get(inv.supplier), # supplier_type
|
||||
inv.credit_to, inv.mode_of_payment, ", ".join(project),
|
||||
inv.bill_no, inv.bill_date, inv.remarks,
|
||||
", ".join(purchase_order), ", ".join(purchase_receipt), company_currency
|
||||
]
|
||||
|
||||
# map expense values
|
||||
base_net_total = 0
|
||||
@ -61,15 +73,20 @@ def execute(filters=None):
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_columns(invoice_list):
|
||||
def get_columns(invoice_list, additional_table_columns):
|
||||
"""return columns based on filters"""
|
||||
columns = [
|
||||
_("Invoice") + ":Link/Purchase Invoice:120", _("Posting Date") + ":Date:80",
|
||||
_("Supplier Id") + "::120", _("Supplier Name") + "::120",
|
||||
_("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120",
|
||||
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
|
||||
_("Invoice") + ":Link/Purchase Invoice:120", _("Posting Date") + ":Date:80",
|
||||
_("Supplier Id") + "::120", _("Supplier Name") + "::120"]
|
||||
|
||||
if additional_table_columns:
|
||||
columns += additional_table_columns
|
||||
|
||||
columns += [
|
||||
_("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120",
|
||||
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
|
||||
_("Bill No") + "::120", _("Bill Date") + ":Date:80", _("Remarks") + "::150",
|
||||
_("Purchase Order") + ":Link/Purchase Order:100",
|
||||
_("Purchase Order") + ":Link/Purchase Order:100",
|
||||
_("Purchase Receipt") + ":Link/Purchase Receipt:100",
|
||||
{
|
||||
"fieldname": "currency",
|
||||
@ -114,27 +131,31 @@ def get_conditions(filters):
|
||||
|
||||
if filters.get("from_date"): conditions += " and posting_date>=%(from_date)s"
|
||||
if filters.get("to_date"): conditions += " and posting_date<=%(to_date)s"
|
||||
|
||||
|
||||
if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
|
||||
|
||||
return conditions
|
||||
|
||||
def get_invoices(filters):
|
||||
def get_invoices(filters, additional_query_columns):
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date, remarks,
|
||||
base_net_total, base_grand_total, outstanding_amount, mode_of_payment
|
||||
from `tabPurchase Invoice`
|
||||
select
|
||||
name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date,
|
||||
remarks, base_net_total, base_grand_total, outstanding_amount,
|
||||
mode_of_payment {0}
|
||||
from `tabPurchase Invoice`
|
||||
where docstatus = 1 %s
|
||||
order by posting_date desc, name desc""" % conditions, filters, as_dict=1)
|
||||
order by posting_date desc, name desc""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
|
||||
|
||||
|
||||
def get_invoice_expense_map(invoice_list):
|
||||
expense_details = frappe.db.sql("""
|
||||
select parent, expense_account, sum(base_net_amount) as amount
|
||||
from `tabPurchase Invoice Item`
|
||||
where parent in (%s)
|
||||
from `tabPurchase Invoice Item`
|
||||
where parent in (%s)
|
||||
group by parent, expense_account
|
||||
""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
|
||||
|
||||
@ -149,7 +170,7 @@ def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
|
||||
tax_details = frappe.db.sql("""
|
||||
select parent, account_head, case add_deduct_tax when "Add" then sum(base_tax_amount_after_discount_amount)
|
||||
else sum(base_tax_amount_after_discount_amount) * -1 end as tax_amount
|
||||
from `tabPurchase Taxes and Charges`
|
||||
from `tabPurchase Taxes and Charges`
|
||||
where parent in (%s) and category in ('Total', 'Valuation and Total')
|
||||
group by parent, account_head, add_deduct_tax
|
||||
""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
|
||||
@ -169,8 +190,8 @@ def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
|
||||
|
||||
def get_invoice_po_pr_map(invoice_list):
|
||||
pi_items = frappe.db.sql("""
|
||||
select parent, purchase_order, purchase_receipt, po_detail, project
|
||||
from `tabPurchase Invoice Item`
|
||||
select parent, purchase_order, purchase_receipt, po_detail, project
|
||||
from `tabPurchase Invoice Item`
|
||||
where parent in (%s) and (ifnull(purchase_order, '') != '' or ifnull(purchase_receipt, '') != '')
|
||||
""" % ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list]), as_dict=1)
|
||||
|
||||
@ -205,9 +226,8 @@ def get_account_details(invoice_list):
|
||||
|
||||
return account_map
|
||||
|
||||
def get_supplier_details(invoice_list):
|
||||
def get_supplier_details(suppliers):
|
||||
supplier_details = {}
|
||||
suppliers = list(set([inv.supplier for inv in invoice_list]))
|
||||
for supp in frappe.db.sql("""select name, supplier_type from `tabSupplier`
|
||||
where name in (%s)""" % ", ".join(["%s"]*len(suppliers)), tuple(suppliers), as_dict=1):
|
||||
supplier_details.setdefault(supp.name, supp.supplier_type)
|
||||
|
@ -12,7 +12,7 @@ def execute(filters=None):
|
||||
def _execute(filters, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = frappe._dict({})
|
||||
|
||||
invoice_list = get_invoices(filters)
|
||||
invoice_list = get_invoices(filters, additional_query_columns)
|
||||
columns, income_accounts, tax_accounts = get_columns(invoice_list, additional_table_columns)
|
||||
|
||||
if not invoice_list:
|
||||
@ -37,8 +37,14 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
|
||||
|
||||
customer_details = customer_map.get(inv.customer, {})
|
||||
row = [
|
||||
inv.name, inv.posting_date, inv.customer, inv.customer_name,
|
||||
inv.customer_gstin, customer_details.get("tax_id"), inv.company_gstin,
|
||||
inv.name, inv.posting_date, inv.customer, inv.customer_name
|
||||
]
|
||||
|
||||
if additional_query_columns:
|
||||
for col in additional_query_columns:
|
||||
row.append(inv.get(col))
|
||||
|
||||
row +=[
|
||||
customer_details.get("customer_group"),
|
||||
customer_details.get("territory"),
|
||||
inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])),
|
||||
@ -134,12 +140,15 @@ def get_conditions(filters):
|
||||
|
||||
return conditions
|
||||
|
||||
def get_invoices(filters):
|
||||
def get_invoices(filters, additional_query_columns):
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""select name, posting_date, debit_to, project, customer, customer_name, remarks,
|
||||
base_net_total, base_grand_total, base_rounded_total, outstanding_amount
|
||||
base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
|
||||
from `tabSales Invoice`
|
||||
where docstatus = 1 %s order by posting_date desc, name desc""" %
|
||||
where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') %
|
||||
conditions, filters, as_dict=1)
|
||||
|
||||
def get_invoice_income_map(invoice_list):
|
||||
@ -197,9 +206,8 @@ def get_invoice_so_dn_map(invoice_list):
|
||||
|
||||
return invoice_so_dn_map
|
||||
|
||||
def get_customer_details(invoice_list):
|
||||
def get_customer_details(customers):
|
||||
customer_map = {}
|
||||
customers = list(set([inv.customer for inv in invoice_list]))
|
||||
for cust in frappe.db.sql("""select name, territory, customer_group from `tabCustomer`
|
||||
where name in (%s)""" % ", ".join(["%s"]*len(customers)), tuple(customers), as_dict=1):
|
||||
customer_map.setdefault(cust.name, cust)
|
||||
|
@ -35,7 +35,7 @@ def get_data():
|
||||
{
|
||||
"type": "report",
|
||||
"name": "Accounts Receivable",
|
||||
"doctype": "Sales Invoice",
|
||||
"doctype": "Sales Invoice",
|
||||
"is_query_report": True
|
||||
},
|
||||
{
|
||||
@ -198,6 +198,35 @@ def get_data():
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Goods and Services Tax (GST India)"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "GST HSN Code",
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "GST Sales Register",
|
||||
"is_query_report": True
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "GST Purchase Register",
|
||||
"is_query_report": True
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "GST Itemised Sales Register",
|
||||
"is_query_report": True
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "GST Itemised Purchase Register",
|
||||
"is_query_report": True
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Budget and Cost Center"),
|
||||
"items": [
|
||||
|
@ -12,4 +12,5 @@ human-resources
|
||||
customer-portal
|
||||
website
|
||||
using-erpnext
|
||||
regional
|
||||
customize-erpnext
|
||||
|
9
erpnext/docs/user/manual/en/regional/index.md
Normal file
9
erpnext/docs/user/manual/en/regional/index.md
Normal file
@ -0,0 +1,9 @@
|
||||
ERPNext aims to support local regulation for all the regions in the world. In most cases ERPNext is very flexible so you can easily add Custom Fields and make Custom Reports to support the regluation of your region.
|
||||
|
||||
As of mid-2017, ERPNext aims to pre-set additional fields and forms required for companies to easily submit reports to the relevant authorities.
|
||||
|
||||
This section is still under-development.
|
||||
|
||||
### Regions
|
||||
|
||||
{index}
|
72
erpnext/docs/user/manual/en/regional/india/index.md
Normal file
72
erpnext/docs/user/manual/en/regional/india/index.md
Normal file
@ -0,0 +1,72 @@
|
||||
# Statutory Requirements for India
|
||||
|
||||
As of 2017, India will fall under the new GST (Goods and Services Tax) regime and ERPNext makes it easy for users to track the details of its Supplier and Customers across Invoices and make the required reports.
|
||||
|
||||
## GST Features in ERPNext
|
||||
|
||||
### 1. Setting up GSTIN
|
||||
|
||||
GST Law requires that you maintain the GSTIN number for all your suppliers and vendors. In ERPNext, GSTIN is linked to the **Address**
|
||||
|
||||
[Add GST in Address]
|
||||
|
||||
**GST for your Company Address**
|
||||
|
||||
You also need to set the Address for your own Company and your Company's GST Number
|
||||
|
||||
Go to the Company master and add the GSTIN to your default address.
|
||||
|
||||
[GST in Company]
|
||||
|
||||
### 2. Setting up HSN Codes
|
||||
|
||||
According to the GST Law, your itemised invoices must contain the HSN Code related to that Item. ERPNext comes pre-installed with all 12,000+ HSN Codes so that you can easily select the relevant HSN Code in your Item
|
||||
|
||||
[Select HSN Code in Item]
|
||||
|
||||
### 3. Making Tax Masters
|
||||
|
||||
To setup Billing in GST, you need to create 3 Tax Accounts for the various GST reporting heads CGST - Central GST, SGST - State GST, IGST - Inter-state GST
|
||||
|
||||
Go to your **Chart of Accounts**, under the Duties and Taxes head of your account, create 3 Accounts
|
||||
|
||||
**Note:** Usually the rate in CGST and SGST is half of IGST. For example if most of your items are billed at 18%, then create IGST at 18%, CGST and SGST at 9% each.
|
||||
|
||||
[Create in COA]
|
||||
|
||||
### 4. Make Tax Templates
|
||||
|
||||
You will have have to make two tax templates for both your sales and purchase, one for in state sales and other for out of state sales.
|
||||
|
||||
In your **In State GST** template, select 2 accounts, SGST and CGST
|
||||
|
||||
[In State]
|
||||
|
||||
In your **Out of State GST** template, select IGST
|
||||
|
||||
[Out of State]
|
||||
|
||||
### 5. Making GST Ready Invoices
|
||||
|
||||
If you have setup the GSTIN of your Customers and Suppliers, and your tax template, you are ready to go for making GST Ready Invoices!
|
||||
|
||||
For **Sales Invoice**,
|
||||
|
||||
1. Select the correct Customer and Item and the address where the transaction will happen.
|
||||
2. Check if the GSTIN of your Company and Supplier have been correctly set.
|
||||
3. Check if the HSN Number has been set in the Item
|
||||
4. Select the the **In State GST** or **Out of State GST** template that you have created based on the type of transaction
|
||||
5. Save and Submit the Invoice
|
||||
|
||||
[Show Invoice]
|
||||
|
||||
### Reports
|
||||
|
||||
ERPNext comes with most of your reports you need to prepare your GST Returns. Go to Accounts > GST India head for the list.
|
||||
|
||||
You can check the impact of your invoice in the **GST Sales Register** and **GST Itemised Sales Register**
|
||||
|
||||
[GST Sales Register]
|
||||
|
||||
[GST Itemised Sales Registe]
|
||||
|
@ -406,4 +406,5 @@ erpnext.patches.v8_0.change_in_words_varchar_length
|
||||
erpnext.patches.v8_0.create_domain_docs #16-05-2017
|
||||
erpnext.patches.v8_0.update_sales_cost_in_project
|
||||
erpnext.patches.v8_0.save_system_settings
|
||||
erpnext.patches.v8_1.delete_deprecated_reports
|
||||
erpnext.patches.v8_1.delete_deprecated_reports
|
||||
erpnext.patches.v8_1.setup_gst_india
|
||||
|
6
erpnext/patches/v8_1/setup_gst_india.py
Normal file
6
erpnext/patches/v8_1/setup_gst_india.py
Normal file
@ -0,0 +1,6 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
if frappe.db.get_single_value('System Settings', 'country')=='India':
|
||||
from erpnext.regional.india.setup import setup
|
||||
setup()
|
@ -104,7 +104,7 @@ body[data-route="pos"] .pos-payment-row {
|
||||
}
|
||||
body[data-route="pos"] .pos-payment-row:hover,
|
||||
body[data-route="pos"] .pos-keyboard-key:hover {
|
||||
background-color: #fafbfc;
|
||||
background-color: #FAFBFC;
|
||||
cursor: pointer;
|
||||
}
|
||||
body[data-route="pos"] .pos-keyboard-key,
|
||||
@ -214,7 +214,7 @@ body[data-route="pos"] .amount-label {
|
||||
font-size: 16px;
|
||||
}
|
||||
body[data-route="pos"] .selected-payment-mode {
|
||||
background-color: #fafbfc;
|
||||
background-color: #FAFBFC;
|
||||
cursor: pointer;
|
||||
}
|
||||
body[data-route="pos"] .pos-invoice-list {
|
||||
|
@ -51,20 +51,28 @@ $.extend(erpnext.queries, {
|
||||
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.contact.contact.contact_query',
|
||||
filters: { link_doctype: frappe.dynamic_link.doctype, link_name: doc[frappe.dynamic_link.fieldname] } };
|
||||
filters: {
|
||||
link_doctype: frappe.dynamic_link.doctype,
|
||||
link_name: doc[frappe.dynamic_link.fieldname]
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
address_query: function(doc) {
|
||||
if(frappe.dynamic_link) {
|
||||
if(!doc[frappe.dynamic_link.fieldname]) {
|
||||
frappe.throw(__("Please set {0}",
|
||||
frappe.throw(__("Please set {0}",
|
||||
[__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))]));
|
||||
}
|
||||
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.address.address.address_query',
|
||||
filters: { link_doctype: frappe.dynamic_link.doctype, link_name: doc[frappe.dynamic_link.fieldname] } };
|
||||
filters: {
|
||||
link_doctype: frappe.dynamic_link.doctype,
|
||||
link_name: doc[frappe.dynamic_link.fieldname]
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@ -85,7 +93,7 @@ $.extend(erpnext.queries, {
|
||||
|
||||
lead_filter: function(doc) {
|
||||
if(!doc.lead) {
|
||||
frappe.throw(__("Please specify a {0}",
|
||||
frappe.throw(__("Please specify a {0}",
|
||||
[__(frappe.meta.get_label(doc.doctype, "lead", doc.name))]));
|
||||
}
|
||||
|
||||
|
8
erpnext/regional/india/address_template.html
Normal file
8
erpnext/regional/india/address_template.html
Normal file
@ -0,0 +1,8 @@
|
||||
{{ address_line1 }}<br>{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}{{ city }}<br>
|
||||
{% if state %}{{ state }}<br>{% endif -%}
|
||||
{% if pincode %}{{ pincode }}<br>{% endif -%}
|
||||
{{ country }}<br>
|
||||
{% if gstin %}GSTIN: {{ gstin }}<br>{% endif -%}
|
||||
{% if phone %}Phone: {{ phone }}<br>{% endif -%}
|
||||
{% if fax %}Fax: {{ fax }}<br>{% endif -%}
|
||||
{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
|
@ -8,16 +8,39 @@ from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||
from frappe.permissions import add_permission
|
||||
from erpnext.regional.india import states
|
||||
|
||||
def install(company):
|
||||
def setup(company=None):
|
||||
make_custom_fields()
|
||||
make_fixtures()
|
||||
add_permissions()
|
||||
add_custom_roles_for_reports()
|
||||
add_hsn_codes()
|
||||
update_address_template()
|
||||
|
||||
def update_address_template():
|
||||
with open(os.path.join(os.path.dirname(__file__), 'address_template.html'), 'r') as f:
|
||||
html = f.read()
|
||||
|
||||
address_template = frappe.db.get_value('Address Template', 'India')
|
||||
if address_template:
|
||||
frappe.db.set_value('Address Template', 'India', 'template', html)
|
||||
else:
|
||||
# make new html template for India
|
||||
frappe.get_doc(
|
||||
doctype='Address Template',
|
||||
country='India',
|
||||
template=html
|
||||
).insert()
|
||||
|
||||
def add_hsn_codes():
|
||||
frappe.reload_doc('regional', 'doctype', 'gst_hsn_code')
|
||||
|
||||
if frappe.db.count('GST HSN Code') > 100:
|
||||
return
|
||||
|
||||
with open(os.path.join(os.path.dirname(__file__), 'hsn_code_data.json'), 'r') as f:
|
||||
hsn_codes = json.loads(f.read())
|
||||
|
||||
frappe.db.commit()
|
||||
frappe.db.sql('truncate `tabGST HSN Code`')
|
||||
|
||||
for d in hsn_codes:
|
||||
@ -26,6 +49,24 @@ def add_hsn_codes():
|
||||
hsn_code.name = hsn_code.hsn_code
|
||||
hsn_code.db_insert()
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
def add_custom_roles_for_reports():
|
||||
for report_name in ('GST Sales Register', 'GST Purchase Register',
|
||||
'GST Itemised Sales Register', 'GST Itemised Purchase Register'):
|
||||
|
||||
frappe.reload_doc('regional', 'report', frappe.scrub(report_name))
|
||||
|
||||
if not frappe.db.get_value('Custom Role', dict(report=report_name)):
|
||||
frappe.get_doc(dict(
|
||||
doctype='Custom Role',
|
||||
report=report_name,
|
||||
roles= [
|
||||
dict(role='Accounts User'),
|
||||
dict(role='Accounts Manager')
|
||||
]
|
||||
)).insert()
|
||||
|
||||
def add_permissions():
|
||||
for doctype in ('GST HSN Code',):
|
||||
add_permission(doctype, 'Accounts Manager', 0)
|
||||
@ -34,23 +75,26 @@ def add_permissions():
|
||||
def make_custom_fields():
|
||||
custom_fields = {
|
||||
'Address': [
|
||||
dict(fieldname='gstin', label='Party GSTIN', fieldtype='Data', insert_after='fax'),
|
||||
dict(fieldname='gstin', label='Party GSTIN', fieldtype='Data',
|
||||
insert_after='fax'),
|
||||
dict(fieldname='gst_state', label='GST State', fieldtype='Select',
|
||||
options='\n'.join(states), insert_after='gstin')
|
||||
],
|
||||
'Purchase Invoice': [
|
||||
dict(fieldname='supplier_gstin', label='Supplier GSTIN',
|
||||
fieldtype='Data', insert_after='supplier_address', options='supplier_address.gstin'),
|
||||
fieldtype='Data', insert_after='supplier_address',
|
||||
options='supplier_address.gstin'),
|
||||
dict(fieldname='company_gstin', label='Company GSTIN',
|
||||
fieldtype='Data', insert_after='fax', options='shipping_address.gstin'),
|
||||
fieldtype='Data', insert_after='shipping_address',
|
||||
options='shipping_address.gstin'),
|
||||
],
|
||||
'Sales Invoice': [
|
||||
dict(fieldname='customer_gstin', label='Customer GSTIN',
|
||||
fieldtype='Data', insert_after='shipping_address', options='shipping_address.gstin'),
|
||||
dict(fieldname='company_address', label='Company Address',
|
||||
fieldtype='Link', insert_after='shipping_address', options='Address'),
|
||||
fieldtype='Data', insert_after='shipping_address',
|
||||
options='shipping_address_name.gstin'),
|
||||
dict(fieldname='company_gstin', label='Company GSTIN',
|
||||
fieldtype='Data', insert_after='fax', options='company_address.gstin'),
|
||||
fieldtype='Data', insert_after='company_address',
|
||||
options='company_address.gstin'),
|
||||
],
|
||||
'Item': [
|
||||
dict(fieldname='gst_hsn_code', label='GST HSN Code',
|
||||
@ -58,11 +102,13 @@ def make_custom_fields():
|
||||
],
|
||||
'Sales Invoice Item': [
|
||||
dict(fieldname='gst_hsn_code', label='GST HSN Code',
|
||||
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='income_account'),
|
||||
fieldtype='Data', options='item_code.gst_hsn_code',
|
||||
insert_after='income_account'),
|
||||
],
|
||||
'Purchase Invoice Item': [
|
||||
dict(fieldname='gst_hsn_code', label='GST HSN Code',
|
||||
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='expense_account'),
|
||||
fieldtype='Data', options='item_code.gst_hsn_code',
|
||||
insert_after='expense_account'),
|
||||
]
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
{% include "erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js" %}
|
||||
|
||||
frappe.query_reports["GST Itemised Purchase Register"] = frappe.query_reports["Item-wise Purchase Register"]
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-06-22 15:25:04.101930",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-06-22 15:25:10.749203",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "GST Itemised Purchase Register",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Purchase Invoice",
|
||||
"report_name": "GST Itemised Purchase Register",
|
||||
"report_type": "Script Report",
|
||||
"roles": []
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from erpnext.accounts.report.item_wise_purchase_register.item_wise_purchase_register import _execute
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters, additional_table_columns=[
|
||||
dict(fieldtype='Data', label='Supplier GSTIN', width=120),
|
||||
dict(fieldtype='Data', label='Company GSTIN', width=120),
|
||||
dict(fieldtype='Data', label='HSN Code', width=120)
|
||||
], additional_query_columns=[
|
||||
'supplier_gstin',
|
||||
'company_gstin',
|
||||
'gst_hsn_code'
|
||||
])
|
@ -0,0 +1,7 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
{% include "erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js" %}
|
||||
|
||||
frappe.query_reports["GST Itemised Sales Register"] = frappe.query_reports["Item-wise Sales Register"]
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-06-22 15:24:43.083217",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-06-22 15:24:50.611910",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "GST Itemised Sales Register",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Sales Invoice",
|
||||
"report_name": "GST Itemised Sales Register",
|
||||
"report_type": "Script Report",
|
||||
"roles": []
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import _execute
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters, additional_table_columns=[
|
||||
dict(fieldtype='Data', label='Customer GSTIN', width=120),
|
||||
dict(fieldtype='Data', label='Company GSTIN', width=120),
|
||||
dict(fieldtype='Data', label='HSN Code', width=120)
|
||||
], additional_query_columns=[
|
||||
'customer_gstin',
|
||||
'company_gstin',
|
||||
'gst_hsn_code'
|
||||
])
|
@ -0,0 +1,7 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
{% include "erpnext/accounts/report/purchase_register/purchase_register.js" %}
|
||||
|
||||
frappe.query_reports["GST Purchase Register"] = frappe.query_reports["Purchase Register"]
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2017-06-22 11:06:40.836073",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-06-22 12:17:15.487392",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "GST Purchase Register",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Purchase Invoice",
|
||||
"report_name": "GST Purchase Register",
|
||||
"report_type": "Script Report",
|
||||
"roles": []
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from erpnext.accounts.report.purchase_register.purchase_register import _execute
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters, additional_table_columns=[
|
||||
dict(fieldtype='Data', label='Supplier GSTIN', width=120),
|
||||
dict(fieldtype='Data', label='Company GSTIN', width=120)
|
||||
], additional_query_columns=[
|
||||
'supplier_gstin',
|
||||
'company_gstin'
|
||||
])
|
||||
|
@ -2,8 +2,6 @@
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
frappe.query_reports["GST Sales Register"] = {
|
||||
"filters": [
|
||||
{% include "erpnext/accounts/report/sales_register/sales_register.js" %}
|
||||
|
||||
]
|
||||
}
|
||||
frappe.query_reports["GST Sales Register"] = frappe.query_reports["Sales Register"]
|
||||
|
@ -7,7 +7,7 @@
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-06-21 16:45:53.253322",
|
||||
"modified": "2017-06-22 11:39:24.609998",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "GST Sales Register",
|
||||
|
@ -2,8 +2,14 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from erpnext.accounts.report.sales_register.sales_register import _execute
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = [], []
|
||||
return columns, data
|
||||
return _execute(filters, additional_table_columns=[
|
||||
dict(fieldtype='Data', label='Customer GSTIN', width=120),
|
||||
dict(fieldtype='Data', label='Company GSTIN', width=120)
|
||||
], additional_query_columns=[
|
||||
'customer_gstin',
|
||||
'company_gstin'
|
||||
])
|
||||
|
@ -20,8 +20,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
},
|
||||
|
||||
setup_queries: function() {
|
||||
|
||||
|
||||
var me = this;
|
||||
|
||||
this.frm.add_fetch("sales_partner", "commission_rate", "commission_rate");
|
||||
|
@ -98,7 +98,7 @@ class Company(Document):
|
||||
def install_country_fixtures(self):
|
||||
path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(self.country))
|
||||
if os.path.exists(path.encode("utf-8")):
|
||||
frappe.get_attr("erpnext.regional.{0}.install.install"
|
||||
frappe.get_attr("erpnext.regional.{0}.setup.setup"
|
||||
.format(self.country.lower()))(self)
|
||||
|
||||
def create_default_warehouses(self):
|
||||
|
@ -584,10 +584,22 @@
|
||||
},
|
||||
|
||||
"India": {
|
||||
"In State GST": {
|
||||
"account_name": ["SGST", "CGST"],
|
||||
"tax_rate": [18.00, 9.00],
|
||||
"default": 1
|
||||
},
|
||||
"Out State GST": {
|
||||
"account_name": "IGST",
|
||||
"tax_rate": 19.00
|
||||
},
|
||||
"SGST": {
|
||||
"account_name": "IGST",
|
||||
"tax_rate": 9.00
|
||||
},
|
||||
"India VAT 5%": {
|
||||
"account_name": "VAT 5%",
|
||||
"tax_rate": 5.00,
|
||||
"default": 1
|
||||
"tax_rate": 5.00
|
||||
},
|
||||
"India VAT 4%": {
|
||||
"account_name": "VAT 4%",
|
||||
|
56
erpnext/setup/setup_wizard/data/test_mfg.json
Normal file
56
erpnext/setup/setup_wizard/data/test_mfg.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"add_sample_data": 1,
|
||||
"bank_account": "HDFC",
|
||||
"company_abbr": "GT",
|
||||
"company_name": "For Testing",
|
||||
"company_tagline": "Just for GST",
|
||||
"country": "India",
|
||||
"currency": "INR",
|
||||
"customer_1": "Test Customer 1",
|
||||
"customer_2": "Test Customer 2",
|
||||
"domain": "Manufacturing",
|
||||
"email": "great@example.com",
|
||||
"full_name": "Great Tester",
|
||||
"fy_end_date": "2018-03-31",
|
||||
"fy_start_date": "2017-04-01",
|
||||
"is_purchase_item_1": 1,
|
||||
"is_purchase_item_2": 1,
|
||||
"is_purchase_item_3": 0,
|
||||
"is_purchase_item_4": 0,
|
||||
"is_purchase_item_5": 0,
|
||||
"is_sales_item_1": 1,
|
||||
"is_sales_item_2": 1,
|
||||
"is_sales_item_3": 1,
|
||||
"is_sales_item_4": 1,
|
||||
"is_sales_item_5": 1,
|
||||
"item_1": "Test Item 1",
|
||||
"item_2": "Test Item 2",
|
||||
"item_group_1": "Products",
|
||||
"item_group_2": "Products",
|
||||
"item_group_3": "Products",
|
||||
"item_group_4": "Products",
|
||||
"item_group_5": "Products",
|
||||
"item_uom_1": "Unit",
|
||||
"item_uom_2": "Unit",
|
||||
"item_uom_3": "Unit",
|
||||
"item_uom_4": "Unit",
|
||||
"item_uom_5": "Unit",
|
||||
"language": "English (United States)",
|
||||
"password": "test",
|
||||
"setup_website": 1,
|
||||
"supplier_1": "Test Supplier 1",
|
||||
"supplier_2": "Test Supplier 2",
|
||||
"timezone": "Asia/Kolkata",
|
||||
"user_accountant_1": 1,
|
||||
"user_accountant_2": 1,
|
||||
"user_accountant_3": 1,
|
||||
"user_accountant_4": 1,
|
||||
"user_purchaser_1": 1,
|
||||
"user_purchaser_2": 1,
|
||||
"user_purchaser_3": 1,
|
||||
"user_purchaser_4": 1,
|
||||
"user_sales_1": 1,
|
||||
"user_sales_2": 1,
|
||||
"user_sales_3": 1,
|
||||
"user_sales_4": 1
|
||||
}
|
@ -84,7 +84,7 @@ def create_fiscal_year_and_company(args):
|
||||
if (args.get('company_name')):
|
||||
frappe.get_doc({
|
||||
"doctype":"Company",
|
||||
'company_name':args.get('company_name').strip(),
|
||||
'company_name':args.get('company_name'),
|
||||
'enable_perpetual_inventory': 1,
|
||||
'abbr':args.get('company_abbr'),
|
||||
'default_currency':args.get('currency'),
|
||||
@ -104,7 +104,7 @@ def enable_shopping_cart(args):
|
||||
frappe.get_doc({
|
||||
"doctype": "Shopping Cart Settings",
|
||||
"enabled": 1,
|
||||
'company': args.get('company_name').strip(),
|
||||
'company': args.get('company_name') ,
|
||||
'price_list': frappe.db.get_value("Price List", {"selling": 1}),
|
||||
'default_customer_group': _("Individual"),
|
||||
'quotation_series': "QTN-",
|
||||
@ -112,7 +112,7 @@ def enable_shopping_cart(args):
|
||||
|
||||
def create_bank_account(args):
|
||||
if args.get("bank_account"):
|
||||
company_name = args.get('company_name').strip()
|
||||
company_name = args.get('company_name')
|
||||
bank_account_group = frappe.db.get_value("Account",
|
||||
{"account_type": "Bank", "is_group": 1, "root_type": "Asset",
|
||||
"company": company_name})
|
||||
@ -152,7 +152,7 @@ def set_defaults(args):
|
||||
global_defaults.update({
|
||||
'current_fiscal_year': args.curr_fiscal_year,
|
||||
'default_currency': args.get('currency'),
|
||||
'default_company':args.get('company_name').strip(),
|
||||
'default_company':args.get('company_name') ,
|
||||
"country": args.get("country"),
|
||||
})
|
||||
|
||||
@ -253,8 +253,10 @@ def create_sales_tax(args):
|
||||
country_wise_tax = get_country_wise_tax(args.get("country"))
|
||||
if country_wise_tax and len(country_wise_tax) > 0:
|
||||
for sales_tax, tax_data in country_wise_tax.items():
|
||||
make_tax_account_and_template(args.get("company_name").strip(),
|
||||
tax_data.get('account_name'), tax_data.get('tax_rate'), sales_tax)
|
||||
make_tax_account_and_template(
|
||||
args.get("company_name"),
|
||||
tax_data.get('account_name'),
|
||||
tax_data.get('tax_rate'), sales_tax)
|
||||
|
||||
def get_country_wise_tax(country):
|
||||
data = {}
|
||||
@ -270,13 +272,20 @@ def create_taxes(args):
|
||||
tax_rate = cstr(args.get("tax_rate_" + str(i)) or "").replace("%", "")
|
||||
account_name = args.get("tax_" + str(i))
|
||||
|
||||
make_tax_account_and_template(args.get("company_name").strip(), account_name, tax_rate)
|
||||
make_tax_account_and_template(args.get("company_name") , account_name, tax_rate)
|
||||
|
||||
def make_tax_account_and_template(company, account_name, tax_rate, template_name=None):
|
||||
try:
|
||||
account = make_tax_account(company, account_name, tax_rate)
|
||||
if account:
|
||||
make_sales_and_purchase_tax_templates(account, template_name)
|
||||
if not isinstance(account_name, (list, tuple)):
|
||||
account_name = [account_name]
|
||||
tax_rate = [tax_rate]
|
||||
|
||||
accounts = []
|
||||
for i, name in enumerate(account_name):
|
||||
accounts.append(make_tax_account(company, account_name[i], tax_rate[i]))
|
||||
|
||||
if accounts:
|
||||
make_sales_and_purchase_tax_templates(accounts, template_name)
|
||||
except frappe.NameError, e:
|
||||
if e.args[2][0]==1062:
|
||||
pass
|
||||
@ -309,30 +318,35 @@ def make_tax_account(company, account_name, tax_rate):
|
||||
"tax_rate": flt(tax_rate) if tax_rate else None
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
def make_sales_and_purchase_tax_templates(account, template_name=None):
|
||||
def make_sales_and_purchase_tax_templates(accounts, template_name=None):
|
||||
if not template_name:
|
||||
template_name = account.name
|
||||
template_name = accounts[0].name
|
||||
|
||||
sales_tax_template = {
|
||||
"doctype": "Sales Taxes and Charges Template",
|
||||
"title": template_name,
|
||||
"company": account.company,
|
||||
"taxes": [{
|
||||
"company": accounts[0].company,
|
||||
'taxes': []
|
||||
}
|
||||
|
||||
for account in accounts:
|
||||
sales_tax_template['taxes'].append({
|
||||
"category": "Valuation and Total",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": account.name,
|
||||
"description": "{0} @ {1}".format(account.account_name, account.tax_rate),
|
||||
"rate": account.tax_rate
|
||||
}]
|
||||
}
|
||||
|
||||
})
|
||||
# Sales
|
||||
frappe.get_doc(copy.deepcopy(sales_tax_template)).insert(ignore_permissions=True)
|
||||
|
||||
# Purchase
|
||||
purchase_tax_template = copy.deepcopy(sales_tax_template)
|
||||
purchase_tax_template["doctype"] = "Purchase Taxes and Charges Template"
|
||||
frappe.get_doc(purchase_tax_template).insert(ignore_permissions=True)
|
||||
|
||||
doc = frappe.get_doc(purchase_tax_template)
|
||||
print frappe.as_json(doc)
|
||||
doc.insert(ignore_permissions=True)
|
||||
|
||||
def create_items(args):
|
||||
for i in xrange(1,6):
|
||||
@ -346,7 +360,7 @@ def create_items(args):
|
||||
if is_stock_item:
|
||||
default_warehouse = frappe.db.get_value("Warehouse", filters={
|
||||
"warehouse_name": _("Finished Goods") if is_sales_item else _("Stores"),
|
||||
"company": args.get("company_name").strip()
|
||||
"company": args.get("company_name")
|
||||
})
|
||||
|
||||
try:
|
||||
@ -405,7 +419,7 @@ def create_customers(args):
|
||||
"customer_type": "Company",
|
||||
"customer_group": _("Commercial"),
|
||||
"territory": args.get("country"),
|
||||
"company": args.get("company_name").strip()
|
||||
"company": args.get("company_name")
|
||||
}).insert()
|
||||
|
||||
if args.get("customer_contact_" + str(i)):
|
||||
@ -423,7 +437,7 @@ def create_suppliers(args):
|
||||
"doctype":"Supplier",
|
||||
"supplier_name": supplier,
|
||||
"supplier_type": _("Local"),
|
||||
"company": args.get("company_name").strip()
|
||||
"company": args.get("company_name")
|
||||
}).insert()
|
||||
|
||||
if args.get("supplier_contact_" + str(i)):
|
||||
@ -434,7 +448,7 @@ def create_suppliers(args):
|
||||
|
||||
def create_contact(contact, party_type, party):
|
||||
"""Create contact based on given contact name"""
|
||||
contact = contact.strip().split(" ")
|
||||
contact = contact .split(" ")
|
||||
|
||||
contact = frappe.get_doc({
|
||||
"doctype":"Contact",
|
||||
@ -466,7 +480,7 @@ def create_logo(args):
|
||||
fileurl = save_file(filename, content, "Website Settings", "Website Settings",
|
||||
decode=True).file_url
|
||||
frappe.db.set_value("Website Settings", "Website Settings", "brand_html",
|
||||
"<img src='{0}' style='max-width: 40px; max-height: 25px;'> {1}".format(fileurl, args.get("company_name").strip()))
|
||||
"<img src='{0}' style='max-width: 40px; max-height: 25px;'> {1}".format(fileurl, args.get("company_name") ))
|
||||
|
||||
def create_territories():
|
||||
"""create two default territories, one for home country and one named Rest of the World"""
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,15 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from erpnext.setup.setup_wizard.test_setup_data import args
|
||||
from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
|
||||
import frappe.utils.scheduler
|
||||
|
||||
if __name__=="__main__":
|
||||
frappe.connect()
|
||||
frappe.local.form_dict = frappe._dict(args)
|
||||
setup_complete()
|
||||
frappe.utils.scheduler.disable_scheduler()
|
15
erpnext/setup/setup_wizard/utils.py
Normal file
15
erpnext/setup/setup_wizard/utils.py
Normal file
@ -0,0 +1,15 @@
|
||||
import json, os
|
||||
|
||||
from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
|
||||
from erpnext.setup.setup_wizard import setup_wizard
|
||||
|
||||
def complete():
|
||||
with open(os.path.join(os.path.dirname(__file__),
|
||||
'data', 'test_mfg.json'), 'r') as f:
|
||||
data = json.loads(f.read())
|
||||
|
||||
#setup_wizard.create_sales_tax(data)
|
||||
setup_complete(data)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user