Merge branch 'develop' of github.com:frappe/erpnext into v4-hotfix
diff --git a/erpnext/accounts/doctype/pos_setting/test_pos_setting.py b/erpnext/accounts/doctype/pos_setting/test_pos_setting.py
deleted file mode 100644
index d563be9..0000000
--- a/erpnext/accounts/doctype/pos_setting/test_pos_setting.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-import frappe
-test_records = frappe.get_test_records('Pos Setting')
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/pos_setting/test_records.json b/erpnext/accounts/doctype/pos_setting/test_records.json
deleted file mode 100644
index 0d382a7..0000000
--- a/erpnext/accounts/doctype/pos_setting/test_records.json
+++ /dev/null
@@ -1,16 +0,0 @@
-[
- {
- "cash_bank_account": "_Test Account Bank Account - _TC",
- "company": "_Test Company",
- "cost_center": "_Test Cost Center - _TC",
- "currency": "INR",
- "doctype": "POS Setting",
- "expense_account": "_Test Account Cost for Goods Sold - _TC",
- "income_account": "Sales - _TC",
- "name": "_Test POS Setting",
- "naming_series": "_T-POS Setting-",
- "selling_price_list": "_Test Price List",
- "territory": "_Test Territory",
- "warehouse": "_Test Warehouse - _TC"
- }
-]
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 2a0bc24..85e5782 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -6,6 +6,8 @@
from frappe.utils import flt
from erpnext.accounts.utils import get_stock_and_account_difference
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
+from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
+
class TestSalesInvoice(unittest.TestCase):
def make(self):
@@ -365,27 +367,30 @@
561.8)
def test_time_log_batch(self):
- tlb = frappe.get_doc("Time Log Batch", "_T-Time Log Batch-00001")
+ delete_time_log_and_batch()
+ time_log = create_time_log()
+ tlb = create_time_log_batch(time_log)
+
+ tlb = frappe.get_doc("Time Log Batch", tlb.name)
tlb.submit()
si = frappe.get_doc(frappe.copy_doc(test_records[0]))
- si.get("entries")[0].time_log_batch = "_T-Time Log Batch-00001"
+ si.get("entries")[0].time_log_batch = tlb.name
si.insert()
si.submit()
- self.assertEquals(frappe.db.get_value("Time Log Batch", "_T-Time Log Batch-00001",
- "status"), "Billed")
+ self.assertEquals(frappe.db.get_value("Time Log Batch", tlb.name, "status"), "Billed")
- self.assertEquals(frappe.db.get_value("Time Log", "_T-Time Log-00001", "status"),
- "Billed")
+ self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Billed")
si.cancel()
- self.assertEquals(frappe.db.get_value("Time Log Batch", "_T-Time Log Batch-00001",
- "status"), "Submitted")
+ self.assertEquals(frappe.db.get_value("Time Log Batch", tlb.name, "status"), "Submitted")
- self.assertEquals(frappe.db.get_value("Time Log", "_T-Time Log-00001", "status"),
- "Batched for Billing")
+ self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Batched for Billing")
+
+ frappe.delete_doc("Sales Invoice", si.name)
+ delete_time_log_and_batch()
def test_sales_invoice_gl_entry_without_aii(self):
self.clear_stock_account_balance()
@@ -423,9 +428,9 @@
def test_pos_gl_entry_with_aii(self):
self.clear_stock_account_balance()
set_perpetual_inventory()
+ self.make_pos_setting()
self._insert_purchase_receipt()
- self._insert_pos_settings()
pos = copy.deepcopy(test_records[1])
pos["is_pos"] = 1
@@ -479,6 +484,26 @@
set_perpetual_inventory(0)
+ frappe.db.sql("delete from `tabPOS Setting`")
+
+ def make_pos_setting(self):
+ pos_setting = frappe.get_doc({
+ "cash_bank_account": "_Test Account Bank Account - _TC",
+ "company": "_Test Company",
+ "cost_center": "_Test Cost Center - _TC",
+ "currency": "INR",
+ "doctype": "POS Setting",
+ "expense_account": "_Test Account Cost for Goods Sold - _TC",
+ "income_account": "Sales - _TC",
+ "name": "_Test POS Setting",
+ "naming_series": "_T-POS Setting-",
+ "selling_price_list": "_Test Price List",
+ "territory": "_Test Territory",
+ "warehouse": "_Test Warehouse - _TC"
+ })
+
+ pos_setting.insert()
+
def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self):
self.clear_stock_account_balance()
set_perpetual_inventory()
@@ -604,14 +629,6 @@
dn.submit()
return dn
- def _insert_pos_settings(self):
- from erpnext.accounts.doctype.pos_setting.test_pos_setting \
- import test_records as pos_setting_test_records
- frappe.db.sql("""delete from `tabPOS Setting`""")
-
- ps = frappe.copy_doc(pos_setting_test_records[0])
- ps.insert()
-
def test_sales_invoice_with_advance(self):
from erpnext.accounts.doctype.journal_voucher.test_journal_voucher \
import test_records as jv_test_records
@@ -843,5 +860,5 @@
self.assertRaises(SerialNoStatusError, si.submit)
-test_dependencies = ["Journal Voucher", "POS Setting", "Contact", "Address"]
+test_dependencies = ["Journal Voucher", "Contact", "Address"]
test_records = frappe.get_test_records('Sales Invoice')
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 43276e5..ad56d8f 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -256,7 +256,7 @@
rm_supplied_idx += 1
- raw_materials_cost += required_qty * flt(item.rate)
+ raw_materials_cost += required_qty * flt(bom_item.rate)
if self.doctype == "Purchase Receipt":
item.rm_supp_cost = raw_materials_cost
diff --git a/erpnext/projects/doctype/time_log/test_time_log.py b/erpnext/projects/doctype/time_log/test_time_log.py
index 7aadf5c..4a312ad 100644
--- a/erpnext/projects/doctype/time_log/test_time_log.py
+++ b/erpnext/projects/doctype/time_log/test_time_log.py
@@ -5,11 +5,17 @@
import unittest
from erpnext.projects.doctype.time_log.time_log import OverlapError
+from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
class TestTimeLog(unittest.TestCase):
def test_duplication(self):
+ frappe.db.sql("delete from `tabTime Log`")
+ frappe.get_doc(frappe.copy_doc(test_records[0])).insert()
+
ts = frappe.get_doc(frappe.copy_doc(test_records[0]))
self.assertRaises(OverlapError, ts.insert)
+ frappe.db.sql("delete from `tabTime Log`")
+
test_records = frappe.get_test_records('Time Log')
test_ignore = ["Time Log Batch", "Sales Invoice"]
diff --git a/erpnext/projects/doctype/time_log_batch/test_records.json b/erpnext/projects/doctype/time_log_batch/test_records.json
deleted file mode 100644
index d386000..0000000
--- a/erpnext/projects/doctype/time_log_batch/test_records.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "doctype": "Time Log Batch",
- "rate": "500",
- "time_log_batch_details": [
- {
- "doctype": "Time Log Batch Detail",
- "parentfield": "time_log_batch_details",
- "parenttype": "Time Log Batch",
- "time_log": "_T-Time Log-00001"
- }
- ]
- }
-]
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
index dceaee7..de57f28 100644
--- a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
+++ b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
@@ -4,36 +4,57 @@
import frappe, unittest
class TimeLogBatchTest(unittest.TestCase):
- def setUp(self):
- for name in frappe.db.sql_list("select name from `tabTime Log Batch` where docstatus=1"):
- frappe.get_doc("Time Log Batch", name).cancel()
- frappe.delete_doc("Time Log Batch", name)
-
- for name in frappe.db.sql_list("select name from `tabTime Log` where docstatus=1"):
- frappe.get_doc("Time Log", name).cancel()
- frappe.delete_doc("Time Log", name)
-
def test_time_log_status(self):
- from erpnext.projects.doctype.time_log.test_time_log import test_records as time_log_records
- time_log = frappe.copy_doc(time_log_records[0])
- time_log.update({
- "from_time": "2013-01-02 10:00:00.000000",
- "to_time": "2013-01-02 11:00:00.000000",
- "docstatus": 0
- })
- time_log.insert()
- time_log.submit()
+ delete_time_log_and_batch()
+ time_log = create_time_log()
- self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Submitted")
- tlb = frappe.copy_doc(test_records[0])
- tlb.get("time_log_batch_details")[0].time_log = time_log.name
- tlb.insert()
- tlb.submit()
+ self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Submitted")
- self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Batched for Billing")
+ tlb = create_time_log_batch(time_log)
+
+ self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Batched for Billing")
tlb.cancel()
- self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Submitted")
+ self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Submitted")
-test_records = frappe.get_test_records('Time Log Batch')
-test_dependencies = ["Time Log"]
+ delete_time_log_and_batch()
+
+def delete_time_log_and_batch():
+ for name in frappe.db.sql_list("select name from `tabTime Log Batch` where docstatus=1"):
+ frappe.get_doc("Time Log Batch", name).cancel()
+ frappe.delete_doc("Time Log Batch", name)
+
+ for name in frappe.db.sql_list("select name from `tabTime Log` where docstatus=1"):
+ frappe.get_doc("Time Log", name).cancel()
+ frappe.delete_doc("Time Log", name)
+
+def create_time_log():
+ from erpnext.projects.doctype.time_log.test_time_log import test_records as time_log_records
+ time_log = frappe.copy_doc(time_log_records[0])
+ time_log.update({
+ "from_time": "2013-01-02 10:00:00.000000",
+ "to_time": "2013-01-02 11:00:00.000000",
+ "docstatus": 0
+ })
+ time_log.insert()
+ time_log.submit()
+ return time_log.name
+
+def create_time_log_batch(time_log):
+ tlb = frappe.get_doc({
+ "doctype": "Time Log Batch",
+ "rate": "500",
+ "time_log_batch_details": [
+ {
+ "doctype": "Time Log Batch Detail",
+ "parentfield": "time_log_batch_details",
+ "parenttype": "Time Log Batch",
+ "time_log": time_log
+ }
+ ]
+ })
+
+ tlb.insert()
+ tlb.submit()
+ return tlb
+
test_ignore = ["Sales Invoice"]
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 0aa3acc..77de44d 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -94,8 +94,9 @@
pr.run_method("calculate_taxes_and_totals")
pr.insert()
- self.assertEquals(pr.get("purchase_receipt_details")[0].rm_supp_cost, 70000.0)
self.assertEquals(len(pr.get("pr_raw_material_details")), 2)
+ self.assertEquals(pr.get("purchase_receipt_details")[0].rm_supp_cost, 70000.0)
+
def test_serial_no_supplier(self):
pr = frappe.copy_doc(test_records[0])
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 4739d21..fc60fce 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -256,7 +256,7 @@
# insert a pos invoice with update stock
si = frappe.copy_doc(sales_invoice_test_records[1])
- si.is_pos = si.update_stock = 1
+ si.update_stock = 1
si.get("entries")[0].warehouse = "_Test Warehouse - _TC"
si.get("entries")[0].item_code = item_code
si.get("entries")[0].qty = 5.0
@@ -663,6 +663,7 @@
def test_serial_no_not_exists(self):
self._clear_stock_account_balance()
+ frappe.db.sql("delete from `tabSerial No` where name in ('ABCD', 'EFGH')")
se = frappe.copy_doc(test_records[0])
se.purpose = "Material Issue"
se.get("mtn_details")[0].item_code = "_Test Serialized Item"
@@ -823,8 +824,6 @@
se.submit()
return se
-test_records = frappe.get_test_records('Stock Entry')
-
def make_stock_entry(item, source, target, qty, incoming_rate=None):
s = frappe.new_doc("Stock Entry")
if source and target:
@@ -845,3 +844,5 @@
s.insert()
s.submit()
return s
+
+test_records = frappe.get_test_records('Stock Entry')
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 4bc34d6..fe65f22 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -47,7 +47,7 @@
self.reconciliation_json = json.dumps(data)
def _get_msg(row_num, msg):
- return _("Row # ") + ("%d: " % (row_num+head_row_no+2)) + _(msg)
+ return _("Row # {0}: ").format(row_num+head_row_no+2) + msg
self.validation_messages = []
item_warehouse_combinations = []
@@ -60,27 +60,30 @@
for row_num, row in enumerate(rows):
# find duplicates
if [row[0], row[1]] in item_warehouse_combinations:
- self.validation_messages.append(_get_msg(row_num, "Duplicate entry"))
+ self.validation_messages.append(_get_msg(row_num, _("Duplicate entry")))
else:
item_warehouse_combinations.append([row[0], row[1]])
self.validate_item(row[0], row_num+head_row_no+2)
- # note: warehouse will be validated through link validation
+
+ # validate warehouse
+ if not frappe.db.get_value("Warehouse", row[1]):
+ self.validation_messages.append(_get_msg(row_num, _("Warehouse not found in the system")))
# if both not specified
if row[2] == "" and row[3] == "":
self.validation_messages.append(_get_msg(row_num,
- "Please specify either Quantity or Valuation Rate or both"))
+ _("Please specify either Quantity or Valuation Rate or both")))
# do not allow negative quantity
if flt(row[2]) < 0:
self.validation_messages.append(_get_msg(row_num,
- "Negative Quantity is not allowed"))
+ _("Negative Quantity is not allowed")))
# do not allow negative valuation
if flt(row[3]) < 0:
self.validation_messages.append(_get_msg(row_num,
- "Negative Valuation Rate is not allowed"))
+ _("Negative Valuation Rate is not allowed")))
# throw all validation messages
if self.validation_messages:
@@ -97,6 +100,8 @@
try:
item = frappe.get_doc("Item", item_code)
+ if not item:
+ raise frappe.ValidationError, (_("Item: {0} not found in the system").format(item_code))
# end of life and stock item
validate_end_of_life(item_code, item.end_of_life, verbose=0)
@@ -104,12 +109,13 @@
# item should not be serialized
if item.has_serial_no == "Yes":
- raise frappe.ValidationError, _("Serialized Item {0} cannot be updated using Stock Reconciliation").format(item_code)
+ raise frappe.ValidationError, _("Serialized Item {0} cannot be updated \
+ using Stock Reconciliation").format(item_code)
# item managed batch-wise not allowed
if item.has_batch_no == "Yes":
- frappe.throw(_("Item: {0} managed batch-wise, can not be reconciled using \
- Stock Reconciliation, instead use Stock Entry").format(item_code))
+ raise frappe.ValidationError, _("Item: {0} managed batch-wise, can not be reconciled using \
+ Stock Reconciliation, instead use Stock Entry").format(item_code)
# docstatus should be < 2
validate_cancelled_item(item_code, item.docstatus, verbose=0)