Merge branch 'develop' into new-subscription
This commit is contained in:
commit
9e863b9572
@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '10.1.2'
|
__version__ = '10.1.4'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
@ -19,5 +19,5 @@ class TestFiscalYear(unittest.TestCase):
|
|||||||
"year_start_date": "2000-04-01"
|
"year_start_date": "2000-04-01"
|
||||||
})
|
})
|
||||||
fy.insert()
|
fy.insert()
|
||||||
self.assertEquals(fy.year_end_date, '2001-03-31')
|
self.assertEqual(fy.year_end_date, '2001-03-31')
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ class TestJournalEntry(unittest.TestCase):
|
|||||||
|
|
||||||
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][field], gle[field])
|
self.assertEqual(expected_values[gle.account][field], gle[field])
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
jv.cancel()
|
jv.cancel()
|
||||||
|
@ -183,7 +183,7 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
pe.set_exchange_rate()
|
pe.set_exchange_rate()
|
||||||
pe.set_amounts()
|
pe.set_amounts()
|
||||||
|
|
||||||
self.assertEquals(pe.difference_amount, 500)
|
self.assertEqual(pe.difference_amount, 500)
|
||||||
|
|
||||||
pe.append("deductions", {
|
pe.append("deductions", {
|
||||||
"account": "_Test Exchange Gain/Loss - _TC",
|
"account": "_Test Exchange Gain/Loss - _TC",
|
||||||
@ -260,10 +260,10 @@ class TestPaymentEntry(unittest.TestCase):
|
|||||||
self.assertTrue(gl_entries)
|
self.assertTrue(gl_entries)
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_gle[gle.account][0], gle.account)
|
self.assertEqual(expected_gle[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_gle[gle.account][1], gle.debit)
|
self.assertEqual(expected_gle[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_gle[gle.account][2], gle.credit)
|
self.assertEqual(expected_gle[gle.account][2], gle.credit)
|
||||||
self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
|
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
|
||||||
|
|
||||||
def get_gle(self, voucher_no):
|
def get_gle(self, voucher_no):
|
||||||
return frappe.db.sql("""select account, debit, credit, against_voucher
|
return frappe.db.sql("""select account, debit, credit, against_voucher
|
||||||
|
@ -34,7 +34,7 @@ class PaymentRequest(Document):
|
|||||||
frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
|
frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
send_mail = True
|
send_mail = self.payment_gateway_validation()
|
||||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||||
|
|
||||||
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \
|
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \
|
||||||
@ -58,6 +58,16 @@ class PaymentRequest(Document):
|
|||||||
si = si.insert(ignore_permissions=True)
|
si = si.insert(ignore_permissions=True)
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
|
def payment_gateway_validation(self):
|
||||||
|
try:
|
||||||
|
controller = get_payment_gateway_controller(self.payment_gateway)
|
||||||
|
if hasattr(controller, 'on_payment_request_submission'):
|
||||||
|
return controller.on_payment_request_submission(self)
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
def set_payment_request_url(self):
|
def set_payment_request_url(self):
|
||||||
if self.payment_account:
|
if self.payment_account:
|
||||||
self.payment_url = self.get_payment_url()
|
self.payment_url = self.get_payment_url()
|
||||||
|
@ -47,18 +47,18 @@ class TestPaymentRequest(unittest.TestCase):
|
|||||||
so_inr = make_sales_order(currency="INR")
|
so_inr = make_sales_order(currency="INR")
|
||||||
pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com")
|
pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com")
|
||||||
|
|
||||||
self.assertEquals(pr.reference_doctype, "Sales Order")
|
self.assertEqual(pr.reference_doctype, "Sales Order")
|
||||||
self.assertEquals(pr.reference_name, so_inr.name)
|
self.assertEqual(pr.reference_name, so_inr.name)
|
||||||
self.assertEquals(pr.currency, "INR")
|
self.assertEqual(pr.currency, "INR")
|
||||||
|
|
||||||
conversion_rate = get_exchange_rate("USD", "INR")
|
conversion_rate = get_exchange_rate("USD", "INR")
|
||||||
|
|
||||||
si_usd = create_sales_invoice(currency="USD", conversion_rate=conversion_rate)
|
si_usd = create_sales_invoice(currency="USD", conversion_rate=conversion_rate)
|
||||||
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com")
|
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com")
|
||||||
|
|
||||||
self.assertEquals(pr.reference_doctype, "Sales Invoice")
|
self.assertEqual(pr.reference_doctype, "Sales Invoice")
|
||||||
self.assertEquals(pr.reference_name, si_usd.name)
|
self.assertEqual(pr.reference_name, si_usd.name)
|
||||||
self.assertEquals(pr.currency, "USD")
|
self.assertEqual(pr.currency, "USD")
|
||||||
|
|
||||||
def test_payment_entry(self):
|
def test_payment_entry(self):
|
||||||
frappe.db.set_value("Company", "_Test Company",
|
frappe.db.set_value("Company", "_Test Company",
|
||||||
@ -75,7 +75,7 @@ class TestPaymentRequest(unittest.TestCase):
|
|||||||
|
|
||||||
so_inr = frappe.get_doc("Sales Order", so_inr.name)
|
so_inr = frappe.get_doc("Sales Order", so_inr.name)
|
||||||
|
|
||||||
self.assertEquals(so_inr.advance_paid, 1000)
|
self.assertEqual(so_inr.advance_paid, 1000)
|
||||||
|
|
||||||
si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
si_usd = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||||
currency="USD", conversion_rate=50)
|
currency="USD", conversion_rate=50)
|
||||||
@ -98,7 +98,7 @@ class TestPaymentRequest(unittest.TestCase):
|
|||||||
self.assertTrue(gl_entries)
|
self.assertTrue(gl_entries)
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_gle[gle.account][0], gle.account)
|
self.assertEqual(expected_gle[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_gle[gle.account][1], gle.debit)
|
self.assertEqual(expected_gle[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_gle[gle.account][2], gle.credit)
|
self.assertEqual(expected_gle[gle.account][2], gle.credit)
|
||||||
self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
|
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
|
||||||
|
@ -25,8 +25,8 @@ class TestPOSProfile(unittest.TestCase):
|
|||||||
products_count = frappe.db.sql(""" select count(name) from tabItem where item_group = '_Test Item Group'""", as_list=1)
|
products_count = frappe.db.sql(""" select count(name) from tabItem where item_group = '_Test Item Group'""", as_list=1)
|
||||||
customers_count = frappe.db.sql(""" select count(name) from tabCustomer where customer_group = '_Test Customer Group'""")
|
customers_count = frappe.db.sql(""" select count(name) from tabCustomer where customer_group = '_Test Customer Group'""")
|
||||||
|
|
||||||
self.assertEquals(len(items), products_count[0][0])
|
self.assertEqual(len(items), products_count[0][0])
|
||||||
self.assertEquals(len(customers), customers_count[0][0])
|
self.assertEqual(len(customers), customers_count[0][0])
|
||||||
|
|
||||||
frappe.db.sql("delete from `tabPOS Profile`")
|
frappe.db.sql("delete from `tabPOS Profile`")
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
"name": None
|
"name": None
|
||||||
})
|
})
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("discount_percentage"), 10)
|
self.assertEqual(details.get("discount_percentage"), 10)
|
||||||
|
|
||||||
prule = frappe.get_doc(test_record.copy())
|
prule = frappe.get_doc(test_record.copy())
|
||||||
prule.applicable_for = "Customer"
|
prule.applicable_for = "Customer"
|
||||||
@ -56,7 +56,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
prule.discount_percentage = 20
|
prule.discount_percentage = 20
|
||||||
prule.insert()
|
prule.insert()
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("discount_percentage"), 20)
|
self.assertEqual(details.get("discount_percentage"), 20)
|
||||||
|
|
||||||
prule = frappe.get_doc(test_record.copy())
|
prule = frappe.get_doc(test_record.copy())
|
||||||
prule.apply_on = "Item Group"
|
prule.apply_on = "Item Group"
|
||||||
@ -67,7 +67,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
|
|
||||||
args.customer = "_Test Customer 1"
|
args.customer = "_Test Customer 1"
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("discount_percentage"), 10)
|
self.assertEqual(details.get("discount_percentage"), 10)
|
||||||
|
|
||||||
prule = frappe.get_doc(test_record.copy())
|
prule = frappe.get_doc(test_record.copy())
|
||||||
prule.applicable_for = "Campaign"
|
prule.applicable_for = "Campaign"
|
||||||
@ -79,7 +79,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
|
|
||||||
args.campaign = "_Test Campaign"
|
args.campaign = "_Test Campaign"
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("discount_percentage"), 5)
|
self.assertEqual(details.get("discount_percentage"), 5)
|
||||||
|
|
||||||
frappe.db.sql("update `tabPricing Rule` set priority=NULL where campaign='_Test Campaign'")
|
frappe.db.sql("update `tabPricing Rule` set priority=NULL where campaign='_Test Campaign'")
|
||||||
from erpnext.accounts.doctype.pricing_rule.pricing_rule import MultiplePricingRuleConflict
|
from erpnext.accounts.doctype.pricing_rule.pricing_rule import MultiplePricingRuleConflict
|
||||||
@ -87,7 +87,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
|
|
||||||
args.item_code = "_Test Item 2"
|
args.item_code = "_Test Item 2"
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("discount_percentage"), 15)
|
self.assertEqual(details.get("discount_percentage"), 15)
|
||||||
|
|
||||||
frappe.db.sql("delete from `tabPricing Rule`")
|
frappe.db.sql("delete from `tabPricing Rule`")
|
||||||
|
|
||||||
@ -135,8 +135,8 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
"name": None
|
"name": None
|
||||||
})
|
})
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("margin_type"), "Percentage")
|
self.assertEqual(details.get("margin_type"), "Percentage")
|
||||||
self.assertEquals(details.get("margin_rate_or_amount"), 10)
|
self.assertEqual(details.get("margin_rate_or_amount"), 10)
|
||||||
|
|
||||||
frappe.db.sql("delete from `tabPricing Rule`")
|
frappe.db.sql("delete from `tabPricing Rule`")
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("discount_percentage"), 7.5)
|
self.assertEqual(details.get("discount_percentage"), 7.5)
|
||||||
|
|
||||||
# add a new pricing rule for that item code, it should take priority
|
# add a new pricing rule for that item code, it should take priority
|
||||||
frappe.get_doc({
|
frappe.get_doc({
|
||||||
@ -210,7 +210,7 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
details = get_item_details(args)
|
details = get_item_details(args)
|
||||||
self.assertEquals(details.get("discount_percentage"), 17.5)
|
self.assertEqual(details.get("discount_percentage"), 17.5)
|
||||||
|
|
||||||
def test_pricing_rule_for_stock_qty(self):
|
def test_pricing_rule_for_stock_qty(self):
|
||||||
frappe.db.sql("delete from `tabPricing Rule`")
|
frappe.db.sql("delete from `tabPricing Rule`")
|
||||||
@ -245,16 +245,16 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
so.items[0].price_list_rate = 100
|
so.items[0].price_list_rate = 100
|
||||||
so.submit()
|
so.submit()
|
||||||
so = frappe.get_doc('Sales Order', so.name)
|
so = frappe.get_doc('Sales Order', so.name)
|
||||||
self.assertEquals(so.items[0].discount_percentage, 17.5)
|
self.assertEqual(so.items[0].discount_percentage, 17.5)
|
||||||
self.assertEquals(so.items[0].rate, 82.5)
|
self.assertEqual(so.items[0].rate, 82.5)
|
||||||
|
|
||||||
# Without pricing rule
|
# Without pricing rule
|
||||||
so = make_sales_order(item_code="_Test Item", qty=2, uom="Box", do_not_submit=True)
|
so = make_sales_order(item_code="_Test Item", qty=2, uom="Box", do_not_submit=True)
|
||||||
so.items[0].price_list_rate = 100
|
so.items[0].price_list_rate = 100
|
||||||
so.submit()
|
so.submit()
|
||||||
so = frappe.get_doc('Sales Order', so.name)
|
so = frappe.get_doc('Sales Order', so.name)
|
||||||
self.assertEquals(so.items[0].discount_percentage, 0)
|
self.assertEqual(so.items[0].discount_percentage, 0)
|
||||||
self.assertEquals(so.items[0].rate, 100)
|
self.assertEqual(so.items[0].rate, 100)
|
||||||
|
|
||||||
def test_pricing_rule_with_margin_and_discount(self):
|
def test_pricing_rule_with_margin_and_discount(self):
|
||||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||||
@ -265,16 +265,16 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
si.insert(ignore_permissions=True)
|
si.insert(ignore_permissions=True)
|
||||||
|
|
||||||
item = si.items[0]
|
item = si.items[0]
|
||||||
self.assertEquals(item.rate, 1100)
|
self.assertEqual(item.rate, 1100)
|
||||||
self.assertEquals(item.margin_rate_or_amount, 10)
|
self.assertEqual(item.margin_rate_or_amount, 10)
|
||||||
|
|
||||||
# With discount
|
# With discount
|
||||||
item.discount_percentage = 10
|
item.discount_percentage = 10
|
||||||
si.payment_schedule = []
|
si.payment_schedule = []
|
||||||
si.save()
|
si.save()
|
||||||
item = si.items[0]
|
item = si.items[0]
|
||||||
self.assertEquals(item.rate, 990)
|
self.assertEqual(item.rate, 990)
|
||||||
self.assertEquals(item.discount_percentage, 10)
|
self.assertEqual(item.discount_percentage, 10)
|
||||||
frappe.db.sql("delete from `tabPricing Rule`")
|
frappe.db.sql("delete from `tabPricing Rule`")
|
||||||
|
|
||||||
def make_pricing_rule(**args):
|
def make_pricing_rule(**args):
|
||||||
|
@ -121,9 +121,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
def test_purchase_invoice_change_naming_series(self):
|
def test_purchase_invoice_change_naming_series(self):
|
||||||
pi = frappe.copy_doc(test_records[1])
|
pi = frappe.copy_doc(test_records[1])
|
||||||
@ -161,9 +161,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[i][0], gle.account)
|
self.assertEqual(expected_values[i][0], gle.account)
|
||||||
self.assertEquals(expected_values[i][1], gle.debit)
|
self.assertEqual(expected_values[i][1], gle.debit)
|
||||||
self.assertEquals(expected_values[i][2], gle.credit)
|
self.assertEqual(expected_values[i][2], gle.credit)
|
||||||
set_perpetual_inventory(0, pi.company)
|
set_perpetual_inventory(0, pi.company)
|
||||||
|
|
||||||
def test_purchase_invoice_calculation(self):
|
def test_purchase_invoice_calculation(self):
|
||||||
@ -363,8 +363,8 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
for gle in gl_entries:
|
for gle in gl_entries:
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.debit)
|
self.assertEqual(expected_values[gle.account][0], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.credit)
|
self.assertEqual(expected_values[gle.account][1], gle.credit)
|
||||||
|
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
@ -400,7 +400,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][field], gle[field])
|
self.assertEqual(expected_values[gle.account][field], gle[field])
|
||||||
|
|
||||||
|
|
||||||
# Check for valid currency
|
# Check for valid currency
|
||||||
@ -437,9 +437,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_gl_entries[gle.account][0], gle.account)
|
self.assertEqual(expected_gl_entries[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_gl_entries[gle.account][1], gle.debit)
|
self.assertEqual(expected_gl_entries[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_gl_entries[gle.account][2], gle.credit)
|
self.assertEqual(expected_gl_entries[gle.account][2], gle.credit)
|
||||||
|
|
||||||
def test_purchase_invoice_for_is_paid_and_update_stock_gl_entry_with_perpetual_inventory(self):
|
def test_purchase_invoice_for_is_paid_and_update_stock_gl_entry_with_perpetual_inventory(self):
|
||||||
set_perpetual_inventory()
|
set_perpetual_inventory()
|
||||||
@ -461,9 +461,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_gl_entries[gle.account][0], gle.account)
|
self.assertEqual(expected_gl_entries[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_gl_entries[gle.account][1], gle.debit)
|
self.assertEqual(expected_gl_entries[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_gl_entries[gle.account][2], gle.credit)
|
self.assertEqual(expected_gl_entries[gle.account][2], gle.credit)
|
||||||
|
|
||||||
def test_auto_batch(self):
|
def test_auto_batch(self):
|
||||||
item_code = frappe.db.get_value('Item',
|
item_code = frappe.db.get_value('Item',
|
||||||
@ -493,20 +493,20 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
posting_time=frappe.utils.nowtime())
|
posting_time=frappe.utils.nowtime())
|
||||||
|
|
||||||
actual_qty_1 = get_qty_after_transaction()
|
actual_qty_1 = get_qty_after_transaction()
|
||||||
self.assertEquals(actual_qty_0 + 5, actual_qty_1)
|
self.assertEqual(actual_qty_0 + 5, actual_qty_1)
|
||||||
|
|
||||||
# return entry
|
# return entry
|
||||||
pi1 = make_purchase_invoice(is_return=1, return_against=pi.name, qty=-2, rate=50, update_stock=1)
|
pi1 = make_purchase_invoice(is_return=1, return_against=pi.name, qty=-2, rate=50, update_stock=1)
|
||||||
|
|
||||||
actual_qty_2 = get_qty_after_transaction()
|
actual_qty_2 = get_qty_after_transaction()
|
||||||
self.assertEquals(actual_qty_1 - 2, actual_qty_2)
|
self.assertEqual(actual_qty_1 - 2, actual_qty_2)
|
||||||
|
|
||||||
pi1.cancel()
|
pi1.cancel()
|
||||||
self.assertEquals(actual_qty_1, get_qty_after_transaction())
|
self.assertEqual(actual_qty_1, get_qty_after_transaction())
|
||||||
|
|
||||||
pi.reload()
|
pi.reload()
|
||||||
pi.cancel()
|
pi.cancel()
|
||||||
self.assertEquals(actual_qty_0, get_qty_after_transaction())
|
self.assertEqual(actual_qty_0, get_qty_after_transaction())
|
||||||
|
|
||||||
def test_subcontracting_via_purchase_invoice(self):
|
def test_subcontracting_via_purchase_invoice(self):
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||||
@ -518,20 +518,20 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
pi = make_purchase_invoice(item_code="_Test FG Item", qty=10, rate=500,
|
pi = make_purchase_invoice(item_code="_Test FG Item", qty=10, rate=500,
|
||||||
update_stock=1, is_subcontracted="Yes")
|
update_stock=1, is_subcontracted="Yes")
|
||||||
|
|
||||||
self.assertEquals(len(pi.get("supplied_items")), 2)
|
self.assertEqual(len(pi.get("supplied_items")), 2)
|
||||||
|
|
||||||
rm_supp_cost = sum([d.amount for d in pi.get("supplied_items")])
|
rm_supp_cost = sum([d.amount for d in pi.get("supplied_items")])
|
||||||
self.assertEquals(pi.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
|
self.assertEqual(pi.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
|
||||||
|
|
||||||
def test_rejected_serial_no(self):
|
def test_rejected_serial_no(self):
|
||||||
pi = make_purchase_invoice(item_code="_Test Serialized Item With Series", received_qty=2, qty=1,
|
pi = make_purchase_invoice(item_code="_Test Serialized Item With Series", received_qty=2, qty=1,
|
||||||
rejected_qty=1, rate=500, update_stock=1,
|
rejected_qty=1, rate=500, update_stock=1,
|
||||||
rejected_warehouse = "_Test Rejected Warehouse - _TC")
|
rejected_warehouse = "_Test Rejected Warehouse - _TC")
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value("Serial No", pi.get("items")[0].serial_no, "warehouse"),
|
self.assertEqual(frappe.db.get_value("Serial No", pi.get("items")[0].serial_no, "warehouse"),
|
||||||
pi.get("items")[0].warehouse)
|
pi.get("items")[0].warehouse)
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value("Serial No", pi.get("items")[0].rejected_serial_no,
|
self.assertEqual(frappe.db.get_value("Serial No", pi.get("items")[0].rejected_serial_no,
|
||||||
"warehouse"), pi.get("items")[0].rejected_warehouse)
|
"warehouse"), pi.get("items")[0].rejected_warehouse)
|
||||||
|
|
||||||
def test_outstanding_amount_after_advance_jv_cancelation(self):
|
def test_outstanding_amount_after_advance_jv_cancelation(self):
|
||||||
@ -643,10 +643,10 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
pi.append("taxes", shipping_charge)
|
pi.append("taxes", shipping_charge)
|
||||||
pi.save()
|
pi.save()
|
||||||
|
|
||||||
self.assertEquals(pi.net_total, 1250)
|
self.assertEqual(pi.net_total, 1250)
|
||||||
|
|
||||||
self.assertEquals(pi.total_taxes_and_charges, 462.3)
|
self.assertEqual(pi.total_taxes_and_charges, 462.3)
|
||||||
self.assertEquals(pi.grand_total, 1712.3)
|
self.assertEqual(pi.grand_total, 1712.3)
|
||||||
|
|
||||||
def test_make_pi_without_terms(self):
|
def test_make_pi_without_terms(self):
|
||||||
pi = make_purchase_invoice(do_not_save=1)
|
pi = make_purchase_invoice(do_not_save=1)
|
||||||
|
@ -101,6 +101,8 @@ class SalesInvoice(SellingController):
|
|||||||
self.set_billing_hours_and_amount()
|
self.set_billing_hours_and_amount()
|
||||||
self.update_timesheet_billing_for_project()
|
self.update_timesheet_billing_for_project()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
if self.is_pos and not self.is_return:
|
||||||
|
self.verify_payment_amount_is_positive()
|
||||||
|
|
||||||
def before_save(self):
|
def before_save(self):
|
||||||
set_account_for_mode_of_payment(self)
|
set_account_for_mode_of_payment(self)
|
||||||
@ -905,6 +907,11 @@ class SalesInvoice(SellingController):
|
|||||||
project.update_billed_amount()
|
project.update_billed_amount()
|
||||||
project.save()
|
project.save()
|
||||||
|
|
||||||
|
def verify_payment_amount_is_positive(self):
|
||||||
|
for entry in self.payments:
|
||||||
|
if entry.amount < 0:
|
||||||
|
frappe.throw(_("Row #{0} (Payment Table): Amount must be positive").format(entry.idx))
|
||||||
|
|
||||||
def get_list_context(context=None):
|
def get_list_context(context=None):
|
||||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||||
list_context = get_list_context(context)
|
list_context = get_list_context(context)
|
||||||
|
@ -78,17 +78,17 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check if children are saved
|
# check if children are saved
|
||||||
self.assertEquals(len(si.get("items")),
|
self.assertEqual(len(si.get("items")),
|
||||||
len(expected_values)-1)
|
len(expected_values)-1)
|
||||||
|
|
||||||
# check if item values are calculated
|
# check if item values are calculated
|
||||||
for d in si.get("items"):
|
for d in si.get("items"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
self.assertEqual(d.get(k), expected_values[d.item_code][i])
|
||||||
|
|
||||||
# check net total
|
# check net total
|
||||||
self.assertEquals(si.base_net_total, 1250)
|
self.assertEqual(si.base_net_total, 1250)
|
||||||
self.assertEquals(si.net_total, 1250)
|
self.assertEqual(si.net_total, 1250)
|
||||||
|
|
||||||
# check tax calculation
|
# check tax calculation
|
||||||
expected_values = {
|
expected_values = {
|
||||||
@ -105,10 +105,10 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
for d in si.get("taxes"):
|
for d in si.get("taxes"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
self.assertEqual(d.get(k), expected_values[d.account_head][i])
|
||||||
|
|
||||||
self.assertEquals(si.base_grand_total, 1627.05)
|
self.assertEqual(si.base_grand_total, 1627.05)
|
||||||
self.assertEquals(si.grand_total, 1627.05)
|
self.assertEqual(si.grand_total, 1627.05)
|
||||||
|
|
||||||
def test_payment_entry_unlink_against_invoice(self):
|
def test_payment_entry_unlink_against_invoice(self):
|
||||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||||
@ -153,18 +153,18 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check if children are saved
|
# check if children are saved
|
||||||
self.assertEquals(len(si.get("items")), len(expected_values)-1)
|
self.assertEqual(len(si.get("items")), len(expected_values)-1)
|
||||||
|
|
||||||
# check if item values are calculated
|
# check if item values are calculated
|
||||||
for d in si.get("items"):
|
for d in si.get("items"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
self.assertEqual(d.get(k), expected_values[d.item_code][i])
|
||||||
|
|
||||||
# check net total
|
# check net total
|
||||||
self.assertEquals(si.total, 25)
|
self.assertEqual(si.total, 25)
|
||||||
self.assertEquals(si.base_total, 1250)
|
self.assertEqual(si.base_total, 1250)
|
||||||
self.assertEquals(si.net_total, 25)
|
self.assertEqual(si.net_total, 25)
|
||||||
self.assertEquals(si.base_net_total, 1250)
|
self.assertEqual(si.base_net_total, 1250)
|
||||||
|
|
||||||
# check tax calculation
|
# check tax calculation
|
||||||
expected_values = {
|
expected_values = {
|
||||||
@ -181,10 +181,10 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
for d in si.get("taxes"):
|
for d in si.get("taxes"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
self.assertEqual(d.get(k), expected_values[d.account_head][i])
|
||||||
|
|
||||||
self.assertEquals(si.base_grand_total, 1627.5)
|
self.assertEqual(si.base_grand_total, 1627.5)
|
||||||
self.assertEquals(si.grand_total, 32.55)
|
self.assertEqual(si.grand_total, 32.55)
|
||||||
|
|
||||||
def test_sales_invoice_with_discount_and_inclusive_tax(self):
|
def test_sales_invoice_with_discount_and_inclusive_tax(self):
|
||||||
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
|
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
|
||||||
@ -199,8 +199,8 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.insert()
|
si.insert()
|
||||||
|
|
||||||
# with inclusive tax
|
# with inclusive tax
|
||||||
self.assertEquals(si.net_total, 4385.96)
|
self.assertEqual(si.net_total, 4385.96)
|
||||||
self.assertEquals(si.grand_total, 5000)
|
self.assertEqual(si.grand_total, 5000)
|
||||||
|
|
||||||
si.reload()
|
si.reload()
|
||||||
|
|
||||||
@ -212,8 +212,8 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.save()
|
si.save()
|
||||||
|
|
||||||
# with inclusive tax and additional discount
|
# with inclusive tax and additional discount
|
||||||
self.assertEquals(si.net_total, 4285.96)
|
self.assertEqual(si.net_total, 4285.96)
|
||||||
self.assertEquals(si.grand_total, 4885.99)
|
self.assertEqual(si.grand_total, 4885.99)
|
||||||
|
|
||||||
si.reload()
|
si.reload()
|
||||||
|
|
||||||
@ -225,8 +225,8 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.save()
|
si.save()
|
||||||
|
|
||||||
# with inclusive tax and additional discount
|
# with inclusive tax and additional discount
|
||||||
self.assertEquals(si.net_total, 4298.25)
|
self.assertEqual(si.net_total, 4298.25)
|
||||||
self.assertEquals(si.grand_total, 4900.00)
|
self.assertEqual(si.grand_total, 4900.00)
|
||||||
|
|
||||||
def test_sales_invoice_discount_amount(self):
|
def test_sales_invoice_discount_amount(self):
|
||||||
si = frappe.copy_doc(test_records[3])
|
si = frappe.copy_doc(test_records[3])
|
||||||
@ -273,16 +273,16 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
# check if children are saved
|
# check if children are saved
|
||||||
self.assertEquals(len(si.get("items")), len(expected_values))
|
self.assertEqual(len(si.get("items")), len(expected_values))
|
||||||
|
|
||||||
# check if item values are calculated
|
# check if item values are calculated
|
||||||
for i, d in enumerate(si.get("items")):
|
for i, d in enumerate(si.get("items")):
|
||||||
for k, v in expected_values[i].items():
|
for k, v in expected_values[i].items():
|
||||||
self.assertEquals(d.get(k), v)
|
self.assertEqual(d.get(k), v)
|
||||||
|
|
||||||
# check net total
|
# check net total
|
||||||
self.assertEquals(si.base_net_total, 1163.45)
|
self.assertEqual(si.base_net_total, 1163.45)
|
||||||
self.assertEquals(si.total, 1578.3)
|
self.assertEqual(si.total, 1578.3)
|
||||||
|
|
||||||
# check tax calculation
|
# check tax calculation
|
||||||
expected_values = {
|
expected_values = {
|
||||||
@ -300,11 +300,11 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
for d in si.get("taxes"):
|
for d in si.get("taxes"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
self.assertEqual(d.get(k), expected_values[d.account_head][i])
|
||||||
|
|
||||||
self.assertEquals(si.base_grand_total, 1500)
|
self.assertEqual(si.base_grand_total, 1500)
|
||||||
self.assertEquals(si.grand_total, 1500)
|
self.assertEqual(si.grand_total, 1500)
|
||||||
self.assertEquals(si.rounding_adjustment, -0.01)
|
self.assertEqual(si.rounding_adjustment, -0.01)
|
||||||
|
|
||||||
def test_discount_amount_gl_entry(self):
|
def test_discount_amount_gl_entry(self):
|
||||||
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
|
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
|
||||||
@ -344,9 +344,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for gle in gl_entries:
|
for gle in gl_entries:
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
si.cancel()
|
si.cancel()
|
||||||
@ -374,12 +374,12 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
si.insert()
|
si.insert()
|
||||||
|
|
||||||
self.assertEquals(si.net_total, 4600)
|
self.assertEqual(si.net_total, 4600)
|
||||||
|
|
||||||
self.assertEquals(si.get("taxes")[0].tax_amount, 874.0)
|
self.assertEqual(si.get("taxes")[0].tax_amount, 874.0)
|
||||||
self.assertEquals(si.get("taxes")[0].total, 5474.0)
|
self.assertEqual(si.get("taxes")[0].total, 5474.0)
|
||||||
|
|
||||||
self.assertEquals(si.grand_total, 5474.0)
|
self.assertEqual(si.grand_total, 5474.0)
|
||||||
|
|
||||||
def test_tax_calculation_with_multiple_items_and_discount(self):
|
def test_tax_calculation_with_multiple_items_and_discount(self):
|
||||||
si = create_sales_invoice(qty=1, rate=75, do_not_save=True)
|
si = create_sales_invoice(qty=1, rate=75, do_not_save=True)
|
||||||
@ -403,13 +403,13 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
si.insert()
|
si.insert()
|
||||||
|
|
||||||
self.assertEquals(si.total, 975)
|
self.assertEqual(si.total, 975)
|
||||||
self.assertEquals(si.net_total, 900)
|
self.assertEqual(si.net_total, 900)
|
||||||
|
|
||||||
self.assertEquals(si.get("taxes")[0].tax_amount, 216.0)
|
self.assertEqual(si.get("taxes")[0].tax_amount, 216.0)
|
||||||
self.assertEquals(si.get("taxes")[0].total, 1116.0)
|
self.assertEqual(si.get("taxes")[0].total, 1116.0)
|
||||||
|
|
||||||
self.assertEquals(si.grand_total, 1116.0)
|
self.assertEqual(si.grand_total, 1116.0)
|
||||||
|
|
||||||
def test_inclusive_rate_validations(self):
|
def test_inclusive_rate_validations(self):
|
||||||
si = frappe.copy_doc(test_records[2])
|
si = frappe.copy_doc(test_records[2])
|
||||||
@ -418,7 +418,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
si.get("items")[0].price_list_rate = 62.5
|
si.get("items")[0].price_list_rate = 62.5
|
||||||
si.get("items")[0].price_list_rate = 191
|
si.get("items")[0].price_list_rate = 191
|
||||||
for i in xrange(6):
|
for i in range(6):
|
||||||
si.get("taxes")[i].included_in_print_rate = 1
|
si.get("taxes")[i].included_in_print_rate = 1
|
||||||
|
|
||||||
# tax type "Actual" cannot be inclusive
|
# tax type "Actual" cannot be inclusive
|
||||||
@ -441,16 +441,16 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check if children are saved
|
# check if children are saved
|
||||||
self.assertEquals(len(si.get("items")), len(expected_values)-1)
|
self.assertEqual(len(si.get("items")), len(expected_values)-1)
|
||||||
|
|
||||||
# check if item values are calculated
|
# check if item values are calculated
|
||||||
for d in si.get("items"):
|
for d in si.get("items"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
self.assertEqual(d.get(k), expected_values[d.item_code][i])
|
||||||
|
|
||||||
# check net total
|
# check net total
|
||||||
self.assertEquals(si.net_total, 1249.97)
|
self.assertEqual(si.net_total, 1249.97)
|
||||||
self.assertEquals(si.total, 1578.3)
|
self.assertEqual(si.total, 1578.3)
|
||||||
|
|
||||||
# check tax calculation
|
# check tax calculation
|
||||||
expected_values = {
|
expected_values = {
|
||||||
@ -467,10 +467,10 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
for d in si.get("taxes"):
|
for d in si.get("taxes"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
self.assertEqual(d.get(k), expected_values[d.account_head][i])
|
||||||
|
|
||||||
self.assertEquals(si.base_grand_total, 1622.97)
|
self.assertEqual(si.base_grand_total, 1622.97)
|
||||||
self.assertEquals(si.grand_total, 1622.97)
|
self.assertEqual(si.grand_total, 1622.97)
|
||||||
|
|
||||||
def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
|
def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
|
||||||
# prepare
|
# prepare
|
||||||
@ -519,17 +519,17 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
# check if children are saved
|
# check if children are saved
|
||||||
self.assertEquals(len(si.get("items")), len(expected_values))
|
self.assertEqual(len(si.get("items")), len(expected_values))
|
||||||
|
|
||||||
# check if item values are calculated
|
# check if item values are calculated
|
||||||
for i, d in enumerate(si.get("items")):
|
for i, d in enumerate(si.get("items")):
|
||||||
for key, val in expected_values[i].items():
|
for key, val in expected_values[i].items():
|
||||||
self.assertEquals(d.get(key), val)
|
self.assertEqual(d.get(key), val)
|
||||||
|
|
||||||
# check net total
|
# check net total
|
||||||
self.assertEquals(si.base_net_total, 49501.5)
|
self.assertEqual(si.base_net_total, 49501.5)
|
||||||
self.assertEquals(si.net_total, 990.03)
|
self.assertEqual(si.net_total, 990.03)
|
||||||
self.assertEquals(si.total, 1250)
|
self.assertEqual(si.total, 1250)
|
||||||
|
|
||||||
# check tax calculation
|
# check tax calculation
|
||||||
expected_values = {
|
expected_values = {
|
||||||
@ -546,17 +546,17 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
for d in si.get("taxes"):
|
for d in si.get("taxes"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
self.assertEqual(d.get(k), expected_values[d.account_head][i])
|
||||||
|
|
||||||
self.assertEquals(si.base_grand_total, 60795)
|
self.assertEqual(si.base_grand_total, 60795)
|
||||||
self.assertEquals(si.grand_total, 1215.90)
|
self.assertEqual(si.grand_total, 1215.90)
|
||||||
self.assertEquals(si.rounding_adjustment, 0.01)
|
self.assertEqual(si.rounding_adjustment, 0.01)
|
||||||
self.assertEquals(si.base_rounding_adjustment, 0.50)
|
self.assertEqual(si.base_rounding_adjustment, 0.50)
|
||||||
|
|
||||||
|
|
||||||
def test_outstanding(self):
|
def test_outstanding(self):
|
||||||
w = self.make()
|
w = self.make()
|
||||||
self.assertEquals(w.outstanding_amount, w.base_rounded_total)
|
self.assertEqual(w.outstanding_amount, w.base_rounded_total)
|
||||||
|
|
||||||
def test_payment(self):
|
def test_payment(self):
|
||||||
w = self.make()
|
w = self.make()
|
||||||
@ -570,7 +570,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
jv.insert()
|
jv.insert()
|
||||||
jv.submit()
|
jv.submit()
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 162.0)
|
self.assertEqual(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 162.0)
|
||||||
|
|
||||||
link_data = get_dynamic_link_map().get('Sales Invoice', [])
|
link_data = get_dynamic_link_map().get('Sales Invoice', [])
|
||||||
link_doctypes = [d.parent for d in link_data]
|
link_doctypes = [d.parent for d in link_data]
|
||||||
@ -579,7 +579,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertTrue(link_doctypes.index('GL Entry') > link_doctypes.index('Journal Entry Account'))
|
self.assertTrue(link_doctypes.index('GL Entry') > link_doctypes.index('Journal Entry Account'))
|
||||||
|
|
||||||
jv.cancel()
|
jv.cancel()
|
||||||
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 562.0)
|
self.assertEqual(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 562.0)
|
||||||
|
|
||||||
def test_sales_invoice_gl_entry_without_perpetual_inventory(self):
|
def test_sales_invoice_gl_entry_without_perpetual_inventory(self):
|
||||||
si = frappe.copy_doc(test_records[1])
|
si = frappe.copy_doc(test_records[1])
|
||||||
@ -601,9 +601,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
si.cancel()
|
si.cancel()
|
||||||
@ -628,7 +628,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
self.assertEquals(si.paid_amount, 600.0)
|
self.assertEqual(si.paid_amount, 600.0)
|
||||||
|
|
||||||
self.pos_gl_entry(si, pos, 300)
|
self.pos_gl_entry(si, pos, 300)
|
||||||
|
|
||||||
@ -648,8 +648,8 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
self.assertEquals(si.grand_total, 630.0)
|
self.assertEqual(si.grand_total, 630.0)
|
||||||
self.assertEquals(si.write_off_amount, -5)
|
self.assertEqual(si.write_off_amount, -5)
|
||||||
|
|
||||||
def test_make_pos_invoice(self):
|
def test_make_pos_invoice(self):
|
||||||
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
|
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
|
||||||
@ -667,11 +667,11 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
invoice_data = [{'09052016142': pos}]
|
invoice_data = [{'09052016142': pos}]
|
||||||
si = make_invoice(invoice_data).get('invoice')
|
si = make_invoice(invoice_data).get('invoice')
|
||||||
self.assertEquals(si[0], '09052016142')
|
self.assertEqual(si[0], '09052016142')
|
||||||
|
|
||||||
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1})
|
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': '09052016142', 'docstatus': 1})
|
||||||
si = frappe.get_doc('Sales Invoice', sales_invoice[0].name)
|
si = frappe.get_doc('Sales Invoice', sales_invoice[0].name)
|
||||||
self.assertEquals(si.grand_total, 630.0)
|
self.assertEqual(si.grand_total, 630.0)
|
||||||
|
|
||||||
self.pos_gl_entry(si, pos, 330)
|
self.pos_gl_entry(si, pos, 330)
|
||||||
|
|
||||||
@ -699,19 +699,19 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
invoice_data = [{timestamp: pos}]
|
invoice_data = [{timestamp: pos}]
|
||||||
si = make_invoice(invoice_data).get('invoice')
|
si = make_invoice(invoice_data).get('invoice')
|
||||||
self.assertEquals(si[0], timestamp)
|
self.assertEqual(si[0], timestamp)
|
||||||
|
|
||||||
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
||||||
self.assertEquals(sales_invoice[0].docstatus, 0)
|
self.assertEqual(sales_invoice[0].docstatus, 0)
|
||||||
|
|
||||||
timestamp = cint(time.time())
|
timestamp = cint(time.time())
|
||||||
pos["offline_pos_name"] = timestamp
|
pos["offline_pos_name"] = timestamp
|
||||||
invoice_data = [{timestamp: pos}]
|
invoice_data = [{timestamp: pos}]
|
||||||
si1 = make_invoice(invoice_data).get('invoice')
|
si1 = make_invoice(invoice_data).get('invoice')
|
||||||
self.assertEquals(si1[0], timestamp)
|
self.assertEqual(si1[0], timestamp)
|
||||||
|
|
||||||
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
||||||
self.assertEquals(sales_invoice1[0].docstatus, 0)
|
self.assertEqual(sales_invoice1[0].docstatus, 0)
|
||||||
|
|
||||||
if allow_negative_stock:
|
if allow_negative_stock:
|
||||||
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 1)
|
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 1)
|
||||||
@ -722,7 +722,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
where voucher_type = 'Sales Invoice' and voucher_no = %s""",
|
where voucher_type = 'Sales Invoice' and voucher_no = %s""",
|
||||||
si.name, as_dict=1)[0]
|
si.name, as_dict=1)[0]
|
||||||
self.assertTrue(sle)
|
self.assertTrue(sle)
|
||||||
self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty],
|
self.assertEqual([sle.item_code, sle.warehouse, sle.actual_qty],
|
||||||
["_Test Item", "_Test Warehouse - _TC", -1.0])
|
["_Test Item", "_Test Warehouse - _TC", -1.0])
|
||||||
|
|
||||||
# check gl entries
|
# check gl entries
|
||||||
@ -747,9 +747,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)):
|
for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)):
|
||||||
self.assertEquals(expected_gl_entries[i][0], gle.account)
|
self.assertEqual(expected_gl_entries[i][0], gle.account)
|
||||||
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
self.assertEqual(expected_gl_entries[i][1], gle.debit)
|
||||||
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
self.assertEqual(expected_gl_entries[i][2], gle.credit)
|
||||||
|
|
||||||
si.cancel()
|
si.cancel()
|
||||||
frappe.delete_doc('Sales Invoice', si.name)
|
frappe.delete_doc('Sales Invoice', si.name)
|
||||||
@ -782,9 +782,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
[test_records[1]["taxes"][1]["account_head"], 0.0, 50.0],
|
[test_records[1]["taxes"][1]["account_head"], 0.0, 50.0],
|
||||||
])
|
])
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
@ -807,9 +807,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
[test_records[1]["taxes"][1]["account_head"], 0.0, 50.0],
|
[test_records[1]["taxes"][1]["account_head"], 0.0, 50.0],
|
||||||
])
|
])
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
@ -881,9 +881,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"))
|
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"))
|
||||||
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0],
|
self.assertEqual(frappe.db.get_value("Serial No", serial_nos[0],
|
||||||
"delivery_document_no"), si.name)
|
"delivery_document_no"), si.name)
|
||||||
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "sales_invoice"),
|
self.assertEqual(frappe.db.get_value("Serial No", serial_nos[0], "sales_invoice"),
|
||||||
si.name)
|
si.name)
|
||||||
|
|
||||||
# check if the serial number is already linked with any other Sales Invoice
|
# check if the serial number is already linked with any other Sales Invoice
|
||||||
@ -899,7 +899,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
serial_nos = get_serial_nos(si.get("items")[0].serial_no)
|
serial_nos = get_serial_nos(si.get("items")[0].serial_no)
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"), "_Test Warehouse - _TC")
|
self.assertEqual(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"), "_Test Warehouse - _TC")
|
||||||
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0],
|
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0],
|
||||||
"delivery_document_no"))
|
"delivery_document_no"))
|
||||||
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "sales_invoice"))
|
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "sales_invoice"))
|
||||||
@ -940,7 +940,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si = make_sales_invoice(dn.name)
|
si = make_sales_invoice(dn.name)
|
||||||
si.save()
|
si.save()
|
||||||
|
|
||||||
self.assertEquals(si.get("items")[0].serial_no, dn.get("items")[0].serial_no)
|
self.assertEqual(si.get("items")[0].serial_no, dn.get("items")[0].serial_no)
|
||||||
|
|
||||||
def test_return_sales_invoice(self):
|
def test_return_sales_invoice(self):
|
||||||
set_perpetual_inventory()
|
set_perpetual_inventory()
|
||||||
@ -951,7 +951,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si = create_sales_invoice(qty=5, rate=500, update_stock=1)
|
si = create_sales_invoice(qty=5, rate=500, update_stock=1)
|
||||||
|
|
||||||
actual_qty_1 = get_qty_after_transaction()
|
actual_qty_1 = get_qty_after_transaction()
|
||||||
self.assertEquals(actual_qty_0 - 5, actual_qty_1)
|
self.assertEqual(actual_qty_0 - 5, actual_qty_1)
|
||||||
|
|
||||||
# outgoing_rate
|
# outgoing_rate
|
||||||
outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice",
|
outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice",
|
||||||
@ -962,20 +962,20 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
actual_qty_2 = get_qty_after_transaction()
|
actual_qty_2 = get_qty_after_transaction()
|
||||||
|
|
||||||
self.assertEquals(actual_qty_1 + 2, actual_qty_2)
|
self.assertEqual(actual_qty_1 + 2, actual_qty_2)
|
||||||
|
|
||||||
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
|
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
|
||||||
{"voucher_type": "Sales Invoice", "voucher_no": si1.name},
|
{"voucher_type": "Sales Invoice", "voucher_no": si1.name},
|
||||||
["incoming_rate", "stock_value_difference"])
|
["incoming_rate", "stock_value_difference"])
|
||||||
|
|
||||||
self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
|
self.assertEqual(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
|
||||||
stock_in_hand_account = get_inventory_account('_Test Company', si1.items[0].warehouse)
|
stock_in_hand_account = get_inventory_account('_Test Company', si1.items[0].warehouse)
|
||||||
|
|
||||||
# Check gl entry
|
# Check gl entry
|
||||||
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
|
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
|
||||||
"voucher_no": si1.name, "account": stock_in_hand_account}, "debit")
|
"voucher_no": si1.name, "account": stock_in_hand_account}, "debit")
|
||||||
|
|
||||||
self.assertEquals(gle_warehouse_amount, stock_value_difference)
|
self.assertEqual(gle_warehouse_amount, stock_value_difference)
|
||||||
|
|
||||||
party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
|
party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
|
||||||
"voucher_no": si1.name, "account": "Debtors - _TC", "party": "_Test Customer"}, "credit")
|
"voucher_no": si1.name, "account": "Debtors - _TC", "party": "_Test Customer"}, "credit")
|
||||||
@ -1003,19 +1003,19 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
# check if children are saved
|
# check if children are saved
|
||||||
self.assertEquals(len(si.get("items")),
|
self.assertEqual(len(si.get("items")),
|
||||||
len(expected_values)-1)
|
len(expected_values)-1)
|
||||||
|
|
||||||
# check if item values are calculated
|
# check if item values are calculated
|
||||||
for d in si.get("items"):
|
for d in si.get("items"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
self.assertEqual(d.get(k), expected_values[d.item_code][i])
|
||||||
|
|
||||||
# check net total
|
# check net total
|
||||||
self.assertEquals(si.base_total, 1250)
|
self.assertEqual(si.base_total, 1250)
|
||||||
self.assertEquals(si.total, 1250)
|
self.assertEqual(si.total, 1250)
|
||||||
self.assertEquals(si.base_net_total, 625)
|
self.assertEqual(si.base_net_total, 625)
|
||||||
self.assertEquals(si.net_total, 625)
|
self.assertEqual(si.net_total, 625)
|
||||||
|
|
||||||
# check tax calculation
|
# check tax calculation
|
||||||
expected_values = {
|
expected_values = {
|
||||||
@ -1034,12 +1034,12 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
for d in si.get("taxes"):
|
for d in si.get("taxes"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
if expected_values.get(d.account_head):
|
if expected_values.get(d.account_head):
|
||||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
self.assertEqual(d.get(k), expected_values[d.account_head][i])
|
||||||
|
|
||||||
|
|
||||||
self.assertEquals(si.total_taxes_and_charges, 234.43)
|
self.assertEqual(si.total_taxes_and_charges, 234.43)
|
||||||
self.assertEquals(si.base_grand_total, 859.43)
|
self.assertEqual(si.base_grand_total, 859.43)
|
||||||
self.assertEquals(si.grand_total, 859.43)
|
self.assertEqual(si.grand_total, 859.43)
|
||||||
|
|
||||||
def test_multi_currency_gle(self):
|
def test_multi_currency_gle(self):
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
@ -1072,7 +1072,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
for field in ("account_currency", "debit", "debit_in_account_currency", "credit", "credit_in_account_currency"):
|
||||||
for i, gle in enumerate(gl_entries):
|
for i, gle in enumerate(gl_entries):
|
||||||
self.assertEquals(expected_values[gle.account][field], gle[field])
|
self.assertEqual(expected_values[gle.account][field], gle[field])
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
si.cancel()
|
si.cancel()
|
||||||
@ -1233,7 +1233,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
# check if the conversion_factor and price_list_rate is calculated according to uom
|
# check if the conversion_factor and price_list_rate is calculated according to uom
|
||||||
for d in si.get("items"):
|
for d in si.get("items"):
|
||||||
for i, k in enumerate(expected_values["keys"]):
|
for i, k in enumerate(expected_values["keys"]):
|
||||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
self.assertEqual(d.get(k), expected_values[d.item_code][i])
|
||||||
|
|
||||||
def test_item_wise_tax_breakup_india(self):
|
def test_item_wise_tax_breakup_india(self):
|
||||||
frappe.flags.country = "India"
|
frappe.flags.country = "India"
|
||||||
@ -1363,9 +1363,9 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
order by account asc""", si.name, as_dict=1)
|
order by account asc""", si.name, as_dict=1)
|
||||||
|
|
||||||
for gle in gl_entries:
|
for gle in gl_entries:
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
def test_sales_invoice_with_shipping_rule(self):
|
def test_sales_invoice_with_shipping_rule(self):
|
||||||
from erpnext.accounts.doctype.shipping_rule.test_shipping_rule \
|
from erpnext.accounts.doctype.shipping_rule.test_shipping_rule \
|
||||||
@ -1395,10 +1395,10 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
si.append("taxes", shipping_charge)
|
si.append("taxes", shipping_charge)
|
||||||
si.save()
|
si.save()
|
||||||
|
|
||||||
self.assertEquals(si.net_total, 1250)
|
self.assertEqual(si.net_total, 1250)
|
||||||
|
|
||||||
self.assertEquals(si.total_taxes_and_charges, 577.05)
|
self.assertEqual(si.total_taxes_and_charges, 577.05)
|
||||||
self.assertEquals(si.grand_total, 1827.05)
|
self.assertEqual(si.grand_total, 1827.05)
|
||||||
|
|
||||||
def test_create_invoice_without_terms(self):
|
def test_create_invoice_without_terms(self):
|
||||||
si = create_sales_invoice(do_not_save=1)
|
si = create_sales_invoice(do_not_save=1)
|
||||||
|
@ -133,8 +133,8 @@ class ShippingRule(Document):
|
|||||||
return (not separate)
|
return (not separate)
|
||||||
|
|
||||||
overlaps = []
|
overlaps = []
|
||||||
for i in xrange(0, len(self.conditions)):
|
for i in range(0, len(self.conditions)):
|
||||||
for j in xrange(i+1, len(self.conditions)):
|
for j in range(i+1, len(self.conditions)):
|
||||||
d1, d2 = self.conditions[i], self.conditions[j]
|
d1, d2 = self.conditions[i], self.conditions[j]
|
||||||
if d1.as_dict() != d2.as_dict():
|
if d1.as_dict() != d2.as_dict():
|
||||||
# in our case, to_value can be zero, hence pass the from_value if so
|
# in our case, to_value can be zero, hence pass the from_value if so
|
||||||
|
@ -18,12 +18,12 @@ class TestSubscription(unittest.TestCase):
|
|||||||
qo.submit()
|
qo.submit()
|
||||||
|
|
||||||
doc = make_subscription(reference_document=qo.name)
|
doc = make_subscription(reference_document=qo.name)
|
||||||
self.assertEquals(doc.next_schedule_date, today())
|
self.assertEqual(doc.next_schedule_date, today())
|
||||||
make_subscription_entry()
|
make_subscription_entry()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
quotation = frappe.get_doc(doc.reference_doctype, doc.reference_document)
|
quotation = frappe.get_doc(doc.reference_doctype, doc.reference_document)
|
||||||
self.assertEquals(quotation.subscription, doc.name)
|
self.assertEqual(quotation.subscription, doc.name)
|
||||||
|
|
||||||
new_quotation = frappe.db.get_value('Quotation',
|
new_quotation = frappe.db.get_value('Quotation',
|
||||||
{'subscription': doc.name, 'name': ('!=', quotation.name)}, 'name')
|
{'subscription': doc.name, 'name': ('!=', quotation.name)}, 'name')
|
||||||
@ -31,10 +31,10 @@ class TestSubscription(unittest.TestCase):
|
|||||||
new_quotation = frappe.get_doc('Quotation', new_quotation)
|
new_quotation = frappe.get_doc('Quotation', new_quotation)
|
||||||
|
|
||||||
for fieldname in ['customer', 'company', 'order_type', 'total', 'net_total']:
|
for fieldname in ['customer', 'company', 'order_type', 'total', 'net_total']:
|
||||||
self.assertEquals(quotation.get(fieldname), new_quotation.get(fieldname))
|
self.assertEqual(quotation.get(fieldname), new_quotation.get(fieldname))
|
||||||
|
|
||||||
for fieldname in ['item_code', 'qty', 'rate', 'amount']:
|
for fieldname in ['item_code', 'qty', 'rate', 'amount']:
|
||||||
self.assertEquals(quotation.items[0].get(fieldname),
|
self.assertEqual(quotation.items[0].get(fieldname),
|
||||||
new_quotation.items[0].get(fieldname))
|
new_quotation.items[0].get(fieldname))
|
||||||
|
|
||||||
def test_monthly_subscription_for_so(self):
|
def test_monthly_subscription_for_so(self):
|
||||||
@ -60,7 +60,7 @@ class TestSubscription(unittest.TestCase):
|
|||||||
|
|
||||||
make_subscription_entry()
|
make_subscription_entry()
|
||||||
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
||||||
self.assertEquals(len(docnames), 1)
|
self.assertEqual(len(docnames), 1)
|
||||||
|
|
||||||
doc = frappe.get_doc('Subscription', doc.name)
|
doc = frappe.get_doc('Subscription', doc.name)
|
||||||
doc.disabled = 0
|
doc.disabled = 0
|
||||||
@ -70,7 +70,7 @@ class TestSubscription(unittest.TestCase):
|
|||||||
make_subscription_entry()
|
make_subscription_entry()
|
||||||
|
|
||||||
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
||||||
self.assertEquals(len(docnames), months)
|
self.assertEqual(len(docnames), months)
|
||||||
|
|
||||||
quotation_records = frappe.get_test_records('Quotation')
|
quotation_records = frappe.get_test_records('Quotation')
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01")
|
sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01")
|
||||||
tax_rule1.save()
|
tax_rule1.save()
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
|
self.assertEqual(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
|
||||||
"_Test Sales Taxes and Charges Template - _TC")
|
"_Test Sales Taxes and Charges Template - _TC")
|
||||||
|
|
||||||
def test_conflict_with_overlapping_dates(self):
|
def test_conflict_with_overlapping_dates(self):
|
||||||
@ -59,7 +59,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
|
|
||||||
def test_tax_template(self):
|
def test_tax_template(self):
|
||||||
tax_rule = make_tax_rule()
|
tax_rule = make_tax_rule()
|
||||||
self.assertEquals(tax_rule.purchase_tax_template, None)
|
self.assertEqual(tax_rule.purchase_tax_template, None)
|
||||||
|
|
||||||
|
|
||||||
def test_select_tax_rule_based_on_customer(self):
|
def test_select_tax_rule_based_on_customer(self):
|
||||||
@ -72,7 +72,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
make_tax_rule(customer= "_Test Customer 2",
|
make_tax_rule(customer= "_Test Customer 2",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 2 - _TC", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 2 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer 2"}),
|
self.assertEqual(get_tax_template("2015-01-01", {"customer":"_Test Customer 2"}),
|
||||||
"_Test Sales Taxes and Charges Template 2 - _TC")
|
"_Test Sales Taxes and Charges Template 2 - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_on_better_match(self):
|
def test_select_tax_rule_based_on_better_match(self):
|
||||||
@ -82,7 +82,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City1", billing_state = "Test State",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City1", billing_state = "Test State",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City", "billing_state": "Test State"}),
|
self.assertEqual(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City", "billing_state": "Test State"}),
|
||||||
"_Test Sales Taxes and Charges Template - _TC")
|
"_Test Sales Taxes and Charges Template - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_on_state_match(self):
|
def test_select_tax_rule_based_on_state_match(self):
|
||||||
@ -92,7 +92,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State12",
|
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State12",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "shipping_state": "Test State"}),
|
self.assertEqual(get_tax_template("2015-01-01", {"customer":"_Test Customer", "shipping_state": "Test State"}),
|
||||||
"_Test Sales Taxes and Charges Template - _TC")
|
"_Test Sales Taxes and Charges Template - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_on_better_priority(self):
|
def test_select_tax_rule_based_on_better_priority(self):
|
||||||
@ -102,7 +102,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City"}),
|
self.assertEqual(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City"}),
|
||||||
"_Test Sales Taxes and Charges Template 1 - _TC")
|
"_Test Sales Taxes and Charges Template 1 - _TC")
|
||||||
|
|
||||||
def test_select_tax_rule_based_cross_matching_keys(self):
|
def test_select_tax_rule_based_cross_matching_keys(self):
|
||||||
@ -112,7 +112,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
make_tax_rule(customer= "_Test Customer 1", billing_city = "Test City 1",
|
make_tax_rule(customer= "_Test Customer 1", billing_city = "Test City 1",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
self.assertEqual(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
||||||
None)
|
None)
|
||||||
|
|
||||||
def test_select_tax_rule_based_cross_partially_keys(self):
|
def test_select_tax_rule_based_cross_partially_keys(self):
|
||||||
@ -122,7 +122,7 @@ class TestTaxRule(unittest.TestCase):
|
|||||||
make_tax_rule(billing_city = "Test City 1",
|
make_tax_rule(billing_city = "Test City 1",
|
||||||
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
|
||||||
|
|
||||||
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
self.assertEqual(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
|
||||||
"_Test Sales Taxes and Charges Template 1 - _TC")
|
"_Test Sales Taxes and Charges Template 1 - _TC")
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
<style>
|
{% if(filters.show_pdc_in_print) { %}
|
||||||
@media screen {
|
<style>
|
||||||
.print-format {
|
@media screen {
|
||||||
padding: 8mm;
|
.print-format {
|
||||||
}
|
padding: 8mm;
|
||||||
}
|
margin:4mm;
|
||||||
</style>
|
font-size:10px;
|
||||||
|
font-family: Tahoma, sans-serif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% } %}
|
||||||
|
|
||||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||||
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
||||||
@ -82,21 +87,24 @@
|
|||||||
<tr>
|
<tr>
|
||||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||||
<th style="width: 10%">{%= __("Date") %}</th>
|
<th style="width: 10%">{%= __("Date") %}</th>
|
||||||
<th style="width: 10%">{%= __("Ref") %}</th>
|
<th style="width: 15%">{%= __("Ref") %}</th>
|
||||||
|
{% if(!filters.show_pdc_in_print) { %}
|
||||||
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||||
|
{% } %}
|
||||||
<th style="width: 10%">{%= __("Invoiced Amount") %}</th>
|
<th style="width: 10%">{%= __("Invoiced Amount") %}</th>
|
||||||
{% if(!filters.show_pdc_in_print) { %}
|
{% if(!filters.show_pdc_in_print) { %}
|
||||||
<th style="width: 10%">{%= __("Paid Amount") %}</th>
|
<th style="width: 10%">{%= __("Paid Amount") %}</th>
|
||||||
<th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
<th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||||
{% } %}
|
{% } %}
|
||||||
<th style="width: 6%">{%= __("Outstanding Amount") %}</th>
|
<th style="width: 15%">{%= __("Outstanding Amount") %}</th>
|
||||||
{% if(filters.show_pdc_in_print) { %}
|
{% if(filters.show_pdc_in_print) { %}
|
||||||
{% if(report.report_name === "Accounts Receivable") { %}
|
{% if(report.report_name === "Accounts Receivable") { %}
|
||||||
<th style="width: 6%">{%= __("Customer LPO No.") %}</th>
|
<th style="width: 10%">{%= __("Customer LPO No.") %}</th>
|
||||||
{% } %}
|
{% } %}
|
||||||
<th style="width: 6%">{%= __("PDC/LC Date") %}</th>
|
<th style="width: 10%">{%= __("PDC/LC Date") %}</th>
|
||||||
<th style="width: 6%">{%= __("PDC/LC Ref") %}</th>
|
<th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
|
||||||
<th style="width: 6%">{%= __("PDC/LC Amount") %}</th>
|
<th style="width: 10%">{%= __("PDC/LC Amount") %}</th>
|
||||||
|
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
|
||||||
{% } %}
|
{% } %}
|
||||||
{% } else { %}
|
{% } else { %}
|
||||||
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||||
@ -115,6 +123,7 @@
|
|||||||
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
||||||
<td>{%= data[i][__("Voucher Type")] %}
|
<td>{%= data[i][__("Voucher Type")] %}
|
||||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||||
|
{% if(!filters.show_pdc_in_print) { %}
|
||||||
<td>
|
<td>
|
||||||
{% if(!(filters.customer || filters.supplier)) { %}
|
{% if(!(filters.customer || filters.supplier)) { %}
|
||||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||||
@ -127,6 +136,7 @@
|
|||||||
<br>{%= __("Remarks") %}:
|
<br>{%= __("Remarks") %}:
|
||||||
{%= data[i][__("Remarks")] %}
|
{%= data[i][__("Remarks")] %}
|
||||||
</td>
|
</td>
|
||||||
|
{% } %}
|
||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
||||||
|
|
||||||
@ -147,10 +157,13 @@
|
|||||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
||||||
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
||||||
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
||||||
|
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||||
{% } %}
|
{% } %}
|
||||||
{% } else { %}
|
{% } else { %}
|
||||||
<td></td>
|
<td></td>
|
||||||
|
{% if(!filters.show_pdc_in_print) { %}
|
||||||
<td></td>
|
<td></td>
|
||||||
|
{% } %}
|
||||||
<td><b>{%= __("Total") %}</b></td>
|
<td><b>{%= __("Total") %}</b></td>
|
||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %}</td>
|
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %}</td>
|
||||||
@ -171,6 +184,7 @@
|
|||||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
||||||
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
||||||
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
<td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
|
||||||
|
<td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||||
{% } %}
|
{% } %}
|
||||||
{% } %}
|
{% } %}
|
||||||
{% } else { %}
|
{% } else { %}
|
||||||
|
@ -159,7 +159,7 @@ class ReceivablePayableReport(object):
|
|||||||
else:
|
else:
|
||||||
row.append(company_currency)
|
row.append(company_currency)
|
||||||
|
|
||||||
pdc = pdc_details.get(gle.voucher_no, {})
|
pdc = pdc_details.get((gle.voucher_no, gle.party), {})
|
||||||
remaining_balance = outstanding_amount - flt(pdc.get("pdc_amount"))
|
remaining_balance = outstanding_amount - flt(pdc.get("pdc_amount"))
|
||||||
row += [pdc.get("pdc_date"), pdc.get("pdc_ref"),
|
row += [pdc.get("pdc_date"), pdc.get("pdc_ref"),
|
||||||
flt(pdc.get("pdc_amount")), remaining_balance]
|
flt(pdc.get("pdc_amount")), remaining_balance]
|
||||||
@ -405,25 +405,33 @@ def get_pdc_details(party_type):
|
|||||||
on
|
on
|
||||||
(pref.parent = pent.name)
|
(pref.parent = pent.name)
|
||||||
where
|
where
|
||||||
pent.docstatus = 0 and pent.reference_date > pent.posting_date
|
pent.docstatus < 2 and pent.reference_date >= pent.posting_date
|
||||||
and pent.party_type = %s
|
and pent.party_type = %s
|
||||||
group by pref.reference_name""", party_type, as_dict=1):
|
group by pent.party, pref.reference_name""", party_type, as_dict=1):
|
||||||
pdc_details.setdefault(pdc.invoice_no, pdc)
|
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
|
||||||
|
|
||||||
|
if scrub(party_type):
|
||||||
|
amount_field = "jea.debit_in_account_currency + jea.credit_in_account_currency"
|
||||||
|
else:
|
||||||
|
amount_field = "jea.debit + jea.credit"
|
||||||
|
|
||||||
for pdc in frappe.db.sql("""
|
for pdc in frappe.db.sql("""
|
||||||
select
|
select
|
||||||
jea.reference_name as invoice_no, jea.party, jea.party_type,
|
jea.reference_name as invoice_no, jea.party, jea.party_type,
|
||||||
max(je.cheque_date) as pdc_date, sum(ifnull(je.total_amount,0)) as pdc_amount,
|
max(je.cheque_date) as pdc_date, sum(ifnull({0},0)) as pdc_amount,
|
||||||
GROUP_CONCAT(je.cheque_no SEPARATOR ', ') as pdc_ref
|
GROUP_CONCAT(je.cheque_no SEPARATOR ', ') as pdc_ref
|
||||||
from
|
from
|
||||||
`tabJournal Entry` as je inner join `tabJournal Entry Account` as jea
|
`tabJournal Entry` as je inner join `tabJournal Entry Account` as jea
|
||||||
on
|
on
|
||||||
(jea.parent = je.name)
|
(jea.parent = je.name)
|
||||||
where
|
where
|
||||||
je.docstatus = 0 and je.cheque_date > je.posting_date
|
je.docstatus < 2 and je.cheque_date >= je.posting_date
|
||||||
and jea.party_type = %s
|
and jea.party_type = %s
|
||||||
group by jea.reference_name""", party_type, as_dict=1):
|
group by jea.party, jea.reference_name""".format(amount_field), party_type, as_dict=1):
|
||||||
pdc_details.setdefault(pdc.invoice_no, pdc)
|
if (pdc.invoice_no, pdc.party) in pdc_details:
|
||||||
|
pdc_details[(pdc.invoice_no, pdc.party)]["pdc_amount"] += pdc.pdc_amount
|
||||||
|
else:
|
||||||
|
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
|
||||||
|
|
||||||
return pdc_details
|
return pdc_details
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
|
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
@ -36,7 +38,7 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v
|
|||||||
start_date = year_start_date
|
start_date = year_start_date
|
||||||
months = get_months(year_start_date, year_end_date)
|
months = get_months(year_start_date, year_end_date)
|
||||||
|
|
||||||
for i in xrange(months / months_to_add):
|
for i in range(months // months_to_add):
|
||||||
period = frappe._dict({
|
period = frappe._dict({
|
||||||
"from_date": start_date
|
"from_date": start_date
|
||||||
})
|
})
|
||||||
@ -325,7 +327,7 @@ def sort_root_accounts(roots):
|
|||||||
return -1
|
return -1
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
roots.sort(compare_roots)
|
roots.sort(key = functools.cmp_to_key(compare_roots))
|
||||||
|
|
||||||
|
|
||||||
def set_gl_entries_by_account(
|
def set_gl_entries_by_account(
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
{% } %}
|
{% } %}
|
||||||
</h4>
|
</h4>
|
||||||
<h5 class="text-center">
|
<h5 class="text-center">
|
||||||
{%= dateutil.str_to_user(filters.from_date) %}
|
{%= frappe.datetime.str_to_user(filters.from_date) %}
|
||||||
{%= __("to") %}
|
{%= __("to") %}
|
||||||
{%= dateutil.str_to_user(filters.to_date) %}
|
{%= frappe.datetime.str_to_user(filters.to_date) %}
|
||||||
</h5>
|
</h5>
|
||||||
<hr>
|
<hr>
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
@ -29,7 +29,7 @@
|
|||||||
{% for(var i=0, l=data.length; i<l; i++) { %}
|
{% for(var i=0, l=data.length; i<l; i++) { %}
|
||||||
<tr>
|
<tr>
|
||||||
{% if(data[i].posting_date) { %}
|
{% if(data[i].posting_date) { %}
|
||||||
<td>{%= dateutil.str_to_user(data[i].posting_date) %}</td>
|
<td>{%= frappe.datetime.str_to_user(data[i].posting_date) %}</td>
|
||||||
<td>{%= data[i].voucher_type %}
|
<td>{%= data[i].voucher_type %}
|
||||||
<br>{%= data[i].voucher_no %}</td>
|
<br>{%= data[i].voucher_no %}</td>
|
||||||
<td>
|
<td>
|
||||||
@ -58,7 +58,7 @@
|
|||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= data[i].account && format_currency(data[i].credit, filters.presentation_currency) %}
|
{%= data[i].account && format_currency(data[i].credit, filters.presentation_currency) %}
|
||||||
</td>
|
</td>
|
||||||
{% } %}
|
{% } %}
|
||||||
<td style="text-align: right">
|
<td style="text-align: right">
|
||||||
{%= format_currency(data[i].balance, filters.presentation_currency) %}
|
{%= format_currency(data[i].balance, filters.presentation_currency) %}
|
||||||
</td>
|
</td>
|
||||||
@ -66,4 +66,4 @@
|
|||||||
{% } %}
|
{% } %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p class="text-right text-muted">Printed On {%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
|
<p class="text-right text-muted">Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
|
||||||
|
@ -105,7 +105,7 @@ def get_conditions(filters):
|
|||||||
|
|
||||||
if filters.get("mode_of_payment"):
|
if filters.get("mode_of_payment"):
|
||||||
conditions += """ and exists(select name from `tabSales Invoice Payment`
|
conditions += """ and exists(select name from `tabSales Invoice Payment`
|
||||||
where parent=si.name
|
where parent=`tabSales Invoice`.name
|
||||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
|
@ -11,4 +11,4 @@ test_dependencies = ["Fertilizer"]
|
|||||||
class TestCrop(unittest.TestCase):
|
class TestCrop(unittest.TestCase):
|
||||||
def test_crop_period(self):
|
def test_crop_period(self):
|
||||||
basil = frappe.get_doc('Crop', 'Basil from seed')
|
basil = frappe.get_doc('Crop', 'Basil from seed')
|
||||||
self.assertEquals(basil.period, 15)
|
self.assertEqual(basil.period, 15)
|
@ -11,11 +11,11 @@ test_dependencies = ["Crop", "Fertilizer", "Land Unit", "Disease"]
|
|||||||
class TestCropCycle(unittest.TestCase):
|
class TestCropCycle(unittest.TestCase):
|
||||||
def test_crop_cycle_creation(self):
|
def test_crop_cycle_creation(self):
|
||||||
cycle = frappe.get_doc('Crop Cycle', 'Basil from seed 2017')
|
cycle = frappe.get_doc('Crop Cycle', 'Basil from seed 2017')
|
||||||
self.assertEquals(frappe.db.exists('Crop Cycle', 'Basil from seed 2017'), 'Basil from seed 2017')
|
self.assertEqual(frappe.db.exists('Crop Cycle', 'Basil from seed 2017'), 'Basil from seed 2017')
|
||||||
|
|
||||||
# check if the tasks were created
|
# check if the tasks were created
|
||||||
self.assertEquals(check_task_creation(), True)
|
self.assertEqual(check_task_creation(), True)
|
||||||
self.assertEquals(check_project_creation(), True)
|
self.assertEqual(check_project_creation(), True)
|
||||||
|
|
||||||
def check_task_creation():
|
def check_task_creation():
|
||||||
all_task_dict = {
|
all_task_dict = {
|
||||||
|
@ -9,4 +9,4 @@ import unittest
|
|||||||
class TestDisease(unittest.TestCase):
|
class TestDisease(unittest.TestCase):
|
||||||
def test_treatment_period(self):
|
def test_treatment_period(self):
|
||||||
disease = frappe.get_doc('Disease', 'Aphids')
|
disease = frappe.get_doc('Disease', 'Aphids')
|
||||||
self.assertEquals(disease.treatment_period, 3)
|
self.assertEqual(disease.treatment_period, 3)
|
@ -8,4 +8,4 @@ import unittest
|
|||||||
|
|
||||||
class TestFertilizer(unittest.TestCase):
|
class TestFertilizer(unittest.TestCase):
|
||||||
def test_fertilizer_creation(self):
|
def test_fertilizer_creation(self):
|
||||||
self.assertEquals(frappe.db.exists('Fertilizer', 'Urea'), 'Urea')
|
self.assertEqual(frappe.db.exists('Fertilizer', 'Urea'), 'Urea')
|
@ -22,5 +22,5 @@ class TestLandUnit(unittest.TestCase):
|
|||||||
formatted_land_units.extend(temp['features'])
|
formatted_land_units.extend(temp['features'])
|
||||||
formatted_land_unit_string = str(formatted_land_units)
|
formatted_land_unit_string = str(formatted_land_units)
|
||||||
test_land = frappe.get_doc('Land Unit', 'Test Land')
|
test_land = frappe.get_doc('Land Unit', 'Test Land')
|
||||||
self.assertEquals(formatted_land_unit_string, str(json.loads(test_land.get('location'))['features']))
|
self.assertEqual(formatted_land_unit_string, str(json.loads(test_land.get('location'))['features']))
|
||||||
self.assertEquals(area, test_land.get('area'))
|
self.assertEqual(area, test_land.get('area'))
|
||||||
|
@ -10,5 +10,5 @@ class TestSoilTexture(unittest.TestCase):
|
|||||||
def test_texture_selection(self):
|
def test_texture_selection(self):
|
||||||
soil_tex = frappe.get_all('Soil Texture', fields=['name'], filters={'collection_datetime': '2017-11-08'})
|
soil_tex = frappe.get_all('Soil Texture', fields=['name'], filters={'collection_datetime': '2017-11-08'})
|
||||||
doc = frappe.get_doc('Soil Texture', soil_tex[0].name)
|
doc = frappe.get_doc('Soil Texture', soil_tex[0].name)
|
||||||
self.assertEquals(doc.silt_composition, 50)
|
self.assertEqual(doc.silt_composition, 50)
|
||||||
self.assertEquals(doc.soil_type, 'Silt Loam')
|
self.assertEqual(doc.soil_type, 'Silt Loam')
|
@ -114,15 +114,15 @@ class Asset(Document):
|
|||||||
and getdate(self.next_depreciation_date) < next_depr_date):
|
and getdate(self.next_depreciation_date) < next_depr_date):
|
||||||
|
|
||||||
number_of_pending_depreciations += 1
|
number_of_pending_depreciations += 1
|
||||||
for n in xrange(number_of_pending_depreciations):
|
for n in range(number_of_pending_depreciations):
|
||||||
if n == xrange(number_of_pending_depreciations)[-1]:
|
if n == range(number_of_pending_depreciations)[-1]:
|
||||||
schedule_date = add_months(self.available_for_use_date, n * 12)
|
schedule_date = add_months(self.available_for_use_date, n * 12)
|
||||||
previous_scheduled_date = add_months(self.next_depreciation_date, (n-1) * 12)
|
previous_scheduled_date = add_months(self.next_depreciation_date, (n-1) * 12)
|
||||||
depreciation_amount = \
|
depreciation_amount = \
|
||||||
self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
|
self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
|
||||||
previous_scheduled_date, schedule_date)
|
previous_scheduled_date, schedule_date)
|
||||||
|
|
||||||
elif n == xrange(number_of_pending_depreciations)[0]:
|
elif n == range(number_of_pending_depreciations)[0]:
|
||||||
schedule_date = self.next_depreciation_date
|
schedule_date = self.next_depreciation_date
|
||||||
depreciation_amount = \
|
depreciation_amount = \
|
||||||
self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
|
self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
|
||||||
@ -141,7 +141,7 @@ class Asset(Document):
|
|||||||
"depreciation_amount": depreciation_amount
|
"depreciation_amount": depreciation_amount
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
for n in xrange(number_of_pending_depreciations):
|
for n in range(number_of_pending_depreciations):
|
||||||
schedule_date = add_months(self.next_depreciation_date,
|
schedule_date = add_months(self.next_depreciation_date,
|
||||||
n * cint(self.frequency_of_depreciation))
|
n * cint(self.frequency_of_depreciation))
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -71,6 +72,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -103,6 +105,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 1,
|
"set_only_once": 1,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -136,6 +139,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -167,6 +171,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -198,6 +203,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -228,6 +234,40 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 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": "eval:doc.is_subcontracted==\"Yes\"",
|
||||||
|
"fieldname": "supplier_warehouse",
|
||||||
|
"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": "Supplier Warehouse",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Warehouse",
|
||||||
|
"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
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -258,6 +298,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0,
|
"unique": 0,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
@ -291,6 +332,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -322,6 +364,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -354,6 +397,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -387,6 +431,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -418,6 +463,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -450,6 +496,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -481,6 +528,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -510,6 +558,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -542,6 +591,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -572,6 +622,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -602,6 +653,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -633,6 +685,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -663,6 +716,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -693,6 +747,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -723,6 +778,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -753,6 +809,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -782,6 +839,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -811,6 +869,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -840,6 +899,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -869,6 +929,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -901,6 +962,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -931,6 +993,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -961,6 +1024,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -993,6 +1057,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1026,6 +1091,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1054,6 +1120,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1084,6 +1151,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1114,6 +1182,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1144,6 +1213,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1173,6 +1243,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1204,6 +1275,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1236,6 +1308,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1267,6 +1340,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1298,6 +1372,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1326,6 +1401,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1357,6 +1433,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1389,6 +1466,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1417,6 +1495,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1448,6 +1527,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1480,6 +1560,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1510,6 +1591,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1541,6 +1623,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1574,6 +1657,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1603,6 +1687,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1634,6 +1719,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1663,6 +1749,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1695,6 +1782,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1725,6 +1813,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1755,6 +1844,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1786,6 +1876,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1818,6 +1909,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1850,6 +1942,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1882,6 +1975,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1911,6 +2005,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1943,6 +2038,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1975,6 +2071,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2006,6 +2103,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2037,6 +2135,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2069,6 +2168,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2100,6 +2200,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2129,6 +2230,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2159,6 +2261,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2190,6 +2293,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2219,6 +2323,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2251,6 +2356,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2282,6 +2388,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2314,6 +2421,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2346,6 +2454,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2375,6 +2484,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2407,6 +2517,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2438,6 +2549,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2469,6 +2581,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2499,6 +2612,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2529,6 +2643,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2560,6 +2675,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2591,6 +2707,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2623,6 +2740,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2655,6 +2773,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2686,6 +2805,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2716,6 +2836,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2749,6 +2870,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 1,
|
"search_index": 1,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2780,6 +2902,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2811,6 +2934,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2840,6 +2964,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2873,6 +2998,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2906,6 +3032,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2937,6 +3064,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0,
|
"unique": 0,
|
||||||
"width": "50%"
|
"width": "50%"
|
||||||
},
|
},
|
||||||
@ -2970,6 +3098,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3002,6 +3131,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3031,6 +3161,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3062,6 +3193,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3094,6 +3226,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3156,6 +3289,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3189,6 +3323,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3219,6 +3354,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3250,6 +3386,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3281,6 +3418,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3310,6 +3448,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3341,6 +3480,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -3355,7 +3495,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-02-17 11:00:05.037716",
|
"modified": "2018-02-21 14:26:17.099336",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
@ -332,7 +332,8 @@ def make_purchase_receipt(source_name, target_doc=None):
|
|||||||
"Purchase Order": {
|
"Purchase Order": {
|
||||||
"doctype": "Purchase Receipt",
|
"doctype": "Purchase Receipt",
|
||||||
"field_map": {
|
"field_map": {
|
||||||
"per_billed": "per_billed"
|
"per_billed": "per_billed",
|
||||||
|
"supplier_warehouse":"supplier_warehouse"
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"docstatus": ["=", 1],
|
"docstatus": ["=", 1],
|
||||||
@ -377,7 +378,8 @@ def make_purchase_invoice(source_name, target_doc=None):
|
|||||||
"Purchase Order": {
|
"Purchase Order": {
|
||||||
"doctype": "Purchase Invoice",
|
"doctype": "Purchase Invoice",
|
||||||
"field_map": {
|
"field_map": {
|
||||||
"party_account_currency": "party_account_currency"
|
"party_account_currency": "party_account_currency",
|
||||||
|
"supplier_warehouse":"supplier_warehouse"
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"docstatus": ["=", 1],
|
"docstatus": ["=", 1],
|
||||||
@ -428,6 +430,7 @@ def make_rm_stock_entry(purchase_order, rm_items):
|
|||||||
stock_entry.supplier_address = purchase_order.supplier_address
|
stock_entry.supplier_address = purchase_order.supplier_address
|
||||||
stock_entry.address_display = purchase_order.address_display
|
stock_entry.address_display = purchase_order.address_display
|
||||||
stock_entry.company = purchase_order.company
|
stock_entry.company = purchase_order.company
|
||||||
|
stock_entry.to_warehouse = purchase_order.supplier_warehouse
|
||||||
stock_entry.from_bom = 1
|
stock_entry.from_bom = 1
|
||||||
for item_code in item_code_list:
|
for item_code in item_code_list:
|
||||||
po_item = [d for d in purchase_order.items if d.item_code == item_code][0]
|
po_item = [d for d in purchase_order.items if d.item_code == item_code][0]
|
||||||
@ -451,4 +454,4 @@ def make_rm_stock_entry(purchase_order, rm_items):
|
|||||||
def update_status(status, name):
|
def update_status(status, name):
|
||||||
po = frappe.get_doc("Purchase Order", name)
|
po = frappe.get_doc("Purchase Order", name)
|
||||||
po.update_status(status)
|
po.update_status(status)
|
||||||
po.update_delivered_qty_in_sales_order()
|
po.update_delivered_qty_in_sales_order()
|
@ -17,7 +17,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
po.submit()
|
po.submit()
|
||||||
|
|
||||||
pr = create_pr_against_po(po.name)
|
pr = create_pr_against_po(po.name)
|
||||||
self.assertEquals(len(pr.get("items")), 1)
|
self.assertEqual(len(pr.get("items")), 1)
|
||||||
|
|
||||||
def test_ordered_qty(self):
|
def test_ordered_qty(self):
|
||||||
existing_ordered_qty = get_ordered_qty()
|
existing_ordered_qty = get_ordered_qty()
|
||||||
@ -32,7 +32,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 6)
|
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 6)
|
||||||
|
|
||||||
po.load_from_db()
|
po.load_from_db()
|
||||||
self.assertEquals(po.get("items")[0].received_qty, 4)
|
self.assertEqual(po.get("items")[0].received_qty, 4)
|
||||||
|
|
||||||
frappe.db.set_value('Item', '_Test Item', 'tolerance', 50)
|
frappe.db.set_value('Item', '_Test Item', 'tolerance', 50)
|
||||||
|
|
||||||
@ -40,13 +40,13 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty)
|
self.assertEqual(get_ordered_qty(), existing_ordered_qty)
|
||||||
|
|
||||||
po.load_from_db()
|
po.load_from_db()
|
||||||
self.assertEquals(po.get("items")[0].received_qty, 12)
|
self.assertEqual(po.get("items")[0].received_qty, 12)
|
||||||
|
|
||||||
pr.cancel()
|
pr.cancel()
|
||||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 6)
|
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 6)
|
||||||
|
|
||||||
po.load_from_db()
|
po.load_from_db()
|
||||||
self.assertEquals(po.get("items")[0].received_qty, 4)
|
self.assertEqual(po.get("items")[0].received_qty, 4)
|
||||||
|
|
||||||
def test_ordered_qty_against_pi_with_update_stock(self):
|
def test_ordered_qty_against_pi_with_update_stock(self):
|
||||||
existing_ordered_qty = get_ordered_qty()
|
existing_ordered_qty = get_ordered_qty()
|
||||||
@ -66,13 +66,13 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty)
|
self.assertEqual(get_ordered_qty(), existing_ordered_qty)
|
||||||
|
|
||||||
po.load_from_db()
|
po.load_from_db()
|
||||||
self.assertEquals(po.get("items")[0].received_qty, 12)
|
self.assertEqual(po.get("items")[0].received_qty, 12)
|
||||||
|
|
||||||
pi.cancel()
|
pi.cancel()
|
||||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10)
|
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10)
|
||||||
|
|
||||||
po.load_from_db()
|
po.load_from_db()
|
||||||
self.assertEquals(po.get("items")[0].received_qty, 0)
|
self.assertEqual(po.get("items")[0].received_qty, 0)
|
||||||
|
|
||||||
def test_make_purchase_invoice(self):
|
def test_make_purchase_invoice(self):
|
||||||
po = create_purchase_order(do_not_submit=True)
|
po = create_purchase_order(do_not_submit=True)
|
||||||
@ -82,8 +82,8 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
po.submit()
|
po.submit()
|
||||||
pi = make_purchase_invoice(po.name)
|
pi = make_purchase_invoice(po.name)
|
||||||
|
|
||||||
self.assertEquals(pi.doctype, "Purchase Invoice")
|
self.assertEqual(pi.doctype, "Purchase Invoice")
|
||||||
self.assertEquals(len(pi.get("items", [])), 1)
|
self.assertEqual(len(pi.get("items", [])), 1)
|
||||||
|
|
||||||
def test_make_purchase_invoice_with_terms(self):
|
def test_make_purchase_invoice_with_terms(self):
|
||||||
po = create_purchase_order(do_not_save=True)
|
po = create_purchase_order(do_not_save=True)
|
||||||
@ -104,8 +104,8 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
pi = make_purchase_invoice(po.name)
|
pi = make_purchase_invoice(po.name)
|
||||||
pi.save()
|
pi.save()
|
||||||
|
|
||||||
self.assertEquals(pi.doctype, "Purchase Invoice")
|
self.assertEqual(pi.doctype, "Purchase Invoice")
|
||||||
self.assertEquals(len(pi.get("items", [])), 1)
|
self.assertEqual(len(pi.get("items", [])), 1)
|
||||||
|
|
||||||
self.assertEqual(pi.payment_schedule[0].payment_amount, 2500.0)
|
self.assertEqual(pi.payment_schedule[0].payment_amount, 2500.0)
|
||||||
self.assertEqual(pi.payment_schedule[0].due_date, po.transaction_date)
|
self.assertEqual(pi.payment_schedule[0].due_date, po.transaction_date)
|
||||||
@ -114,7 +114,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
def test_subcontracting(self):
|
def test_subcontracting(self):
|
||||||
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
|
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
|
||||||
self.assertEquals(len(po.get("supplied_items")), 2)
|
self.assertEqual(len(po.get("supplied_items")), 2)
|
||||||
|
|
||||||
def test_warehouse_company_validation(self):
|
def test_warehouse_company_validation(self):
|
||||||
from erpnext.stock.utils import InvalidWarehouseCompany
|
from erpnext.stock.utils import InvalidWarehouseCompany
|
||||||
@ -134,11 +134,11 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
|
|
||||||
po = create_purchase_order(item_code= "_Test Item", qty=1)
|
po = create_purchase_order(item_code= "_Test Item", qty=1)
|
||||||
|
|
||||||
self.assertEquals(get_ordered_qty(item_code= "_Test Item", warehouse="_Test Warehouse - _TC"), existing_ordered_qty+1)
|
self.assertEqual(get_ordered_qty(item_code= "_Test Item", warehouse="_Test Warehouse - _TC"), existing_ordered_qty+1)
|
||||||
|
|
||||||
po.update_status("Closed")
|
po.update_status("Closed")
|
||||||
|
|
||||||
self.assertEquals(get_ordered_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_ordered_qty)
|
self.assertEqual(get_ordered_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_ordered_qty)
|
||||||
|
|
||||||
def test_group_same_items(self):
|
def test_group_same_items(self):
|
||||||
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
|
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
|
||||||
@ -199,8 +199,8 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
bin2 = frappe.db.get_value("Bin",
|
bin2 = frappe.db.get_value("Bin",
|
||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
|
fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1)
|
||||||
self.assertEquals(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
|
self.assertEqual(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
|
||||||
self.assertEquals(bin2.projected_qty, bin1.projected_qty - 10)
|
self.assertEqual(bin2.projected_qty, bin1.projected_qty - 10)
|
||||||
|
|
||||||
# Create stock transfer
|
# Create stock transfer
|
||||||
rm_item = [{"item_code":"_Test FG Item","rm_item_code":"_Test Item","item_name":"_Test Item",
|
rm_item = [{"item_code":"_Test FG Item","rm_item_code":"_Test Item","item_name":"_Test Item",
|
||||||
@ -215,7 +215,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
self.assertEqual(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||||
|
|
||||||
# close PO
|
# close PO
|
||||||
po.update_status("Closed")
|
po.update_status("Closed")
|
||||||
@ -223,7 +223,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
self.assertEqual(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||||
|
|
||||||
# Re-open PO
|
# Re-open PO
|
||||||
po.update_status("Submitted")
|
po.update_status("Submitted")
|
||||||
@ -231,7 +231,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
self.assertEqual(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||||
|
|
||||||
# make Purchase Receipt against PO
|
# make Purchase Receipt against PO
|
||||||
pr = make_purchase_receipt(po.name)
|
pr = make_purchase_receipt(po.name)
|
||||||
@ -243,7 +243,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
self.assertEqual(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||||
|
|
||||||
# Cancel PR
|
# Cancel PR
|
||||||
pr.cancel()
|
pr.cancel()
|
||||||
@ -251,7 +251,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
self.assertEqual(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||||
|
|
||||||
# Make Purchase Invoice
|
# Make Purchase Invoice
|
||||||
pi = make_purchase_invoice(po.name)
|
pi = make_purchase_invoice(po.name)
|
||||||
@ -263,7 +263,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
self.assertEqual(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||||
|
|
||||||
# Cancel PR
|
# Cancel PR
|
||||||
pi.cancel()
|
pi.cancel()
|
||||||
@ -271,14 +271,14 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
self.assertEqual(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
|
||||||
|
|
||||||
# Cancel Stock Entry
|
# Cancel Stock Entry
|
||||||
se.cancel()
|
se.cancel()
|
||||||
bin10 = frappe.db.get_value("Bin",
|
bin10 = frappe.db.get_value("Bin",
|
||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
self.assertEquals(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
|
self.assertEqual(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
|
||||||
|
|
||||||
# Cancel PO
|
# Cancel PO
|
||||||
po.reload()
|
po.reload()
|
||||||
@ -287,7 +287,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||||
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
fieldname="reserved_qty_for_sub_contract", as_dict=1)
|
||||||
|
|
||||||
self.assertEquals(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
self.assertEqual(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
|
||||||
|
|
||||||
def get_same_items():
|
def get_same_items():
|
||||||
return [
|
return [
|
||||||
|
@ -14,8 +14,8 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
|
||||||
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Pending')
|
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Pending')
|
||||||
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'Pending')
|
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'Pending')
|
||||||
|
|
||||||
# Submit the first supplier quotation
|
# Submit the first supplier quotation
|
||||||
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
sq = make_supplier_quotation(rfq.name, rfq.get('suppliers')[0].supplier)
|
||||||
@ -27,8 +27,8 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
|
|
||||||
rfq.update_rfq_supplier_status() #rfq.get('suppliers')[1].supplier)
|
rfq.update_rfq_supplier_status() #rfq.get('suppliers')[1].supplier)
|
||||||
|
|
||||||
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Received')
|
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Received')
|
||||||
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
||||||
|
|
||||||
def test_make_supplier_quotation(self):
|
def test_make_supplier_quotation(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||||
@ -40,15 +40,15 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
sq1 = make_supplier_quotation(rfq.name, rfq.get('suppliers')[1].supplier)
|
sq1 = make_supplier_quotation(rfq.name, rfq.get('suppliers')[1].supplier)
|
||||||
sq1.submit()
|
sq1.submit()
|
||||||
|
|
||||||
self.assertEquals(sq.supplier, rfq.get('suppliers')[0].supplier)
|
self.assertEqual(sq.supplier, rfq.get('suppliers')[0].supplier)
|
||||||
self.assertEquals(sq.get('items')[0].request_for_quotation, rfq.name)
|
self.assertEqual(sq.get('items')[0].request_for_quotation, rfq.name)
|
||||||
self.assertEquals(sq.get('items')[0].item_code, "_Test Item")
|
self.assertEqual(sq.get('items')[0].item_code, "_Test Item")
|
||||||
self.assertEquals(sq.get('items')[0].qty, 5)
|
self.assertEqual(sq.get('items')[0].qty, 5)
|
||||||
|
|
||||||
self.assertEquals(sq1.supplier, rfq.get('suppliers')[1].supplier)
|
self.assertEqual(sq1.supplier, rfq.get('suppliers')[1].supplier)
|
||||||
self.assertEquals(sq1.get('items')[0].request_for_quotation, rfq.name)
|
self.assertEqual(sq1.get('items')[0].request_for_quotation, rfq.name)
|
||||||
self.assertEquals(sq1.get('items')[0].item_code, "_Test Item")
|
self.assertEqual(sq1.get('items')[0].item_code, "_Test Item")
|
||||||
self.assertEquals(sq1.get('items')[0].qty, 5)
|
self.assertEqual(sq1.get('items')[0].qty, 5)
|
||||||
|
|
||||||
def test_make_supplier_quotation_with_special_characters(self):
|
def test_make_supplier_quotation_with_special_characters(self):
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||||
@ -84,11 +84,11 @@ class TestRequestforQuotation(unittest.TestCase):
|
|||||||
|
|
||||||
supplier_quotation_doc = frappe.get_doc('Supplier Quotation', supplier_quotation_name)
|
supplier_quotation_doc = frappe.get_doc('Supplier Quotation', supplier_quotation_name)
|
||||||
|
|
||||||
self.assertEquals(supplier_quotation_doc.supplier, rfq.get('suppliers')[0].supplier)
|
self.assertEqual(supplier_quotation_doc.supplier, rfq.get('suppliers')[0].supplier)
|
||||||
self.assertEquals(supplier_quotation_doc.get('items')[0].request_for_quotation, rfq.name)
|
self.assertEqual(supplier_quotation_doc.get('items')[0].request_for_quotation, rfq.name)
|
||||||
self.assertEquals(supplier_quotation_doc.get('items')[0].item_code, "_Test Item")
|
self.assertEqual(supplier_quotation_doc.get('items')[0].item_code, "_Test Item")
|
||||||
self.assertEquals(supplier_quotation_doc.get('items')[0].qty, 5)
|
self.assertEqual(supplier_quotation_doc.get('items')[0].qty, 5)
|
||||||
self.assertEquals(supplier_quotation_doc.get('items')[0].amount, 500)
|
self.assertEqual(supplier_quotation_doc.get('items')[0].amount, 500)
|
||||||
|
|
||||||
|
|
||||||
def make_request_for_quotation(supplier_data=None):
|
def make_request_for_quotation(supplier_data=None):
|
||||||
|
@ -20,8 +20,8 @@ class TestPurchaseOrder(unittest.TestCase):
|
|||||||
sq.submit()
|
sq.submit()
|
||||||
po = make_purchase_order(sq.name)
|
po = make_purchase_order(sq.name)
|
||||||
|
|
||||||
self.assertEquals(po.doctype, "Purchase Order")
|
self.assertEqual(po.doctype, "Purchase Order")
|
||||||
self.assertEquals(len(po.get("items")), len(sq.get("items")))
|
self.assertEqual(len(po.get("items")), len(sq.get("items")))
|
||||||
|
|
||||||
po.naming_series = "_T-Purchase Order-"
|
po.naming_series = "_T-Purchase Order-"
|
||||||
|
|
||||||
|
@ -13,9 +13,9 @@ class TestSupplierScorecardVariable(unittest.TestCase):
|
|||||||
def test_variable_exist(self):
|
def test_variable_exist(self):
|
||||||
for d in test_existing_variables:
|
for d in test_existing_variables:
|
||||||
my_doc = frappe.get_doc("Supplier Scorecard Variable", d.get("name"))
|
my_doc = frappe.get_doc("Supplier Scorecard Variable", d.get("name"))
|
||||||
self.assertEquals(my_doc.param_name, d.get('param_name'))
|
self.assertEqual(my_doc.param_name, d.get('param_name'))
|
||||||
self.assertEquals(my_doc.variable_label, d.get('variable_label'))
|
self.assertEqual(my_doc.variable_label, d.get('variable_label'))
|
||||||
self.assertEquals(my_doc.path, d.get('path'))
|
self.assertEqual(my_doc.path, d.get('path'))
|
||||||
|
|
||||||
def test_path_exists(self):
|
def test_path_exists(self):
|
||||||
for d in test_good_variables:
|
for d in test_good_variables:
|
||||||
|
22
erpnext/config/erpnext_integrations.py
Normal file
22
erpnext/config/erpnext_integrations.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"label": _("Payments"),
|
||||||
|
"icon": "fa fa-star",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "GoCardless Settings",
|
||||||
|
"description": _("GoCardless payment gateway settings"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "GoCardless Mandate",
|
||||||
|
"description": _("GoCardless SEPA Mandate"),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -182,7 +182,7 @@ def get_period_date_ranges(period, fiscal_year=None, year_start_date=None):
|
|||||||
}.get(period)
|
}.get(period)
|
||||||
|
|
||||||
period_date_ranges = []
|
period_date_ranges = []
|
||||||
for i in xrange(1, 13, increment):
|
for i in range(1, 13, increment):
|
||||||
period_end_date = getdate(year_start_date) + relativedelta(months=increment, days=-1)
|
period_end_date = getdate(year_start_date) + relativedelta(months=increment, days=-1)
|
||||||
if period_end_date > getdate(year_end_date):
|
if period_end_date > getdate(year_end_date):
|
||||||
period_end_date = year_end_date
|
period_end_date = year_end_date
|
||||||
|
@ -15,8 +15,8 @@ class TestLead(unittest.TestCase):
|
|||||||
frappe.delete_doc_if_exists("Customer", "_Test Lead")
|
frappe.delete_doc_if_exists("Customer", "_Test Lead")
|
||||||
|
|
||||||
customer = make_customer("_T-Lead-00001")
|
customer = make_customer("_T-Lead-00001")
|
||||||
self.assertEquals(customer.doctype, "Customer")
|
self.assertEqual(customer.doctype, "Customer")
|
||||||
self.assertEquals(customer.lead_name, "_T-Lead-00001")
|
self.assertEqual(customer.lead_name, "_T-Lead-00001")
|
||||||
|
|
||||||
customer.company = "_Test Company"
|
customer.company = "_Test Company"
|
||||||
customer.customer_group = "_Test Customer Group"
|
customer.customer_group = "_Test Customer Group"
|
||||||
@ -26,8 +26,8 @@ class TestLead(unittest.TestCase):
|
|||||||
from erpnext.crm.doctype.lead.lead import make_customer
|
from erpnext.crm.doctype.lead.lead import make_customer
|
||||||
|
|
||||||
customer = make_customer("_T-Lead-00002")
|
customer = make_customer("_T-Lead-00002")
|
||||||
self.assertEquals(customer.doctype, "Customer")
|
self.assertEqual(customer.doctype, "Customer")
|
||||||
self.assertEquals(customer.lead_name, "_T-Lead-00002")
|
self.assertEqual(customer.lead_name, "_T-Lead-00002")
|
||||||
|
|
||||||
customer.company = "_Test Company"
|
customer.company = "_Test Company"
|
||||||
customer.customer_group = "_Test Customer Group"
|
customer.customer_group = "_Test Customer Group"
|
||||||
|
@ -24,7 +24,7 @@ class TestOpportunity(unittest.TestCase):
|
|||||||
quotation.submit()
|
quotation.submit()
|
||||||
|
|
||||||
doc = frappe.get_doc('Opportunity', doc.name)
|
doc = frappe.get_doc('Opportunity', doc.name)
|
||||||
self.assertEquals(doc.status, "Quotation")
|
self.assertEqual(doc.status, "Quotation")
|
||||||
|
|
||||||
def test_make_new_lead_if_required(self):
|
def test_make_new_lead_if_required(self):
|
||||||
args = {
|
args = {
|
||||||
@ -38,8 +38,8 @@ class TestOpportunity(unittest.TestCase):
|
|||||||
opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
|
opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
|
||||||
|
|
||||||
self.assertTrue(opp_doc.lead)
|
self.assertTrue(opp_doc.lead)
|
||||||
self.assertEquals(opp_doc.enquiry_from, "Lead")
|
self.assertEqual(opp_doc.enquiry_from, "Lead")
|
||||||
self.assertEquals(frappe.db.get_value("Lead", opp_doc.lead, "email_id"),
|
self.assertEqual(frappe.db.get_value("Lead", opp_doc.lead, "email_id"),
|
||||||
'new.opportunity@example.com')
|
'new.opportunity@example.com')
|
||||||
|
|
||||||
# create new customer and create new contact against 'new.opportunity@example.com'
|
# create new customer and create new contact against 'new.opportunity@example.com'
|
||||||
@ -56,8 +56,8 @@ class TestOpportunity(unittest.TestCase):
|
|||||||
|
|
||||||
opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
|
opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
|
||||||
self.assertTrue(opp_doc.customer)
|
self.assertTrue(opp_doc.customer)
|
||||||
self.assertEquals(opp_doc.enquiry_from, "Customer")
|
self.assertEqual(opp_doc.enquiry_from, "Customer")
|
||||||
self.assertEquals(opp_doc.customer, customer.name)
|
self.assertEqual(opp_doc.customer, customer.name)
|
||||||
|
|
||||||
def make_opportunity(**args):
|
def make_opportunity(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
@ -63,7 +63,7 @@ def simulate(domain='Manufacturing', days=100):
|
|||||||
# runs_for = 100
|
# runs_for = 100
|
||||||
|
|
||||||
fixed_asset.work()
|
fixed_asset.work()
|
||||||
for i in xrange(runs_for):
|
for i in range(runs_for):
|
||||||
sys.stdout.write("\rSimulating {0}: Day {1}".format(
|
sys.stdout.write("\rSimulating {0}: Day {1}".format(
|
||||||
current_date.strftime("%Y-%m-%d"), i))
|
current_date.strftime("%Y-%m-%d"), i))
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
@ -65,7 +65,7 @@ def make_appointment():
|
|||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
def make_consulation():
|
def make_consulation():
|
||||||
for i in xrange(3):
|
for i in range(3):
|
||||||
physician = get_random("Physician")
|
physician = get_random("Physician")
|
||||||
department = frappe.get_value("Physician", physician, "department")
|
department = frappe.get_value("Physician", physician, "department")
|
||||||
patient = get_random("Patient")
|
patient = get_random("Patient")
|
||||||
@ -74,7 +74,7 @@ def make_consulation():
|
|||||||
consultation.save(ignore_permissions=True)
|
consultation.save(ignore_permissions=True)
|
||||||
|
|
||||||
def consulation_on_appointment():
|
def consulation_on_appointment():
|
||||||
for i in xrange(3):
|
for i in range(3):
|
||||||
appointment = get_random("Patient Appointment")
|
appointment = get_random("Patient Appointment")
|
||||||
appointment = frappe.get_doc("Patient Appointment",appointment)
|
appointment = frappe.get_doc("Patient Appointment",appointment)
|
||||||
consultation = set_consultation(appointment.patient, appointment.patient_sex, appointment.physician, appointment.department, appointment.appointment_date, i)
|
consultation = set_consultation(appointment.patient, appointment.patient_sex, appointment.physician, appointment.department, appointment.appointment_date, i)
|
||||||
|
@ -80,7 +80,7 @@ def setup_demo_page():
|
|||||||
|
|
||||||
def setup_fiscal_year():
|
def setup_fiscal_year():
|
||||||
fiscal_year = None
|
fiscal_year = None
|
||||||
for year in xrange(2010, now_datetime().year + 1, 1):
|
for year in range(2010, now_datetime().year + 1, 1):
|
||||||
try:
|
try:
|
||||||
fiscal_year = frappe.get_doc({
|
fiscal_year = frappe.get_doc({
|
||||||
"doctype": "Fiscal Year",
|
"doctype": "Fiscal Year",
|
||||||
|
@ -15,7 +15,7 @@ from erpnext.education.api import get_student_group_students, make_attendance_re
|
|||||||
|
|
||||||
def work():
|
def work():
|
||||||
frappe.set_user(frappe.db.get_global('demo_education_user'))
|
frappe.set_user(frappe.db.get_global('demo_education_user'))
|
||||||
for d in xrange(20):
|
for d in range(20):
|
||||||
approve_random_student_applicant()
|
approve_random_student_applicant()
|
||||||
enroll_random_student(frappe.flags.current_date)
|
enroll_random_student(frappe.flags.current_date)
|
||||||
# if frappe.flags.current_date.weekday()== 0:
|
# if frappe.flags.current_date.weekday()== 0:
|
||||||
@ -94,7 +94,7 @@ def make_course_schedule(start_date, end_date):
|
|||||||
cs.course_start_date = cstr(start_date)
|
cs.course_start_date = cstr(start_date)
|
||||||
cs.course_end_date = cstr(end_date)
|
cs.course_end_date = cstr(end_date)
|
||||||
day = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
day = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
||||||
for x in xrange(3):
|
for x in range(3):
|
||||||
random_day = random.choice(day)
|
random_day = random.choice(day)
|
||||||
cs.day = random_day
|
cs.day = random_day
|
||||||
cs.from_time = timedelta(hours=(random.randrange(7, 17,1)))
|
cs.from_time = timedelta(hours=(random.randrange(7, 17,1)))
|
||||||
|
@ -116,7 +116,7 @@ def make_material_request(item_code, qty):
|
|||||||
return mr
|
return mr
|
||||||
|
|
||||||
def add_suppliers(rfq):
|
def add_suppliers(rfq):
|
||||||
for i in xrange(2):
|
for i in range(2):
|
||||||
supplier = get_random("Supplier")
|
supplier = get_random("Supplier")
|
||||||
if supplier not in [d.supplier for d in rfq.get('suppliers')]:
|
if supplier not in [d.supplier for d in rfq.get('suppliers')]:
|
||||||
rfq.append("suppliers", { "supplier": supplier })
|
rfq.append("suppliers", { "supplier": supplier })
|
||||||
|
@ -13,27 +13,27 @@ from erpnext.accounts.doctype.payment_request.payment_request import make_paymen
|
|||||||
def work():
|
def work():
|
||||||
frappe.set_user(frappe.db.get_global('demo_sales_user_2'))
|
frappe.set_user(frappe.db.get_global('demo_sales_user_2'))
|
||||||
if random.random() < 0.5:
|
if random.random() < 0.5:
|
||||||
for i in xrange(random.randint(1,7)):
|
for i in range(random.randint(1,7)):
|
||||||
make_opportunity()
|
make_opportunity()
|
||||||
|
|
||||||
if random.random() < 0.5:
|
if random.random() < 0.5:
|
||||||
for i in xrange(random.randint(1,3)):
|
for i in range(random.randint(1,3)):
|
||||||
make_quotation()
|
make_quotation()
|
||||||
|
|
||||||
# lost quotations / inquiries
|
# lost quotations / inquiries
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.3:
|
||||||
for i in xrange(random.randint(1,3)):
|
for i in range(random.randint(1,3)):
|
||||||
quotation = get_random('Quotation', doc=True)
|
quotation = get_random('Quotation', doc=True)
|
||||||
if quotation and quotation.status == 'Submitted':
|
if quotation and quotation.status == 'Submitted':
|
||||||
quotation.declare_order_lost('Did not ask')
|
quotation.declare_order_lost('Did not ask')
|
||||||
|
|
||||||
for i in xrange(random.randint(1,3)):
|
for i in range(random.randint(1,3)):
|
||||||
opportunity = get_random('Opportunity', doc=True)
|
opportunity = get_random('Opportunity', doc=True)
|
||||||
if opportunity and opportunity.status in ('Open', 'Replied'):
|
if opportunity and opportunity.status in ('Open', 'Replied'):
|
||||||
opportunity.declare_enquiry_lost('Did not ask')
|
opportunity.declare_enquiry_lost('Did not ask')
|
||||||
|
|
||||||
if random.random() < 0.3:
|
if random.random() < 0.3:
|
||||||
for i in xrange(random.randint(1,3)):
|
for i in range(random.randint(1,3)):
|
||||||
make_sales_order()
|
make_sales_order()
|
||||||
|
|
||||||
if random.random() < 0.1:
|
if random.random() < 0.1:
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
erpnext/docs/assets/img/setup/integrations/gocardless_coa.png
Normal file
BIN
erpnext/docs/assets/img/setup/integrations/gocardless_coa.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
@ -0,0 +1,44 @@
|
|||||||
|
# Setting up GoCardless
|
||||||
|
|
||||||
|
To setup GoCardless, go to `Explore > Integrations > GoCardless Settings`
|
||||||
|
|
||||||
|
## Setup GoCardless
|
||||||
|
|
||||||
|
To enable GoCardless in your ERPNext account, you need to configure the following parameters and Access Token and optionally (but highly recommended), a Webhooks Secret key.
|
||||||
|
|
||||||
|
|
||||||
|
You can setup several GoCardless payment gateways if needed. The choice of payment gateway account will determine which GoCardless account is used for the payment.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
On enabling service, the system will create a Payment Gateway record and an Account head in chart of account with account type as Bank.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
It will also create a payment gateway account. You can change the default bank account if needed and create a template for the payment request.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
After configuring the Payment Gateway Account, your system is able to accept online payments through GoCardless.
|
||||||
|
|
||||||
|
## SEPA Payments Flow
|
||||||
|
|
||||||
|
When a new payment SEPA payment in initiated, the customer is asked to enter his IBAN (or local account number) and to validate a SEPA mandate.
|
||||||
|
|
||||||
|
Upon validation of the mandate, a payment request is sent to GoCardless and processed.
|
||||||
|
|
||||||
|
If the customer has already a valid SEPA mandate, when instead of sending a payment request to the customer, the payment request is directly sent to GoCardless without the need for the customer to validate it.
|
||||||
|
The customer will only receive a confirmation email from GoCardless informing him that a payment has been processed.
|
||||||
|
|
||||||
|
|
||||||
|
## Mandate cancellation
|
||||||
|
|
||||||
|
You can setup a Webhook in GoCardless to automatically disabled cancelled or expired mandates in ERPNext.
|
||||||
|
|
||||||
|
The Endpoint URL of your webhook should be: https://yoursite.com/api/method/erpnext.erpnext_integrations.doctype.gocardless_settings.webhooks
|
||||||
|
|
||||||
|
In this case do not forget to configure your Webhooks Secret Key in your GoCardless account settings in ERPNext.
|
||||||
|
|
||||||
|
|
||||||
|
## Supported transaction currencies
|
||||||
|
"EUR", "DKK", "GBP", "SEK"
|
@ -12,8 +12,8 @@ from erpnext.education.api import get_grade
|
|||||||
class TestAssessmentResult(unittest.TestCase):
|
class TestAssessmentResult(unittest.TestCase):
|
||||||
def test_grade(self):
|
def test_grade(self):
|
||||||
grade = get_grade("_Test Grading Scale", 80)
|
grade = get_grade("_Test Grading Scale", 80)
|
||||||
self.assertEquals("A", grade)
|
self.assertEqual("A", grade)
|
||||||
|
|
||||||
grade = get_grade("_Test Grading Scale", 70)
|
grade = get_grade("_Test Grading Scale", 70)
|
||||||
self.assertEquals("B", grade)
|
self.assertEqual("B", grade)
|
||||||
|
|
@ -42,12 +42,12 @@ class TestFees(unittest.TestCase):
|
|||||||
from `tabGL Entry` where voucher_type=%s and voucher_no=%s""", ("Fees", fee.name), as_dict=True)
|
from `tabGL Entry` where voucher_type=%s and voucher_no=%s""", ("Fees", fee.name), as_dict=True)
|
||||||
|
|
||||||
if gl_entries[0].account == "_Test Receivable - _TC":
|
if gl_entries[0].account == "_Test Receivable - _TC":
|
||||||
self.assertEquals(gl_entries[0].debit, 50000)
|
self.assertEqual(gl_entries[0].debit, 50000)
|
||||||
self.assertEquals(gl_entries[0].credit, 0)
|
self.assertEqual(gl_entries[0].credit, 0)
|
||||||
self.assertEquals(gl_entries[1].debit, 0)
|
self.assertEqual(gl_entries[1].debit, 0)
|
||||||
self.assertEquals(gl_entries[1].credit, 50000)
|
self.assertEqual(gl_entries[1].credit, 50000)
|
||||||
else:
|
else:
|
||||||
self.assertEquals(gl_entries[0].credit, 50000)
|
self.assertEqual(gl_entries[0].credit, 50000)
|
||||||
self.assertEquals(gl_entries[0].debit, 0)
|
self.assertEqual(gl_entries[0].debit, 0)
|
||||||
self.assertEquals(gl_entries[1].credit, 0)
|
self.assertEqual(gl_entries[1].credit, 0)
|
||||||
self.assertEquals(gl_entries[1].debit, 50000)
|
self.assertEqual(gl_entries[1].debit, 50000)
|
||||||
|
@ -23,5 +23,5 @@ class TestStudentGroup(unittest.TestCase):
|
|||||||
|
|
||||||
doc.extend("students", [{"student":d} for d in student_list])
|
doc.extend("students", [{"student":d} for d in student_list])
|
||||||
doc.save()
|
doc.save()
|
||||||
self.assertEquals(max([d.group_roll_number for d in doc.students]), 3)
|
self.assertEqual(max([d.group_roll_number for d in doc.students]), 3)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ def execute(filters=None):
|
|||||||
student_guardians = guardian_map.get(d.student)
|
student_guardians = guardian_map.get(d.student)
|
||||||
|
|
||||||
if student_guardians:
|
if student_guardians:
|
||||||
for i in xrange(2):
|
for i in range(2):
|
||||||
if i < len(student_guardians):
|
if i < len(student_guardians):
|
||||||
g = student_guardians[i]
|
g = student_guardians[i]
|
||||||
row += [g.guardian_name, g.relation, g.mobile_number, g.email_address]
|
row += [g.guardian_name, g.relation, g.mobile_number, g.email_address]
|
||||||
|
0
erpnext/erpnext_integrations/doctype/__init__.py
Normal file
0
erpnext/erpnext_integrations/doctype/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('GoCardless Mandate', {
|
||||||
|
});
|
@ -0,0 +1,184 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"autoname": "field:mandate",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-02-08 11:33:15.721919",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "disabled",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"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": "Disabled",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "customer",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Customer",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Customer",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "mandate",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"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": "Mandate",
|
||||||
|
"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": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "gocardless_customer",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "GoCardless Customer",
|
||||||
|
"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": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-02-11 12:28:03.183095",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "ERPNext Integrations",
|
||||||
|
"name": "GoCardless Mandate",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class GoCardlessMandate(Document):
|
||||||
|
pass
|
@ -0,0 +1,23 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
|
// and remove above this line
|
||||||
|
|
||||||
|
QUnit.test("test: GoCardless Mandate", function (assert) {
|
||||||
|
let done = assert.async();
|
||||||
|
|
||||||
|
// number of asserts
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
frappe.run_serially([
|
||||||
|
// insert a new GoCardless Mandate
|
||||||
|
() => frappe.tests.make('GoCardless Mandate', [
|
||||||
|
// values to be set
|
||||||
|
{key: 'value'}
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestGoCardlessMandate(unittest.TestCase):
|
||||||
|
pass
|
@ -0,0 +1,70 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
import json
|
||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
def webhooks():
|
||||||
|
r = frappe.request
|
||||||
|
if not r:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not authenticate_signature(r):
|
||||||
|
raise frappe.AuthenticationError
|
||||||
|
|
||||||
|
gocardless_events = json.loads(r.get_data()) or []
|
||||||
|
for event in gocardless_events["events"]:
|
||||||
|
set_status(event)
|
||||||
|
|
||||||
|
return 200
|
||||||
|
def set_status(event):
|
||||||
|
resource_type = event.get("resource_type", {})
|
||||||
|
|
||||||
|
if resource_type == "mandates":
|
||||||
|
set_mandate_status(event)
|
||||||
|
|
||||||
|
def set_mandate_status(event):
|
||||||
|
mandates = []
|
||||||
|
if isinstance(event["links"], (list,)):
|
||||||
|
for link in event["links"]:
|
||||||
|
mandates.append(link["mandate"])
|
||||||
|
else:
|
||||||
|
mandates.append(event["links"]["mandate"])
|
||||||
|
|
||||||
|
if event["action"] == "pending_customer_approval" or event["action"] == "pending_submission" or event["action"] == "submitted" or event["action"] == "active":
|
||||||
|
disabled = 0
|
||||||
|
else:
|
||||||
|
disabled = 1
|
||||||
|
|
||||||
|
for mandate in mandates:
|
||||||
|
frappe.db.set_value("GoCardless Mandate", mandate, "disabled", disabled)
|
||||||
|
|
||||||
|
def authenticate_signature(r):
|
||||||
|
"""Returns True if the received signature matches the generated signature"""
|
||||||
|
received_signature = frappe.get_request_header("Webhook-Signature")
|
||||||
|
|
||||||
|
if not received_signature:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for key in get_webhook_keys():
|
||||||
|
computed_signature = hmac.new(key.encode("utf-8"), r.get_data(), hashlib.sha256).hexdigest()
|
||||||
|
if hmac.compare_digest(str(received_signature), computed_signature):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_webhook_keys():
|
||||||
|
def _get_webhook_keys():
|
||||||
|
webhook_keys = [d.webhooks_secret for d in frappe.get_all("GoCardless Settings", fields=["webhooks_secret"],) if d.webhooks_secret]
|
||||||
|
|
||||||
|
return webhook_keys
|
||||||
|
|
||||||
|
return frappe.cache().get_value("gocardless_webhooks_secret", _get_webhook_keys)
|
||||||
|
|
||||||
|
def clear_cache():
|
||||||
|
frappe.cache().delete_value("gocardless_webhooks_secret")
|
@ -0,0 +1,5 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('GoCardless Settings', {
|
||||||
|
});
|
@ -0,0 +1,212 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"autoname": "field:gateway_name",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-02-06 16:11:10.028249",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "gateway_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Gateway Name",
|
||||||
|
"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": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "section_break_2",
|
||||||
|
"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,
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "access_token",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Access Token",
|
||||||
|
"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": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "webhooks_secret",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"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": "Webhooks Secret",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "use_sandbox",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"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": "Use Sandbox",
|
||||||
|
"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,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-02-12 14:18:47.209114",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "ERPNext Integrations",
|
||||||
|
"name": "GoCardless Settings",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"apply_user_permissions": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
import gocardless_pro
|
||||||
|
from frappe import _
|
||||||
|
from six.moves.urllib.parse import urlencode
|
||||||
|
from frappe.utils import get_url, call_hook_method, flt, cint
|
||||||
|
from frappe.integrations.utils import create_request_log, create_payment_gateway
|
||||||
|
|
||||||
|
class GoCardlessSettings(Document):
|
||||||
|
supported_currencies = ["EUR", "DKK", "GBP", "SEK"]
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.initialize_client()
|
||||||
|
|
||||||
|
def initialize_client(self):
|
||||||
|
self.environment = self.get_environment()
|
||||||
|
try:
|
||||||
|
self.client = gocardless_pro.Client(
|
||||||
|
access_token=self.access_token,
|
||||||
|
environment=self.environment
|
||||||
|
)
|
||||||
|
return self.client
|
||||||
|
except Exception as e:
|
||||||
|
frappe.throw(e)
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
create_payment_gateway('GoCardless-' + self.gateway_name, settings='GoCardLess Settings', controller=self.gateway_name)
|
||||||
|
call_hook_method('payment_gateway_enabled', gateway='GoCardless-' + self.gateway_name)
|
||||||
|
|
||||||
|
def on_payment_request_submission(self, data):
|
||||||
|
if data.reference_doctype != "Fees":
|
||||||
|
customer_data = frappe.db.get_value(data.reference_doctype, data.reference_name, ["company", "customer_name"], as_dict=1)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"amount": flt(data.grand_total, data.precision("grand_total")),
|
||||||
|
"title": customer_data.company.encode("utf-8"),
|
||||||
|
"description": data.subject.encode("utf-8"),
|
||||||
|
"reference_doctype": data.doctype,
|
||||||
|
"reference_docname": data.name,
|
||||||
|
"payer_email": data.email_to or frappe.session.user,
|
||||||
|
"payer_name": customer_data.customer_name,
|
||||||
|
"order_id": data.name,
|
||||||
|
"currency": data.currency
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_mandate = self.check_mandate_validity(data)
|
||||||
|
if valid_mandate is not None:
|
||||||
|
data.update(valid_mandate)
|
||||||
|
|
||||||
|
self.create_payment_request(data)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def check_mandate_validity(self, data):
|
||||||
|
|
||||||
|
if frappe.db.exists("GoCardless Mandate", dict(customer=data.get('payer_name'), disabled=0)):
|
||||||
|
registered_mandate = frappe.db.get_value("GoCardless Mandate", dict(customer=data.get('payer_name'), disabled=0), 'mandate')
|
||||||
|
self.initialize_client()
|
||||||
|
mandate = self.client.mandates.get(registered_mandate)
|
||||||
|
|
||||||
|
if mandate.status=="pending_customer_approval" or mandate.status=="pending_submission" or mandate.status=="submitted" or mandate.status=="active":
|
||||||
|
return {"mandate": registered_mandate}
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_environment(self):
|
||||||
|
if self.use_sandbox:
|
||||||
|
return 'sandbox'
|
||||||
|
else:
|
||||||
|
return 'live'
|
||||||
|
|
||||||
|
def validate_transaction_currency(self, currency):
|
||||||
|
if currency not in self.supported_currencies:
|
||||||
|
frappe.throw(_("Please select another payment method. Stripe does not support transactions in currency '{0}'").format(currency))
|
||||||
|
|
||||||
|
def get_payment_url(self, **kwargs):
|
||||||
|
return get_url("./integrations/gocardless_checkout?{0}".format(urlencode(kwargs)))
|
||||||
|
|
||||||
|
def create_payment_request(self, data):
|
||||||
|
self.data = frappe._dict(data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.integration_request = create_request_log(self.data, "Host", "GoCardless")
|
||||||
|
return self.create_charge_on_gocardless()
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
frappe.log_error(frappe.get_traceback())
|
||||||
|
return{
|
||||||
|
"redirect_to": frappe.redirect_to_message(_('Server Error'), _("There seems to be an issue with the server's GoCardless configuration. Don't worry, in case of failure, the amount will get refunded to your account.")),
|
||||||
|
"status": 401
|
||||||
|
}
|
||||||
|
|
||||||
|
def create_charge_on_gocardless(self):
|
||||||
|
redirect_to = self.data.get('redirect_to') or None
|
||||||
|
redirect_message = self.data.get('redirect_message') or None
|
||||||
|
|
||||||
|
reference_doc = frappe.get_doc(self.data.get('reference_doctype'), self.data.get('reference_docname'))
|
||||||
|
self.initialize_client()
|
||||||
|
|
||||||
|
try:
|
||||||
|
payment = self.client.payments.create(
|
||||||
|
params={
|
||||||
|
"amount" : cint(reference_doc.grand_total * 100),
|
||||||
|
"currency" : reference_doc.currency,
|
||||||
|
"links" : {
|
||||||
|
"mandate": self.data.get('mandate')
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"reference_doctype": reference_doc.doctype,
|
||||||
|
"reference_document": reference_doc.name
|
||||||
|
}
|
||||||
|
}, headers={
|
||||||
|
'Idempotency-Key' : self.data.get('reference_docname'),
|
||||||
|
})
|
||||||
|
|
||||||
|
if payment.status=="pending_submission" or payment.status=="pending_customer_approval" or payment.status=="submitted":
|
||||||
|
self.integration_request.db_set('status', 'Authorized', update_modified=False)
|
||||||
|
self.flags.status_changed_to = "Completed"
|
||||||
|
self.integration_request.db_set('output', payment.status, update_modified=False)
|
||||||
|
|
||||||
|
elif payment.status=="confirmed" or payment.status=="paid_out":
|
||||||
|
self.integration_request.db_set('status', 'Completed', update_modified=False)
|
||||||
|
self.flags.status_changed_to = "Completed"
|
||||||
|
self.integration_request.db_set('output', payment.status, update_modified=False)
|
||||||
|
|
||||||
|
elif payment.status=="cancelled" or payment.status=="customer_approval_denied" or payment.status=="charged_back":
|
||||||
|
self.integration_request.db_set('status', 'Cancelled', update_modified=False)
|
||||||
|
frappe.log_error(_("Payment Cancelled. Please check your GoCardless Account for more details"), "GoCardless Payment Error")
|
||||||
|
self.integration_request.db_set('error', payment.status, update_modified=False)
|
||||||
|
else:
|
||||||
|
self.integration_request.db_set('status', 'Failed', update_modified=False)
|
||||||
|
frappe.log_error(_("Payment Failed. Please check your GoCardless Account for more details"), "GoCardless Payment Error")
|
||||||
|
self.integration_request.db_set('error', payment.status, update_modified=False)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
frappe.log_error(e, "GoCardless Payment Error")
|
||||||
|
|
||||||
|
if self.flags.status_changed_to == "Completed":
|
||||||
|
status = 'Completed'
|
||||||
|
if self.data.reference_doctype and self.data.reference_docname:
|
||||||
|
custom_redirect_to = None
|
||||||
|
try:
|
||||||
|
custom_redirect_to = frappe.get_doc(self.data.reference_doctype,
|
||||||
|
self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to)
|
||||||
|
except Exception:
|
||||||
|
frappe.log_error(frappe.get_traceback())
|
||||||
|
|
||||||
|
if custom_redirect_to:
|
||||||
|
redirect_to = custom_redirect_to
|
||||||
|
|
||||||
|
redirect_url = redirect_to
|
||||||
|
else:
|
||||||
|
status = 'Error'
|
||||||
|
redirect_url = 'payment-failed'
|
||||||
|
|
||||||
|
if redirect_message:
|
||||||
|
redirect_url += '&' + urlencode({'redirect_message': redirect_message})
|
||||||
|
|
||||||
|
redirect_url = get_url(redirect_url)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"redirect_to": redirect_url,
|
||||||
|
"status": status
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_gateway_controller(doc):
|
||||||
|
payment_request = frappe.get_doc("Payment Request", doc)
|
||||||
|
gateway_controller = frappe.db.get_value("Payment Gateway", payment_request.payment_gateway, "gateway_controller")
|
||||||
|
return gateway_controller
|
||||||
|
|
||||||
|
def gocardless_initialization(doc):
|
||||||
|
gateway_controller = get_gateway_controller(doc)
|
||||||
|
settings = frappe.get_doc("GoCardless Settings", gateway_controller)
|
||||||
|
client = settings.initialize_client()
|
||||||
|
return client
|
@ -0,0 +1,23 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
|
// and remove above this line
|
||||||
|
|
||||||
|
QUnit.test("test: GoCardless Settings", function (assert) {
|
||||||
|
let done = assert.async();
|
||||||
|
|
||||||
|
// number of asserts
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
frappe.run_serially([
|
||||||
|
// insert a new GoCardless Settings
|
||||||
|
() => frappe.tests.make('GoCardless Settings', [
|
||||||
|
// values to be set
|
||||||
|
{key: 'value'}
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestGoCardlessSettings(unittest.TestCase):
|
||||||
|
pass
|
@ -11,7 +11,7 @@ app_email = "info@erpnext.com"
|
|||||||
app_license = "GNU General Public License (v3)"
|
app_license = "GNU General Public License (v3)"
|
||||||
source_link = "https://github.com/frappe/erpnext"
|
source_link = "https://github.com/frappe/erpnext"
|
||||||
|
|
||||||
develop_version = '10.x.x-develop'
|
develop_version = '11.x.x-develop'
|
||||||
|
|
||||||
error_report_email = "support@erpnext.com"
|
error_report_email = "support@erpnext.com"
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class HotelRoomReservation(Document):
|
|||||||
self.validate_availability()
|
self.validate_availability()
|
||||||
|
|
||||||
def validate_availability(self):
|
def validate_availability(self):
|
||||||
for i in xrange(date_diff(self.to_date, self.from_date)):
|
for i in range(date_diff(self.to_date, self.from_date)):
|
||||||
day = add_days(self.from_date, i)
|
day = add_days(self.from_date, i)
|
||||||
self.rooms_booked = {}
|
self.rooms_booked = {}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ class HotelRoomReservation(Document):
|
|||||||
self.net_total = 0
|
self.net_total = 0
|
||||||
for d in self.items:
|
for d in self.items:
|
||||||
net_rate = 0.0
|
net_rate = 0.0
|
||||||
for i in xrange(date_diff(self.to_date, self.from_date)):
|
for i in range(date_diff(self.to_date, self.from_date)):
|
||||||
day = add_days(self.from_date, i)
|
day = add_days(self.from_date, i)
|
||||||
if not d.item:
|
if not d.item:
|
||||||
continue
|
continue
|
||||||
|
@ -24,7 +24,7 @@ def get_data(filters):
|
|||||||
out = []
|
out = []
|
||||||
for room_type in frappe.get_all('Hotel Room Type'):
|
for room_type in frappe.get_all('Hotel Room Type'):
|
||||||
total_booked = 0
|
total_booked = 0
|
||||||
for i in xrange(date_diff(filters.to_date, filters.from_date)):
|
for i in range(date_diff(filters.to_date, filters.from_date)):
|
||||||
day = add_days(filters.from_date, i)
|
day = add_days(filters.from_date, i)
|
||||||
total_booked += get_rooms_booked(room_type.name, day)
|
total_booked += get_rooms_booked(room_type.name, day)
|
||||||
|
|
||||||
|
@ -32,6 +32,19 @@ frappe.ui.form.on('Employee Advance', {
|
|||||||
frm.add_custom_button(__('Payment'),
|
frm.add_custom_button(__('Payment'),
|
||||||
function() { frm.events.make_payment_entry(frm); }, __("Make"));
|
function() { frm.events.make_payment_entry(frm); }, __("Make"));
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
frm.doc.docstatus === 1
|
||||||
|
&& flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount)
|
||||||
|
&& frappe.model.can_create("Expense Claim")
|
||||||
|
) {
|
||||||
|
frm.add_custom_button(
|
||||||
|
__("Expense Claim"),
|
||||||
|
function() {
|
||||||
|
frm.events.make_expense_claim(frm);
|
||||||
|
},
|
||||||
|
__("Make")
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
make_payment_entry: function(frm) {
|
make_payment_entry: function(frm) {
|
||||||
@ -51,4 +64,22 @@ frappe.ui.form.on('Employee Advance', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
make_expense_claim: function(frm) {
|
||||||
|
return frappe.call({
|
||||||
|
method: "erpnext.hr.doctype.expense_claim.expense_claim.get_expense_claim",
|
||||||
|
args: {
|
||||||
|
"employee_name": frm.doc.employee,
|
||||||
|
"company": frm.doc.company,
|
||||||
|
"employee_advance_name": frm.doc.name,
|
||||||
|
"posting_date": frm.doc.posting_date,
|
||||||
|
"paid_amount": frm.doc.paid_amount,
|
||||||
|
"claimed_amount": frm.doc.claimed_amount
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
const doclist = frappe.model.sync(r.message);
|
||||||
|
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -17,26 +17,26 @@ class TestEmployeeLoan(unittest.TestCase):
|
|||||||
|
|
||||||
def test_employee_loan(self):
|
def test_employee_loan(self):
|
||||||
employee_loan = frappe.get_doc("Employee Loan", {"employee":self.employee})
|
employee_loan = frappe.get_doc("Employee Loan", {"employee":self.employee})
|
||||||
self.assertEquals(employee_loan.monthly_repayment_amount, 15052)
|
self.assertEqual(employee_loan.monthly_repayment_amount, 15052)
|
||||||
self.assertEquals(employee_loan.total_interest_payable, 21034)
|
self.assertEqual(employee_loan.total_interest_payable, 21034)
|
||||||
self.assertEquals(employee_loan.total_payment, 301034)
|
self.assertEqual(employee_loan.total_payment, 301034)
|
||||||
|
|
||||||
schedule = employee_loan.repayment_schedule
|
schedule = employee_loan.repayment_schedule
|
||||||
|
|
||||||
self.assertEquals(len(schedule), 20)
|
self.assertEqual(len(schedule), 20)
|
||||||
|
|
||||||
for idx, principal_amount, interest_amount, balance_loan_amount in [[3, 13369, 1683, 227079], [19, 14941, 105, 0], [17, 14740, 312, 29785]]:
|
for idx, principal_amount, interest_amount, balance_loan_amount in [[3, 13369, 1683, 227079], [19, 14941, 105, 0], [17, 14740, 312, 29785]]:
|
||||||
self.assertEquals(schedule[idx].principal_amount, principal_amount)
|
self.assertEqual(schedule[idx].principal_amount, principal_amount)
|
||||||
self.assertEquals(schedule[idx].interest_amount, interest_amount)
|
self.assertEqual(schedule[idx].interest_amount, interest_amount)
|
||||||
self.assertEquals(schedule[idx].balance_loan_amount, balance_loan_amount)
|
self.assertEqual(schedule[idx].balance_loan_amount, balance_loan_amount)
|
||||||
|
|
||||||
employee_loan.repayment_method = "Repay Fixed Amount per Period"
|
employee_loan.repayment_method = "Repay Fixed Amount per Period"
|
||||||
employee_loan.monthly_repayment_amount = 14000
|
employee_loan.monthly_repayment_amount = 14000
|
||||||
employee_loan.save()
|
employee_loan.save()
|
||||||
|
|
||||||
self.assertEquals(len(employee_loan.repayment_schedule), 22)
|
self.assertEqual(len(employee_loan.repayment_schedule), 22)
|
||||||
self.assertEquals(employee_loan.total_interest_payable, 22712)
|
self.assertEqual(employee_loan.total_interest_payable, 22712)
|
||||||
self.assertEquals(employee_loan.total_payment, 302712)
|
self.assertEqual(employee_loan.total_payment, 302712)
|
||||||
|
|
||||||
def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
|
def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
|
||||||
if not frappe.db.exists("Loan Type", loan_name):
|
if not frappe.db.exists("Loan Type", loan_name):
|
||||||
|
@ -38,14 +38,14 @@ class TestEmployeeLoanApplication(unittest.TestCase):
|
|||||||
|
|
||||||
def test_loan_totals(self):
|
def test_loan_totals(self):
|
||||||
loan_application = frappe.get_doc("Employee Loan Application", {"employee":self.employee})
|
loan_application = frappe.get_doc("Employee Loan Application", {"employee":self.employee})
|
||||||
self.assertEquals(loan_application.repayment_amount, 11445)
|
self.assertEqual(loan_application.repayment_amount, 11445)
|
||||||
self.assertEquals(loan_application.total_payable_interest, 24657)
|
self.assertEqual(loan_application.total_payable_interest, 24657)
|
||||||
self.assertEquals(loan_application.total_payable_amount, 274657)
|
self.assertEqual(loan_application.total_payable_amount, 274657)
|
||||||
|
|
||||||
loan_application.repayment_method = "Repay Fixed Amount per Period"
|
loan_application.repayment_method = "Repay Fixed Amount per Period"
|
||||||
loan_application.repayment_amount = 15000
|
loan_application.repayment_amount = 15000
|
||||||
loan_application.save()
|
loan_application.save()
|
||||||
|
|
||||||
self.assertEquals(loan_application.repayment_periods, 18)
|
self.assertEqual(loan_application.repayment_periods, 18)
|
||||||
self.assertEquals(loan_application.total_payable_interest, 18506)
|
self.assertEqual(loan_application.total_payable_interest, 18506)
|
||||||
self.assertEquals(loan_application.total_payable_amount, 268506)
|
self.assertEqual(loan_application.total_payable_amount, 268506)
|
@ -297,4 +297,30 @@ def get_advances(employee, advance_id=None):
|
|||||||
from
|
from
|
||||||
`tabEmployee Advance`
|
`tabEmployee Advance`
|
||||||
where {0}
|
where {0}
|
||||||
""".format(condition), as_dict=1)
|
""".format(condition), as_dict=1)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_expense_claim(
|
||||||
|
employee_name, company, employee_advance_name, posting_date, paid_amount, claimed_amount):
|
||||||
|
default_payable_account = frappe.db.get_value("Company", company, "default_payable_account")
|
||||||
|
default_cost_center = frappe.db.get_value('Company', company, 'cost_center')
|
||||||
|
|
||||||
|
expense_claim = frappe.new_doc('Expense Claim')
|
||||||
|
expense_claim.company = company
|
||||||
|
expense_claim.employee = employee_name
|
||||||
|
expense_claim.payable_account = default_payable_account
|
||||||
|
expense_claim.cost_center = default_cost_center
|
||||||
|
expense_claim.is_paid = 1 if flt(paid_amount) else 0
|
||||||
|
expense_claim.append(
|
||||||
|
'advances',
|
||||||
|
{
|
||||||
|
'employee_advance': employee_advance_name,
|
||||||
|
'posting_date': posting_date,
|
||||||
|
'advance_paid': flt(paid_amount),
|
||||||
|
'unclaimed_amount': flt(paid_amount) - flt(claimed_amount),
|
||||||
|
'allocated_amount': flt(paid_amount) - flt(claimed_amount)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return expense_claim
|
||||||
|
@ -77,9 +77,9 @@ class TestExpenseClaim(unittest.TestCase):
|
|||||||
])
|
])
|
||||||
|
|
||||||
for gle in gl_entries:
|
for gle in gl_entries:
|
||||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
def get_payable_account(company):
|
def get_payable_account(company):
|
||||||
return frappe.db.get_value('Company', company, 'default_payable_account')
|
return frappe.db.get_value('Company', company, 'default_payable_account')
|
||||||
|
@ -23,7 +23,7 @@ class TestLeaveBlockList(unittest.TestCase):
|
|||||||
frappe.set_user("test1@example.com")
|
frappe.set_user("test1@example.com")
|
||||||
frappe.db.set_value("Department", "_Test Department 1", "leave_block_list",
|
frappe.db.set_value("Department", "_Test Department 1", "leave_block_list",
|
||||||
"_Test Leave Block List")
|
"_Test Leave Block List")
|
||||||
self.assertEquals([], [d.block_date for d in get_applicable_block_dates("2013-01-01", "2013-01-03")])
|
self.assertEqual([], [d.block_date for d in get_applicable_block_dates("2013-01-01", "2013-01-03")])
|
||||||
|
|
||||||
def test_get_applicable_block_dates_all_lists(self):
|
def test_get_applicable_block_dates_all_lists(self):
|
||||||
frappe.set_user("test1@example.com")
|
frappe.set_user("test1@example.com")
|
||||||
|
@ -37,14 +37,14 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
ss = frappe.get_doc("Salary Slip",
|
ss = frappe.get_doc("Salary Slip",
|
||||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||||
|
|
||||||
self.assertEquals(ss.total_working_days, no_of_days[0])
|
self.assertEqual(ss.total_working_days, no_of_days[0])
|
||||||
self.assertEquals(ss.payment_days, no_of_days[0])
|
self.assertEqual(ss.payment_days, no_of_days[0])
|
||||||
self.assertEquals(ss.earnings[0].amount, 25000)
|
self.assertEqual(ss.earnings[0].amount, 25000)
|
||||||
self.assertEquals(ss.earnings[1].amount, 3000)
|
self.assertEqual(ss.earnings[1].amount, 3000)
|
||||||
self.assertEquals(ss.deductions[0].amount, 5000)
|
self.assertEqual(ss.deductions[0].amount, 5000)
|
||||||
self.assertEquals(ss.deductions[1].amount, 5000)
|
self.assertEqual(ss.deductions[1].amount, 5000)
|
||||||
self.assertEquals(ss.gross_pay, 40500)
|
self.assertEqual(ss.gross_pay, 40500)
|
||||||
self.assertEquals(ss.net_pay, 29918)
|
self.assertEqual(ss.net_pay, 29918)
|
||||||
|
|
||||||
def test_salary_slip_with_holidays_excluded(self):
|
def test_salary_slip_with_holidays_excluded(self):
|
||||||
no_of_days = self.get_no_of_days()
|
no_of_days = self.get_no_of_days()
|
||||||
@ -55,15 +55,15 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
ss = frappe.get_doc("Salary Slip",
|
ss = frappe.get_doc("Salary Slip",
|
||||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||||
|
|
||||||
self.assertEquals(ss.total_working_days, no_of_days[0] - no_of_days[1])
|
self.assertEqual(ss.total_working_days, no_of_days[0] - no_of_days[1])
|
||||||
self.assertEquals(ss.payment_days, no_of_days[0] - no_of_days[1])
|
self.assertEqual(ss.payment_days, no_of_days[0] - no_of_days[1])
|
||||||
self.assertEquals(ss.earnings[0].amount, 25000)
|
self.assertEqual(ss.earnings[0].amount, 25000)
|
||||||
self.assertEquals(ss.earnings[0].default_amount, 25000)
|
self.assertEqual(ss.earnings[0].default_amount, 25000)
|
||||||
self.assertEquals(ss.earnings[1].amount, 3000)
|
self.assertEqual(ss.earnings[1].amount, 3000)
|
||||||
self.assertEquals(ss.deductions[0].amount, 5000)
|
self.assertEqual(ss.deductions[0].amount, 5000)
|
||||||
self.assertEquals(ss.deductions[1].amount, 5000)
|
self.assertEqual(ss.deductions[1].amount, 5000)
|
||||||
self.assertEquals(ss.gross_pay, 40500)
|
self.assertEqual(ss.gross_pay, 40500)
|
||||||
self.assertEquals(ss.net_pay, 29918)
|
self.assertEqual(ss.net_pay, 29918)
|
||||||
|
|
||||||
def test_payment_days(self):
|
def test_payment_days(self):
|
||||||
no_of_days = self.get_no_of_days()
|
no_of_days = self.get_no_of_days()
|
||||||
@ -95,8 +95,8 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
ss = frappe.get_doc("Salary Slip",
|
ss = frappe.get_doc("Salary Slip",
|
||||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||||
|
|
||||||
self.assertEquals(ss.total_working_days, no_of_days[0])
|
self.assertEqual(ss.total_working_days, no_of_days[0])
|
||||||
self.assertEquals(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1))
|
self.assertEqual(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1))
|
||||||
|
|
||||||
# set relieving date in the same month
|
# set relieving date in the same month
|
||||||
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
|
||||||
@ -104,8 +104,8 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
|
||||||
ss.save()
|
ss.save()
|
||||||
|
|
||||||
self.assertEquals(ss.total_working_days, no_of_days[0])
|
self.assertEqual(ss.total_working_days, no_of_days[0])
|
||||||
self.assertEquals(ss.payment_days, getdate(relieving_date).day)
|
self.assertEqual(ss.payment_days, getdate(relieving_date).day)
|
||||||
|
|
||||||
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
|
||||||
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
|
||||||
@ -143,8 +143,8 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
ss = frappe.get_doc("Salary Slip",
|
ss = frappe.get_doc("Salary Slip",
|
||||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||||
ss.submit()
|
ss.submit()
|
||||||
self.assertEquals(ss.total_loan_repayment, 582)
|
self.assertEqual(ss.total_loan_repayment, 582)
|
||||||
self.assertEquals(ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.total_loan_repayment))))
|
self.assertEqual(ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.total_loan_repayment))))
|
||||||
|
|
||||||
def test_payroll_frequency(self):
|
def test_payroll_frequency(self):
|
||||||
fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")[0]
|
fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")[0]
|
||||||
|
@ -36,12 +36,12 @@ class TestSalaryStructure(unittest.TestCase):
|
|||||||
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee@salary.com"})
|
sal_slip = frappe.get_value("Salary Slip", {"employee_name":"test_employee@salary.com"})
|
||||||
if not sal_slip:
|
if not sal_slip:
|
||||||
sal_slip = make_salary_slip_from_salary_structure(employee=frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}))
|
sal_slip = make_salary_slip_from_salary_structure(employee=frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}))
|
||||||
self.assertEquals(sal_slip.get("salary_structure"), 'Salary Structure Sample')
|
self.assertEqual(sal_slip.get("salary_structure"), 'Salary Structure Sample')
|
||||||
self.assertEquals(sal_slip.get("earnings")[0].amount, 5000)
|
self.assertEqual(sal_slip.get("earnings")[0].amount, 5000)
|
||||||
self.assertEquals(sal_slip.get("deductions")[0].amount, 5000)
|
self.assertEqual(sal_slip.get("deductions")[0].amount, 5000)
|
||||||
self.assertEquals(sal_slip.get("deductions")[1].amount, 2500)
|
self.assertEqual(sal_slip.get("deductions")[1].amount, 2500)
|
||||||
self.assertEquals(sal_slip.get("total_deduction"), 7500)
|
self.assertEqual(sal_slip.get("total_deduction"), 7500)
|
||||||
self.assertEquals(sal_slip.get("net_pay"), 7500)
|
self.assertEqual(sal_slip.get("net_pay"), 7500)
|
||||||
|
|
||||||
def test_whitespaces_in_formula_conditions_fields(self):
|
def test_whitespaces_in_formula_conditions_fields(self):
|
||||||
make_salary_structure("Salary Structure Sample")
|
make_salary_structure("Salary Structure Sample")
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
frappe.query_reports["Employee Advance Summary"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname":"employee",
|
||||||
|
"label": __("Employee"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Employee",
|
||||||
|
"width": "80"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"from_date",
|
||||||
|
"label": __("From Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.defaults.get_user_default("year_start_date"),
|
||||||
|
"width": "80"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname":"status",
|
||||||
|
"label": __("Status"),
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": "\nDraft\nPaid\nUnpaid\nClaimed\nCancelled"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"add_total_row": 1,
|
||||||
|
"apply_user_permissions": 1,
|
||||||
|
"creation": "2018-02-21 07:12:37.299923",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"modified": "2018-02-22 13:33:41.532005",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "HR",
|
||||||
|
"name": "Employee Advance Summary",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"ref_doctype": "Employee Advance",
|
||||||
|
"report_name": "Employee Advance Summary",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Employee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Expense Approver"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import msgprint, _
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
if not filters: filters = {}
|
||||||
|
|
||||||
|
advances_list = get_advances(filters)
|
||||||
|
columns = get_columns()
|
||||||
|
|
||||||
|
if not advances_list:
|
||||||
|
msgprint(_("No record found"))
|
||||||
|
return columns, advances_list
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for advance in advances_list:
|
||||||
|
row = [advance.name, advance.employee, advance.company, advance.posting_date,
|
||||||
|
advance.advance_amount, advance.paid_amount, advance.claimed_amount, advance.status]
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def get_columns():
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"label": _("Title"),
|
||||||
|
"fieldname": "title",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Employee Advance",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Employee"),
|
||||||
|
"fieldname": "employee",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Employee",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Company"),
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Posting Date"),
|
||||||
|
"fieldname": "posting_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Advance Amount"),
|
||||||
|
"fieldname": "advance_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Paid Amount"),
|
||||||
|
"fieldname": "paid_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Claimed Amount"),
|
||||||
|
"fieldname": "claimed_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": _("Status"),
|
||||||
|
"fieldname": "status",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_conditions(filters):
|
||||||
|
conditions = ""
|
||||||
|
|
||||||
|
if filters.get("employee"):
|
||||||
|
conditions += "and employee = %(employee)s"
|
||||||
|
if filters.get("company"):
|
||||||
|
conditions += " and company = %(company)s"
|
||||||
|
if filters.get("status"):
|
||||||
|
conditions += " and status = %(status)s"
|
||||||
|
if filters.get("from_date"):
|
||||||
|
conditions += " and posting_date>=%(from_date)s"
|
||||||
|
if filters.get("to_date"):
|
||||||
|
conditions += " and posting_date<=%(to_date)s"
|
||||||
|
|
||||||
|
return conditions
|
||||||
|
|
||||||
|
def get_advances(filters):
|
||||||
|
conditions = get_conditions(filters)
|
||||||
|
return frappe.db.sql("""select name, employee, paid_amount, status, advance_amount, claimed_amount, company,
|
||||||
|
posting_date, purpose
|
||||||
|
from `tabEmployee Advance`
|
||||||
|
where docstatus<2 %s order by posting_date, name desc""" %
|
||||||
|
conditions, filters, as_dict=1)
|
@ -112,7 +112,7 @@ class MaintenanceSchedule(TransactionBase):
|
|||||||
if not validated and holidays:
|
if not validated and holidays:
|
||||||
|
|
||||||
# max iterations = len(holidays)
|
# max iterations = len(holidays)
|
||||||
for i in xrange(len(holidays)):
|
for i in range(len(holidays)):
|
||||||
if schedule_date in holidays:
|
if schedule_date in holidays:
|
||||||
schedule_date = add_days(schedule_date, -1)
|
schedule_date = add_days(schedule_date, -1)
|
||||||
else:
|
else:
|
||||||
|
@ -9,6 +9,8 @@ from erpnext.setup.utils import get_exchange_rate
|
|||||||
from frappe.website.website_generator import WebsiteGenerator
|
from frappe.website.website_generator import WebsiteGenerator
|
||||||
from erpnext.stock.get_item_details import get_conversion_factor
|
from erpnext.stock.get_item_details import get_conversion_factor
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
|
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
@ -585,7 +587,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_bom_items(bom, company, qty=1, fetch_exploded=1):
|
def get_bom_items(bom, company, qty=1, fetch_exploded=1):
|
||||||
items = get_bom_items_as_dict(bom, company, qty, fetch_exploded).values()
|
items = get_bom_items_as_dict(bom, company, qty, fetch_exploded).values()
|
||||||
items.sort(lambda a, b: a.item_code > b.item_code and 1 or -1)
|
items.sort(key = functools.cmp_to_key(lambda a, b: a.item_code > b.item_code and 1 or -1))
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def validate_bom_no(item, bom_no):
|
def validate_bom_no(item, bom_no):
|
||||||
|
@ -18,7 +18,7 @@ class TestBOM(unittest.TestCase):
|
|||||||
company="_Test Company", qty=1, fetch_exploded=0)
|
company="_Test Company", 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.assertEqual(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
|
||||||
@ -28,11 +28,11 @@ class TestBOM(unittest.TestCase):
|
|||||||
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)
|
||||||
self.assertTrue(test_records[0]["items"][1]["item_code"] in items_dict)
|
self.assertTrue(test_records[0]["items"][1]["item_code"] in items_dict)
|
||||||
self.assertEquals(len(items_dict.values()), 3)
|
self.assertEqual(len(items_dict.values()), 3)
|
||||||
|
|
||||||
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
|
||||||
self.assertEquals(len(get_bom_items(bom=get_default_bom(), company="_Test Company")), 3)
|
self.assertEqual(len(get_bom_items(bom=get_default_bom(), company="_Test Company")), 3)
|
||||||
|
|
||||||
def test_default_bom(self):
|
def test_default_bom(self):
|
||||||
def _get_default_bom_in_item():
|
def _get_default_bom_in_item():
|
||||||
|
@ -38,8 +38,11 @@ frappe.ui.form.on('Member', {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
callback: function (data) {
|
callback: function (data) {
|
||||||
frappe.model.set_value(frm.doctype,frm.docname, "membership_expiry_date", data.message.to_date);
|
if(data.message) {
|
||||||
|
frappe.model.set_value(frm.doctype,frm.docname,
|
||||||
|
"membership_expiry_date", data.message.to_date);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -3,7 +3,7 @@
|
|||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "field:email",
|
"autoname": "naming_series:",
|
||||||
"beta": 0,
|
"beta": 0,
|
||||||
"creation": "2017-09-11 09:24:52.898356",
|
"creation": "2017-09-11 09:24:52.898356",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
@ -13,6 +13,38 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "naming_series",
|
||||||
|
"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": "Series",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "MEM-",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -41,6 +73,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -71,6 +104,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -100,6 +134,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -131,6 +166,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -162,6 +198,7 @@
|
|||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -192,6 +229,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -222,6 +260,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -253,6 +292,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -284,6 +324,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -314,6 +355,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -345,6 +387,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -376,6 +419,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -406,6 +450,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -435,6 +480,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -465,6 +511,7 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -479,7 +526,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-02-15 05:08:48.561998",
|
"modified": "2018-02-23 10:55:29.721224",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Non Profit",
|
"module": "Non Profit",
|
||||||
"name": "Member",
|
"name": "Member",
|
||||||
|
@ -6,7 +6,6 @@ from __future__ import unicode_literals
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.contacts.address_and_contact import load_address_and_contact
|
from frappe.contacts.address_and_contact import load_address_and_contact
|
||||||
|
|
||||||
STANDARD_USERS = ("Guest", "Administrator")
|
|
||||||
|
|
||||||
class Member(Document):
|
class Member(Document):
|
||||||
def onload(self):
|
def onload(self):
|
||||||
@ -15,10 +14,7 @@ class Member(Document):
|
|||||||
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if self.name not in STANDARD_USERS:
|
self.validate_email_type(self.email)
|
||||||
self.validate_email_type(self.email)
|
|
||||||
self.validate_email_type(self.name)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_email_type(self, email):
|
def validate_email_type(self, email):
|
||||||
from frappe.utils import validate_email_add
|
from frappe.utils import validate_email_add
|
||||||
|
@ -504,4 +504,4 @@ execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=
|
|||||||
erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group
|
erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group
|
||||||
erpnext.patches.v10_0.add_default_cash_flow_mappers
|
erpnext.patches.v10_0.add_default_cash_flow_mappers
|
||||||
erpnext.patches.v11_0.make_quality_inspection_template
|
erpnext.patches.v11_0.make_quality_inspection_template
|
||||||
erpnext.patches.v10_0.update_territory_and_customer_group
|
# erpnext.patches.v10_0.update_territory_and_customer_group
|
@ -7,16 +7,20 @@ import frappe
|
|||||||
|
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
items_barcode = frappe.db.sql("""SELECT name, barcode FROM tabItem
|
items_barcode = frappe.get_list('Item', ['name', 'barcode'], { 'barcode': ('!=', '') })
|
||||||
WHERE barcode IS NOT NULL and barcode != ''""", as_dict=1)
|
|
||||||
|
|
||||||
frappe.reload_doc("stock", "doctype", "item")
|
frappe.reload_doc("stock", "doctype", "item")
|
||||||
frappe.reload_doc("stock", "doctype", "item_barcode")
|
frappe.reload_doc("stock", "doctype", "item_barcode")
|
||||||
|
|
||||||
for item in items_barcode:
|
for item in items_barcode:
|
||||||
doc = frappe.get_doc("Item", item.get("name"))
|
barcode = item.barcode.strip()
|
||||||
if item.get("barcode"):
|
|
||||||
doc.append("barcodes", {"barcode": item.get("barcode")})
|
if barcode and '<' not in barcode:
|
||||||
doc.flags.ignore_validate = True
|
frappe.get_doc({
|
||||||
doc.flags.ignore_mandatory = True
|
'idx': 0,
|
||||||
doc.save()
|
'doctype': 'Item Barcode',
|
||||||
|
'barcode': barcode,
|
||||||
|
'parenttype': 'Item',
|
||||||
|
'parent': item.name,
|
||||||
|
'parentfield': 'barcodes'
|
||||||
|
}).insert()
|
||||||
|
@ -12,6 +12,7 @@ def execute():
|
|||||||
if not po_item:
|
if not po_item:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
frappe.reload_doc("stock", "doctype", "bin")
|
||||||
frappe.reload_doc("buying", "doctype", "purchase_order_item_supplied")
|
frappe.reload_doc("buying", "doctype", "purchase_order_item_supplied")
|
||||||
company_warehouse = frappe._dict(frappe.db.sql("""select company, min(name) from `tabWarehouse`
|
company_warehouse = frappe._dict(frappe.db.sql("""select company, min(name) from `tabWarehouse`
|
||||||
where is_group = 0 group by company"""))
|
where is_group = 0 group by company"""))
|
||||||
@ -30,7 +31,7 @@ def execute():
|
|||||||
|
|
||||||
# Update bin
|
# Update bin
|
||||||
item_wh_bin = frappe.db.sql(("""
|
item_wh_bin = frappe.db.sql(("""
|
||||||
select distinct poitemsup.rm_item_code as rm_item_code,
|
select distinct poitemsup.rm_item_code as rm_item_code,
|
||||||
poitemsup.reserve_warehouse as reserve_warehouse
|
poitemsup.reserve_warehouse as reserve_warehouse
|
||||||
from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
|
from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
|
||||||
where po.name = poitemsup.parent
|
where po.name = poitemsup.parent
|
||||||
|
@ -1,13 +1,36 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.model.rename_doc import update_linked_doctypes
|
from frappe.model.rename_doc import get_fetch_fields
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
customers = frappe.get_all('Customer')
|
ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"]
|
||||||
for customer in customers:
|
customers = frappe.get_all('Customer', fields=["name", "territory", "customer_group"])
|
||||||
# Update Territory across all transaction
|
|
||||||
terr = frappe.get_value('Customer', customer, 'territory')
|
|
||||||
update_linked_doctypes("Customer", "Territory", customer.name, terr)
|
|
||||||
|
|
||||||
# Update Territory across all transaction
|
territory_fetch = get_fetch_fields('Customer', 'Territory', ignore_doctypes)
|
||||||
cust_group = frappe.get_value('Customer', customer, 'customer_group')
|
customer_group_fetch = get_fetch_fields('Customer', 'Customer Group', ignore_doctypes)
|
||||||
update_linked_doctypes("Customer", "Customer Group", customer.name, cust_group)
|
|
||||||
|
batch_size = 1000
|
||||||
|
for i in range(0, len(customers), batch_size):
|
||||||
|
batch_customers = customers[i:i + batch_size]
|
||||||
|
for source_fieldname, linked_doctypes_info in [["customer_group", customer_group_fetch], ["territory", territory_fetch]]:
|
||||||
|
for d in linked_doctypes_info:
|
||||||
|
when_then = []
|
||||||
|
for customer in batch_customers:
|
||||||
|
when_then.append('''
|
||||||
|
WHEN `{master_fieldname}` = "{docname}" and {linked_to_fieldname} != "{value}"
|
||||||
|
THEN "{value}"
|
||||||
|
'''.format(
|
||||||
|
master_fieldname=d["master_fieldname"],
|
||||||
|
linked_to_fieldname=d["linked_to_fieldname"],
|
||||||
|
docname=frappe.db.escape(customer.name).encode("utf-8"),
|
||||||
|
value=frappe.db.escape(customer.get(source_fieldname)).encode("utf-8")))
|
||||||
|
|
||||||
|
frappe.db.sql("""
|
||||||
|
update
|
||||||
|
`tab{doctype}`
|
||||||
|
set
|
||||||
|
{linked_to_fieldname} = CASE {when_then_cond} ELSE `{linked_to_fieldname}` END
|
||||||
|
""".format(
|
||||||
|
doctype = d['doctype'],
|
||||||
|
when_then_cond=" ".join(when_then),
|
||||||
|
linked_to_fieldname=d.linked_to_fieldname
|
||||||
|
))
|
||||||
|
@ -50,7 +50,7 @@ class Task(NestedSet):
|
|||||||
clear(self.doctype, self.name)
|
clear(self.doctype, self.name)
|
||||||
|
|
||||||
def validate_progress(self):
|
def validate_progress(self):
|
||||||
if self.progress > 100:
|
if (self.progress or 0) > 100:
|
||||||
frappe.throw(_("Progress % for a task cannot be more than 100."))
|
frappe.throw(_("Progress % for a task cannot be more than 100."))
|
||||||
|
|
||||||
def update_depends_on(self):
|
def update_depends_on(self):
|
||||||
|
@ -78,16 +78,16 @@ class TestTask(unittest.TestCase):
|
|||||||
|
|
||||||
assign()
|
assign()
|
||||||
todo = get_owner_and_status()
|
todo = get_owner_and_status()
|
||||||
self.assertEquals(todo.owner, "test@example.com")
|
self.assertEqual(todo.owner, "test@example.com")
|
||||||
self.assertEquals(todo.status, "Open")
|
self.assertEqual(todo.status, "Open")
|
||||||
|
|
||||||
# assignment should be
|
# assignment should be
|
||||||
task.load_from_db()
|
task.load_from_db()
|
||||||
task.status = "Closed"
|
task.status = "Closed"
|
||||||
task.save()
|
task.save()
|
||||||
todo = get_owner_and_status()
|
todo = get_owner_and_status()
|
||||||
self.assertEquals(todo.owner, "test@example.com")
|
self.assertEqual(todo.owner, "test@example.com")
|
||||||
self.assertEquals(todo.status, "Closed")
|
self.assertEqual(todo.status, "Closed")
|
||||||
|
|
||||||
def test_overdue(self):
|
def test_overdue(self):
|
||||||
task = create_task("Testing Overdue", add_days(nowdate(), -10), add_days(nowdate(), -5))
|
task = create_task("Testing Overdue", add_days(nowdate(), -10), add_days(nowdate(), -5))
|
||||||
@ -95,7 +95,7 @@ class TestTask(unittest.TestCase):
|
|||||||
from erpnext.projects.doctype.task.task import set_tasks_as_overdue
|
from erpnext.projects.doctype.task.task import set_tasks_as_overdue
|
||||||
set_tasks_as_overdue()
|
set_tasks_as_overdue()
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value("Task", task.name, "status"), "Overdue")
|
self.assertEqual(frappe.db.get_value("Task", task.name, "status"), "Overdue")
|
||||||
|
|
||||||
def create_task(subject, start=None, end=None, depends_on=None, project=None):
|
def create_task(subject, start=None, end=None, depends_on=None, project=None):
|
||||||
if not frappe.db.exists("Task", subject):
|
if not frappe.db.exists("Task", subject):
|
||||||
|
@ -17,21 +17,21 @@ class TestTimesheet(unittest.TestCase):
|
|||||||
make_salary_structure("_T-Employee-0001")
|
make_salary_structure("_T-Employee-0001")
|
||||||
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1)
|
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1)
|
||||||
|
|
||||||
self.assertEquals(timesheet.total_hours, 2)
|
self.assertEqual(timesheet.total_hours, 2)
|
||||||
self.assertEquals(timesheet.total_billable_hours, 2)
|
self.assertEqual(timesheet.total_billable_hours, 2)
|
||||||
self.assertEquals(timesheet.time_logs[0].billing_rate, 50)
|
self.assertEqual(timesheet.time_logs[0].billing_rate, 50)
|
||||||
self.assertEquals(timesheet.time_logs[0].billing_amount, 100)
|
self.assertEqual(timesheet.time_logs[0].billing_amount, 100)
|
||||||
self.assertEquals(timesheet.total_billable_amount, 100)
|
self.assertEqual(timesheet.total_billable_amount, 100)
|
||||||
|
|
||||||
def test_timesheet_billing_amount_not_billable(self):
|
def test_timesheet_billing_amount_not_billable(self):
|
||||||
make_salary_structure("_T-Employee-0001")
|
make_salary_structure("_T-Employee-0001")
|
||||||
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=0)
|
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=0)
|
||||||
|
|
||||||
self.assertEquals(timesheet.total_hours, 2)
|
self.assertEqual(timesheet.total_hours, 2)
|
||||||
self.assertEquals(timesheet.total_billable_hours, 0)
|
self.assertEqual(timesheet.total_billable_hours, 0)
|
||||||
self.assertEquals(timesheet.time_logs[0].billing_rate, 0)
|
self.assertEqual(timesheet.time_logs[0].billing_rate, 0)
|
||||||
self.assertEquals(timesheet.time_logs[0].billing_amount, 0)
|
self.assertEqual(timesheet.time_logs[0].billing_amount, 0)
|
||||||
self.assertEquals(timesheet.total_billable_amount, 0)
|
self.assertEqual(timesheet.total_billable_amount, 0)
|
||||||
|
|
||||||
def test_salary_slip_from_timesheet(self):
|
def test_salary_slip_from_timesheet(self):
|
||||||
salary_structure = make_salary_structure("_T-Employee-0001")
|
salary_structure = make_salary_structure("_T-Employee-0001")
|
||||||
@ -39,18 +39,18 @@ class TestTimesheet(unittest.TestCase):
|
|||||||
salary_slip = make_salary_slip(timesheet.name)
|
salary_slip = make_salary_slip(timesheet.name)
|
||||||
salary_slip.submit()
|
salary_slip.submit()
|
||||||
|
|
||||||
self.assertEquals(salary_slip.total_working_hours, 2)
|
self.assertEqual(salary_slip.total_working_hours, 2)
|
||||||
self.assertEquals(salary_slip.hour_rate, 50)
|
self.assertEqual(salary_slip.hour_rate, 50)
|
||||||
self.assertEquals(salary_slip.net_pay, 150)
|
self.assertEqual(salary_slip.net_pay, 150)
|
||||||
self.assertEquals(salary_slip.timesheets[0].time_sheet, timesheet.name)
|
self.assertEqual(salary_slip.timesheets[0].time_sheet, timesheet.name)
|
||||||
self.assertEquals(salary_slip.timesheets[0].working_hours, 2)
|
self.assertEqual(salary_slip.timesheets[0].working_hours, 2)
|
||||||
|
|
||||||
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
||||||
self.assertEquals(timesheet.status, 'Payslip')
|
self.assertEqual(timesheet.status, 'Payslip')
|
||||||
salary_slip.cancel()
|
salary_slip.cancel()
|
||||||
|
|
||||||
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
||||||
self.assertEquals(timesheet.status, 'Submitted')
|
self.assertEqual(timesheet.status, 'Submitted')
|
||||||
|
|
||||||
def test_sales_invoice_from_timesheet(self):
|
def test_sales_invoice_from_timesheet(self):
|
||||||
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1)
|
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1)
|
||||||
@ -58,14 +58,14 @@ class TestTimesheet(unittest.TestCase):
|
|||||||
sales_invoice.due_date = nowdate()
|
sales_invoice.due_date = nowdate()
|
||||||
sales_invoice.submit()
|
sales_invoice.submit()
|
||||||
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
||||||
self.assertEquals(sales_invoice.total_billing_amount, 100)
|
self.assertEqual(sales_invoice.total_billing_amount, 100)
|
||||||
self.assertEquals(timesheet.status, 'Billed')
|
self.assertEqual(timesheet.status, 'Billed')
|
||||||
self.assertEquals(sales_invoice.customer, '_Test Customer')
|
self.assertEqual(sales_invoice.customer, '_Test Customer')
|
||||||
|
|
||||||
item = sales_invoice.items[0]
|
item = sales_invoice.items[0]
|
||||||
self.assertEquals(item.item_code, '_Test Item')
|
self.assertEqual(item.item_code, '_Test Item')
|
||||||
self.assertEquals(item.qty, 2.00)
|
self.assertEqual(item.qty, 2.00)
|
||||||
self.assertEquals(item.rate, 50.00)
|
self.assertEqual(item.rate, 50.00)
|
||||||
|
|
||||||
def test_timesheet_billing_based_on_project(self):
|
def test_timesheet_billing_based_on_project(self):
|
||||||
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1, project = '_Test Project', company='_Test Company')
|
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1, project = '_Test Project', company='_Test Company')
|
||||||
@ -74,8 +74,8 @@ class TestTimesheet(unittest.TestCase):
|
|||||||
sales_invoice.submit()
|
sales_invoice.submit()
|
||||||
|
|
||||||
ts = frappe.get_doc('Timesheet', timesheet.name)
|
ts = frappe.get_doc('Timesheet', timesheet.name)
|
||||||
self.assertEquals(ts.per_billed, 100)
|
self.assertEqual(ts.per_billed, 100)
|
||||||
self.assertEquals(ts.time_logs[0].sales_invoice, sales_invoice.name)
|
self.assertEqual(ts.time_logs[0].sales_invoice, sales_invoice.name)
|
||||||
|
|
||||||
def test_timesheet_time_overlap(self):
|
def test_timesheet_time_overlap(self):
|
||||||
settings = frappe.get_single('Projects Settings')
|
settings = frappe.get_single('Projects Settings')
|
||||||
|
@ -292,7 +292,7 @@ def get_projectwise_timesheet_data(project, parent=None):
|
|||||||
cond = "and parent = %(parent)s"
|
cond = "and parent = %(parent)s"
|
||||||
|
|
||||||
return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
|
return frappe.db.sql("""select name, parent, billing_hours, billing_amount as billing_amt
|
||||||
from `tabTimesheet Detail` where docstatus=1 and project = %(project)s {0} and billable = 1
|
from `tabTimesheet Detail` where parenttype = 'Timesheet' and docstatus=1 and project = %(project)s {0} and billable = 1
|
||||||
and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
|
and sales_invoice is null""".format(cond), {'project': project, 'parent': parent}, as_dict=1)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
@ -38,15 +38,15 @@ class TestRestaurantMenu(unittest.TestCase):
|
|||||||
menu2.save()
|
menu2.save()
|
||||||
|
|
||||||
self.assertTrue(frappe.db.get_value('Price List', 'Test Restaurant 1 Menu 1'))
|
self.assertTrue(frappe.db.get_value('Price List', 'Test Restaurant 1 Menu 1'))
|
||||||
self.assertEquals(frappe.db.get_value('Item Price',
|
self.assertEqual(frappe.db.get_value('Item Price',
|
||||||
dict(price_list = 'Test Restaurant 1 Menu 1', item_code='Food Item 1'), 'price_list_rate'), 400)
|
dict(price_list = 'Test Restaurant 1 Menu 1', item_code='Food Item 1'), 'price_list_rate'), 400)
|
||||||
self.assertEquals(frappe.db.get_value('Item Price',
|
self.assertEqual(frappe.db.get_value('Item Price',
|
||||||
dict(price_list = 'Test Restaurant 1 Menu 2', item_code='Food Item 1'), 'price_list_rate'), 450)
|
dict(price_list = 'Test Restaurant 1 Menu 2', item_code='Food Item 1'), 'price_list_rate'), 450)
|
||||||
|
|
||||||
menu1.items[0].rate = 401
|
menu1.items[0].rate = 401
|
||||||
menu1.save()
|
menu1.save()
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value('Item Price',
|
self.assertEqual(frappe.db.get_value('Item Price',
|
||||||
dict(price_list = 'Test Restaurant 1 Menu 1', item_code='Food Item 1'), 'price_list_rate'), 401)
|
dict(price_list = 'Test Restaurant 1 Menu 1', item_code='Food Item 1'), 'price_list_rate'), 401)
|
||||||
|
|
||||||
menu1.items[0].rate = 400
|
menu1.items[0].rate = 400
|
||||||
|
@ -15,8 +15,8 @@ frappe.ui.form.on('Restaurant Order Entry', {
|
|||||||
frm.set_query('add_item', get_item_query);
|
frm.set_query('add_item', get_item_query);
|
||||||
},
|
},
|
||||||
onload_post_render: function(frm) {
|
onload_post_render: function(frm) {
|
||||||
if(!this.item_selector) {
|
if(!frm.item_selector) {
|
||||||
this.item_selector = new erpnext.ItemSelector({
|
frm.item_selector = new erpnext.ItemSelector({
|
||||||
frm: frm,
|
frm: frm,
|
||||||
item_field: 'item',
|
item_field: 'item',
|
||||||
item_query: 'erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry.item_query_restaurant',
|
item_query: 'erpnext.restaurant.doctype.restaurant_order_entry.restaurant_order_entry.item_query_restaurant',
|
||||||
|
@ -57,13 +57,13 @@ class Customer(TransactionBase):
|
|||||||
self.check_customer_group_or_territory_change()
|
self.check_customer_group_or_territory_change()
|
||||||
|
|
||||||
def check_customer_group_or_territory_change(self):
|
def check_customer_group_or_territory_change(self):
|
||||||
frappe.flags.customer_group, frappe.flags.territory = False, False
|
frappe.flags.customer_group_changed, frappe.flags.territory_changed = False, False
|
||||||
|
|
||||||
if not self.get('__islocal'):
|
if not self.get('__islocal'):
|
||||||
if self.customer_group != frappe.db.get_value('Customer', self.name, 'customer_group'):
|
if self.customer_group != frappe.db.get_value('Customer', self.name, 'customer_group'):
|
||||||
frappe.flags.customer_group = True
|
frappe.flags.customer_group_changed = True
|
||||||
if self.territory != frappe.db.get_value('Customer', self.name, 'territory'):
|
if self.territory != frappe.db.get_value('Customer', self.name, 'territory'):
|
||||||
frappe.flags.territory = True
|
frappe.flags.territory_changed = True
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
self.validate_name_with_customer_group()
|
self.validate_name_with_customer_group()
|
||||||
@ -76,10 +76,15 @@ class Customer(TransactionBase):
|
|||||||
if self.flags.is_new_doc:
|
if self.flags.is_new_doc:
|
||||||
self.create_lead_address_contact()
|
self.create_lead_address_contact()
|
||||||
|
|
||||||
if frappe.flags.territory:
|
self.update_territory_and_customer_groups()
|
||||||
update_linked_doctypes("Customer", "Territory", self.name, self.territory)
|
|
||||||
if frappe.flags.customer_group:
|
def update_territory_and_customer_groups(self):
|
||||||
update_linked_doctypes("Customer", "Customer Group", self.name, self.customer_group)
|
ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"]
|
||||||
|
if frappe.flags.territory_changed:
|
||||||
|
update_linked_doctypes('Customer', self.name, 'Territory', self.territory, ignore_doctypes)
|
||||||
|
if frappe.flags.customer_group_changed:
|
||||||
|
update_linked_doctypes('Customer', self.name, 'Customer Group',
|
||||||
|
self.customer_group, ignore_doctypes)
|
||||||
|
|
||||||
def create_primary_contact(self):
|
def create_primary_contact(self):
|
||||||
if not self.customer_primary_contact and not self.lead_name:
|
if not self.customer_primary_contact and not self.lead_name:
|
||||||
|
@ -54,7 +54,7 @@ class TestCustomer(unittest.TestCase):
|
|||||||
details = get_party_details("_Test Customer")
|
details = get_party_details("_Test Customer")
|
||||||
|
|
||||||
for key, value in iteritems(to_check):
|
for key, value in iteritems(to_check):
|
||||||
self.assertEquals(value, details.get(key))
|
self.assertEqual(value, details.get(key))
|
||||||
|
|
||||||
def test_rename(self):
|
def test_rename(self):
|
||||||
# delete communication linked to these 2 customers
|
# delete communication linked to these 2 customers
|
||||||
@ -74,7 +74,7 @@ class TestCustomer(unittest.TestCase):
|
|||||||
self.assertFalse(frappe.db.exists("Customer", "_Test Customer 1"))
|
self.assertFalse(frappe.db.exists("Customer", "_Test Customer 1"))
|
||||||
|
|
||||||
# test that comment gets linked to renamed doc
|
# test that comment gets linked to renamed doc
|
||||||
self.assertEquals(frappe.db.get_value("Communication", {
|
self.assertEqual(frappe.db.get_value("Communication", {
|
||||||
"communication_type": "Comment",
|
"communication_type": "Comment",
|
||||||
"reference_doctype": "Customer",
|
"reference_doctype": "Customer",
|
||||||
"reference_name": "_Test Customer 1 Renamed"
|
"reference_name": "_Test Customer 1 Renamed"
|
||||||
@ -125,9 +125,9 @@ class TestCustomer(unittest.TestCase):
|
|||||||
duplicate_customer = frappe.get_doc(
|
duplicate_customer = frappe.get_doc(
|
||||||
get_customer_dict('_Test Customer 1')).insert(ignore_permissions=True)
|
get_customer_dict('_Test Customer 1')).insert(ignore_permissions=True)
|
||||||
|
|
||||||
self.assertEquals("_Test Customer 1", test_customer_1.name)
|
self.assertEqual("_Test Customer 1", test_customer_1.name)
|
||||||
self.assertEquals("_Test Customer 1 - 1", duplicate_customer.name)
|
self.assertEqual("_Test Customer 1 - 1", duplicate_customer.name)
|
||||||
self.assertEquals(test_customer_1.customer_name, duplicate_customer.customer_name)
|
self.assertEqual(test_customer_1.customer_name, duplicate_customer.customer_name)
|
||||||
|
|
||||||
def get_customer_outstanding_amount(self):
|
def get_customer_outstanding_amount(self):
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
|
@ -42,7 +42,11 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
|||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
if (doc.__islocal) {
|
if (doc.__islocal) {
|
||||||
this.frm.set_value('valid_till', frappe.datetime.add_months(doc.transaction_date, 1))
|
if(frappe.boot.sysdefaults.quotation_valid_till){
|
||||||
|
this.frm.set_value('valid_till', frappe.datetime.add_days(doc.transaction_date, frappe.boot.sysdefaults.quotation_valid_till));
|
||||||
|
} else {
|
||||||
|
this.frm.set_value('valid_till', frappe.datetime.add_months(doc.transaction_date, 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(doc.docstatus == 1 && doc.status!=='Lost') {
|
if(doc.docstatus == 1 && doc.status!=='Lost') {
|
||||||
|
@ -44,11 +44,11 @@ class TestQuotation(unittest.TestCase):
|
|||||||
|
|
||||||
sales_order = make_sales_order(quotation.name)
|
sales_order = make_sales_order(quotation.name)
|
||||||
|
|
||||||
self.assertEquals(sales_order.doctype, "Sales Order")
|
self.assertEqual(sales_order.doctype, "Sales Order")
|
||||||
self.assertEquals(len(sales_order.get("items")), 1)
|
self.assertEqual(len(sales_order.get("items")), 1)
|
||||||
self.assertEquals(sales_order.get("items")[0].doctype, "Sales Order Item")
|
self.assertEqual(sales_order.get("items")[0].doctype, "Sales Order Item")
|
||||||
self.assertEquals(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
self.assertEqual(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
||||||
self.assertEquals(sales_order.customer, "_Test Customer")
|
self.assertEqual(sales_order.customer, "_Test Customer")
|
||||||
|
|
||||||
sales_order.delivery_date = "2014-01-01"
|
sales_order.delivery_date = "2014-01-01"
|
||||||
sales_order.naming_series = "_T-Quotation-"
|
sales_order.naming_series = "_T-Quotation-"
|
||||||
@ -77,11 +77,11 @@ class TestQuotation(unittest.TestCase):
|
|||||||
|
|
||||||
sales_order = make_sales_order(quotation.name)
|
sales_order = make_sales_order(quotation.name)
|
||||||
|
|
||||||
self.assertEquals(sales_order.doctype, "Sales Order")
|
self.assertEqual(sales_order.doctype, "Sales Order")
|
||||||
self.assertEquals(len(sales_order.get("items")), 1)
|
self.assertEqual(len(sales_order.get("items")), 1)
|
||||||
self.assertEquals(sales_order.get("items")[0].doctype, "Sales Order Item")
|
self.assertEqual(sales_order.get("items")[0].doctype, "Sales Order Item")
|
||||||
self.assertEquals(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
self.assertEqual(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
||||||
self.assertEquals(sales_order.customer, "_Test Customer")
|
self.assertEqual(sales_order.customer, "_Test Customer")
|
||||||
|
|
||||||
sales_order.delivery_date = "2014-01-01"
|
sales_order.delivery_date = "2014-01-01"
|
||||||
sales_order.naming_series = "_T-Quotation-"
|
sales_order.naming_series = "_T-Quotation-"
|
||||||
@ -123,7 +123,7 @@ class TestQuotation(unittest.TestCase):
|
|||||||
quotation.valid_till = add_months(quotation.transaction_date, 1)
|
quotation.valid_till = add_months(quotation.transaction_date, 1)
|
||||||
quotation.insert()
|
quotation.insert()
|
||||||
|
|
||||||
self.assertEquals(quotation.get("items")[0].rate, rate_with_margin)
|
self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)
|
||||||
self.assertRaises(frappe.ValidationError, make_sales_order, quotation.name)
|
self.assertRaises(frappe.ValidationError, make_sales_order, quotation.name)
|
||||||
quotation.submit()
|
quotation.submit()
|
||||||
|
|
||||||
@ -134,16 +134,16 @@ class TestQuotation(unittest.TestCase):
|
|||||||
|
|
||||||
sales_order.insert()
|
sales_order.insert()
|
||||||
|
|
||||||
self.assertEquals(quotation.get("items")[0].rate, rate_with_margin)
|
self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)
|
||||||
|
|
||||||
sales_order.submit()
|
sales_order.submit()
|
||||||
|
|
||||||
dn = make_delivery_note(sales_order.name)
|
dn = make_delivery_note(sales_order.name)
|
||||||
self.assertEquals(quotation.get("items")[0].rate, rate_with_margin)
|
self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)
|
||||||
dn.save()
|
dn.save()
|
||||||
|
|
||||||
si = make_sales_invoice(sales_order.name)
|
si = make_sales_invoice(sales_order.name)
|
||||||
self.assertEquals(quotation.get("items")[0].rate, rate_with_margin)
|
self.assertEqual(quotation.get("items")[0].rate, rate_with_margin)
|
||||||
si.save()
|
si.save()
|
||||||
|
|
||||||
def test_create_two_quotations(self):
|
def test_create_two_quotations(self):
|
||||||
|
@ -104,8 +104,8 @@ class SalesOrder(SellingController):
|
|||||||
def validate_delivery_date(self):
|
def validate_delivery_date(self):
|
||||||
if self.order_type == 'Sales':
|
if self.order_type == 'Sales':
|
||||||
if not self.delivery_date:
|
if not self.delivery_date:
|
||||||
self.delivery_date = max([d.delivery_date for d in self.get("items") if d.delivery_date])
|
delivery_date_list = [d.delivery_date for d in self.get("items") if d.delivery_date]
|
||||||
|
self.delivery_date = max(delivery_date_list) if delivery_date_list else None
|
||||||
if self.delivery_date:
|
if self.delivery_date:
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if not d.delivery_date:
|
if not d.delivery_date:
|
||||||
|
@ -29,8 +29,8 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
so.submit()
|
so.submit()
|
||||||
mr = make_material_request(so.name)
|
mr = make_material_request(so.name)
|
||||||
|
|
||||||
self.assertEquals(mr.material_request_type, "Purchase")
|
self.assertEqual(mr.material_request_type, "Purchase")
|
||||||
self.assertEquals(len(mr.get("items")), len(so.get("items")))
|
self.assertEqual(len(mr.get("items")), len(so.get("items")))
|
||||||
|
|
||||||
def test_make_delivery_note(self):
|
def test_make_delivery_note(self):
|
||||||
so = make_sales_order(do_not_submit=True)
|
so = make_sales_order(do_not_submit=True)
|
||||||
@ -40,8 +40,8 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
so.submit()
|
so.submit()
|
||||||
dn = make_delivery_note(so.name)
|
dn = make_delivery_note(so.name)
|
||||||
|
|
||||||
self.assertEquals(dn.doctype, "Delivery Note")
|
self.assertEqual(dn.doctype, "Delivery Note")
|
||||||
self.assertEquals(len(dn.get("items")), len(so.get("items")))
|
self.assertEqual(len(dn.get("items")), len(so.get("items")))
|
||||||
|
|
||||||
def test_make_sales_invoice(self):
|
def test_make_sales_invoice(self):
|
||||||
so = make_sales_order(do_not_submit=True)
|
so = make_sales_order(do_not_submit=True)
|
||||||
@ -51,14 +51,14 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
so.submit()
|
so.submit()
|
||||||
si = make_sales_invoice(so.name)
|
si = make_sales_invoice(so.name)
|
||||||
|
|
||||||
self.assertEquals(len(si.get("items")), len(so.get("items")))
|
self.assertEqual(len(si.get("items")), len(so.get("items")))
|
||||||
self.assertEquals(len(si.get("items")), 1)
|
self.assertEqual(len(si.get("items")), 1)
|
||||||
|
|
||||||
si.insert()
|
si.insert()
|
||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
si1 = make_sales_invoice(so.name)
|
si1 = make_sales_invoice(so.name)
|
||||||
self.assertEquals(len(si1.get("items")), 0)
|
self.assertEqual(len(si1.get("items")), 0)
|
||||||
|
|
||||||
def test_make_sales_invoice_with_terms(self):
|
def test_make_sales_invoice_with_terms(self):
|
||||||
so = make_sales_order(do_not_submit=True)
|
so = make_sales_order(do_not_submit=True)
|
||||||
@ -71,8 +71,8 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
so.submit()
|
so.submit()
|
||||||
si = make_sales_invoice(so.name)
|
si = make_sales_invoice(so.name)
|
||||||
|
|
||||||
self.assertEquals(len(si.get("items")), len(so.get("items")))
|
self.assertEqual(len(si.get("items")), len(so.get("items")))
|
||||||
self.assertEquals(len(si.get("items")), 1)
|
self.assertEqual(len(si.get("items")), 1)
|
||||||
|
|
||||||
si.insert()
|
si.insert()
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
si.submit()
|
si.submit()
|
||||||
|
|
||||||
si1 = make_sales_invoice(so.name)
|
si1 = make_sales_invoice(so.name)
|
||||||
self.assertEquals(len(si1.get("items")), 0)
|
self.assertEqual(len(si1.get("items")), 0)
|
||||||
|
|
||||||
def test_update_qty(self):
|
def test_update_qty(self):
|
||||||
so = make_sales_order()
|
so = make_sales_order()
|
||||||
@ -92,7 +92,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
create_dn_against_so(so.name, 6)
|
create_dn_against_so(so.name, 6)
|
||||||
|
|
||||||
so.load_from_db()
|
so.load_from_db()
|
||||||
self.assertEquals(so.get("items")[0].delivered_qty, 6)
|
self.assertEqual(so.get("items")[0].delivered_qty, 6)
|
||||||
|
|
||||||
# Check delivered_qty after make_sales_invoice without update_stock checked
|
# Check delivered_qty after make_sales_invoice without update_stock checked
|
||||||
si1 = make_sales_invoice(so.name)
|
si1 = make_sales_invoice(so.name)
|
||||||
@ -101,7 +101,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
si1.submit()
|
si1.submit()
|
||||||
|
|
||||||
so.load_from_db()
|
so.load_from_db()
|
||||||
self.assertEquals(so.get("items")[0].delivered_qty, 6)
|
self.assertEqual(so.get("items")[0].delivered_qty, 6)
|
||||||
|
|
||||||
# Check delivered_qty after make_sales_invoice with update_stock checked
|
# Check delivered_qty after make_sales_invoice with update_stock checked
|
||||||
si2 = make_sales_invoice(so.name)
|
si2 = make_sales_invoice(so.name)
|
||||||
@ -111,7 +111,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
si2.submit()
|
si2.submit()
|
||||||
|
|
||||||
so.load_from_db()
|
so.load_from_db()
|
||||||
self.assertEquals(so.get("items")[0].delivered_qty, 9)
|
self.assertEqual(so.get("items")[0].delivered_qty, 9)
|
||||||
|
|
||||||
def test_reserved_qty_for_partial_delivery(self):
|
def test_reserved_qty_for_partial_delivery(self):
|
||||||
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
|
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
|
||||||
@ -342,7 +342,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
|
|
||||||
make_sales_order(item_code = "_Test Item for Auto Price List", selling_price_list="_Test Price List", rate=100)
|
make_sales_order(item_code = "_Test Item for Auto Price List", selling_price_list="_Test Price List", rate=100)
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value("Item Price",
|
self.assertEqual(frappe.db.get_value("Item Price",
|
||||||
{"price_list": "_Test Price List", "item_code": "_Test Item for Auto Price List"}, "price_list_rate"), 100)
|
{"price_list": "_Test Price List", "item_code": "_Test Item for Auto Price List"}, "price_list_rate"), 100)
|
||||||
|
|
||||||
|
|
||||||
@ -356,7 +356,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
|
|
||||||
make_sales_order(item_code = "_Test Item for Auto Price List", selling_price_list="_Test Price List", rate=100)
|
make_sales_order(item_code = "_Test Item for Auto Price List", selling_price_list="_Test Price List", rate=100)
|
||||||
|
|
||||||
self.assertEquals(frappe.db.get_value("Item Price",
|
self.assertEqual(frappe.db.get_value("Item Price",
|
||||||
{"price_list": "_Test Price List", "item_code": "_Test Item for Auto Price List"}, "price_list_rate"), None)
|
{"price_list": "_Test Price List", "item_code": "_Test Item for Auto Price List"}, "price_list_rate"), None)
|
||||||
|
|
||||||
frappe.db.set_value("Stock Settings", None, "auto_insert_price_list_rate_if_missing", 1)
|
frappe.db.set_value("Stock Settings", None, "auto_insert_price_list_rate_if_missing", 1)
|
||||||
@ -419,10 +419,10 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
|
|
||||||
dn = create_dn_against_so(so.name, delivered_qty=1)
|
dn = create_dn_against_so(so.name, delivered_qty=1)
|
||||||
|
|
||||||
self.assertEquals(so.customer, po.customer)
|
self.assertEqual(so.customer, po.customer)
|
||||||
self.assertEquals(po.items[0].sales_order, so.name)
|
self.assertEqual(po.items[0].sales_order, so.name)
|
||||||
self.assertEquals(po.items[0].item_code, po_item.item_code)
|
self.assertEqual(po.items[0].item_code, po_item.item_code)
|
||||||
self.assertEquals(dn.items[0].item_code, dn_item.item_code)
|
self.assertEqual(dn.items[0].item_code, dn_item.item_code)
|
||||||
|
|
||||||
#test ordered_qty and reserved_qty
|
#test ordered_qty and reserved_qty
|
||||||
bin = frappe.get_all("Bin", filters={"item_code": po_item.item_code, "warehouse": "_Test Warehouse - _TC"},
|
bin = frappe.get_all("Bin", filters={"item_code": po_item.item_code, "warehouse": "_Test Warehouse - _TC"},
|
||||||
@ -431,27 +431,27 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
ordered_qty = bin[0].ordered_qty if bin else 0.0
|
ordered_qty = bin[0].ordered_qty if bin else 0.0
|
||||||
reserved_qty = bin[0].reserved_qty if bin else 0.0
|
reserved_qty = bin[0].reserved_qty if bin else 0.0
|
||||||
|
|
||||||
self.assertEquals(abs(flt(ordered_qty)), existing_ordered_qty)
|
self.assertEqual(abs(flt(ordered_qty)), existing_ordered_qty)
|
||||||
self.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty)
|
self.assertEqual(abs(flt(reserved_qty)), existing_reserved_qty)
|
||||||
|
|
||||||
reserved_qty = frappe.db.get_value("Bin",
|
reserved_qty = frappe.db.get_value("Bin",
|
||||||
{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
|
{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
|
||||||
|
|
||||||
self.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty_for_dn_item + 1)
|
self.assertEqual(abs(flt(reserved_qty)), existing_reserved_qty_for_dn_item + 1)
|
||||||
|
|
||||||
#test po_item length
|
#test po_item length
|
||||||
self.assertEquals(len(po.items), 1)
|
self.assertEqual(len(po.items), 1)
|
||||||
|
|
||||||
#test per_delivered status
|
#test per_delivered status
|
||||||
update_status("Delivered", po.name)
|
update_status("Delivered", po.name)
|
||||||
self.assertEquals(flt(frappe.db.get_value("Sales Order", so.name, "per_delivered"), 2), 75.00)
|
self.assertEqual(flt(frappe.db.get_value("Sales Order", so.name, "per_delivered"), 2), 75.00)
|
||||||
|
|
||||||
#test reserved qty after complete delivery
|
#test reserved qty after complete delivery
|
||||||
dn = create_dn_against_so(so.name, delivered_qty=1)
|
dn = create_dn_against_so(so.name, delivered_qty=1)
|
||||||
reserved_qty = frappe.db.get_value("Bin",
|
reserved_qty = frappe.db.get_value("Bin",
|
||||||
{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
|
{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
|
||||||
|
|
||||||
self.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty_for_dn_item)
|
self.assertEqual(abs(flt(reserved_qty)), existing_reserved_qty_for_dn_item)
|
||||||
|
|
||||||
#test after closing so
|
#test after closing so
|
||||||
so.db_set('status', "Closed")
|
so.db_set('status', "Closed")
|
||||||
@ -463,13 +463,13 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
ordered_qty = bin[0].ordered_qty if bin else 0.0
|
ordered_qty = bin[0].ordered_qty if bin else 0.0
|
||||||
reserved_qty = bin[0].reserved_qty if bin else 0.0
|
reserved_qty = bin[0].reserved_qty if bin else 0.0
|
||||||
|
|
||||||
self.assertEquals(abs(flt(ordered_qty)), existing_ordered_qty)
|
self.assertEqual(abs(flt(ordered_qty)), existing_ordered_qty)
|
||||||
self.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty)
|
self.assertEqual(abs(flt(reserved_qty)), existing_reserved_qty)
|
||||||
|
|
||||||
reserved_qty = frappe.db.get_value("Bin",
|
reserved_qty = frappe.db.get_value("Bin",
|
||||||
{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
|
{"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, "reserved_qty")
|
||||||
|
|
||||||
self.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty_for_dn_item)
|
self.assertEqual(abs(flt(reserved_qty)), existing_reserved_qty_for_dn_item)
|
||||||
|
|
||||||
def test_reserved_qty_for_closing_so(self):
|
def test_reserved_qty_for_closing_so(self):
|
||||||
bin = frappe.get_all("Bin", filters={"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"},
|
bin = frappe.get_all("Bin", filters={"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"},
|
||||||
@ -479,11 +479,11 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
|
|
||||||
so = make_sales_order(item_code="_Test Item", qty=1)
|
so = make_sales_order(item_code="_Test Item", qty=1)
|
||||||
|
|
||||||
self.assertEquals(get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_reserved_qty+1)
|
self.assertEqual(get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_reserved_qty+1)
|
||||||
|
|
||||||
so.update_status("Closed")
|
so.update_status("Closed")
|
||||||
|
|
||||||
self.assertEquals(get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_reserved_qty)
|
self.assertEqual(get_reserved_qty(item_code="_Test Item", warehouse="_Test Warehouse - _TC"), existing_reserved_qty)
|
||||||
|
|
||||||
def test_create_so_with_margin(self):
|
def test_create_so_with_margin(self):
|
||||||
so = make_sales_order(item_code="_Test Item", qty=1, do_not_submit=True)
|
so = make_sales_order(item_code="_Test Item", qty=1, do_not_submit=True)
|
||||||
@ -495,13 +495,13 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
new_so = frappe.copy_doc(so)
|
new_so = frappe.copy_doc(so)
|
||||||
new_so.save(ignore_permissions=True)
|
new_so.save(ignore_permissions=True)
|
||||||
|
|
||||||
self.assertEquals(new_so.get("items")[0].rate, flt((price_list_rate*25)/100 + price_list_rate))
|
self.assertEqual(new_so.get("items")[0].rate, flt((price_list_rate*25)/100 + price_list_rate))
|
||||||
new_so.items[0].margin_rate_or_amount = 25
|
new_so.items[0].margin_rate_or_amount = 25
|
||||||
new_so.payment_schedule = []
|
new_so.payment_schedule = []
|
||||||
new_so.save()
|
new_so.save()
|
||||||
new_so.submit()
|
new_so.submit()
|
||||||
|
|
||||||
self.assertEquals(new_so.get("items")[0].rate, flt((price_list_rate*25)/100 + price_list_rate))
|
self.assertEqual(new_so.get("items")[0].rate, flt((price_list_rate*25)/100 + price_list_rate))
|
||||||
|
|
||||||
def test_terms_auto_added(self):
|
def test_terms_auto_added(self):
|
||||||
so = make_sales_order(do_not_save=1)
|
so = make_sales_order(do_not_save=1)
|
||||||
@ -562,7 +562,7 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
# Check if Production Orders were raised
|
# Check if Production Orders were raised
|
||||||
for item in so_item_name:
|
for item in so_item_name:
|
||||||
po_qty = frappe.db.sql("select sum(qty) from `tabProduction Order` where sales_order=%s and sales_order_item=%s", (so.name, item))
|
po_qty = frappe.db.sql("select sum(qty) from `tabProduction Order` where sales_order=%s and sales_order_item=%s", (so.name, item))
|
||||||
self.assertEquals(po_qty[0][0], so_item_name.get(item))
|
self.assertEqual(po_qty[0][0], so_item_name.get(item))
|
||||||
|
|
||||||
def make_sales_order(**args):
|
def make_sales_order(**args):
|
||||||
so = frappe.new_doc("Sales Order")
|
so = frappe.new_doc("Sales Order")
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user