From 3a15c92c5e4cfdd12e2dbafc7114c95d0c6d233e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 4 Mar 2016 12:30:46 +0530 Subject: [PATCH] Fixed Asset Depreciation first commit --- erpnext/accounts/doctype/asset/__init__.py | 0 erpnext/accounts/doctype/asset/asset.js | 23 + erpnext/accounts/doctype/asset/asset.json | 462 ++++++++++++++++++ erpnext/accounts/doctype/asset/asset.py | 65 +++ .../accounts/doctype/asset/depreciation.py | 117 +++++ erpnext/accounts/doctype/asset/test_asset.py | 12 + .../doctype/asset_category/__init__.py | 0 .../doctype/asset_category/asset_category.js | 8 + .../asset_category/asset_category.json | 257 ++++++++++ .../doctype/asset_category/asset_category.py | 10 + .../asset_category/test_asset_category.py | 12 + .../doctype/depreciation_schedule/__init__.py | 0 .../depreciation_schedule.json | 159 ++++++ .../depreciation_schedule.py | 10 + .../doctype/journal_entry/journal_entry.json | 50 +- .../purchase_invoice/purchase_invoice.js | 6 +- .../purchase_invoice/purchase_invoice.py | 57 ++- .../purchase_invoice_item.json | 28 +- .../doctype/sales_invoice/sales_invoice.py | 9 - .../sales_invoice_item.json | 28 +- erpnext/controllers/queries.py | 24 + erpnext/manufacturing/doctype/bom/bom.py | 2 +- erpnext/patches.txt | 3 +- erpnext/patches/v6_24/rename_item_field.py | 10 + erpnext/setup/doctype/company/company.json | 159 +++++- erpnext/stock/doctype/item/item.js | 21 +- erpnext/stock/doctype/item/item.json | 6 +- erpnext/stock/doctype/item/test_records.json | 24 +- 28 files changed, 1462 insertions(+), 100 deletions(-) create mode 100644 erpnext/accounts/doctype/asset/__init__.py create mode 100644 erpnext/accounts/doctype/asset/asset.js create mode 100644 erpnext/accounts/doctype/asset/asset.json create mode 100644 erpnext/accounts/doctype/asset/asset.py create mode 100644 erpnext/accounts/doctype/asset/depreciation.py create mode 100644 erpnext/accounts/doctype/asset/test_asset.py create mode 100644 erpnext/accounts/doctype/asset_category/__init__.py create mode 100644 erpnext/accounts/doctype/asset_category/asset_category.js create mode 100644 erpnext/accounts/doctype/asset_category/asset_category.json create mode 100644 erpnext/accounts/doctype/asset_category/asset_category.py create mode 100644 erpnext/accounts/doctype/asset_category/test_asset_category.py create mode 100644 erpnext/accounts/doctype/depreciation_schedule/__init__.py create mode 100644 erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json create mode 100644 erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.py create mode 100644 erpnext/patches/v6_24/rename_item_field.py diff --git a/erpnext/accounts/doctype/asset/__init__.py b/erpnext/accounts/doctype/asset/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/asset/asset.js b/erpnext/accounts/doctype/asset/asset.js new file mode 100644 index 0000000000..e961b7d5ed --- /dev/null +++ b/erpnext/accounts/doctype/asset/asset.js @@ -0,0 +1,23 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.provide("erpnext.asset"); + +frappe.ui.form.on('Asset', { + refresh: function(frm) { + cur_frm.add_custom_button("Scrap", function() { + erpnext.asset.scrap_asset(); + }); + }, +}); + +erpnext.asset.scrap_asset = function() { + frappe.confirm(__("Do you really want to scrap this asset?"), function () { + frappe.call({ + args: { + "asset_name": frm.doc.name + }, + method: "erpnext.accounts.doctype.asset.depreciation.scrap_asset" + }) + }) +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset/asset.json b/erpnext/accounts/doctype/asset/asset.json new file mode 100644 index 0000000000..760e00d5a5 --- /dev/null +++ b/erpnext/accounts/doctype/asset/asset.json @@ -0,0 +1,462 @@ +{ + "allow_copy": 0, + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:asset_name", + "creation": "2016-03-01 17:01:27.920130", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Document", + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "asset_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Asset Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "asset_category", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Asset Category", + "length": 0, + "no_copy": 0, + "options": "Asset Category", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Available", + "fieldname": "status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Status", + "length": 0, + "no_copy": 0, + "options": "Available\nSold\nScrapped", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_3", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "purchase_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Purchase Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "supplier", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Supplier", + "length": 0, + "no_copy": 0, + "options": "Supplier", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "company", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Company", + "length": 0, + "no_copy": 0, + "options": "Company", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "section_break_5", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Straight Line", + "depends_on": "", + "fieldname": "depreciation_method", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Depreciation Method", + "length": 0, + "no_copy": 0, + "options": "\nStraight Line\nDouble Declining Balance", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "The time period over which the company expects that the asset will be productive", + "fieldname": "useful_life", + "fieldtype": "Int", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Useful Life (Years)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "start_depreciation_from_purchase_date", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Start Depreciation from Purchase Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_11", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "gross_value", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Gross Value", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "The estimated resale value of an asset at the end of its useful life", + "fieldname": "salvage_value", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Salvage Value", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "fieldname": "section_break_14", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Depreciation Schedule", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "schedules", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Depreciation Schedules", + "length": 0, + "no_copy": 0, + "options": "Depreciation Schedule", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2016-03-03 17:34:00.991228", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Asset", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset/asset.py b/erpnext/accounts/doctype/asset/asset.py new file mode 100644 index 0000000000..0479d0aeaf --- /dev/null +++ b/erpnext/accounts/doctype/asset/asset.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import flt, add_years +from frappe.model.document import Document + +class Asset(Document): + def validate(self): + self.validate_mandatory() + self.make_depreciation_schedule() + + def validate_mandatory(self): + if not self.useful_life: + self.useful_life = frappe.db.get_value("Asset Category", self.asset_category, "useful_life") + if not self.useful_life: + frappe.throw(_("Useful Life is mandatory")) + + def make_depreciation_schedule(self): + self.schedules = [] + if not self.get("schedules") and self.status == "Available": + depreciation_method = self.get_depreciation_method() + + accumulated_depreciation = 0 + value_after_depreciation = flt(self.gross_value) + for n in xrange(self.useful_life): + depreciation_date = add_years(self.purchase_date, + n if self.start_depreciation_from_purchase_date else n+1) + depreciation_amount = self.get_depreciation_amount(value_after_depreciation, + depreciation_method) + + self.append("schedules", { + "depreciation_date": depreciation_date, + "depreciation_amount": depreciation_amount, + "accumulated_depreciation_amount": accumulated_depreciation + depreciation_amount + }) + + def get_depreciation_method(self): + depreciation_method = self.depreciation_method or \ + frappe.db.get_value("Asset Category", self.asset_category, "depreciation_method") or \ + frappe.db.get_value("Company", self.company, "depreciation_method") + + if not depreciation_method: + frappe.throw(_("Please set Depreciation Method in Asset Category {0} or Company {1}") + .format(self.asset_category, self.company)) + + def get_depreciation_amount(self, depreciable_value, depreciation_method=None): + if not depreciation_method: + depreciation_method = self.get_depreciation_method() + + if depreciation_method == "Straight Line": + depreciation_amount = (flt(self.gross_value) - flt(self.salvage_value)) / flt(self.useful_life) + else: + factor = 200 / self.useful_life + depreciation_amount = depreciable_value * factor / 100 + + value_after_depreciation = flt(depreciable_value) - depreciation_amount + if value_after_depreciation < self.salvage_value: + depreciation_amount = flt(depreciable_value) - flt(self.salvage_value) + + return depreciation_amount + \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset/depreciation.py b/erpnext/accounts/doctype/asset/depreciation.py new file mode 100644 index 0000000000..48a964a6eb --- /dev/null +++ b/erpnext/accounts/doctype/asset/depreciation.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import flt, today + + +# Depreciate +#------------ + +def post_depreciation_entries(self): + assets = get_depreciable_assets() + for asset in assets: + depreciate_asset(asset.asset_name, asset.depreciation_amount, asset.schedule_row) + +def get_depreciable_assets(date=None): + if not date: + date = today() + + return frappe.db.sql(""" + select a.name as asset_name, ds.depreciation_amount, ds.name as schedule_row + from tabAsset a, `tabDepreciation Schedule` ds + where + a.name = ds.parent and ds.depreciation_date=%s + and a.status = 'Available' and ds.posted=0 and a.docstatus < 2""", date, as_dict=1) + +def depreciate_asset(asset_name, depreciation_amount, schedule_row): + asset = frappe.get_doc("Asset", asset_name) + accumulated_depreciation_account, depreciation_expense_account = get_depreciation_accounts(asset) + + je = frappe.new_doc("Journal Entry") + je.voucher_type = "Depreciation Entry" + je.posting_date = today() + je.company = asset.company + je.remark = "Depreciation Entry against {0} worth {1}".format(asset_name, depreciation_amount) + + je.append("accounts", { + "account": accumulated_depreciation_account, + "credit_in_account_currency": depreciation_amount, + "reference_type": "Asset", + "reference_name": asset.name + }) + + je.append("accounts", { + "account": depreciation_expense_account, + "debit_in_account_currency": depreciation_amount, + "reference_type": "Asset", + "reference_name": asset.name + }) + + je.flags.ignore_permissions = True + je.submit() + + frappe.db.sql("""update `tabDepreciation Schedule` + set posted=1, journal_entry=%s, modified=now(), modified_by=%s where name=%s""", + (je.name, frappe.session.user, schedule_row)) + +def get_depreciation_accounts(asset): + accumulated_depreciation_account, depreciation_expense_account = frappe.db.get_value("Asset Category", + asset.asset_category, ["accumulated_depreciation_account", "depreciation_expense_account"]) + + if not accumulated_depreciation_account or not depreciation_expense_account: + accounts = frappe.db.get_value("Company", asset.company, + ["accumulated_depreciation_account", "depreciation_expense_account"]) + if not accumulated_depreciation_account: + accumulated_depreciation_account = accounts[0] + if not depreciation_expense_account: + depreciation_expense_account = accounts[1] + + if not accumulated_depreciation_account or not depreciation_expense_account: + frappe.throw(_("Please set Depreciation related Accounts in Asset Category {0} or Company {1}") + .format(asset.asset_category, asset.company)) + + return accumulated_depreciation_account, depreciation_expense_account + +# Scrap +#--------- + +@frappe.whitelist() +def scrap_asset(asset_name): + asset = frappe.get_doc("Asset", asset_name) + asset.status = "Scrapped" + + accumulated_depr_amount = frappe.db.sql("""select accumulated_depreciation_amount + from `tabDepreciation Schedule` + where parent=%s and posted=1 + order by depreciation_date desc limit 1""") + + accumulated_depr_amount = flt(accumulated_depr_amount[0][0]) if accumulated_depr_amount else 0 + + net_value_after_depreciation = flt(asset.gross_value) - accumulated_depr_amount + + je = frappe.new_doc("Journal Entry") + je.voucher_type = "Depreciation Entry" + je.posting_date = today() + je.company = asset.company + je.remark = "Disposal Entry for asset {0}".format(asset_name) + + # je.append("accounts", { + # "account": accumulated_depreciation_account, + # "credit_in_account_currency": depreciation_amount, + # "reference_type": "Asset", + # "reference_name": asset.name + # }) + # + # je.append("accounts", { + # "account": depreciation_expense_account, + # "debit_in_account_currency": depreciation_amount, + # "reference_type": "Asset", + # "reference_name": asset.name + # }) + + je.flags.ignore_permissions = True + je.submit() \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset/test_asset.py b/erpnext/accounts/doctype/asset/test_asset.py new file mode 100644 index 0000000000..cada250b46 --- /dev/null +++ b/erpnext/accounts/doctype/asset/test_asset.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +# test_records = frappe.get_test_records('Asset') + +class TestAsset(unittest.TestCase): + pass diff --git a/erpnext/accounts/doctype/asset_category/__init__.py b/erpnext/accounts/doctype/asset_category/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/asset_category/asset_category.js b/erpnext/accounts/doctype/asset_category/asset_category.js new file mode 100644 index 0000000000..84f0dfc76c --- /dev/null +++ b/erpnext/accounts/doctype/asset_category/asset_category.js @@ -0,0 +1,8 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Asset Category', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/accounts/doctype/asset_category/asset_category.json b/erpnext/accounts/doctype/asset_category/asset_category.json new file mode 100644 index 0000000000..9338e22e16 --- /dev/null +++ b/erpnext/accounts/doctype/asset_category/asset_category.json @@ -0,0 +1,257 @@ +{ + "allow_copy": 0, + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:asset_category_name", + "creation": "2016-03-01 17:41:39.778765", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Document", + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "asset_category_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Asset Category Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "section_break_2", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Straight Line", + "fieldname": "depreciation_method", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Depreciation Method", + "length": 0, + "no_copy": 0, + "options": "\nStraight Line\nDouble Declining Balance", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "useful_life", + "fieldtype": "Int", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Useful Life (Years)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_5", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "fixed_asset_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Fixed Asset Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "accumulated_depreciation_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Accumulated Depreciation Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "depreciation_expense_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Depreciation Expense Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2016-03-03 15:17:44.877003", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Asset Category", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset_category/asset_category.py b/erpnext/accounts/doctype/asset_category/asset_category.py new file mode 100644 index 0000000000..8f922d1d95 --- /dev/null +++ b/erpnext/accounts/doctype/asset_category/asset_category.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class AssetCategory(Document): + pass diff --git a/erpnext/accounts/doctype/asset_category/test_asset_category.py b/erpnext/accounts/doctype/asset_category/test_asset_category.py new file mode 100644 index 0000000000..a85fe3d15e --- /dev/null +++ b/erpnext/accounts/doctype/asset_category/test_asset_category.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +# test_records = frappe.get_test_records('Asset Category') + +class TestAssetCategory(unittest.TestCase): + pass diff --git a/erpnext/accounts/doctype/depreciation_schedule/__init__.py b/erpnext/accounts/doctype/depreciation_schedule/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json b/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json new file mode 100644 index 0000000000..89685ccf2a --- /dev/null +++ b/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.json @@ -0,0 +1,159 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 1, + "autoname": "", + "creation": "2016-03-02 15:11:01.278862", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Document", + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "depreciation_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Depreciation Date", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "depreciation_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Depreciation Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "accumulated_depreciation_amount", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Accumulated Depreciation Amount", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "posted", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Posted", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "journal_entry", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Journal Entry", + "length": 0, + "no_copy": 0, + "options": "Journal Entry", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2016-03-03 14:50:39.794061", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Depreciation Schedule", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC" +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.py b/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.py new file mode 100644 index 0000000000..957d6d119f --- /dev/null +++ b/erpnext/accounts/doctype/depreciation_schedule/depreciation_schedule.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class DepreciationSchedule(Document): + pass diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.json b/erpnext/accounts/doctype/journal_entry/journal_entry.json index 63ba380bee..080b1bd295 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.json +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.json @@ -60,31 +60,31 @@ "unique": 0 }, { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "default": "Journal Entry", - "fieldname": "voucher_type", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 1, - "in_list_view": 0, - "label": "Entry Type", - "length": 0, - "no_copy": 0, - "oldfieldname": "voucher_type", - "oldfieldtype": "Select", - "options": "Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry", - "permlevel": 0, - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Journal Entry", + "fieldname": "voucher_type", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_list_view": 0, + "label": "Entry Type", + "length": 0, + "no_copy": 0, + "oldfieldname": "voucher_type", + "oldfieldtype": "Select", + "options": "Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 0, "unique": 0 }, { diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 4d865b8de8..8ab76512f6 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -196,7 +196,7 @@ cur_frm.fields_dict['credit_to'].get_query = function(doc) { // Get Print Heading cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) { -return{ + return { filters:[ ['Print Heading', 'docstatus', '!=', 2] ] @@ -204,8 +204,8 @@ return{ } cur_frm.set_query("expense_account", "items", function(doc) { - return{ - query: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.get_expense_account", + return { + query: "erpnext.controllers.queries.get_expense_account", filters: {'company': doc.company} } }); diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index f95569dc6e..5edfcb9758 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -55,14 +55,15 @@ class PurchaseInvoice(BuyingController): self.set_against_expense_account() self.validate_write_off_account() self.update_valuation_rate("items") - self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", - "items") + self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", "items") + self.validate_fixed_asset_account() self.create_remarks() def create_remarks(self): if not self.remarks: if self.bill_no and self.bill_date: - self.remarks = _("Against Supplier Invoice {0} dated {1}").format(self.bill_no, formatdate(self.bill_date)) + self.remarks = _("Against Supplier Invoice {0} dated {1}").format(self.bill_no, + formatdate(self.bill_date)) else: self.remarks = _("No Remarks") @@ -152,12 +153,13 @@ class PurchaseInvoice(BuyingController): stock_items = self.get_stock_items() for item in self.get("items"): # in case of auto inventory accounting, - # against expense account is always "Stock Received But Not Billed" - # for a stock item and if not epening entry and not drop-ship entry + # expense account is always "Stock Received But Not Billed" for a stock item + # except epening entry, drop-ship entry and fixed asset items - if auto_accounting_for_stock and item.item_code in stock_items \ - and self.is_opening == 'No' and (not item.po_detail or - not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")): + if auto_accounting_for_stock and item.item_code in stock_items and self.is_opening == 'No' \ + and (not item.po_detail + or not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier") + or not frappe.db.get_value("Item", item.item_code, "is_fixed_asset")): item.expense_account = stock_not_billed_account item.cost_center = None @@ -235,6 +237,7 @@ class PurchaseInvoice(BuyingController): def on_submit(self): self.check_prev_docstatus() + self.post_asset_depreciation() frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype, self.company, self.base_grand_total) @@ -248,6 +251,20 @@ class PurchaseInvoice(BuyingController): self.update_billing_status_in_pr() self.update_project() + + def post_asset_depreciation(self): + from erpnext.accounts.doctype.asset.asset import depreciate_asset + for d in self.get("items"): + if frappe.db.get_value("Item", d.item_code, "is_fixed_asset"): + if not d.asset: + frappe.throw(_("Row #{0}: Asset is mandatory against a Fixed Asset Item").format(d.idx)) + else: + asset = frappe.get_doc("Asset", d.asset) + if asset.start_depreciation_from_purchase_date: + for schedule in asset.get("schedules"): + if schedule.depreciation_date == asset.purchase_date: + depreciate_asset(asset.name, schedule.depreciation_amount, schedule.name) + break def make_gl_entries(self): auto_accounting_for_stock = \ @@ -465,27 +482,17 @@ class PurchaseInvoice(BuyingController): for pr in set(updated_pr): frappe.get_doc("Purchase Receipt", pr).update_billing_percentage(update_modified=update_modified) + + def validate_fixed_asset_account(self): + for d in self.get('items'): + if frappe.db.get_value("Item", d.item_code, "is_fixed_asset"): + account_type = frappe.db.get_value("Account", d.expense_account, "account_type") + if account_type != 'Fixed Asset': + frappe.throw(_("Row {0}# Account must be of type 'Fixed Asset'").format(d.idx)) def on_recurring(self, reference_doc): self.due_date = None -@frappe.whitelist() -def get_expense_account(doctype, txt, searchfield, start, page_len, filters): - from erpnext.controllers.queries import get_match_cond - - # expense account can be any Debit account, - # but can also be a Liability account with account_type='Expense Account' in special circumstances. - # Hence the first condition is an "OR" - return frappe.db.sql("""select tabAccount.name from `tabAccount` - where (tabAccount.report_type = "Profit and Loss" - or tabAccount.account_type in ("Expense Account", "Fixed Asset", "Temporary")) - and tabAccount.is_group=0 - and tabAccount.docstatus!=2 - and tabAccount.company = %(company)s - and tabAccount.{key} LIKE %(txt)s - {mcond}""".format( key=frappe.db.escape(searchfield), mcond=get_match_cond(doctype) ), - { 'company': filters['company'], 'txt': "%%%s%%" % frappe.db.escape(txt) }) - @frappe.whitelist() def make_debit_note(source_name, target_doc=None): from erpnext.controllers.sales_and_purchase_return import make_return_doc diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index ae44c1a4b7..784c7478d8 100755 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -1076,6 +1076,32 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "asset", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Asset", + "length": 0, + "no_copy": 1, + "options": "Asset", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -1239,7 +1265,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-03-18 05:05:27.752823", + "modified": "2016-03-28 05:05:27.752823", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Item", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 2d45abefda..7b9701310b 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -55,7 +55,6 @@ class SalesInvoice(SellingController): self.validate_uom_is_integer("stock_uom", "qty") self.check_close_sales_order("sales_order") self.validate_debit_to_acc() - self.validate_fixed_asset_account() self.clear_unallocated_advances("Sales Invoice Advance", "advances") self.validate_advance_jv("Sales Order") self.add_remarks() @@ -309,14 +308,6 @@ class SalesInvoice(SellingController): self.party_account_currency = account.account_currency - def validate_fixed_asset_account(self): - """Validate Fixed Asset and whether Income Account Entered Exists""" - for d in self.get('items'): - is_asset_item = frappe.db.get_value("Item", d.item_code, "is_asset_item") - account_type = frappe.db.get_value("Account", d.income_account, "account_type") - if is_asset_item == 1 and account_type != 'Fixed Asset': - msgprint(_("Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item").format(d.income_account, d.item_code), raise_exception=True) - def validate_with_previous_doc(self): super(SalesInvoice, self).validate_with_previous_doc({ "Sales Order": { diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 41bff7c47e..498caaf0d6 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -1573,6 +1573,32 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "asset", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Asset", + "length": 0, + "no_copy": 1, + "options": "Asset", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -1631,7 +1657,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-03-22 11:09:35.263922", + "modified": "2016-03-29 11:09:35.263922", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index eff5f53e18..eb16ac5494 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -341,3 +341,27 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters): 'txt': "%%%s%%" % frappe.db.escape(txt), 'company': filters.get("company", "") }) + + +@frappe.whitelist() +def get_expense_account(doctype, txt, searchfield, start, page_len, filters): + from erpnext.controllers.queries import get_match_cond + + if not filters: filters = {} + + condition = "" + if filters.get("company"): + condition += "and tabAccount.company = %(company)s" + + return frappe.db.sql("""select tabAccount.name from `tabAccount` + where (tabAccount.report_type = "Profit and Loss" + or tabAccount.account_type in ("Expense Account", "Fixed Asset", "Temporary")) + and tabAccount.is_group=0 + and tabAccount.docstatus!=2 + and tabAccount.{key} LIKE %(txt)s + {condition} {match_condition}""" + .format(condition=condition, key=frappe.db.escape(searchfield), + match_condition=get_match_cond(doctype)), { + 'company': filters['company'], + 'txt': "%%%s%%" % frappe.db.escape(txt) + }) \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 24a21d96ab..97196f071c 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -56,7 +56,7 @@ class BOM(Document): self.manage_default_bom() def get_item_det(self, item_code): - item = frappe.db.sql("""select name, item_name, is_asset_item, is_purchase_item, + item = frappe.db.sql("""select name, item_name, is_fixed_asset, is_purchase_item, docstatus, description, image, is_sub_contracted_item, stock_uom, default_bom, last_purchase_rate from `tabItem` where name=%s""", item_code, as_dict = 1) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d0b738fd43..5c2376eef8 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -258,4 +258,5 @@ execute:frappe.delete_doc_if_exists("Web Form", "contact") #2016-03-10 erpnext.patches.v6_20x.remove_fiscal_year_from_holiday_list erpnext.patches.v6_24.map_customer_address_to_shipping_address_on_po erpnext.patches.v6_27.fix_recurring_order_status -erpnext.patches.v6_20x.remove_customer_supplier_roles \ No newline at end of file +erpnext.patches.v6_20x.remove_customer_supplier_roles +erpnext.patches.v6_24.rename_item_field diff --git a/erpnext/patches/v6_24/rename_item_field.py b/erpnext/patches/v6_24/rename_item_field.py new file mode 100644 index 0000000000..1425d8f68b --- /dev/null +++ b/erpnext/patches/v6_24/rename_item_field.py @@ -0,0 +1,10 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.utils.rename_field import rename_field + +def execute(): + frappe.reload_doctype("Item") + rename_field("Item", "is_asset_item", "is_fixed_asset") \ No newline at end of file diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json index 76165ef48e..3de72fdc3a 100644 --- a/erpnext/setup/doctype/company/company.json +++ b/erpnext/setup/doctype/company/company.json @@ -961,6 +961,160 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "fixed_asset_depreciation_settings", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Fixed Asset Depreciation Settings", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Straight Line", + "fieldname": "depreciation_method", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Depreciation Method", + "length": 0, + "no_copy": 0, + "options": "Straight Line\nDouble Declining Balance", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "accumulated_depreciation_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Accumulated Depreciation Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "column_break_40", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "depreciation_expense_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Depreciation Expense Account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "fieldname": "gain_loss_account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Gain/Loss Account on Asset Sale/Disposal", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -1236,7 +1390,7 @@ "max_attachments": 0, "menu_index": 0, "modified": "2016-03-08 20:21:46.331870", - "modified_by": "anand@erpnext.com", + "modified_by": "Administrator", "module": "Setup", "name": "Company", "owner": "Administrator", @@ -1384,5 +1538,6 @@ ], "read_only": 0, "read_only_onload": 0, - "sort_order": "ASC" + "sort_order": "ASC", + "version": 0 } \ No newline at end of file diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index a691f2f9d2..213050c348 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -111,40 +111,27 @@ frappe.ui.form.on("Item", { $.extend(erpnext.item, { setup_queries: function(frm) { - // Expense Account - // --------------------------------- frm.fields_dict['expense_account'].get_query = function(doc) { return { - filters: { - "report_type": "Profit and Loss", - "is_group": 0 - } + query: "erpnext.controllers.queries.get_expense_account", } } - // Income Account - // -------------------------------- frm.fields_dict['income_account'].get_query = function(doc) { return { query: "erpnext.controllers.queries.get_income_account" } } - - // Purchase Cost Center - // ----------------------------- frm.fields_dict['buying_cost_center'].get_query = function(doc) { return { - filters:{ "is_group": 0 } + filters: { "is_group": 0 } } } - - // Sales Cost Center - // ----------------------------- frm.fields_dict['selling_cost_center'].get_query = function(doc) { return { - filters:{ "is_group": 0 } + filters: { "is_group": 0 } } } @@ -159,7 +146,7 @@ $.extend(erpnext.item, { } } - frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) { + frm.fields_dict['item_group'].get_query = function(doc, cdt, cdn) { return { filters: [ ['Item Group', 'docstatus', '!=', 2] diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index 37d0b778bd..e628d0dec5 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -607,14 +607,14 @@ "default": "", "depends_on": "eval:doc.is_stock_item", "description": "", - "fieldname": "is_asset_item", + "fieldname": "is_fixed_asset", "fieldtype": "Check", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Is Fixed Asset Item", + "label": "Is Fixed Asset", "length": 0, "no_copy": 0, "oldfieldname": "is_asset_item", @@ -2323,7 +2323,7 @@ "issingle": 0, "istable": 0, "max_attachments": 1, - "modified": "2016-03-28 08:29:07.922559", + "modified": "2016-03-29 08:29:07.922559", "modified_by": "Administrator", "module": "Stock", "name": "Item", diff --git a/erpnext/stock/doctype/item/test_records.json b/erpnext/stock/doctype/item/test_records.json index ca40d45e1a..91a7493b65 100644 --- a/erpnext/stock/doctype/item/test_records.json +++ b/erpnext/stock/doctype/item/test_records.json @@ -9,7 +9,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -41,7 +41,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -64,7 +64,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -93,7 +93,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -113,7 +113,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -134,7 +134,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 1, "is_purchase_item": 1, "is_sales_item": 1, @@ -151,7 +151,7 @@ "has_batch_no": 0, "has_serial_no": 0, "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -169,7 +169,7 @@ "has_batch_no": 0, "has_serial_no": 1, "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -187,7 +187,7 @@ "has_batch_no": 0, "has_serial_no": 1, "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 0, "is_purchase_item": 1, "is_sales_item": 1, @@ -209,7 +209,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 1, "is_sales_item": 1, "is_stock_item": 1, @@ -229,7 +229,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 1, "is_purchase_item": 1, "is_sales_item": 1, @@ -250,7 +250,7 @@ "has_serial_no": 0, "income_account": "Sales - _TC", "inspection_required": 0, - "is_asset_item": 0, + "is_fixed_asset": 0, "is_pro_applicable": 1, "is_purchase_item": 1, "is_sales_item": 1,