From 70f05df0753edd5fbb05c8502625e71604d76533 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Apr 2016 18:49:17 +0530 Subject: [PATCH] Asset Movement --- erpnext/accounts/doctype/asset/asset.js | 5 +- erpnext/accounts/doctype/asset/asset.json | 4 +- erpnext/accounts/doctype/asset/asset.py | 15 +- .../doctype/asset_movement/__init__.py | 0 .../doctype/asset_movement/asset_movement.js | 15 + .../asset_movement/asset_movement.json | 274 ++++++++++++++++++ .../doctype/asset_movement/asset_movement.py | 48 +++ .../asset_movement/test_asset_movement.py | 51 ++++ erpnext/config/accounts.py | 5 + 9 files changed, 411 insertions(+), 6 deletions(-) create mode 100644 erpnext/accounts/doctype/asset_movement/__init__.py create mode 100644 erpnext/accounts/doctype/asset_movement/asset_movement.js create mode 100644 erpnext/accounts/doctype/asset_movement/asset_movement.json create mode 100644 erpnext/accounts/doctype/asset_movement/asset_movement.py create mode 100644 erpnext/accounts/doctype/asset_movement/test_asset_movement.py diff --git a/erpnext/accounts/doctype/asset/asset.js b/erpnext/accounts/doctype/asset/asset.js index 9b7efb94184..19653c2e107 100644 --- a/erpnext/accounts/doctype/asset/asset.js +++ b/erpnext/accounts/doctype/asset/asset.js @@ -63,7 +63,7 @@ frappe.ui.form.on('Asset', { var asset_values = ["Asset Value", frm.doc.gross_purchase_amount]; if(frm.doc.opening_accumulated_depreciation) { - x_intervals.push(dateutil.str_to_obj(frm.doc.creation)); + x_intervals.push(moment(frm.doc.creation).format('YYYY-MM-DD')); asset_values.push(flt(frm.doc.gross_purchase_amount) - flt(frm.doc.opening_accumulated_depreciation)) } @@ -81,7 +81,6 @@ frappe.ui.form.on('Asset', { x_intervals.push(frm.doc.disposal_date); asset_values.push(0) } - frm.dashboard.reset(); frm.dashboard.add_graph([x_intervals, asset_values]); @@ -190,7 +189,7 @@ erpnext.asset.transfer_asset = function(frm) { args: { args: { "asset": frm.doc.name, - "transfer_date": args.transfer_date, + "transaction_date": args.transfer_date, "source_warehouse": frm.doc.warehouse, "target_warehouse": args.target_warehouse, "company": frm.doc.company diff --git a/erpnext/accounts/doctype/asset/asset.json b/erpnext/accounts/doctype/asset/asset.json index b4e90eef4a7..c272a5809ac 100644 --- a/erpnext/accounts/doctype/asset/asset.json +++ b/erpnext/accounts/doctype/asset/asset.json @@ -97,7 +97,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 0, + "in_list_view": 1, "label": "Status", "length": 0, "no_copy": 1, @@ -738,7 +738,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-04-21 11:30:57.008128", + "modified": "2016-04-22 11:15:40.055518", "modified_by": "Administrator", "module": "Accounts", "name": "Asset", diff --git a/erpnext/accounts/doctype/asset/asset.py b/erpnext/accounts/doctype/asset/asset.py index da229fee9fd..23bb08be59f 100644 --- a/erpnext/accounts/doctype/asset/asset.py +++ b/erpnext/accounts/doctype/asset/asset.py @@ -190,4 +190,17 @@ def make_sales_invoice(asset, item_code, company): "qty": 1 }) si.set_missing_values() - return si \ No newline at end of file + return si + +@frappe.whitelist() +def transfer_asset(args): + import json + args = json.loads(args) + movement_entry = frappe.new_doc("Asset Movement") + movement_entry.update(args) + movement_entry.insert() + movement_entry.submit() + + frappe.db.commit() + + frappe.msgprint(_("Asset Movement record {0} created").format("{0}".format(movement_entry.name))) \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset_movement/__init__.py b/erpnext/accounts/doctype/asset_movement/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/asset_movement/asset_movement.js b/erpnext/accounts/doctype/asset_movement/asset_movement.js new file mode 100644 index 00000000000..680eedc9bc6 --- /dev/null +++ b/erpnext/accounts/doctype/asset_movement/asset_movement.js @@ -0,0 +1,15 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Asset Movement', { + onload: function(frm) { + frm.add_fetch("asset", "warehouse", "source_warehouse"); + + frm.set_query("target_warehouse", function() { + return { + filters: [["Warehouse", "company", "in", ["", cstr(frm.doc.company)]]] + } + }) + + } +}); diff --git a/erpnext/accounts/doctype/asset_movement/asset_movement.json b/erpnext/accounts/doctype/asset_movement/asset_movement.json new file mode 100644 index 00000000000..59b88236dad --- /dev/null +++ b/erpnext/accounts/doctype/asset_movement/asset_movement.json @@ -0,0 +1,274 @@ +{ + "allow_copy": 0, + "allow_import": 1, + "allow_rename": 0, + "autoname": "AM-.#####", + "creation": "2016-04-25 18:00:23.559973", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "fields": [ + { + "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": 0, + "options": "Asset", + "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": "transaction_date", + "fieldtype": "Datetime", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Transaction 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": "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": "column_break_4", + "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": "source_warehouse", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Source Warehouse", + "length": 0, + "no_copy": 0, + "options": "Warehouse", + "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, + "bold": 0, + "collapsible": 0, + "fieldname": "target_warehouse", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Target Warehouse", + "length": 0, + "no_copy": 0, + "options": "Warehouse", + "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": "amended_from", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Amended From", + "length": 0, + "no_copy": 1, + "options": "Asset Movement", + "permlevel": 0, + "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 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 1, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2016-04-25 19:14:08.853429", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Asset Movement", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 1, + "apply_user_permissions": 0, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 1, + "apply_user_permissions": 0, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Accounts Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 + }, + { + "amend": 1, + "apply_user_permissions": 0, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Stock Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset_movement/asset_movement.py b/erpnext/accounts/doctype/asset_movement/asset_movement.py new file mode 100644 index 00000000000..574c49992b4 --- /dev/null +++ b/erpnext/accounts/doctype/asset_movement/asset_movement.py @@ -0,0 +1,48 @@ +# -*- 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 import _ +from frappe.model.document import Document + +class AssetMovement(Document): + def validate(self): + self.validate_asset() + self.validate_warehouses() + + def validate_asset(self): + status, company = frappe.db.get_value("Asset", self.asset, ["status", "company"]) + if status in ("Draft", "Scrapped", "Sold"): + frappe.throw(_("{0} asset cannot be transferred").format(status)) + + if company != self.company: + frappe.throw(_("Asset {0} does not belong to company {1}").format(self.asset, self.company)) + + def validate_warehouses(self): + if not self.source_warehouse: + self.source_warehouse = frappe.db.get_value("Asset", self.asset, "warehouse") + + if self.source_warehouse == self.target_warehouse: + frappe.throw(_("Source and Target Warehouse cannot be same")) + + def on_submit(self): + self.set_latest_warehouse_in_asset() + + def on_cancel(self): + self.set_latest_warehouse_in_asset() + + def set_latest_warehouse_in_asset(self): + latest_movement_entry = frappe.db.sql("""select target_warehouse from `tabAsset Movement` + where asset=%s and docstatus=1 and company=%s + order by transaction_date desc limit 1""", (self.asset, self.company)) + + if latest_movement_entry: + warehouse = latest_movement_entry[0][0] + else: + warehouse = frappe.db.sql("""select source_warehouse from `tabAsset Movement` + where asset=%s and docstatus=2 and company=%s + order by transaction_date asc limit 1""", (self.asset, self.company))[0][0] + + frappe.db.set_value("Asset", self.asset, "warehouse", warehouse) \ No newline at end of file diff --git a/erpnext/accounts/doctype/asset_movement/test_asset_movement.py b/erpnext/accounts/doctype/asset_movement/test_asset_movement.py new file mode 100644 index 00000000000..9880efc37f8 --- /dev/null +++ b/erpnext/accounts/doctype/asset_movement/test_asset_movement.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +from frappe.utils import now +import unittest +from erpnext.accounts.doctype.asset.test_asset import create_asset + + +class TestAssetMovement(unittest.TestCase): + def test_movement(self): + asset = create_asset() + + if asset.docstatus == 0: + asset.submit() + + movement1 = create_asset_movement(asset, target_warehouse="_Test Warehouse 1 - _TC") + self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse 1 - _TC") + + movement2 = create_asset_movement(asset, target_warehouse="_Test Warehouse 2 - _TC") + self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse 2 - _TC") + + movement1.cancel() + self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse 2 - _TC") + + movement2.cancel() + self.assertEqual(frappe.db.get_value("Asset", asset.name, "warehouse"), "_Test Warehouse - _TC") + + asset.load_from_db() + asset.cancel() + frappe.delete_doc("Asset", asset.name) + + +def create_asset_movement(asset, target_warehouse, transaction_date=None): + if not transaction_date: + transaction_date = now() + + movement = frappe.new_doc("Asset Movement") + movement.update({ + "asset": asset.name, + "transaction_date": transaction_date, + "target_warehouse": target_warehouse, + "company": asset.company + }) + + movement.insert() + movement.submit() + + return movement diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py index 72ed0f9bbca..d0629e7cb0e 100644 --- a/erpnext/config/accounts.py +++ b/erpnext/config/accounts.py @@ -221,6 +221,11 @@ def get_data(): "name": "Period Closing Voucher", "description": _("Close Balance Sheet and book Profit or Loss.") }, + { + "type": "doctype", + "name": "Asset Movement", + "description": _("Transfer an asset from one warehouse to another") + }, ] }, {