mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-18 12:39:18 +00:00
Test case fixes
This commit is contained in:
@@ -103,11 +103,10 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
def test_monthly_budget_crossed_ignore(self):
|
def test_monthly_budget_crossed_ignore(self):
|
||||||
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
||||||
|
|
||||||
existing_expense = self.get_actual_expense("2013-02-28")
|
self.set_total_expense_zero("2013-02-28")
|
||||||
current_expense = - existing_expense + 20000 if existing_expense < 0 else 20000
|
|
||||||
|
|
||||||
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Account Bank Account - _TC", current_expense, "_Test Cost Center - _TC", submit=True)
|
"_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC", submit=True)
|
||||||
|
|
||||||
self.assertTrue(frappe.db.get_value("GL Entry",
|
self.assertTrue(frappe.db.get_value("GL Entry",
|
||||||
{"voucher_type": "Journal Entry", "voucher_no": jv.name}))
|
{"voucher_type": "Journal Entry", "voucher_no": jv.name}))
|
||||||
@@ -115,12 +114,11 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
def test_monthly_budget_crossed_stop(self):
|
def test_monthly_budget_crossed_stop(self):
|
||||||
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
|
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
|
||||||
|
|
||||||
existing_expense = self.get_actual_expense("2013-02-28")
|
self.set_total_expense_zero("2013-02-28")
|
||||||
current_expense = - existing_expense + 20000 if existing_expense < 0 else 20000
|
|
||||||
|
|
||||||
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Account Bank Account - _TC", current_expense, "_Test Cost Center - _TC")
|
"_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC")
|
||||||
|
|
||||||
self.assertRaises(BudgetError, jv.submit)
|
self.assertRaises(BudgetError, jv.submit)
|
||||||
|
|
||||||
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
||||||
@@ -130,35 +128,33 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
|
|
||||||
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Stop")
|
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Stop")
|
||||||
|
|
||||||
existing_expense = self.get_actual_expense("2013-02-28")
|
self.set_total_expense_zero("2013-02-28")
|
||||||
current_expense = - existing_expense + 150000 if existing_expense < 0 else 150000
|
|
||||||
|
|
||||||
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Account Bank Account - _TC", current_expense, "_Test Cost Center - _TC")
|
"_Test Account Bank Account - _TC", 150000, "_Test Cost Center - _TC")
|
||||||
|
|
||||||
self.assertRaises(BudgetError, jv.submit)
|
self.assertRaises(BudgetError, jv.submit)
|
||||||
|
|
||||||
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Ignore")
|
frappe.db.set_value("Company", "_Test Company", "yearly_bgt_flag", "Ignore")
|
||||||
|
|
||||||
def test_monthly_budget_on_cancellation(self):
|
def test_monthly_budget_on_cancellation(self):
|
||||||
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
|
self.set_total_expense_zero("2013-02-28")
|
||||||
|
|
||||||
existing_expense = self.get_actual_expense("2013-02-28")
|
|
||||||
current_expense = - existing_expense - 30000 if existing_expense < 0 else 30000
|
|
||||||
|
|
||||||
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
|
||||||
"_Test Account Bank Account - _TC", current_expense, "_Test Cost Center - _TC", submit=True)
|
|
||||||
|
|
||||||
self.assertTrue(frappe.db.get_value("GL Entry",
|
|
||||||
{"voucher_type": "Journal Entry", "voucher_no": jv.name}))
|
|
||||||
|
|
||||||
jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
jv1 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
"_Test Account Bank Account - _TC", 40000, "_Test Cost Center - _TC", submit=True)
|
"_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True)
|
||||||
|
|
||||||
self.assertTrue(frappe.db.get_value("GL Entry",
|
self.assertTrue(frappe.db.get_value("GL Entry",
|
||||||
{"voucher_type": "Journal Entry", "voucher_no": jv1.name}))
|
{"voucher_type": "Journal Entry", "voucher_no": jv1.name}))
|
||||||
|
|
||||||
|
jv2 = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
|
"_Test Account Bank Account - _TC", 20000, "_Test Cost Center - _TC", submit=True)
|
||||||
|
|
||||||
|
self.assertTrue(frappe.db.get_value("GL Entry",
|
||||||
|
{"voucher_type": "Journal Entry", "voucher_no": jv2.name}))
|
||||||
|
|
||||||
|
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Stop")
|
||||||
|
|
||||||
self.assertRaises(BudgetError, jv.cancel)
|
self.assertRaises(BudgetError, jv1.cancel)
|
||||||
|
|
||||||
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
frappe.db.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
||||||
|
|
||||||
@@ -171,6 +167,11 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
"fiscal_year": get_fiscal_year(monthly_end_date)[0]
|
"fiscal_year": get_fiscal_year(monthly_end_date)[0]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def set_total_expense_zero(self, posting_date):
|
||||||
|
existing_expense = self.get_actual_expense(posting_date)
|
||||||
|
make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||||
|
"_Test Account Bank Account - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True)
|
||||||
|
|
||||||
def make_journal_entry(account1, account2, amount, cost_center=None, submit=False):
|
def make_journal_entry(account1, account2, amount, cost_center=None, submit=False):
|
||||||
jv = frappe.new_doc("Journal Entry")
|
jv = frappe.new_doc("Journal Entry")
|
||||||
jv.posting_date = "2013-02-14"
|
jv.posting_date = "2013-02-14"
|
||||||
|
|||||||
@@ -513,8 +513,6 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertFalse(gle)
|
self.assertFalse(gle)
|
||||||
|
|
||||||
self.assertFalse(get_stock_and_account_difference([stock_in_hand]))
|
|
||||||
|
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
frappe.db.sql("delete from `tabPOS Setting`")
|
frappe.db.sql("delete from `tabPOS Setting`")
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ test_records = frappe.get_test_records('BOM')
|
|||||||
class TestBOM(unittest.TestCase):
|
class TestBOM(unittest.TestCase):
|
||||||
def test_get_items(self):
|
def test_get_items(self):
|
||||||
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
||||||
items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=0)
|
items_dict = get_bom_items_as_dict(bom=get_default_bom(), qty=1, fetch_exploded=0)
|
||||||
self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict)
|
self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict)
|
||||||
self.assertTrue(test_records[2]["items"][1]["item_code"] in items_dict)
|
self.assertTrue(test_records[2]["items"][1]["item_code"] in items_dict)
|
||||||
self.assertEquals(len(items_dict.values()), 2)
|
self.assertEquals(len(items_dict.values()), 2)
|
||||||
|
|
||||||
def test_get_items_exploded(self):
|
def test_get_items_exploded(self):
|
||||||
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
||||||
items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=1)
|
items_dict = get_bom_items_as_dict(bom=get_default_bom(), qty=1, fetch_exploded=1)
|
||||||
self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict)
|
self.assertTrue(test_records[2]["items"][0]["item_code"] in items_dict)
|
||||||
self.assertFalse(test_records[2]["items"][1]["item_code"] in items_dict)
|
self.assertFalse(test_records[2]["items"][1]["item_code"] in items_dict)
|
||||||
self.assertTrue(test_records[0]["items"][0]["item_code"] in items_dict)
|
self.assertTrue(test_records[0]["items"][0]["item_code"] in items_dict)
|
||||||
@@ -28,8 +28,7 @@ class TestBOM(unittest.TestCase):
|
|||||||
|
|
||||||
def test_get_items_list(self):
|
def test_get_items_list(self):
|
||||||
from erpnext.manufacturing.doctype.bom.bom import get_bom_items
|
from erpnext.manufacturing.doctype.bom.bom import get_bom_items
|
||||||
default_bom = frappe.db.get_value("BOM", {"item":"_Test FG Item 2", "is_default": 1})
|
self.assertEquals(len(get_bom_items(bom=get_default_bom())), 3)
|
||||||
self.assertEquals(len(get_bom_items(bom=default_bom)), 3)
|
|
||||||
|
|
||||||
def test_default_bom(self):
|
def test_default_bom(self):
|
||||||
def _get_default_bom_in_item():
|
def _get_default_bom_in_item():
|
||||||
@@ -47,3 +46,6 @@ class TestBOM(unittest.TestCase):
|
|||||||
bom.save()
|
bom.save()
|
||||||
|
|
||||||
self.assertTrue(_get_default_bom_in_item(), bom.name)
|
self.assertTrue(_get_default_bom_in_item(), bom.name)
|
||||||
|
|
||||||
|
def get_default_bom(item_code="_Test FG Item 2"):
|
||||||
|
return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
|
||||||
|
|||||||
@@ -253,17 +253,18 @@ class ProductionOrder(Document):
|
|||||||
def set_operation_start_end_time(self, i, d):
|
def set_operation_start_end_time(self, i, d):
|
||||||
"""Set start and end time for given operation. If first operation, set start as
|
"""Set start and end time for given operation. If first operation, set start as
|
||||||
`planned_start_date`, else add time diff to end time of earlier operation."""
|
`planned_start_date`, else add time diff to end time of earlier operation."""
|
||||||
if i==0:
|
if self.planned_start_date:
|
||||||
# first operation at planned_start date
|
if i==0:
|
||||||
d.planned_start_time = self.planned_start_date
|
# first operation at planned_start date
|
||||||
else:
|
d.planned_start_time = self.planned_start_date
|
||||||
d.planned_start_time = get_datetime(self.operations[i-1].planned_end_time)\
|
else:
|
||||||
+ self.get_mins_between_operations()
|
d.planned_start_time = get_datetime(self.operations[i-1].planned_end_time)\
|
||||||
|
+ self.get_mins_between_operations()
|
||||||
|
|
||||||
d.planned_end_time = get_datetime(d.planned_start_time) + relativedelta(minutes = d.time_in_mins)
|
d.planned_end_time = get_datetime(d.planned_start_time) + relativedelta(minutes = d.time_in_mins)
|
||||||
|
|
||||||
if d.planned_start_time == d.planned_end_time:
|
if d.planned_start_time == d.planned_end_time:
|
||||||
frappe.throw(_("Capacity Planning Error"))
|
frappe.throw(_("Capacity Planning Error"))
|
||||||
|
|
||||||
def get_mins_between_operations(self):
|
def get_mins_between_operations(self):
|
||||||
if not hasattr(self, "_mins_between_operations"):
|
if not hasattr(self, "_mins_between_operations"):
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import unittest
|
import unittest
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import flt, get_datetime
|
from frappe.utils import flt, get_datetime, cstr, time_diff_in_hours
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||||
from erpnext.manufacturing.doctype.production_order.production_order import make_stock_entry
|
from erpnext.manufacturing.doctype.production_order.production_order import make_stock_entry, make_time_log
|
||||||
from erpnext.stock.doctype.stock_entry import test_stock_entry
|
from erpnext.stock.doctype.stock_entry import test_stock_entry
|
||||||
from erpnext.projects.doctype.time_log.time_log import OverProductionLoggedError
|
from erpnext.projects.doctype.time_log.time_log import OverProductionLoggedError
|
||||||
|
|
||||||
@@ -15,11 +15,15 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
def check_planned_qty(self):
|
def check_planned_qty(self):
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
planned0 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty") or 0
|
planned0 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
|
||||||
|
"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty") or 0
|
||||||
|
|
||||||
pro_doc = frappe.copy_doc(test_records[0])
|
pro_order = make_prod_order_test_record()
|
||||||
pro_doc.insert()
|
|
||||||
pro_doc.submit()
|
planned1 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
|
||||||
|
"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty")
|
||||||
|
|
||||||
|
self.assertEqual(planned1, planned0 + 10)
|
||||||
|
|
||||||
# add raw materials to stores
|
# add raw materials to stores
|
||||||
test_stock_entry.make_stock_entry(item_code="_Test Item",
|
test_stock_entry.make_stock_entry(item_code="_Test Item",
|
||||||
@@ -28,28 +32,25 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
target="Stores - _TC", qty=100, incoming_rate=100)
|
target="Stores - _TC", qty=100, incoming_rate=100)
|
||||||
|
|
||||||
# from stores to wip
|
# from stores to wip
|
||||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer for Manufacture", 4))
|
s = frappe.get_doc(make_stock_entry(pro_order.name, "Material Transfer for Manufacture", 4))
|
||||||
for d in s.get("items"):
|
for d in s.get("items"):
|
||||||
d.s_warehouse = "Stores - _TC"
|
d.s_warehouse = "Stores - _TC"
|
||||||
s.fiscal_year = "_Test Fiscal Year 2013"
|
|
||||||
s.posting_date = "2013-01-02"
|
|
||||||
s.insert()
|
s.insert()
|
||||||
s.submit()
|
s.submit()
|
||||||
|
|
||||||
# from wip to fg
|
# from wip to fg
|
||||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 4))
|
s = frappe.get_doc(make_stock_entry(pro_order.name, "Manufacture", 4))
|
||||||
s.fiscal_year = "_Test Fiscal Year 2013"
|
|
||||||
s.posting_date = "2013-01-03"
|
|
||||||
s.insert()
|
s.insert()
|
||||||
s.submit()
|
s.submit()
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Production Order", pro_doc.name,
|
self.assertEqual(frappe.db.get_value("Production Order", pro_order.name, "produced_qty"), 4)
|
||||||
"produced_qty"), 4)
|
|
||||||
planned1 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty")
|
planned2 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
|
||||||
|
"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty")
|
||||||
|
|
||||||
|
self.assertEqual(planned2, planned0 + 6)
|
||||||
|
|
||||||
self.assertEqual(planned1 - planned0, 6)
|
return pro_order
|
||||||
|
|
||||||
return pro_doc
|
|
||||||
|
|
||||||
def test_over_production(self):
|
def test_over_production(self):
|
||||||
from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError
|
from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError
|
||||||
@@ -61,31 +62,18 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
target="_Test Warehouse - _TC", qty=100, incoming_rate=100)
|
target="_Test Warehouse - _TC", qty=100, incoming_rate=100)
|
||||||
|
|
||||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7))
|
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7))
|
||||||
s.fiscal_year = "_Test Fiscal Year 2013"
|
|
||||||
s.posting_date = "2013-01-04"
|
|
||||||
s.insert()
|
s.insert()
|
||||||
|
|
||||||
self.assertRaises(StockOverProductionError, s.submit)
|
self.assertRaises(StockOverProductionError, s.submit)
|
||||||
|
|
||||||
def test_make_time_log(self):
|
def test_make_time_log(self):
|
||||||
from erpnext.manufacturing.doctype.production_order.production_order import make_time_log
|
prod_order = make_prod_order_test_record(item="_Test FG Item 2",
|
||||||
from frappe.utils import cstr
|
planned_start_date="2014-11-25 00:00:00", qty=1, do_not_save=True)
|
||||||
from frappe.utils import time_diff_in_hours
|
|
||||||
|
|
||||||
prod_order = frappe.get_doc({
|
|
||||||
"doctype": "Production Order",
|
|
||||||
"production_item": "_Test FG Item 2",
|
|
||||||
"bom_no": "BOM/_Test FG Item 2/001",
|
|
||||||
"qty": 1,
|
|
||||||
"wip_warehouse": "_Test Warehouse - _TC",
|
|
||||||
"fg_warehouse": "_Test Warehouse 1 - _TC",
|
|
||||||
"company": "_Test Company",
|
|
||||||
"planned_start_date": "2014-11-25 00:00:00"
|
|
||||||
})
|
|
||||||
|
|
||||||
prod_order.set_production_order_operations()
|
prod_order.set_production_order_operations()
|
||||||
prod_order.insert()
|
prod_order.insert()
|
||||||
prod_order.submit()
|
prod_order.submit()
|
||||||
|
|
||||||
d = prod_order.operations[0]
|
d = prod_order.operations[0]
|
||||||
|
|
||||||
d.completed_qty = flt(d.completed_qty)
|
d.completed_qty = flt(d.completed_qty)
|
||||||
@@ -112,8 +100,10 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
self.assertEqual(prod_order.operations[0].status, "Completed")
|
self.assertEqual(prod_order.operations[0].status, "Completed")
|
||||||
self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)
|
self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)
|
||||||
|
|
||||||
self.assertEqual(get_datetime(prod_order.operations[0].actual_start_time), get_datetime(time_log.from_time))
|
self.assertEqual(get_datetime(prod_order.operations[0].actual_start_time),
|
||||||
self.assertEqual(get_datetime(prod_order.operations[0].actual_end_time), get_datetime(time_log.to_time))
|
get_datetime(time_log.from_time))
|
||||||
|
self.assertEqual(get_datetime(prod_order.operations[0].actual_end_time),
|
||||||
|
get_datetime(time_log.to_time))
|
||||||
|
|
||||||
self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
|
self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
|
||||||
self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)
|
self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)
|
||||||
@@ -136,4 +126,25 @@ class TestProductionOrder(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
self.assertRaises(OverProductionLoggedError, time_log2.save)
|
self.assertRaises(OverProductionLoggedError, time_log2.save)
|
||||||
|
|
||||||
|
def make_prod_order_test_record(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
|
||||||
|
pro_order = frappe.new_doc("Production Order")
|
||||||
|
pro_order.production_item = args.production_item or args.item or args.item_code or "_Test FG Item"
|
||||||
|
pro_order.bom_no = frappe.db.get_value("BOM", {"item": pro_order.production_item,
|
||||||
|
"is_active": 1, "is_default": 1})
|
||||||
|
pro_order.qty = args.qty or 10
|
||||||
|
pro_order.wip_warehouse = args.wip_warehouse or "_Test Warehouse - _TC"
|
||||||
|
pro_order.fg_warehouse = args.fg_warehouse or "_Test Warehouse 1 - _TC"
|
||||||
|
pro_order.company = args.company or "_Test Company"
|
||||||
|
pro_order.stock_uom = "_Test UOM"
|
||||||
|
if args.planned_start_date:
|
||||||
|
pro_order.planned_start_date = args.planned_start_date
|
||||||
|
|
||||||
|
if not args.do_not_save:
|
||||||
|
pro_order.insert()
|
||||||
|
if not args.do_not_submit:
|
||||||
|
pro_order.submit()
|
||||||
|
return pro_order
|
||||||
|
|
||||||
test_records = frappe.get_test_records('Production Order')
|
test_records = frappe.get_test_records('Production Order')
|
||||||
|
|||||||
@@ -48,11 +48,12 @@ def get_default_holiday_list():
|
|||||||
return frappe.db.get_value("Company", frappe.defaults.get_user_default("company"), "default_holiday_list")
|
return frappe.db.get_value("Company", frappe.defaults.get_user_default("company"), "default_holiday_list")
|
||||||
|
|
||||||
def check_if_within_operating_hours(workstation, operation, from_datetime, to_datetime):
|
def check_if_within_operating_hours(workstation, operation, from_datetime, to_datetime):
|
||||||
if not cint(frappe.db.get_value("Manufacturing Settings", "None", "allow_production_on_holidays")):
|
if from_datetime and to_datetime:
|
||||||
check_workstation_for_holiday(workstation, from_datetime, to_datetime)
|
if not cint(frappe.db.get_value("Manufacturing Settings", "None", "allow_production_on_holidays")):
|
||||||
|
check_workstation_for_holiday(workstation, from_datetime, to_datetime)
|
||||||
|
|
||||||
if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")):
|
if not cint(frappe.db.get_value("Manufacturing Settings", None, "allow_overtime")):
|
||||||
is_within_operating_hours(workstation, operation, from_datetime, to_datetime)
|
is_within_operating_hours(workstation, operation, from_datetime, to_datetime)
|
||||||
|
|
||||||
def is_within_operating_hours(workstation, operation, from_datetime, to_datetime):
|
def is_within_operating_hours(workstation, operation, from_datetime, to_datetime):
|
||||||
operation_length = time_diff_in_seconds(to_datetime, from_datetime)
|
operation_length = time_diff_in_seconds(to_datetime, from_datetime)
|
||||||
@@ -67,10 +68,11 @@ def is_within_operating_hours(workstation, operation, from_datetime, to_datetime
|
|||||||
|
|
||||||
def check_workstation_for_holiday(workstation, from_datetime, to_datetime):
|
def check_workstation_for_holiday(workstation, from_datetime, to_datetime):
|
||||||
holiday_list = frappe.db.get_value("Workstation", workstation, "holiday_list")
|
holiday_list = frappe.db.get_value("Workstation", workstation, "holiday_list")
|
||||||
if holiday_list:
|
if holiday_list and from_datetime and to_datetime:
|
||||||
applicable_holidays = []
|
applicable_holidays = []
|
||||||
for d in frappe.db.sql("""select holiday_date from `tabHoliday` where parent = %s
|
for d in frappe.db.sql("""select holiday_date from `tabHoliday` where parent = %s
|
||||||
and holiday_date between %s and %s """, (holiday_list, getdate(from_datetime), getdate(to_datetime))):
|
and holiday_date between %s and %s """,
|
||||||
|
(holiday_list, getdate(from_datetime), getdate(to_datetime))):
|
||||||
applicable_holidays.append(formatdate(d[0]))
|
applicable_holidays.append(formatdate(d[0]))
|
||||||
|
|
||||||
if applicable_holidays:
|
if applicable_holidays:
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import unittest
|
|||||||
|
|
||||||
from erpnext.projects.doctype.time_log.time_log import OverlapError
|
from erpnext.projects.doctype.time_log.time_log import OverlapError
|
||||||
from erpnext.projects.doctype.time_log.time_log import NotSubmittedError
|
from erpnext.projects.doctype.time_log.time_log import NotSubmittedError
|
||||||
|
|
||||||
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
|
||||||
from erpnext.manufacturing.doctype.workstation.workstation import NotInWorkingHoursError
|
from erpnext.manufacturing.doctype.workstation.workstation import NotInWorkingHoursError
|
||||||
|
|
||||||
from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
|
from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
|
||||||
|
from erpnext.manufacturing.doctype.production_order.test_production_order import make_prod_order_test_record
|
||||||
|
|
||||||
|
|
||||||
class TestTimeLog(unittest.TestCase):
|
class TestTimeLog(unittest.TestCase):
|
||||||
def test_duplication(self):
|
def test_duplication(self):
|
||||||
@@ -30,8 +30,8 @@ class TestTimeLog(unittest.TestCase):
|
|||||||
frappe.db.sql("delete from `tabTime Log`")
|
frappe.db.sql("delete from `tabTime Log`")
|
||||||
|
|
||||||
def test_production_order_status(self):
|
def test_production_order_status(self):
|
||||||
prod_order = make_prod_order(self)
|
prod_order = make_prod_order_test_record(item="_Test FG Item 2", qty=1, do_not_submit=True)
|
||||||
|
prod_order.set_production_order_operations()
|
||||||
prod_order.save()
|
prod_order.save()
|
||||||
|
|
||||||
time_log = frappe.get_doc({
|
time_log = frappe.get_doc({
|
||||||
@@ -46,7 +46,8 @@ class TestTimeLog(unittest.TestCase):
|
|||||||
self.assertRaises(NotSubmittedError, time_log.save)
|
self.assertRaises(NotSubmittedError, time_log.save)
|
||||||
|
|
||||||
def test_time_log_on_holiday(self):
|
def test_time_log_on_holiday(self):
|
||||||
prod_order = make_prod_order(self)
|
prod_order = make_prod_order_test_record(item="_Test FG Item 2", qty=1,
|
||||||
|
planned_start_date="2014-11-25 00:00:00", do_not_save=True)
|
||||||
prod_order.set_production_order_operations()
|
prod_order.set_production_order_operations()
|
||||||
prod_order.save()
|
prod_order.save()
|
||||||
prod_order.submit()
|
prod_order.submit()
|
||||||
@@ -85,16 +86,5 @@ class TestTimeLog(unittest.TestCase):
|
|||||||
self.assertRaises(frappe.ValidationError, test_time_log.save)
|
self.assertRaises(frappe.ValidationError, test_time_log.save)
|
||||||
frappe.db.sql("delete from `tabTime Log`")
|
frappe.db.sql("delete from `tabTime Log`")
|
||||||
|
|
||||||
def make_prod_order(self):
|
|
||||||
return frappe.get_doc({
|
|
||||||
"doctype":"Production Order",
|
|
||||||
"production_item": "_Test FG Item 2",
|
|
||||||
"bom_no": "BOM/_Test FG Item 2/001",
|
|
||||||
"qty": 1,
|
|
||||||
"wip_warehouse": "_Test Warehouse - _TC",
|
|
||||||
"fg_warehouse": "_Test Warehouse 1 - _TC",
|
|
||||||
"company": "_Test Company"
|
|
||||||
})
|
|
||||||
|
|
||||||
test_records = frappe.get_test_records('Time Log')
|
test_records = frappe.get_test_records('Time Log')
|
||||||
test_ignore = ["Time Log Batch", "Sales Invoice"]
|
test_ignore = ["Time Log Batch", "Sales Invoice"]
|
||||||
|
|||||||
@@ -96,12 +96,13 @@ class TimeLog(Document):
|
|||||||
return existing[0] if existing else None
|
return existing[0] if existing else None
|
||||||
|
|
||||||
def validate_timings(self):
|
def validate_timings(self):
|
||||||
if get_datetime(self.to_time) < get_datetime(self.from_time):
|
if self.to_time and self.from_time and get_datetime(self.to_time) < get_datetime(self.from_time):
|
||||||
frappe.throw(_("From Time cannot be greater than To Time"))
|
frappe.throw(_("From Time cannot be greater than To Time"))
|
||||||
|
|
||||||
def calculate_total_hours(self):
|
def calculate_total_hours(self):
|
||||||
from frappe.utils import time_diff_in_seconds
|
if self.to_time and self.from_time:
|
||||||
self.hours = flt(time_diff_in_seconds(self.to_time, self.from_time)) / 3600
|
from frappe.utils import time_diff_in_seconds
|
||||||
|
self.hours = flt(time_diff_in_seconds(self.to_time, self.from_time)) / 3600
|
||||||
|
|
||||||
def validate_time_log_for(self):
|
def validate_time_log_for(self):
|
||||||
if self.time_log_for == "Project":
|
if self.time_log_for == "Project":
|
||||||
@@ -110,7 +111,7 @@ class TimeLog(Document):
|
|||||||
|
|
||||||
def check_workstation_timings(self):
|
def check_workstation_timings(self):
|
||||||
"""Checks if **Time Log** is between operating hours of the **Workstation**."""
|
"""Checks if **Time Log** is between operating hours of the **Workstation**."""
|
||||||
if self.workstation:
|
if self.workstation and self.from_time and self.to_time:
|
||||||
from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
|
from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
|
||||||
check_if_within_operating_hours(self.workstation, self.operation, self.from_time, self.to_time)
|
check_if_within_operating_hours(self.workstation, self.operation, self.from_time, self.to_time)
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,13 @@ def get_quotation(user=None):
|
|||||||
party.doctype.lower(): party.name,
|
party.doctype.lower(): party.name,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"contact_email": user,
|
"contact_email": user,
|
||||||
"selling_price_list": "_Test Price List Rest of the World"
|
"selling_price_list": "_Test Price List Rest of the World",
|
||||||
|
"currency": "USD"
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
quotation = frappe.get_doc("Quotation", values)
|
quotation = frappe.get_doc("Quotation", values)
|
||||||
|
|
||||||
except frappe.DoesNotExistError:
|
except frappe.DoesNotExistError:
|
||||||
quotation = frappe.new_doc("Quotation")
|
quotation = frappe.new_doc("Quotation")
|
||||||
quotation.update(values)
|
quotation.update(values)
|
||||||
@@ -43,7 +45,6 @@ def set_item_in_cart(item_code, qty, user=None):
|
|||||||
quotation = get_quotation(user=user)
|
quotation = get_quotation(user=user)
|
||||||
qty = flt(qty)
|
qty = flt(qty)
|
||||||
quotation_item = quotation.get("items", {"item_code": item_code})
|
quotation_item = quotation.get("items", {"item_code": item_code})
|
||||||
|
|
||||||
if qty==0:
|
if qty==0:
|
||||||
if quotation_item:
|
if quotation_item:
|
||||||
# remove
|
# remove
|
||||||
@@ -58,7 +59,6 @@ def set_item_in_cart(item_code, qty, user=None):
|
|||||||
"item_code": item_code,
|
"item_code": item_code,
|
||||||
"qty": qty
|
"qty": qty
|
||||||
})
|
})
|
||||||
|
|
||||||
quotation.save(ignore_permissions=True)
|
quotation.save(ignore_permissions=True)
|
||||||
return quotation
|
return quotation
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
# test if lead is created and quotation with new lead is fetched
|
# test if lead is created and quotation with new lead is fetched
|
||||||
quotation = get_quotation()
|
quotation = get_quotation()
|
||||||
self.assertEquals(quotation.quotation_to, "Lead")
|
self.assertEquals(quotation.quotation_to, "Lead")
|
||||||
self.assertEquals(frappe.db.get_value("Lead", quotation.lead, "email_id"), "test_cart_user@example.com")
|
self.assertEquals(frappe.db.get_value("Lead", quotation.lead, "email_id"),
|
||||||
|
"test_cart_user@example.com")
|
||||||
self.assertEquals(quotation.customer, None)
|
self.assertEquals(quotation.customer, None)
|
||||||
self.assertEquals(quotation.contact_email, frappe.session.user)
|
self.assertEquals(quotation.contact_email, frappe.session.user)
|
||||||
|
|
||||||
@@ -109,37 +110,6 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
self.assertEquals(quotation.net_total, 0)
|
self.assertEquals(quotation.net_total, 0)
|
||||||
self.assertEquals(len(quotation.get("items")), 0)
|
self.assertEquals(len(quotation.get("items")), 0)
|
||||||
|
|
||||||
def test_set_billing_address(self):
|
|
||||||
return
|
|
||||||
|
|
||||||
# first, add to cart
|
|
||||||
self.test_add_to_cart()
|
|
||||||
|
|
||||||
quotation = self.test_get_cart_lead()
|
|
||||||
default_address = frappe.get_doc("Address", {"lead": quotation.lead, "is_primary_address": 1})
|
|
||||||
self.assertEquals("customer_address", default_address.name)
|
|
||||||
|
|
||||||
def test_set_shipping_address(self):
|
|
||||||
# first, add to cart
|
|
||||||
self.test_add_to_cart()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_shipping_rule(self):
|
|
||||||
self.test_set_shipping_address()
|
|
||||||
|
|
||||||
# check if shipping rule changed
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_price_list(self):
|
|
||||||
self.test_set_billing_address()
|
|
||||||
|
|
||||||
# check if price changed
|
|
||||||
pass
|
|
||||||
|
|
||||||
def test_place_order(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# helper functions
|
# helper functions
|
||||||
def enable_shopping_cart(self):
|
def enable_shopping_cart(self):
|
||||||
settings = frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings")
|
settings = frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings")
|
||||||
@@ -199,7 +169,8 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
"email_id": "test_cart_lead@example.com",
|
"email_id": "test_cart_lead@example.com",
|
||||||
"lead_name": "_Test Website Lead",
|
"lead_name": "_Test Website Lead",
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"territory": "_Test Territory Rest Of The World"
|
"territory": "_Test Territory Rest Of The World",
|
||||||
|
"company": "_Test Company"
|
||||||
})
|
})
|
||||||
lead.insert(ignore_permissions=True)
|
lead.insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ def make_purchase_receipt(**args):
|
|||||||
"received_qty": args.qty or 5,
|
"received_qty": args.qty or 5,
|
||||||
"rate": args.rate or 50,
|
"rate": args.rate or 50,
|
||||||
"conversion_factor": 1.0,
|
"conversion_factor": 1.0,
|
||||||
"serial_no": args.serial_no
|
"serial_no": args.serial_no,
|
||||||
|
"stock_uom": "_Test UOM"
|
||||||
})
|
})
|
||||||
if not args.do_not_save:
|
if not args.do_not_save:
|
||||||
pr.insert()
|
pr.insert()
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ class StockEntry(StockController):
|
|||||||
pro_doc = frappe.get_doc("Production Order", self.production_order)
|
pro_doc = frappe.get_doc("Production Order", self.production_order)
|
||||||
_validate_production_order(pro_doc)
|
_validate_production_order(pro_doc)
|
||||||
pro_doc.run_method("update_status")
|
pro_doc.run_method("update_status")
|
||||||
if self.purpose in ["Material Transfer for Manufacture","Manufacture"]:
|
if self.purpose == "Manufacture":
|
||||||
pro_doc.run_method("update_production_order_qty")
|
pro_doc.run_method("update_production_order_qty")
|
||||||
self.update_planned_qty(pro_doc)
|
self.update_planned_qty(pro_doc)
|
||||||
|
|
||||||
|
|||||||
@@ -99,11 +99,14 @@ class StockReconciliation(StockController):
|
|||||||
_("Negative Valuation Rate is not allowed")))
|
_("Negative Valuation Rate is not allowed")))
|
||||||
|
|
||||||
if row.qty and not row.valuation_rate:
|
if row.qty and not row.valuation_rate:
|
||||||
# try if there is a buying price list in default currency
|
row.valuation_rate = get_stock_balance(row.item_code, row.warehouse,
|
||||||
buying_rate = frappe.db.get_value("Item Price", {"item_code": row.item_code,
|
self.posting_date, self.posting_time, with_valuation_rate=True)[1]
|
||||||
"buying": 1, "currency": default_currency}, "price_list_rate")
|
if not row.valuation_rate:
|
||||||
if buying_rate:
|
# try if there is a buying price list in default currency
|
||||||
row.valuation_rate = buying_rate
|
buying_rate = frappe.db.get_value("Item Price", {"item_code": row.item_code,
|
||||||
|
"buying": 1, "currency": default_currency}, "price_list_rate")
|
||||||
|
if buying_rate:
|
||||||
|
row.valuation_rate = buying_rate
|
||||||
|
|
||||||
# throw all validation messages
|
# throw all validation messages
|
||||||
if self.validation_messages:
|
if self.validation_messages:
|
||||||
@@ -147,14 +150,13 @@ class StockReconciliation(StockController):
|
|||||||
from erpnext.stock.stock_ledger import get_previous_sle
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
|
|
||||||
for row in self.items:
|
for row in self.items:
|
||||||
if row.qty in ("", None) or row.valuation_rate in ("", None):
|
previous_sle = get_previous_sle({
|
||||||
previous_sle = get_previous_sle({
|
"item_code": row.item_code,
|
||||||
"item_code": row.item_code,
|
"warehouse": row.warehouse,
|
||||||
"warehouse": row.warehouse,
|
"posting_date": self.posting_date,
|
||||||
"posting_date": self.posting_date,
|
"posting_time": self.posting_time
|
||||||
"posting_time": self.posting_time
|
})
|
||||||
})
|
if previous_sle:
|
||||||
|
|
||||||
if row.qty in ("", None):
|
if row.qty in ("", None):
|
||||||
row.qty = previous_sle.get("qty_after_transaction")
|
row.qty = previous_sle.get("qty_after_transaction")
|
||||||
|
|
||||||
@@ -163,7 +165,11 @@ class StockReconciliation(StockController):
|
|||||||
|
|
||||||
if row.qty and not row.valuation_rate:
|
if row.qty and not row.valuation_rate:
|
||||||
frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code))
|
frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code))
|
||||||
|
|
||||||
|
if previous_sle and row.qty == previous_sle.get("qty_after_transaction") \
|
||||||
|
and row.valuation_rate == previous_sle.get("valuation_rate"):
|
||||||
|
continue
|
||||||
|
|
||||||
self.insert_entries(row)
|
self.insert_entries(row)
|
||||||
|
|
||||||
def insert_entries(self, row):
|
def insert_entries(self, row):
|
||||||
|
|||||||
Reference in New Issue
Block a user