Merge pull request #22223 from deepeshgarg007/grn_posting
feat: Accounting entries for service item in Purchase receipt
diff --git a/erpnext/accounts/doctype/account/account.json b/erpnext/accounts/doctype/account/account.json
index af252e6..d2659d4 100644
--- a/erpnext/accounts/doctype/account/account.json
+++ b/erpnext/accounts/doctype/account/account.json
@@ -34,11 +34,15 @@
{
"fieldname": "properties",
"fieldtype": "Section Break",
- "oldfieldtype": "Section Break"
+ "oldfieldtype": "Section Break",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "column_break0",
"fieldtype": "Column Break",
+ "show_days": 1,
+ "show_seconds": 1,
"width": "50%"
},
{
@@ -49,7 +53,9 @@
"no_copy": 1,
"oldfieldname": "account_name",
"oldfieldtype": "Data",
- "reqd": 1
+ "reqd": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "account_number",
@@ -57,13 +63,17 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Account Number",
- "read_only": 1
+ "read_only": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
"fieldname": "is_group",
"fieldtype": "Check",
- "label": "Is Group"
+ "label": "Is Group",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "company",
@@ -75,7 +85,9 @@
"options": "Company",
"read_only": 1,
"remember_last_selected_value": 1,
- "reqd": 1
+ "reqd": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "root_type",
@@ -83,7 +95,9 @@
"in_standard_filter": 1,
"label": "Root Type",
"options": "\nAsset\nLiability\nIncome\nExpense\nEquity",
- "read_only": 1
+ "read_only": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "report_type",
@@ -91,24 +105,32 @@
"in_standard_filter": 1,
"label": "Report Type",
"options": "\nBalance Sheet\nProfit and Loss",
- "read_only": 1
+ "read_only": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "eval:doc.is_group==0",
"fieldname": "account_currency",
"fieldtype": "Link",
"label": "Currency",
- "options": "Currency"
+ "options": "Currency",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
"fieldname": "inter_company_account",
"fieldtype": "Check",
- "label": "Inter Company Account"
+ "label": "Inter Company Account",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "column_break1",
"fieldtype": "Column Break",
+ "show_days": 1,
+ "show_seconds": 1,
"width": "50%"
},
{
@@ -120,7 +142,9 @@
"oldfieldtype": "Link",
"options": "Account",
"reqd": 1,
- "search_index": 1
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"description": "Setting Account Type helps in selecting this Account in transactions.",
@@ -130,7 +154,9 @@
"label": "Account Type",
"oldfieldname": "account_type",
"oldfieldtype": "Select",
- "options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nDepreciation\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nTax\nTemporary"
+ "options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nDepreciation\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"description": "Rate at which this tax is applied",
@@ -138,7 +164,9 @@
"fieldtype": "Float",
"label": "Rate",
"oldfieldname": "tax_rate",
- "oldfieldtype": "Currency"
+ "oldfieldtype": "Currency",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"description": "If the account is frozen, entries are allowed to restricted users.",
@@ -147,13 +175,17 @@
"label": "Frozen",
"oldfieldname": "freeze_account",
"oldfieldtype": "Select",
- "options": "No\nYes"
+ "options": "No\nYes",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "balance_must_be",
"fieldtype": "Select",
"label": "Balance must be",
- "options": "\nDebit\nCredit"
+ "options": "\nDebit\nCredit",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "lft",
@@ -162,7 +194,9 @@
"label": "Lft",
"print_hide": 1,
"read_only": 1,
- "search_index": 1
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "rgt",
@@ -171,7 +205,9 @@
"label": "Rgt",
"print_hide": 1,
"read_only": 1,
- "search_index": 1
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "old_parent",
@@ -179,27 +215,33 @@
"hidden": 1,
"label": "Old Parent",
"print_hide": 1,
- "read_only": 1
+ "read_only": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
"depends_on": "eval:(doc.report_type == 'Profit and Loss' && !doc.is_group)",
"fieldname": "include_in_gross",
"fieldtype": "Check",
- "label": "Include in gross"
+ "label": "Include in gross",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
"fieldname": "disabled",
"fieldtype": "Check",
- "label": "Disable"
+ "label": "Disable",
+ "show_days": 1,
+ "show_seconds": 1
}
],
"icon": "fa fa-money",
"idx": 1,
"is_tree": 1,
"links": [],
- "modified": "2020-03-18 17:57:52.063233",
+ "modified": "2020-06-11 15:15:54.338622",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 870718c..3cd57d4 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -587,6 +587,20 @@
else:
amount = flt(item.base_net_amount + item.item_tax_amount, item.precision("base_net_amount"))
+ auto_accounting_for_non_stock_items = cint(frappe.db.get_value('Company', self.company, 'enable_perpetual_inventory_for_non_stock_items'))
+
+ if auto_accounting_for_non_stock_items:
+ service_received_but_not_billed_account = self.get_company_default("service_received_but_not_billed")
+
+ if item.purchase_receipt:
+ # Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
+ expense_booked_in_pr = frappe.db.get_value('GL Entry', {'is_cancelled': 0,
+ 'voucher_type': 'Purchase Receipt', 'voucher_no': item.purchase_receipt, 'voucher_detail_no': item.pr_detail,
+ 'account':service_received_but_not_billed_account}, ['name'])
+
+ if expense_booked_in_pr:
+ expense_account = service_received_but_not_billed_account
+
gl_entries.append(self.get_gl_dict({
"account": expense_account,
"against": self.supplier,
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 875904f..7ae5385 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -264,7 +264,10 @@
["expenses_included_in_valuation",
{"root_type": "Expense", "account_type": "Expenses Included in Valuation"}],
["stock_received_but_not_billed",
- {"root_type": "Liability", "account_type": "Stock Received But Not Billed"}]
+ {"root_type": "Liability", "account_type": "Stock Received But Not Billed"}],
+ ["service_received_but_not_billed",
+ {"root_type": "Liability", "account_type": "Service Received But Not Billed"}],
+
], function(i, v) {
erpnext.company.set_custom_query(frm, v);
});
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index 020a93f..c25edc5 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -67,10 +67,12 @@
"payment_terms",
"auto_accounting_for_stock_settings",
"enable_perpetual_inventory",
+ "enable_perpetual_inventory_for_non_stock_items",
"default_inventory_account",
"stock_adjustment_account",
"column_break_32",
"stock_received_but_not_billed",
+ "service_received_but_not_billed",
"expenses_included_in_valuation",
"fixed_asset_depreciation_settings",
"accumulated_depreciation_account",
@@ -723,6 +725,20 @@
"fieldtype": "Link",
"label": "Default Buying Terms",
"options": "Terms and Conditions"
+ },
+ {
+ "fieldname": "service_received_but_not_billed",
+ "fieldtype": "Link",
+ "ignore_user_permissions": 1,
+ "label": "Service Received But Not Billed",
+ "no_copy": 1,
+ "options": "Account"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_perpetual_inventory_for_non_stock_items",
+ "fieldtype": "Check",
+ "label": "Enable Perpetual Inventory For Non Stock Items"
}
],
"icon": "fa fa-building",
@@ -730,7 +746,7 @@
"image_field": "company_logo",
"is_tree": 1,
"links": [],
- "modified": "2020-03-21 18:09:53.534211",
+ "modified": "2020-06-20 11:38:43.178970",
"modified_by": "Administrator",
"module": "Setup",
"name": "Company",
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 8bcaa28..47b41a9 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -46,6 +46,7 @@
self.validate_currency()
self.validate_coa_input()
self.validate_perpetual_inventory()
+ self.validate_perpetual_inventory_for_non_stock_items()
self.check_country_change()
self.set_chart_of_accounts()
self.validate_parent_company()
@@ -182,6 +183,12 @@
frappe.msgprint(_("Set default inventory account for perpetual inventory"),
alert=True, indicator='orange')
+ def validate_perpetual_inventory_for_non_stock_items(self):
+ if not self.get("__islocal"):
+ if cint(self.enable_perpetual_inventory_for_non_stock_items) == 1 and not self.service_received_but_not_billed:
+ frappe.throw(_("Set default {0} account for perpetual inventory for non stock items").format(
+ frappe.bold('Service Received But Not Billed')))
+
def check_country_change(self):
frappe.flags.country_change = False
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index e6ab8d6..d0ba001 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -211,6 +211,7 @@
stock_rbnb = self.get_company_default("stock_received_but_not_billed")
landed_cost_entries = get_item_account_wise_additional_cost(self.name)
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
+ auto_accounting_for_non_stock_items = cint(frappe.db.get_value('Company', self.company, 'enable_perpetual_inventory_for_non_stock_items'))
gl_entries = []
warehouse_with_no_account = []
@@ -301,6 +302,32 @@
elif d.warehouse not in warehouse_with_no_account or \
d.rejected_warehouse not in warehouse_with_no_account:
warehouse_with_no_account.append(d.warehouse)
+ elif d.item_code not in stock_items and flt(d.qty) and auto_accounting_for_non_stock_items:
+
+ service_received_but_not_billed_account = self.get_company_default("service_received_but_not_billed")
+ credit_currency = get_account_currency(service_received_but_not_billed_account)
+
+ gl_entries.append(self.get_gl_dict({
+ "account": service_received_but_not_billed_account,
+ "against": d.expense_account,
+ "cost_center": d.cost_center,
+ "remarks": self.get("remarks") or _("Accounting Entry for Service"),
+ "project": d.project,
+ "credit": d.amount,
+ "voucher_detail_no": d.name
+ }, credit_currency, item=d))
+
+ debit_currency = get_account_currency(d.expense_account)
+
+ gl_entries.append(self.get_gl_dict({
+ "account": d.expense_account,
+ "against": service_received_but_not_billed_account,
+ "cost_center": d.cost_center,
+ "remarks": self.get("remarks") or _("Accounting Entry for Service"),
+ "project": d.project,
+ "debit": d.amount,
+ "voucher_detail_no": d.name
+ }, debit_currency, item=d))
self.get_asset_gl_entry(gl_entries)
# Cost center-wise amount breakup for other charges included for valuation
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json
index c9a3527..9c5d3d8 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.json
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.json
@@ -216,7 +216,7 @@
"idx": 1,
"issingle": 1,
"links": [],
- "modified": "2020-04-01 18:11:25.417678",
+ "modified": "2020-06-20 11:39:15.344112",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Settings",