Asset linked to purchase receipt and serial no
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 67b41a3..d2cc4ee 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -305,24 +305,8 @@
self.make_gl_entries()
self.update_project()
- self.update_fixed_asset()
update_linked_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
- def update_fixed_asset(self):
- for d in self.get("items"):
- if d.is_fixed_asset:
- asset = frappe.get_doc("Asset", d.asset)
- if self.docstatus==1:
- asset.purchase_invoice = self.name
- asset.purchase_date = self.posting_date
- asset.supplier = self.supplier
- else:
- asset.purchase_invoice = None
- asset.supplier = None
-
- asset.flags.ignore_validate_update_after_submit = True
- asset.save()
-
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
if not self.grand_total:
return
@@ -636,7 +620,6 @@
self.make_gl_entries_on_cancel()
self.update_project()
- self.update_fixed_asset()
frappe.db.set(self, 'status', 'Cancelled')
unlink_inter_company_invoice(self.doctype, self.name, self.inter_company_invoice_reference)
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 d1f99ab..ef9b2f6 100755
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -2258,7 +2258,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-02-22 15:15:25.297672",
+ "modified": "2018-04-23 14:07:33.576495",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index f4a01ae..edc1e36 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -181,7 +181,8 @@
args: {
"asset": frm.doc.name,
"item_code": frm.doc.item_code,
- "company": frm.doc.company
+ "company": frm.doc.company,
+ "serial_no": frm.doc.serial_no
},
method: "erpnext.assets.doctype.asset.asset.make_sales_invoice",
callback: function(r) {
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index 49b574d..63b9167 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -40,6 +40,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -71,6 +72,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -102,6 +104,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -133,6 +136,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -165,6 +169,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -196,6 +201,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -228,6 +234,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -260,6 +267,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -292,6 +300,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -322,6 +331,38 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "serial_no",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Serial No",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -351,6 +392,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -382,6 +424,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -413,6 +456,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -444,6 +488,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -474,6 +519,39 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "purchase_receipt",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Purchase Receipt",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Purchase Receipt",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -505,6 +583,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -535,6 +614,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -565,6 +645,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -595,6 +676,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -626,6 +708,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -655,6 +738,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -686,6 +770,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -715,6 +800,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -747,6 +833,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -779,6 +866,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -808,6 +896,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -838,6 +927,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -869,6 +959,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -902,6 +993,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -933,6 +1025,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -963,6 +1056,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -992,6 +1086,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1023,6 +1118,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1053,6 +1149,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1084,6 +1181,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1115,6 +1213,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1146,6 +1245,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1176,6 +1276,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1207,6 +1308,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1237,6 +1339,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -1251,7 +1354,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-01-05 09:53:05.945328",
+ "modified": "2018-04-19 20:03:13.669957",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",
@@ -1260,7 +1363,6 @@
"permissions": [
{
"amend": 1,
- "apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
@@ -1280,7 +1382,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
@@ -1307,4 +1408,4 @@
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
-}
+}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index baffdd7..a9cc924 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -10,6 +10,7 @@
from erpnext.accounts.doctype.purchase_invoice.purchase_invoice import get_fixed_asset_account
from erpnext.assets.doctype.asset.depreciation \
import get_disposal_account_and_cost_center, get_depreciation_accounts
+from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
class Asset(Document):
def validate(self):
@@ -26,12 +27,16 @@
def on_submit(self):
self.set_status()
+ self.update_stock_movement()
def on_cancel(self):
self.validate_cancellation()
self.delete_depreciation_entries()
self.set_status()
+ def on_update(self):
+ self.update_serial_nos()
+
def validate_item(self):
item = frappe.db.get_value("Item", self.item_code,
["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1)
@@ -219,6 +224,9 @@
if self.purchase_invoice:
frappe.throw(_("Please cancel Purchase Invoice {0} first").format(self.purchase_invoice))
+ if self.purchase_receipt:
+ frappe.throw(_("Please cancel Purchase Receipt {0} first").format(self.purchase_receipt))
+
def delete_depreciation_entries(self):
for d in self.get("schedules"):
if d.journal_entry:
@@ -250,6 +258,20 @@
status = "Cancelled"
return status
+ def update_serial_nos(self):
+ if self.serial_no:
+ serial_nos = get_serial_nos(self.serial_no)
+ frappe.db.sql(""" update `tabSerial No` set asset = '%s' where
+ name in(%s)"""%(self.name, ','.join(['%s'] * len(serial_nos))), tuple(serial_nos))
+
+ def update_stock_movement(self):
+ asset_movement = frappe.db.get_value('Asset Movement',
+ {'asset': self.name, 'reference_name': self.purchase_receipt, 'docstatus': 0}, 'name')
+
+ if asset_movement:
+ doc = frappe.get_doc('Asset Movement', asset_movement)
+ doc.submit()
+
def update_maintenance_status():
assets = frappe.get_all('Asset', filters = {'docstatus': 1, 'maintenance_required': 1})
@@ -280,7 +302,7 @@
return pi
@frappe.whitelist()
-def make_sales_invoice(asset, item_code, company):
+def make_sales_invoice(asset, item_code, company, serial_no):
si = frappe.new_doc("Sales Invoice")
si.company = company
si.currency = frappe.db.get_value("Company", company, "default_currency")
@@ -290,6 +312,7 @@
"is_fixed_asset": 1,
"asset": asset,
"income_account": disposal_account,
+ "serial_no": serial_no,
"cost_center": depreciation_cost_center,
"qty": 1
})
diff --git a/erpnext/assets/doctype/asset/asset_dashboard.py b/erpnext/assets/doctype/asset/asset_dashboard.py
index 94dad1b..89699f3 100644
--- a/erpnext/assets/doctype/asset/asset_dashboard.py
+++ b/erpnext/assets/doctype/asset/asset_dashboard.py
@@ -1,6 +1,9 @@
def get_data():
return {
'fieldname': 'asset_name',
+ 'non_standard_fieldnames': {
+ 'Asset Movement': 'asset'
+ },
'transactions': [
{
'label': ['Maintenance'],
@@ -9,6 +12,10 @@
{
'label': ['Repair'],
'items': ['Asset Repair']
+ },
+ {
+ 'label': ['Movement'],
+ 'items': ['Asset Movement']
}
]
}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json
index 72d96b0..f36fe4e 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.json
@@ -42,6 +42,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -73,6 +74,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -104,6 +106,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -135,6 +138,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -164,6 +168,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -195,6 +200,39 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "serial_no",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Serial No",
+ "length": 0,
+ "no_copy": 0,
+ "options": "asset_name.serial_no",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -224,6 +262,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -255,6 +294,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -284,6 +324,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -315,6 +356,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -346,6 +388,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -376,6 +419,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -407,6 +451,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -420,7 +465,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-12-01 15:13:29.816396",
+ "modified": "2018-04-20 08:39:27.072622",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Maintenance",
@@ -429,7 +474,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -449,7 +493,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
index 7551eae..b30685f 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
@@ -11,6 +11,9 @@
class AssetMaintenance(Document):
def validate(self):
+ if not self.serial_no:
+ self.serial_no = frappe.db.get_value("Asset", self.asset_name, 'serial_no')
+
for task in self.get('asset_maintenance_tasks'):
if task.end_date and (getdate(task.start_date) >= getdate(task.end_date)):
throw(_("Start date should be less than end date for task {0}").format(task.maintenance_task))
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.json b/erpnext/assets/doctype/asset_movement/asset_movement.json
index 0c05552..3c3a1dc 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.json
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.json
@@ -18,6 +18,39 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "Transfer",
+ "fieldname": "purpose",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Purpose",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Receipt\nTransfer",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "asset",
"fieldtype": "Link",
"hidden": 0,
@@ -41,6 +74,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -71,6 +105,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -102,6 +137,38 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "serial_no",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Serial No",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -131,6 +198,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -162,6 +230,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -193,6 +262,102 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "reference",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Reference",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "reference_doctype",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Reference DocType",
+ "length": 0,
+ "no_copy": 1,
+ "options": "DocType",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "reference_name",
+ "fieldtype": "Dynamic Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Reference Name",
+ "length": 0,
+ "no_copy": 1,
+ "options": "reference_doctype",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -223,6 +388,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -236,7 +402,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-10-19 16:08:17.389257",
+ "modified": "2018-04-20 15:45:54.156501",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Movement",
@@ -245,7 +411,6 @@
"permissions": [
{
"amend": 1,
- "apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
@@ -265,7 +430,6 @@
},
{
"amend": 1,
- "apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
@@ -285,7 +449,6 @@
},
{
"amend": 1,
- "apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
diff --git a/erpnext/assets/doctype/asset_movement/asset_movement.py b/erpnext/assets/doctype/asset_movement/asset_movement.py
index 574c499..42ed249 100644
--- a/erpnext/assets/doctype/asset_movement/asset_movement.py
+++ b/erpnext/assets/doctype/asset_movement/asset_movement.py
@@ -11,19 +11,22 @@
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"):
+ status, company, serial_no = frappe.db.get_value("Asset", self.asset, ["status", "company", "serial_no"])
+ if self.purpose == 'Transfer' and 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))
-
+
+ if serial_no and not self.serial_no:
+ self.serial_no = serial_no
+
def validate_warehouses(self):
- if not self.source_warehouse:
+ if self.purpose == 'Transfer' and 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"))
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index c70cfcd..40028af 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -600,40 +600,36 @@
if d.qty > 1:
frappe.throw(_("Row #{0}: Qty must be 1, as item is a fixed asset. Please use separate row for multiple qty.").format(d.idx))
- if d.meta.get_field("asset"):
- if not d.asset:
- frappe.throw(_("Row #{0}: Asset is mandatory for fixed asset purchase/sale")
- .format(d.idx))
- else:
- asset = frappe.get_doc("Asset", d.asset)
+ if d.meta.get_field("asset") and d.asset:
+ asset = frappe.get_doc("Asset", d.asset)
- if asset.company != self.company:
- frappe.throw(_("Row #{0}: Asset {1} does not belong to company {2}")
- .format(d.idx, d.asset, self.company))
+ if asset.company != self.company:
+ frappe.throw(_("Row #{0}: Asset {1} does not belong to company {2}")
+ .format(d.idx, d.asset, self.company))
- elif asset.item_code != d.item_code:
- frappe.throw(_("Row #{0}: Asset {1} does not linked to Item {2}")
- .format(d.idx, d.asset, d.item_code))
+ elif asset.item_code != d.item_code:
+ frappe.throw(_("Row #{0}: Asset {1} does not linked to Item {2}")
+ .format(d.idx, d.asset, d.item_code))
- elif asset.docstatus != 1:
- frappe.throw(_("Row #{0}: Asset {1} must be submitted").format(d.idx, d.asset))
+ elif asset.docstatus != 1:
+ frappe.throw(_("Row #{0}: Asset {1} must be submitted").format(d.idx, d.asset))
- elif self.doctype == "Purchase Invoice":
- if asset.status != "Submitted":
- frappe.throw(_("Row #{0}: Asset {1} is already {2}")
- .format(d.idx, d.asset, asset.status))
- elif getdate(asset.purchase_date) != getdate(self.posting_date):
- frappe.throw(_("Row #{0}: Posting Date must be same as purchase date {1} of asset {2}").format(d.idx, asset.purchase_date, d.asset))
- elif asset.is_existing_asset:
- frappe.throw(_("Row #{0}: Purchase Invoice cannot be made against an existing asset {1}").format(d.idx, d.asset))
+ elif self.doctype == "Purchase Invoice":
+ if asset.status != "Submitted":
+ frappe.throw(_("Row #{0}: Asset {1} is already {2}")
+ .format(d.idx, d.asset, asset.status))
+ elif getdate(asset.purchase_date) != getdate(self.posting_date):
+ frappe.throw(_("Row #{0}: Posting Date must be same as purchase date {1} of asset {2}").format(d.idx, asset.purchase_date, d.asset))
+ elif asset.is_existing_asset:
+ frappe.throw(_("Row #{0}: Purchase Invoice cannot be made against an existing asset {1}").format(d.idx, d.asset))
- elif self.docstatus=="Sales Invoice" and self.docstatus == 1:
- if self.update_stock:
- frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale"))
+ elif self.docstatus=="Sales Invoice" and self.docstatus == 1:
+ if self.update_stock:
+ frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale"))
- elif asset.status in ("Scrapped", "Cancelled", "Sold"):
- frappe.throw(_("Row #{0}: Asset {1} cannot be submitted, it is already {2}")
- .format(d.idx, d.asset, asset.status))
+ elif asset.status in ("Scrapped", "Cancelled", "Sold"):
+ frappe.throw(_("Row #{0}: Asset {1} cannot be submitted, it is already {2}")
+ .format(d.idx, d.asset, asset.status))
def delink_advance_entries(self, linked_doc_name):
total_allocated_amount = 0
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index de6ed79..c340901 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -11,6 +11,7 @@
from erpnext.buying.utils import validate_for_items, update_last_purchase_rate
from erpnext.stock.stock_ledger import get_valuation_rate
from erpnext.stock.doctype.stock_entry.stock_entry import get_used_alternative_items
+from erpnext.stock.doctype.serial_no.serial_no import get_auto_serial_nos, auto_make_serial_nos
from erpnext.controllers.stock_controller import StockController
@@ -439,6 +440,11 @@
if self.get('is_return'):
return
+ if self.doctype in ['Purchase Receipt', 'Purchase Invoice']:
+ if self.doctype == 'Purchase Receipt':
+ self.process_fixed_asset()
+ self.update_fixed_asset()
+
update_last_purchase_rate(self, is_submit = 1)
def on_cancel(self):
@@ -446,6 +452,118 @@
return
update_last_purchase_rate(self, is_submit = 0)
+ if self.doctype in ['Purchase Receipt', 'Purchase Invoice']:
+ if self.doctype == 'Purchase Receipt':
+ self.delete_linked_asset()
+ self.update_fixed_asset()
+
+ def process_fixed_asset(self):
+ if not self.doctype in ['Purchase Receipt', 'Purchase Invoice']:
+ return
+
+ asset_items = [d.item_code for d in self.items if d.is_fixed_asset]
+ if asset_items:
+ self.make_serial_nos_for_asset(asset_items)
+
+ def make_serial_nos_for_asset(self, asset_items):
+ items_data = get_asset_item_details(asset_items)
+
+ for d in self.items:
+ if d.is_fixed_asset:
+ item_data = items_data.get(d.item_code)
+
+ if item_data.get('has_serial_no'):
+ # If item has serial no
+ if item_data.get('serial_no_series') and not d.serial_no:
+ serial_nos = get_auto_serial_nos(item_data.get('serial_no_series'), d.qty)
+ elif d.serial_no:
+ serial_nos = d.serial_no
+ elif not d.serial_no:
+ frappe.throw(_("Serial no is mandatory for the item {0}").format(d.item_code))
+
+ auto_make_serial_nos({
+ 'serial_no': serial_nos,
+ 'item_code': d.item_code,
+ 'via_stock_ledger': False,
+ 'company': self.company,
+ 'actual_qty': d.qty,
+ 'purchase_document_type': self.doctype,
+ 'purchase_document_no': self.name
+ })
+ d.db_set('serial_no', serial_nos)
+
+ if not d.asset:
+ asset = self.make_asset(d)
+ d.db_set('asset', asset)
+
+ if d.asset:
+ self.make_asset_movement(d)
+
+ def make_asset(self, row):
+ asset = frappe.get_doc({
+ 'doctype': 'Asset',
+ 'item_code': row.item_code,
+ 'asset_name': '{0} - {1}'.format(self.name, row.item_code),
+ 'warehouse': row.warehouse,
+ 'serial_no': row.serial_no,
+ 'company': self.company,
+ 'purchase_date': self.posting_date,
+ 'purchase_receipt': self.name if self.doctype == 'Purchase Receipt' else None,
+ 'purchase_invoice': self.name if self.doctype == 'Purchase Invoice' else None
+ })
+
+ asset.flags.ignore_validate = True
+ asset.flags.ignore_mandatory = True
+ asset.insert()
+
+ frappe.msgprint(_("Asset {0} created").format(asset.name))
+ return asset.name
+
+ def make_asset_movement(self, row):
+ asset_movement = frappe.get_doc({
+ 'doctype': 'Asset Movement',
+ 'asset': row.asset,
+ 'source_warehouse': '',
+ 'target_warehouse': row.warehouse,
+ 'purpose': 'Receipt',
+ 'serial_no': row.serial_no,
+ 'company': self.company,
+ 'transaction_date': self.posting_date,
+ 'reference_doctype': self.doctype,
+ 'reference_name': self.name
+ }).insert()
+
+ return asset_movement.name
+
+ def update_fixed_asset(self):
+ field = 'purchase_invoice' if self.doctype == 'Purchase Invoice' else 'purchase_receipt'
+
+ for d in self.get("items"):
+ if d.is_fixed_asset and d.asset:
+ asset = frappe.get_doc("Asset", d.asset)
+ if self.docstatus in [0, 1] and not asset.get(field):
+ asset.set(field, self.name)
+ asset.purchase_date = self.posting_date
+ asset.supplier = self.supplier
+ else:
+ asset.set(field, None)
+ asset.supplier = None
+
+ asset.flags.ignore_validate_update_after_submit = True
+ if asset.docstatus == 0:
+ asset.flags.ignore_validate = True
+
+ asset.save()
+
+ def delete_linked_asset(self):
+ if not self.doctype in ['Purchase Receipt', 'Purchase Invoice']:
+ return
+
+ if self.doctype == 'Purchase Invoice' and self.get('update_stock'):
+ return
+
+ frappe.db.sql("delete from `tabAsset Movement` where reference_name=%s and docstatus = 0", self.name)
+ frappe.db.sql("delete from `tabSerial No` where purchase_document_no=%s", self.name)
def validate_schedule_date(self):
if not self.schedule_date:
@@ -480,3 +598,11 @@
msgprint(_("Specified BOM {0} does not exist for Item {1}").format(bom, item_code), raise_exception=1)
return bom_items
+
+def get_asset_item_details(asset_items):
+ asset_items_data = {}
+ for d in frappe.get_all('Item', fields = ["name", "has_serial_no", "serial_no_series"],
+ filters = {'name': ('in', asset_items)}):
+ asset_items_data.setdefault(d.name, d)
+
+ return asset_items_data
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index e164d69..d409577 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -5,6 +5,14 @@
frappe.ui.form.on("Company", {
setup: function(frm) {
+ frm.fields_dict.fixed_asset_account.get_query = function() {
+ return {
+ filters: {
+ account_type: "Fixed Asset",
+ company: frm.doc.name
+ }
+ }
+ }
erpnext.company.setup_queries(frm);
},
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 21900ad..251717e 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -1285,7 +1285,7 @@
"collapsible": 1,
"collapsible_depends_on": "eval:doc.has_batch_no || doc.has_serial_no",
"columns": 0,
- "depends_on": "is_stock_item",
+ "depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset",
"fieldname": "serial_nos_and_batches",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1513,7 +1513,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
- "depends_on": "eval:doc.is_stock_item",
+ "depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset",
"description": "",
"fieldname": "has_serial_no",
"fieldtype": "Check",
@@ -3725,7 +3725,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -3745,7 +3744,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -3765,7 +3763,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -3785,7 +3782,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -3805,7 +3801,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -3825,7 +3820,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -3845,7 +3839,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -3865,7 +3858,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 123e73f..fafdaab 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -444,7 +444,7 @@
_("Conversion factor for default Unit of Measure must be 1 in row {0}").format(d.idx))
def validate_item_type(self):
- if self.has_serial_no == 1 and self.is_stock_item == 0:
+ if self.has_serial_no == 1 and self.is_stock_item == 0 and not self.is_fixed_asset:
msgprint(_("'Has Serial No' can not be 'Yes' for non-stock item"), raise_exception=1)
if self.has_serial_no == 0 and self.serial_no_series:
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 791b253..69d2f2a 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -65,6 +65,20 @@
if (erpnext.is_perpetual_inventory_enabled(this.frm.doc.company)) {
this.show_general_ledger();
}
+
+ this.frm.add_custom_button(__('Asset'), function() {
+ frappe.route_options = {
+ purchase_receipt: me.frm.doc.name,
+ };
+ frappe.set_route("List", "Asset");
+ }, __("View"));
+
+ this.frm.add_custom_button(__('Asset Movement'), function() {
+ frappe.route_options = {
+ reference_name: me.frm.doc.name,
+ };
+ frappe.set_route("List", "Asset Movement");
+ }, __("View"));
}
if(!this.frm.doc.is_return && this.frm.doc.status!="Closed") {
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 46eee31..c7083be 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -393,6 +393,8 @@
"parent": "purchase_receipt",
"purchase_order_item": "po_detail",
"purchase_order": "purchase_order",
+ "is_fixed_asset": "is_fixed_asset",
+ "asset": "asset",
},
"postprocess": update_item,
"filter": lambda d: abs(d.qty) - abs(invoiced_qty_map.get(d.name, 0))<=0
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
index 9ade1af..bcedd71 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
@@ -5,6 +5,7 @@
'fieldname': 'purchase_receipt_no',
'non_standard_fieldnames': {
'Purchase Invoice': 'purchase_receipt',
+ 'Asset': 'purchase_receipt',
'Landed Cost Voucher': 'receipt_document',
'Subscription': 'reference_document'
},
@@ -16,7 +17,7 @@
'transactions': [
{
'label': _('Related'),
- 'items': ['Purchase Invoice', 'Landed Cost Voucher']
+ 'items': ['Purchase Invoice', 'Landed Cost Voucher', 'Asset']
},
{
'label': _('Reference'),
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index d9f40cc..ffcc954 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -289,13 +289,53 @@
serial_no=serial_no, basic_rate=100, do_not_submit=True)
self.assertRaises(SerialNoDuplicateError, se.submit)
+ def test_serialized_asset_item(self):
+ asset_item = "Test Serialized Asset Item"
+
+ if not frappe.db.exists('Item', asset_item):
+ asset_category = frappe.get_all('Asset Category')
+
+ if asset_category:
+ asset_category = asset_category[0].name
+
+ if not asset_category:
+ doc = frappe.get_doc({
+ 'doctype': 'Asset Category',
+ 'asset_category_name': 'Test Asset Category',
+ 'depreciation_method': 'Straight Line',
+ 'total_number_of_depreciations': 12,
+ 'frequency_of_depreciation': 1,
+ 'accounts': [{
+ 'company_name': '_Test Company',
+ 'fixed_asset_account': '_Test Fixed Asset - _TC',
+ 'accumulated_depreciation_account': 'Depreciation - _TC',
+ 'depreciation_expense_account': 'Depreciation - _TC'
+ }]
+ }).insert()
+
+ asset_category = doc.name
+
+ asset_item = make_item(asset_item, {'is_stock_item':0,
+ 'stock_uom': 'Box', 'is_fixed_asset': 1, 'has_serial_no': 1,
+ 'asset_category': asset_category, 'serial_no_series': 'ABC.###'})
+
+ pr = make_purchase_receipt(item_code=asset_item, qty=3)
+ asset = frappe.db.get_value('Asset', {'purchase_receipt': pr.name}, 'name')
+ asset_movement = frappe.db.get_value('Asset Movement', {'reference_name': pr.name}, 'name')
+ serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name')
+
+ self.assertEquals(len(serial_nos), 3)
+ pr.cancel()
+ serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') or []
+ self.assertEquals(len(serial_nos), 0)
+ frappe.db.sql("delete from `tabAsset Category`")
+ frappe.db.sql("delete from `tabAsset`")
def get_gl_entries(voucher_type, voucher_no):
return frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
order by account desc""", (voucher_type, voucher_no), as_dict=1)
-
def make_purchase_receipt(**args):
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
pr = frappe.new_doc("Purchase Receipt")
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index 754bd71..a7b0a03 100755
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -1583,6 +1583,70 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "is_fixed_asset",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Fixed Asset",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "is_fixed_asset",
+ "fieldname": "asset",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Asset",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Asset",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "purchase_order",
"fieldtype": "Link",
"hidden": 0,
@@ -2395,7 +2459,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-02-22 15:15:38.793425",
+ "modified": "2018-04-23 14:07:48.438379",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json
index b37713b..fa4fa69 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.json
+++ b/erpnext/stock/doctype/serial_no/serial_no.json
@@ -41,6 +41,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -69,6 +70,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -100,6 +102,7 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -132,6 +135,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -165,6 +169,39 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "asset",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Asset",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Asset",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -193,6 +230,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -222,6 +260,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -253,6 +292,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "300px"
},
@@ -287,6 +327,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -319,6 +360,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -348,6 +390,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -376,6 +419,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "50%"
},
@@ -407,6 +451,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -437,6 +482,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -468,6 +514,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -497,6 +544,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -529,6 +577,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -557,6 +606,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "50%"
},
@@ -588,6 +638,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -617,6 +668,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -647,6 +699,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -677,6 +730,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -707,6 +761,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -738,6 +793,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -767,6 +823,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -799,6 +856,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -827,6 +885,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "50%"
},
@@ -860,6 +919,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -891,6 +951,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -921,6 +982,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -952,6 +1014,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -981,6 +1044,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1009,6 +1073,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "50%"
},
@@ -1042,6 +1107,7 @@
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1074,6 +1140,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1103,6 +1170,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "50%"
},
@@ -1135,6 +1203,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1167,6 +1236,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
@@ -1197,6 +1267,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1226,6 +1297,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1256,6 +1328,7 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -1270,7 +1343,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-05-15 18:22:23.685286",
+ "modified": "2018-04-19 20:25:52.066995",
"modified_by": "Administrator",
"module": "Stock",
"name": "Serial No",
@@ -1278,7 +1351,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -1298,7 +1370,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
@@ -1318,7 +1389,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 0,
"delete": 0,
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 98f15a8..17bf1bb 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
+from frappe.model.naming import make_autoname
from frappe.utils import cint, cstr, flt, add_days, nowdate, getdate
from frappe import _, ValidationError
@@ -276,24 +277,31 @@
def update_serial_nos(sle, item_det):
if sle.is_cancelled == "No" and not sle.serial_no and sle.actual_qty > 0 \
and item_det.has_serial_no == 1 and item_det.serial_no_series:
- from frappe.model.naming import make_autoname
- serial_nos = []
- for i in range(cint(sle.actual_qty)):
- serial_nos.append(make_autoname(item_det.serial_no_series, "Serial No"))
- frappe.db.set(sle, "serial_no", "\n".join(serial_nos))
+ serial_nos = get_auto_serial_nos(item_det.serial_no_series, sle.actual_qty)
+ frappe.db.set(sle, "serial_no", serial_nos)
validate_serial_no(sle, item_det)
if sle.serial_no:
- serial_nos = get_serial_nos(sle.serial_no)
- for serial_no in serial_nos:
- if frappe.db.exists("Serial No", serial_no):
- sr = frappe.get_doc("Serial No", serial_no)
- sr.via_stock_ledger = True
- sr.item_code = sle.item_code
- sr.warehouse = sle.warehouse if sle.actual_qty > 0 else None
- sr.save(ignore_permissions=True)
- elif sle.actual_qty > 0:
- make_serial_no(serial_no, sle)
+ auto_make_serial_nos(sle)
+
+def get_auto_serial_nos(serial_no_series, qty):
+ serial_nos = []
+ for i in range(cint(qty)):
+ serial_nos.append(make_autoname(serial_no_series, "Serial No"))
+
+ return "\n".join(serial_nos)
+
+def auto_make_serial_nos(args):
+ serial_nos = get_serial_nos(args.get('serial_no'))
+ for serial_no in serial_nos:
+ if frappe.db.exists("Serial No", serial_no):
+ sr = frappe.get_doc("Serial No", serial_no)
+ sr.via_stock_ledger = True
+ sr.item_code = args.get('item_code')
+ sr.warehouse = args.get('warehouse') if args.get('actual_qty', 0) > 0 else None
+ sr.save(ignore_permissions=True)
+ elif args.get('actual_qty', 0) > 0:
+ make_serial_no(serial_no, args)
def get_item_details(item_code):
return frappe.db.sql("""select name, has_batch_no, docstatus,
@@ -304,20 +312,26 @@
return [s.strip() for s in cstr(serial_no).strip().upper().replace(',', '\n').split('\n')
if s.strip()]
-def make_serial_no(serial_no, sle):
+def make_serial_no(serial_no, args):
sr = frappe.new_doc("Serial No")
sr.warehouse = None
sr.dont_update_if_missing.append("warehouse")
sr.flags.ignore_permissions = True
sr.serial_no = serial_no
- sr.item_code = sle.item_code
- sr.company = sle.company
- sr.via_stock_ledger = True
+ sr.item_code = args.get('item_code')
+ sr.company = args.get('company')
+ sr.via_stock_ledger = args.get('via_stock_ledger') or True
sr.insert()
- sr.warehouse = sle.warehouse
- sr.save()
+ if args.get('purchase_document_type'):
+ sr.purchase_document_type = args.get('purchase_document_type')
+ sr.purchase_document_no = args.get('purchase_document_no')
+
+ if args.get('warehouse'):
+ sr.warehouse = args.get('warehouse')
+ sr.save()
+
frappe.msgprint(_("Serial No {0} created").format(sr.name))
return sr.name
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 7e456dd..0d03b4d 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -287,6 +287,10 @@
or frappe.db.get_value("Item Group", item.item_group, "default_income_account"))
def get_default_expense_account(args, item):
+ if item and item.is_fixed_asset:
+ return frappe.db.get_value("Company", args.company, "fixed_asset_account")
+ if account: return account
+
return (item.expense_account
or args.expense_account
or frappe.db.get_value("Item Group", item.item_group, "default_expense_account"))