Merge pull request #5666 from nabinhait/fixed_asset_revisited

Fixed asset revisited
This commit is contained in:
Nabin Hait 2016-07-07 10:33:53 +05:30 committed by GitHub
commit ac418d44d9
17 changed files with 263 additions and 108 deletions

View File

@ -16,7 +16,7 @@ class Account(Document):
frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings", frozen_accounts_modifier = frappe.db.get_value("Accounts Settings", "Accounts Settings",
"frozen_accounts_modifier") "frozen_accounts_modifier")
if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.get_roles(): if not frozen_accounts_modifier or frozen_accounts_modifier in frappe.get_roles():
self.get("__onload").can_freeze_account = True self.set_onload("can_freeze_account", True)
def autoname(self): def autoname(self):
# first validate if company exists # first validate if company exists

View File

@ -27,9 +27,9 @@ frappe.treeview_settings["Account"] = {
{fieldtype:'Select', fieldname:'root_type', label:__('Root Type'), {fieldtype:'Select', fieldname:'root_type', label:__('Root Type'),
options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n')}, options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n')},
{fieldtype:'Select', fieldname:'account_type', label:__('Account Type'), {fieldtype:'Select', fieldname:'account_type', label:__('Account Type'),
options: ['', 'Bank', 'Cash', 'Stock', 'Tax', 'Chargeable'].join('\n'), options: ['', 'Bank', 'Cash', 'Stock', 'Tax', 'Chargeable', 'Fixed Asset'].join('\n'),
description: __("Optional. This setting will be used to filter in various transactions."), description: __("Optional. This setting will be used to filter in various transactions.")
depends_on: 'eval:doc.is_group==1'}, },
{fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate'), {fieldtype:'Float', fieldname:'tax_rate', label:__('Tax Rate'),
depends_on: 'eval:doc.is_group==1&&doc.account_type=="Tax"'}, depends_on: 'eval:doc.is_group==1&&doc.account_type=="Tax"'},
{fieldtype:'Link', fieldname:'warehouse', label:__('Warehouse'), options:"Warehouse", {fieldtype:'Link', fieldname:'warehouse', label:__('Warehouse'), options:"Warehouse",

View File

@ -8,7 +8,9 @@ frappe.ui.form.on('Asset', {
frm.set_query("item_code", function() { frm.set_query("item_code", function() {
return { return {
"filters": { "filters": {
"disabled": 0 "disabled": 0,
"is_fixed_asset": 1,
"is_stock_item": 0
} }
}; };
}); });
@ -25,7 +27,7 @@ frappe.ui.form.on('Asset', {
refresh: function(frm) { refresh: function(frm) {
frappe.ui.form.trigger("Asset", "is_existing_asset"); frappe.ui.form.trigger("Asset", "is_existing_asset");
frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1); frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1);
if (frm.doc.docstatus==1) { if (frm.doc.docstatus==1) {
if (frm.doc.status=='Submitted' && !frm.doc.is_existing_asset && !frm.doc.purchase_invoice) { if (frm.doc.status=='Submitted' && !frm.doc.is_existing_asset && !frm.doc.purchase_invoice) {
frm.add_custom_button("Make Purchase Invoice", function() { frm.add_custom_button("Make Purchase Invoice", function() {
@ -103,7 +105,10 @@ frappe.ui.form.on('Asset', {
}, },
axis: { axis: {
x: { x: {
type: 'category' type: 'timeseries',
tick: {
format: "%d-%m-%Y"
}
}, },
y: { y: {
min: 0, min: 0,
@ -113,12 +118,49 @@ frappe.ui.form.on('Asset', {
}); });
}, },
item_code: function(frm) {
if(frm.doc.item_code) {
frappe.call({
method: "erpnext.accounts.doctype.asset.asset.get_item_details",
args: {
item_code: frm.doc.item_code
},
callback: function(r, rt) {
if(r.message) {
$.each(r.message, function(field, value) {
frm.set_value(field, value);
})
}
}
})
}
},
is_existing_asset: function(frm) { is_existing_asset: function(frm) {
frm.toggle_enable("supplier", frm.doc.is_existing_asset); frm.toggle_enable("supplier", frm.doc.is_existing_asset);
frm.toggle_reqd("next_depreciation_date", !frm.doc.is_existing_asset); frm.toggle_reqd("next_depreciation_date", !frm.doc.is_existing_asset);
} },
}); });
frappe.ui.form.on('Depreciation Schedule', {
make_depreciation_entry: function(frm, cdt, cdn) {
var row = locals[cdt][cdn];
if (!row.journal_entry) {
frappe.call({
method: "erpnext.accounts.doctype.asset.depreciation.make_depreciation_entry",
args: {
"asset_name": frm.doc.name,
"date": row.schedule_date
},
callback: function(r) {
frappe.model.sync(r.message);
frm.refresh();
}
})
}
}
})
erpnext.asset.make_purchase_invoice = function(frm) { erpnext.asset.make_purchase_invoice = function(frm) {
frappe.call({ frappe.call({
args: { args: {

View File

@ -35,32 +35,6 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 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, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -87,6 +61,32 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 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": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -733,13 +733,14 @@
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 72, "idx": 72,
"image_field": "image", "image_field": "image",
"image_view": 0,
"in_create": 0, "in_create": 0,
"in_dialog": 0, "in_dialog": 0,
"is_submittable": 1, "is_submittable": 1,
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-05-30 18:09:56.158782", "modified": "2016-07-05 12:54:38.585259",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Asset", "name": "Asset",

View File

@ -18,6 +18,7 @@ class Asset(Document):
self.validate_asset_values() self.validate_asset_values()
self.set_depreciation_settings() self.set_depreciation_settings()
self.make_depreciation_schedule() self.make_depreciation_schedule()
self.validate_expected_value_after_useful_life()
# Validate depreciation related accounts # Validate depreciation related accounts
get_depreciation_accounts(self) get_depreciation_accounts(self)
@ -30,9 +31,16 @@ class Asset(Document):
self.set_status() self.set_status()
def validate_item(self): def validate_item(self):
item = frappe.get_doc("Item", self.item_code) item = frappe.db.get_value("Item", self.item_code,
if item.disabled: ["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1)
if not item:
frappe.throw(_("Item {0} does not exist").format(self.item_code))
elif item.disabled:
frappe.throw(_("Item {0} has been disabled").format(self.item_code)) frappe.throw(_("Item {0} has been disabled").format(self.item_code))
elif not item.is_fixed_asset:
frappe.throw(_("Item {0} must be a Fixed Asset Item").format(self.item_code))
elif item.is_stock_item:
frappe.throw(_("Item {0} must be a non-stock item").format(self.item_code))
def validate_asset_values(self): def validate_asset_values(self):
self.value_after_depreciation = flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation) self.value_after_depreciation = flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)
@ -117,6 +125,18 @@ class Asset(Document):
depreciation_amount = flt(depreciable_value) - flt(self.expected_value_after_useful_life) depreciation_amount = flt(depreciable_value) - flt(self.expected_value_after_useful_life)
return depreciation_amount return depreciation_amount
def validate_expected_value_after_useful_life(self):
if self.depreciation_method == "Double Declining Balance":
accumulated_depreciation_after_full_schedule = \
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
flt(accumulated_depreciation_after_full_schedule))
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")
.format(asset_value_after_full_schedule))
def validate_cancellation(self): def validate_cancellation(self):
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"): if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
@ -203,4 +223,17 @@ def transfer_asset(args):
frappe.db.commit() frappe.db.commit()
frappe.msgprint(_("Asset Movement record {0} created").format("<a href='#Form/Asset Movement/{0}'>{0}</a>".format(movement_entry.name))) frappe.msgprint(_("Asset Movement record {0} created").format("<a href='#Form/Asset Movement/{0}'>{0}</a>".format(movement_entry.name)))
@frappe.whitelist()
def get_item_details(item_code):
asset_category = frappe.db.get_value("Item", item_code, "asset_category")
ret = frappe.db.get_value("Asset Category", asset_category,
["depreciation_method", "total_number_of_depreciations", "frequency_of_depreciation"], as_dict=1)
ret.update({
"asset_category": asset_category
})
return ret

View File

@ -21,7 +21,10 @@ def get_depreciable_assets(date):
and a.status in ('Submitted', 'Partially Depreciated') and a.status in ('Submitted', 'Partially Depreciated')
and ifnull(ds.journal_entry, '')=''""", date) and ifnull(ds.journal_entry, '')=''""", date)
@frappe.whitelist()
def make_depreciation_entry(asset_name, date=None): def make_depreciation_entry(asset_name, date=None):
frappe.has_permission('Journal Entry', throw=True)
if not date: if not date:
date = today() date = today()
@ -62,6 +65,8 @@ def make_depreciation_entry(asset_name, date=None):
asset.db_set("value_after_depreciation", asset.value_after_depreciation) asset.db_set("value_after_depreciation", asset.value_after_depreciation)
asset.set_status() asset.set_status()
return asset
def get_depreciation_accounts(asset): def get_depreciation_accounts(asset):
fixed_asset_account = accumulated_depreciation_account = depreciation_expense_account = None fixed_asset_account = accumulated_depreciation_account = depreciation_expense_account = None
@ -119,6 +124,8 @@ def scrap_asset(asset_name):
frappe.db.set_value("Asset", asset_name, "disposal_date", today()) frappe.db.set_value("Asset", asset_name, "disposal_date", today())
frappe.db.set_value("Asset", asset_name, "journal_entry_for_scrap", je.name) frappe.db.set_value("Asset", asset_name, "journal_entry_for_scrap", je.name)
asset.set_status("Scrapped") asset.set_status("Scrapped")
frappe.msgprint(_("Asset scrapped via Journal Entry {0}").format(je.name))
@frappe.whitelist() @frappe.whitelist()
def restore_asset(asset_name): def restore_asset(asset_name):

View File

@ -258,9 +258,11 @@ def create_fixed_asset_item():
"item_code": "Macbook Pro", "item_code": "Macbook Pro",
"item_name": "Macbook Pro", "item_name": "Macbook Pro",
"description": "Macbook Pro Retina Display", "description": "Macbook Pro Retina Display",
"asset_category": "Computers",
"item_group": "All Item Groups", "item_group": "All Item Groups",
"stock_uom": "Nos", "stock_uom": "Nos",
"is_stock_item": 0 "is_stock_item": 0,
"is_fixed_asset": 1
}).insert() }).insert()
except frappe.DuplicateEntryError: except frappe.DuplicateEntryError:
pass pass

View File

@ -2,9 +2,18 @@
// For license information, please see license.txt // For license information, please see license.txt
frappe.ui.form.on('Asset Category', { frappe.ui.form.on('Asset Category', {
setup: function(frm) {
frm.get_field('accounts').grid.editable_fields = [
{fieldname: 'company_name', columns: 2},
{fieldname: 'fixed_asset_account', columns: 3},
{fieldname: 'accumulated_depreciation_account', columns: 3},
{fieldname: 'depreciation_expense_account', columns: 3}
];
},
onload: function(frm) { onload: function(frm) {
frm.add_fetch('company_name', 'accumulated_depreciation_account', 'accumulated_depreciation_account'); frm.add_fetch('company_name', 'accumulated_depreciation_account', 'accumulated_depreciation_account');
frm.add_fetch('company_name', 'depreciation_expense_account', 'depreciation_expense_account'); frm.add_fetch('company_name', 'depreciation_expense_account', 'accumulated_depreciation_account');
frm.set_query('fixed_asset_account', 'accounts', function(doc, cdt, cdn) { frm.set_query('fixed_asset_account', 'accounts', function(doc, cdt, cdn) {
var d = locals[cdt][cdn]; var d = locals[cdt][cdn];
@ -13,7 +22,7 @@ frappe.ui.form.on('Asset Category', {
"account_type": "Fixed Asset", "account_type": "Fixed Asset",
"root_type": "Asset", "root_type": "Asset",
"is_group": 0, "is_group": 0,
"company": d.company "company": d.company_name
} }
}; };
}); });
@ -24,7 +33,7 @@ frappe.ui.form.on('Asset Category', {
"filters": { "filters": {
"root_type": "Asset", "root_type": "Asset",
"is_group": 0, "is_group": 0,
"company": d.company "company": d.company_name
} }
}; };
}); });
@ -35,7 +44,7 @@ frappe.ui.form.on('Asset Category', {
"filters": { "filters": {
"root_type": "Expense", "root_type": "Expense",
"is_group": 0, "is_group": 0,
"company": d.company "company": d.company_name
} }
}; };
}); });

View File

@ -3,6 +3,7 @@
"allow_import": 0, "allow_import": 0,
"allow_rename": 1, "allow_rename": 1,
"autoname": "", "autoname": "",
"beta": 0,
"creation": "2016-03-02 15:11:01.278862", "creation": "2016-03-02 15:11:01.278862",
"custom": 0, "custom": 0,
"docstatus": 0, "docstatus": 0,
@ -135,18 +136,45 @@
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
},
{
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"depends_on": "eval:(!doc.journal_entry && doc.schedule_date <= get_today())",
"fieldname": "make_depreciation_entry",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Make Depreciation Entry",
"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
} }
], ],
"hide_heading": 0, "hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 0, "idx": 0,
"image_view": 0,
"in_create": 0, "in_create": 0,
"in_dialog": 0, "in_dialog": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-04-20 16:43:21.407123", "modified": "2016-07-06 12:38:32.456903",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Depreciation Schedule", "name": "Depreciation Schedule",

View File

@ -165,7 +165,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
var row = locals[cdt][cdn]; var row = locals[cdt][cdn];
if(row.asset) { if(row.asset) {
frappe.call({ frappe.call({
method: erpnext.accounts.doctype.purchase_invoice.purchase_invoice.get_fixed_asset_account, method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.get_fixed_asset_account",
args: { args: {
"asset": row.asset, "asset": row.asset,
"account": row.expense_account "account": row.expense_account

View File

@ -181,15 +181,16 @@ class PurchaseInvoice(BuyingController):
# expense account is always "Stock Received But Not Billed" for a stock item # expense account is always "Stock Received But Not Billed" for a stock item
# except epening entry, drop-ship entry and fixed asset items # 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' \ if auto_accounting_for_stock and item.item_code in stock_items \
and (not item.po_detail or not item.is_fixed_asset and self.is_opening == 'No' and not item.is_fixed_asset \
or not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")): and (not item.po_detail or
not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")):
if self.update_stock: if self.update_stock:
item.expense_account = warehouse_account[item.warehouse]["name"] item.expense_account = warehouse_account[item.warehouse]["name"]
else: else:
item.expense_account = stock_not_billed_account item.expense_account = stock_not_billed_account
elif not item.expense_account: elif not item.expense_account:
throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name)) throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))

View File

@ -3,6 +3,7 @@
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
"autoname": "hash", "autoname": "hash",
"beta": 0,
"creation": "2013-05-22 12:43:10", "creation": "2013-05-22 12:43:10",
"custom": 0, "custom": 0,
"docstatus": 0, "docstatus": 0,
@ -1016,31 +1017,6 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"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",
"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, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -1357,6 +1333,31 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "is_fixed_asset",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Is Fixed Asset",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -1566,13 +1567,14 @@
"hide_heading": 0, "hide_heading": 0,
"hide_toolbar": 0, "hide_toolbar": 0,
"idx": 1, "idx": 1,
"image_view": 0,
"in_create": 0, "in_create": 0,
"in_dialog": 0, "in_dialog": 0,
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-04-18 08:08:53.056819", "modified": "2016-07-05 13:29:00.829144",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Purchase Invoice Item", "name": "Purchase Invoice Item",

View File

@ -975,31 +975,6 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"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",
"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, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -1574,6 +1549,31 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "is_fixed_asset",
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Is Fixed Asset",
"length": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{ {
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
@ -1659,7 +1659,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2016-06-24 16:01:59.719026", "modified": "2016-07-05 13:28:51.981000",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice Item", "name": "Sales Invoice Item",

View File

@ -40,8 +40,9 @@ frappe.ui.form.on("Item", {
// make sensitive fields(has_serial_no, is_stock_item, valuation_method) // make sensitive fields(has_serial_no, is_stock_item, valuation_method)
// read only if any stock ledger entry exists // read only if any stock ledger entry exists
if(!frm.doc.is_fixed_asset) {
erpnext.item.make_dashboard(frm); erpnext.item.make_dashboard(frm);
}
// clear intro // clear intro
frm.set_intro(); frm.set_intro();
@ -76,7 +77,8 @@ frappe.ui.form.on("Item", {
erpnext.item.toggle_attributes(frm); erpnext.item.toggle_attributes(frm);
frm.toggle_enable("is_fixed_asset", !frm.doc.is_stock_item &&
((frm.doc.__onload && frm.doc.__onload.asset_exists) ? false : true));
}, },
validate: function(frm){ validate: function(frm){
@ -86,6 +88,16 @@ frappe.ui.form.on("Item", {
image: function(frm) { image: function(frm) {
refresh_field("image_view"); refresh_field("image_view");
}, },
is_fixed_asset: function(frm) {
if (frm.doc.is_fixed_asset) {
frm.set_value("is_stock_item", 0);
}
},
is_stock_item: function(frm) {
frm.toggle_enable("is_fixed_asset", !frm.doc.is_stock_item);
},
page_name: frappe.utils.warn_page_name_change, page_name: frappe.utils.warn_page_name_change,

View File

@ -2307,7 +2307,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 1, "max_attachments": 1,
"modified": "2016-07-06 16:00:45.561339", "modified": "2016-07-06 17:00:45.561349",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Item", "name": "Item",

View File

@ -28,6 +28,9 @@ class Item(WebsiteGenerator):
def onload(self): def onload(self):
super(Item, self).onload() super(Item, self).onload()
self.set_onload('sle_exists', self.check_if_sle_exists()) self.set_onload('sle_exists', self.check_if_sle_exists())
if self.is_fixed_asset:
asset = frappe.db.get_all("Asset", filters={"item_code": self.name, "docstatus": 1}, limit=1)
self.set_onload("asset_exists", True if asset else False)
def autoname(self): def autoname(self):
if frappe.db.get_default("item_naming_by")=="Naming Series": if frappe.db.get_default("item_naming_by")=="Naming Series":
@ -86,6 +89,7 @@ class Item(WebsiteGenerator):
self.validate_variant_attributes() self.validate_variant_attributes()
self.validate_website_image() self.validate_website_image()
self.make_thumbnail() self.make_thumbnail()
self.validate_fixed_asset()
if not self.get("__islocal"): if not self.get("__islocal"):
self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group") self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")
@ -220,6 +224,14 @@ class Item(WebsiteGenerator):
file_doc.make_thumbnail() file_doc.make_thumbnail()
self.thumbnail = file_doc.thumbnail_url self.thumbnail = file_doc.thumbnail_url
def validate_fixed_asset(self):
if self.is_fixed_asset:
if self.is_stock_item:
frappe.throw(_("Fixed Asset Item must be a non-stock item."))
if not self.asset_category:
frappe.throw(_("Asset Category is mandatory for Fixed Asset item"))
def get_context(self, context): def get_context(self, context):
context.show_search=True context.show_search=True
@ -441,8 +453,8 @@ class Item(WebsiteGenerator):
def cant_change(self): def cant_change(self):
if not self.get("__islocal"): if not self.get("__islocal"):
vals = frappe.db.get_value("Item", self.name, vals = frappe.db.get_value("Item", self.name, ["has_serial_no", "is_stock_item",
["has_serial_no", "is_stock_item", "valuation_method", "has_batch_no"], as_dict=True) "valuation_method", "has_batch_no", "is_fixed_asset"], as_dict=True)
if vals and ((self.is_stock_item != vals.is_stock_item) or if vals and ((self.is_stock_item != vals.is_stock_item) or
vals.has_serial_no != self.has_serial_no or vals.has_serial_no != self.has_serial_no or
@ -451,6 +463,11 @@ class Item(WebsiteGenerator):
if self.check_if_linked_document_exists(): if self.check_if_linked_document_exists():
frappe.throw(_("As there are existing transactions for this item, \ frappe.throw(_("As there are existing transactions for this item, \
you can not change the values of 'Has Serial No', 'Has Batch No', 'Is Stock Item' and 'Valuation Method'")) you can not change the values of 'Has Serial No', 'Has Batch No', 'Is Stock Item' and 'Valuation Method'"))
if vals and not self.is_fixed_asset and self.is_fixed_asset != vals.is_fixed_asset:
asset = frappe.db.get_all("Asset", filters={"item_code": self.name, "docstatus": 1}, limit=1)
if asset:
frappe.throw(_('"Is Fixed Asset" cannot be unchecked, as Asset record exists against the item'))
def check_if_linked_document_exists(self): def check_if_linked_document_exists(self):
for doctype in ("Sales Order Item", "Delivery Note Item", "Sales Invoice Item", for doctype in ("Sales Order Item", "Delivery Note Item", "Sales Invoice Item",

View File

@ -173,7 +173,8 @@ def get_basic_details(args, item):
"net_amount": 0.0, "net_amount": 0.0,
"discount_percentage": 0.0, "discount_percentage": 0.0,
"supplier": item.default_supplier, "supplier": item.default_supplier,
"delivered_by_supplier": item.delivered_by_supplier "delivered_by_supplier": item.delivered_by_supplier,
"is_fixed_asset": item.is_fixed_asset
}) })
# if default specified in item is for another company, fetch from company # if default specified in item is for another company, fetch from company