Fixed merge conflict
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index a4950e7..29e81f1 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__ = '9.2.19'
+__version__ = '9.2.20'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json
index 5a6292b..1042071 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.json
+++ b/erpnext/accounts/doctype/payment_request/payment_request.json
@@ -26,7 +26,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
- "in_list_view": 0,
+ "in_list_view": 1,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
@@ -432,7 +432,7 @@
"options": "<pre><h5>Message Example</h5>\n\n<p>Dear {{ doc.contact_person }},</p>\n\n<p>Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.</p>\n\n<a href=\"{{ payment_url }}\"> click here to pay </a>\n\n</pre>\n",
"permlevel": 0,
"precision": "",
- "print_hide": 0,
+ "print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -728,7 +728,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-06-13 14:29:20.388372",
+ "modified": "2017-12-02 15:50:41.775006",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
index 2b7fe77..e620065 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
@@ -19,7 +19,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "Valuation and Total",
+ "default": "Total",
"fieldname": "category",
"fieldtype": "Select",
"hidden": 0,
@@ -679,7 +679,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-11-15 19:26:57.074345",
+ "modified": "2017-12-06 13:37:44.483509",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Taxes and Charges",
diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
index 890833b..67112b6 100644
--- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
+++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
@@ -86,17 +86,20 @@
for d in assets:
asset = frappe.get_doc("Asset", d.name)
- asset_depreciations.setdefault(d.asset_category, frappe._dict({
- "accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
- "depreciation_amount_during_the_period": 0,
- "depreciation_eliminated_during_the_period": 0
- }))
+ if d.asset_category in asset_depreciations:
+ asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
+ else:
+ asset_depreciations.setdefault(d.asset_category, frappe._dict({
+ "accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
+ "depreciation_amount_during_the_period": 0,
+ "depreciation_eliminated_during_the_period": 0
+ }))
depr = asset_depreciations[d.asset_category]
for schedule in asset.get("schedules"):
if getdate(schedule.schedule_date) < getdate(filters.from_date):
- if not asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date):
+ if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 9eea472..5df2a65 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -134,8 +134,12 @@
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
+ "opening_debit": 0.0,
+ "opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
+ "closing_debit": 0.0,
+ "closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
@@ -156,7 +160,10 @@
total_row["debit"] += d["debit"]
total_row["credit"] += d["credit"]
-
+ total_row["opening_debit"] += d["opening_debit"]
+ total_row["opening_credit"] += d["opening_credit"]
+ total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
+ total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
return total_row
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index 8d1fb3d..0cab383 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -232,7 +232,7 @@
"new_quotations","pending_quotations","sales_order","purchase_order","pending_sales_orders","pending_purchase_orders",
"invoiced_amount", "payables", "bank_balance", "credit_balance"):
if self.get(key):
- cache_key = "email_digest:card:{0}:{1}:{2}".format(self.company, self.frequency, key)
+ cache_key = "email_digest:card:{0}:{1}:{2}:{3}".format(self.company, self.frequency, key, self.from_date)
card = cache.get(cache_key)
if card:
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 364f21a..5d3ef78 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -78,7 +78,7 @@
@frappe.whitelist(allow_guest=True)
def get_product_list_for_group(product_group=None, start=0, limit=10, search=None):
- child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(product_group)])
+ child_groups = ", ".join(['"' + frappe.db.escape(i[0]) + '"' for i in get_child_groups(product_group)])
# base query
query = """select I.name, I.item_name, I.item_code, I.route, I.image, I.website_image, I.thumbnail, I.item_group,
diff --git a/erpnext/stock/doctype/batch/batch.js b/erpnext/stock/doctype/batch/batch.js
index 20581dc..677d0f0 100644
--- a/erpnext/stock/doctype/batch/batch.js
+++ b/erpnext/stock/doctype/batch/batch.js
@@ -70,31 +70,38 @@
// move - ask for target warehouse and make stock entry
rows.find('.btn-move').on('click', function() {
var $btn = $(this);
- frappe.prompt({
- fieldname: 'to_warehouse',
- label: __('To Warehouse'),
- fieldtype: 'Link',
- options: 'Warehouse'
- },
- (data) => {
- frappe.call({
- method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
- args: {
- item_code: frm.doc.item,
- batch_no: frm.doc.name,
- qty: $btn.attr('data-qty'),
- from_warehouse: $btn.attr('data-warehouse'),
- to_warehouse: data.to_warehouse
- },
- callback: (r) => {
- frappe.show_alert(__('Stock Entry {0} created',
- ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
- frm.refresh();
- },
- });
- },
- __('Select Target Warehouse'),
- __('Move')
+ const fields = [
+ {
+ fieldname: 'to_warehouse',
+ label: __('To Warehouse'),
+ fieldtype: 'Link',
+ options: 'Warehouse'
+ }
+ ];
+
+ frappe.prompt(
+ fields,
+ (data) => {
+ frappe.call({
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
+ args: {
+ item_code: frm.doc.item,
+ batch_no: frm.doc.name,
+ qty: $btn.attr('data-qty'),
+ from_warehouse: $btn.attr('data-warehouse'),
+ to_warehouse: data.to_warehouse,
+ source_document: frm.doc.reference_name,
+ reference_doctype: frm.doc.reference_doctype
+ },
+ callback: (r) => {
+ frappe.show_alert(__('Stock Entry {0} created',
+ ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+ frm.refresh();
+ },
+ });
+ },
+ __('Select Target Warehouse'),
+ __('Move')
);
});
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 6af8c09..b656c3f 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -12,6 +12,7 @@
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
from erpnext.accounts.doctype.account.test_account import get_inventory_account
+
class TestPurchaseReceipt(unittest.TestCase):
def setUp(self):
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
@@ -259,7 +260,7 @@
item_code = frappe.db.get_value('Item', {'has_serial_no': 1})
if not item_code:
- item = make_item("Test Serial Item 1", dict(has_serial_no = 1))
+ item = make_item("Test Serial Item 1", dict(has_serial_no=1))
item_code = item.name
serial_no = random_string(5)
@@ -273,11 +274,13 @@
serial_no=serial_no, basic_rate=100, do_not_submit=True)
self.assertRaises(SerialNoDuplicateError, se.submit)
+
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/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
index e1ec3ee..446f718 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
@@ -20,6 +20,16 @@
:do_not_save: Optional flag
:do_not_submit: Optional flag
'''
+
+ def process_serial_numbers(serial_nos_list):
+ serial_nos_list = [
+ '\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list)
+ ]
+
+ uniques = list(set(serial_nos_list[0].split('\n')))
+
+ return '\n'.join(uniques)
+
s = frappe.new_doc("Stock Entry")
args = frappe._dict(args)
@@ -77,6 +87,25 @@
if not args.cost_center:
args.cost_center = frappe.get_value('Company', s.company, 'cost_center')
+ if not args.expense_account:
+ args.expense_account = frappe.get_value('Company', s.company, 'stock_adjustment_account')
+
+ # We can find out the serial number using the batch source document
+ serial_number = args.serial_no
+
+ if not args.serial_no and args.qty and args.batch_no:
+ serial_number_list = frappe.get_list(
+ doctype='Stock Ledger Entry',
+ fields=['serial_no'],
+ filters={
+ 'batch_no': args.batch_no,
+ 'warehouse': args.from_warehouse
+ }
+ )
+ serial_number = process_serial_numbers(serial_number_list)
+
+ args.serial_no = serial_number
+
s.append("items", {
"item_code": args.item,
"s_warehouse": args.source,