Merge branch 'master' into staging-fixes
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 217d091..223049a 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '10.1.54'
+__version__ = '10.1.55'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 11e48db..7219d87 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -403,16 +403,20 @@
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
warehouse_account = get_warehouse_account_map()
+ voucher_wise_stock_value = {}
+ if self.update_stock:
+ for d in frappe.get_all('Stock Ledger Entry',
+ fields = ["voucher_detail_no", "stock_value_difference"], filters={'voucher_no': self.name}):
+ voucher_wise_stock_value.setdefault(d.voucher_detail_no, d.stock_value_difference)
+
for item in self.get("items"):
if flt(item.base_net_amount):
account_currency = get_account_currency(item.expense_account)
if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
- val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
-
# warehouse account
- warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
- * flt(item.qty) * flt(item.conversion_factor), item.precision("base_net_amount"))
+ warehouse_debit_amount = self.make_stock_adjustment_entry(gl_entries,
+ item, voucher_wise_stock_value, account_currency)
gl_entries.append(
self.get_gl_dict({
@@ -552,6 +556,36 @@
return gl_entries
+ def make_stock_adjustment_entry(self, gl_entries, item, voucher_wise_stock_value, account_currency):
+ net_amt_precision = item.precision("base_net_amount")
+ val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
+
+ warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
+ * flt(item.qty) * flt(item.conversion_factor), net_amt_precision)
+
+ # Stock ledger value is not matching with the warehouse amount
+ if (self.update_stock and voucher_wise_stock_value.get(item.name) and
+ warehouse_debit_amount != flt(voucher_wise_stock_value.get(item.name), net_amt_precision)):
+
+ cost_of_goods_sold_account = self.get_company_default("default_expense_account")
+ stock_amount = flt(voucher_wise_stock_value.get(item.name), net_amt_precision)
+ stock_adjustment_amt = warehouse_debit_amount - stock_amount
+
+ gl_entries.append(
+ self.get_gl_dict({
+ "account": cost_of_goods_sold_account,
+ "against": item.expense_account,
+ "debit": stock_adjustment_amt,
+ "remarks": self.get("remarks") or _("Stock Adjustment"),
+ "cost_center": item.cost_center,
+ "project": item.project
+ }, account_currency)
+ )
+
+ warehouse_debit_amount = stock_amount
+
+ return warehouse_debit_amount
+
def make_tax_gl_entries(self, gl_entries):
# tax table gl entries
valuation_tax = {}
diff --git a/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py b/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py
index fb59882..4170092 100644
--- a/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py
+++ b/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py
@@ -3,55 +3,76 @@
from __future__ import unicode_literals
import frappe, erpnext
+from frappe.utils import flt
from frappe import _
def execute(filters=None):
columns, data = get_columns(), get_data(filters)
return columns, data
-
+
def get_data(filters):
- data = frappe.db.sql("""
- select
- a.name as asset, a.asset_category, a.status,
- ds.depreciation_method, a.purchase_date, a.gross_purchase_amount,
- ds.schedule_date as depreciation_date, ds.depreciation_amount,
- ds.accumulated_depreciation_amount,
- (a.gross_purchase_amount - ds.accumulated_depreciation_amount) as amount_after_depreciation,
- ds.journal_entry as depreciation_entry
- from
- `tabAsset` a, `tabDepreciation Schedule` ds
- where
- a.name = ds.parent
- and a.docstatus=1
- and ifnull(ds.journal_entry, '') != ''
- and ds.schedule_date between %(from_date)s and %(to_date)s
- and a.company = %(company)s
- {conditions}
- order by
- a.name asc, ds.schedule_date asc
- """.format(conditions=get_filter_conditions(filters)), filters, as_dict=1)
+ data = []
+ depreciation_accounts = frappe.db.sql_list(""" select name from tabAccount
+ where ifnull(account_type, '') = 'Depreciation' """)
+
+ filters_data = [["company", "=", filters.get('company')],
+ ["posting_date", ">=", filters.get('from_date')],
+ ["posting_date", "<=", filters.get('to_date')],
+ ["against_voucher_type", "=", "Asset"],
+ ["account", "in", depreciation_accounts]]
+
+ if filters.get("asset"):
+ filters_data.append(["against_voucher", "=", filters.get("asset")])
+
+ if filters.get("asset_category"):
+
+ assets = frappe.db.sql_list("""select name from tabAsset
+ where asset_category = %s and docstatus=1""", filters.get("asset_category"))
+
+ filters_data.append(["against_voucher", "in", assets])
+
+ gl_entries = frappe.get_all('GL Entry',
+ filters= filters_data,
+ fields = ["against_voucher", "debit_in_account_currency as debit", "voucher_no", "posting_date"],
+ order_by= "against_voucher, posting_date")
+
+ if not gl_entries:
+ return data
+
+ assets = [d.against_voucher for d in gl_entries]
+ assets_details = get_assets_details(assets)
+
+ for d in gl_entries:
+ asset_data = assets_details.get(d.against_voucher)
+ if not asset_data.get("accumulated_depreciation_amount"):
+ asset_data.accumulated_depreciation_amount = d.debit
+ else:
+ asset_data.accumulated_depreciation_amount += d.debit
+
+ row = frappe._dict(asset_data)
+ row.update({
+ "depreciation_amount": d.debit,
+ "depreciation_date": d.posting_date,
+ "amount_after_depreciation": (flt(row.gross_purchase_amount) -
+ flt(row.accumulated_depreciation_amount)),
+ "depreciation_entry": d.voucher_no
+ })
+
+ data.append(row)
return data
-def get_filter_conditions(filters):
- conditions = ""
-
- if filters.get("asset"):
- conditions += " and a.name = %(asset)s"
-
- if filters.get("asset_category"):
- conditions += " and a.asset_category = %(asset_category)s"
-
- company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
+def get_assets_details(assets):
+ assets_details = {}
- if (not filters.get('finance_book') or (filters.get('finance_book') == company_finance_book)):
- filters['finance_book'] = company_finance_book
- conditions += " and ifnull(ds.finance_book, '') in (%(finance_book)s, '') "
- elif filters.get("finance_book"):
- conditions += " and ifnull(ds.finance_book, '') = %(finance_book)s"
+ fields = ["name as asset", "gross_purchase_amount",
+ "asset_category", "status", "depreciation_method", "purchase_date"]
- return conditions
-
+ for d in frappe.get_all("Asset", fields = fields, filters = {'name': ('in', assets)}):
+ assets_details.setdefault(d.asset, d)
+
+ return assets_details
+
def get_columns():
return [
{
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 58b96ff..ed02d87 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -94,6 +94,12 @@
}, __("Make"));
}
+ if (!frm.doc.calculate_depreciation) {
+ frm.add_custom_button(__("Depreciation Entry"), function() {
+ frm.trigger("make_journal_entry");
+ }, __("Make"));
+ }
+
frm.page.set_inner_btn_group_as_primary(__("Make"));
frm.trigger("setup_chart");
}
@@ -103,6 +109,21 @@
}
},
+ make_journal_entry: function(frm) {
+ frappe.call({
+ method: "erpnext.assets.doctype.asset.asset.make_journal_entry",
+ args: {
+ asset_name: frm.doc.name
+ },
+ callback: function(r) {
+ if (r.message) {
+ var doclist = frappe.model.sync(r.message);
+ frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+ }
+ }
+ })
+ },
+
setup_chart: function(frm) {
var x_intervals = [frm.doc.purchase_date];
var asset_values = [frm.doc.gross_purchase_amount];
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 04fa8dc..6997776 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -511,3 +511,34 @@
.format(account_name.replace('_', ' ').title(), asset_category, company))
return account
+
+@frappe.whitelist()
+def make_journal_entry(asset_name):
+ asset = frappe.get_doc("Asset", asset_name)
+ fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
+ get_depreciation_accounts(asset)
+
+ depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
+ ["depreciation_cost_center", "series_for_depreciation_entry"])
+ depreciation_cost_center = asset.cost_center or depreciation_cost_center
+
+ je = frappe.new_doc("Journal Entry")
+ je.voucher_type = "Depreciation Entry"
+ je.naming_series = depreciation_series
+ je.company = asset.company
+ je.remark = "Depreciation Entry against asset {0}".format(asset_name)
+
+ je.append("accounts", {
+ "account": depreciation_expense_account,
+ "reference_type": "Asset",
+ "reference_name": asset.name,
+ "cost_center": depreciation_cost_center
+ })
+
+ je.append("accounts", {
+ "account": accumulated_depreciation_account,
+ "reference_type": "Asset",
+ "reference_name": asset.name
+ })
+
+ return je
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 1a96579..797075b 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -9,8 +9,9 @@
def post_depreciation_entries(date=None):
# Return if automatic booking of asset depreciation is disabled
- if not frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically"):
+ if not cint(frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically")):
return
+
if not date:
date = today()
for asset in get_depreciable_assets(date):
@@ -197,4 +198,4 @@
if not depreciation_cost_center:
frappe.throw(_("Please set 'Asset Depreciation Cost Center' in Company {0}").format(company))
- return disposal_account, depreciation_cost_center
\ No newline at end of file
+ return disposal_account, depreciation_cost_center
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index d0f3ccd..15294f6 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -137,7 +137,7 @@
.format(args.item_code), StockOverReturnError)
elif abs(current_stock_qty) > max_returnable_qty:
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
- .format(args.idx, reference_qty, args.item_code), StockOverReturnError)
+ .format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
def get_ref_item_dict(valid_items, ref_item_row):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index 0d22c44..affbb55 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -122,16 +122,14 @@
// Get leave details
//---------------------------------------------------------------------
var get_emp_and_leave_details = function(doc, dt, dn) {
- if(!doc.start_date){
- return frappe.call({
- method: 'get_emp_and_leave_details',
- doc: locals[dt][dn],
- callback: function(r, rt) {
- cur_frm.refresh();
- calculate_all(doc, dt, dn);
- }
- });
- }
+ return frappe.call({
+ method: 'get_emp_and_leave_details',
+ doc: locals[dt][dn],
+ callback: function(r, rt) {
+ cur_frm.refresh();
+ calculate_all(doc, dt, dn);
+ }
+ });
}
cur_frm.cscript.employee = function(doc,dt,dn){
diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.py b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
index e8b4698..3d080a7 100644
--- a/erpnext/hr/doctype/upload_attendance/upload_attendance.py
+++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
@@ -5,7 +5,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import cstr, add_days, date_diff
+from frappe.utils import cstr, add_days, date_diff, getdate
from frappe import _
from frappe.utils.csvutils import UnicodeWriter
from frappe.model.document import Document
@@ -48,8 +48,9 @@
for employee in employees:
existing_attendance = {}
if existing_attendance_records \
- and tuple([date, employee.name]) in existing_attendance_records:
- existing_attendance = existing_attendance_records[tuple([date, employee.name])]
+ and tuple([getdate(date), employee.name]) in existing_attendance_records:
+ existing_attendance = existing_attendance_records[tuple([getdate(date), employee.name])]
+
row = [
existing_attendance and existing_attendance.name or "",
employee.name, employee.employee_name, date,
@@ -114,6 +115,7 @@
if not row: continue
row_idx = i + 5
d = frappe._dict(zip(columns, row))
+
d["doctype"] = "Attendance"
if d.name:
d["docstatus"] = frappe.db.get_value("Attendance", d.name, "docstatus")
@@ -121,6 +123,8 @@
try:
check_record(d)
ret.append(import_doc(d, "Attendance", 1, row_idx, submit=True))
+ except AttributeError:
+ pass
except Exception as e:
error = True
ret.append('Error for row (#%d) %s : %s' % (row_idx,
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
index 7ed7dd6..36d5d22 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_dashboard.py
@@ -8,6 +8,7 @@
'Asset': 'purchase_receipt',
'Landed Cost Voucher': 'receipt_document',
'Auto Repeat': 'reference_document'
+ 'Purchase Receipt': 'return_against'
},
'internal_links': {
'Purchase Order': ['items', 'purchase_order'],
@@ -25,11 +26,11 @@
},
{
'label': _('Returns'),
- 'items': ['Stock Entry']
+ 'items': ['Purchase Receipt']
},
{
'label': _('Subscription'),
'items': ['Auto Repeat']
},
]
- }
\ No newline at end of file
+ }