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 frappe.utils import getdate
|
||||
|
||||
__version__ = '10.1.2'
|
||||
__version__ = '10.1.4'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
@ -19,5 +19,5 @@ class TestFiscalYear(unittest.TestCase):
|
||||
"year_start_date": "2000-04-01"
|
||||
})
|
||||
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 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
|
||||
jv.cancel()
|
||||
|
@ -183,7 +183,7 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
pe.set_exchange_rate()
|
||||
pe.set_amounts()
|
||||
|
||||
self.assertEquals(pe.difference_amount, 500)
|
||||
self.assertEqual(pe.difference_amount, 500)
|
||||
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Exchange Gain/Loss - _TC",
|
||||
@ -260,10 +260,10 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_gle[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_gle[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_gle[gle.account][2], gle.credit)
|
||||
self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
|
||||
self.assertEqual(expected_gle[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_gle[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_gle[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_gle[gle.account][3], gle.against_voucher)
|
||||
|
||||
def get_gle(self, voucher_no):
|
||||
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"))
|
||||
|
||||
def on_submit(self):
|
||||
send_mail = True
|
||||
send_mail = self.payment_gateway_validation()
|
||||
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") \
|
||||
@ -58,6 +58,16 @@ class PaymentRequest(Document):
|
||||
si = si.insert(ignore_permissions=True)
|
||||
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):
|
||||
if self.payment_account:
|
||||
self.payment_url = self.get_payment_url()
|
||||
|
@ -47,18 +47,18 @@ class TestPaymentRequest(unittest.TestCase):
|
||||
so_inr = make_sales_order(currency="INR")
|
||||
pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com")
|
||||
|
||||
self.assertEquals(pr.reference_doctype, "Sales Order")
|
||||
self.assertEquals(pr.reference_name, so_inr.name)
|
||||
self.assertEquals(pr.currency, "INR")
|
||||
self.assertEqual(pr.reference_doctype, "Sales Order")
|
||||
self.assertEqual(pr.reference_name, so_inr.name)
|
||||
self.assertEqual(pr.currency, "INR")
|
||||
|
||||
conversion_rate = get_exchange_rate("USD", "INR")
|
||||
|
||||
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")
|
||||
|
||||
self.assertEquals(pr.reference_doctype, "Sales Invoice")
|
||||
self.assertEquals(pr.reference_name, si_usd.name)
|
||||
self.assertEquals(pr.currency, "USD")
|
||||
self.assertEqual(pr.reference_doctype, "Sales Invoice")
|
||||
self.assertEqual(pr.reference_name, si_usd.name)
|
||||
self.assertEqual(pr.currency, "USD")
|
||||
|
||||
def test_payment_entry(self):
|
||||
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)
|
||||
|
||||
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",
|
||||
currency="USD", conversion_rate=50)
|
||||
@ -98,7 +98,7 @@ class TestPaymentRequest(unittest.TestCase):
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_gle[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_gle[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_gle[gle.account][2], gle.credit)
|
||||
self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
|
||||
self.assertEqual(expected_gle[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_gle[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_gle[gle.account][2], gle.credit)
|
||||
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)
|
||||
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.assertEquals(len(customers), customers_count[0][0])
|
||||
self.assertEqual(len(items), products_count[0][0])
|
||||
self.assertEqual(len(customers), customers_count[0][0])
|
||||
|
||||
frappe.db.sql("delete from `tabPOS Profile`")
|
||||
|
||||
|
@ -45,7 +45,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
"name": None
|
||||
})
|
||||
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.applicable_for = "Customer"
|
||||
@ -56,7 +56,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
prule.discount_percentage = 20
|
||||
prule.insert()
|
||||
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.apply_on = "Item Group"
|
||||
@ -67,7 +67,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
|
||||
args.customer = "_Test Customer 1"
|
||||
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.applicable_for = "Campaign"
|
||||
@ -79,7 +79,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
|
||||
args.campaign = "_Test Campaign"
|
||||
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'")
|
||||
from erpnext.accounts.doctype.pricing_rule.pricing_rule import MultiplePricingRuleConflict
|
||||
@ -87,7 +87,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
|
||||
args.item_code = "_Test Item 2"
|
||||
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`")
|
||||
|
||||
@ -135,8 +135,8 @@ class TestPricingRule(unittest.TestCase):
|
||||
"name": None
|
||||
})
|
||||
details = get_item_details(args)
|
||||
self.assertEquals(details.get("margin_type"), "Percentage")
|
||||
self.assertEquals(details.get("margin_rate_or_amount"), 10)
|
||||
self.assertEqual(details.get("margin_type"), "Percentage")
|
||||
self.assertEqual(details.get("margin_rate_or_amount"), 10)
|
||||
|
||||
frappe.db.sql("delete from `tabPricing Rule`")
|
||||
|
||||
@ -193,7 +193,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
})
|
||||
|
||||
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
|
||||
frappe.get_doc({
|
||||
@ -210,7 +210,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
}).insert()
|
||||
|
||||
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):
|
||||
frappe.db.sql("delete from `tabPricing Rule`")
|
||||
@ -245,16 +245,16 @@ class TestPricingRule(unittest.TestCase):
|
||||
so.items[0].price_list_rate = 100
|
||||
so.submit()
|
||||
so = frappe.get_doc('Sales Order', so.name)
|
||||
self.assertEquals(so.items[0].discount_percentage, 17.5)
|
||||
self.assertEquals(so.items[0].rate, 82.5)
|
||||
self.assertEqual(so.items[0].discount_percentage, 17.5)
|
||||
self.assertEqual(so.items[0].rate, 82.5)
|
||||
|
||||
# Without pricing rule
|
||||
so = make_sales_order(item_code="_Test Item", qty=2, uom="Box", do_not_submit=True)
|
||||
so.items[0].price_list_rate = 100
|
||||
so.submit()
|
||||
so = frappe.get_doc('Sales Order', so.name)
|
||||
self.assertEquals(so.items[0].discount_percentage, 0)
|
||||
self.assertEquals(so.items[0].rate, 100)
|
||||
self.assertEqual(so.items[0].discount_percentage, 0)
|
||||
self.assertEqual(so.items[0].rate, 100)
|
||||
|
||||
def test_pricing_rule_with_margin_and_discount(self):
|
||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||
@ -265,16 +265,16 @@ class TestPricingRule(unittest.TestCase):
|
||||
si.insert(ignore_permissions=True)
|
||||
|
||||
item = si.items[0]
|
||||
self.assertEquals(item.rate, 1100)
|
||||
self.assertEquals(item.margin_rate_or_amount, 10)
|
||||
self.assertEqual(item.rate, 1100)
|
||||
self.assertEqual(item.margin_rate_or_amount, 10)
|
||||
|
||||
# With discount
|
||||
item.discount_percentage = 10
|
||||
si.payment_schedule = []
|
||||
si.save()
|
||||
item = si.items[0]
|
||||
self.assertEquals(item.rate, 990)
|
||||
self.assertEquals(item.discount_percentage, 10)
|
||||
self.assertEqual(item.rate, 990)
|
||||
self.assertEqual(item.discount_percentage, 10)
|
||||
frappe.db.sql("delete from `tabPricing Rule`")
|
||||
|
||||
def make_pricing_rule(**args):
|
||||
|
@ -121,9 +121,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
])
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
def test_purchase_invoice_change_naming_series(self):
|
||||
pi = frappe.copy_doc(test_records[1])
|
||||
@ -161,9 +161,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
])
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[i][0], gle.account)
|
||||
self.assertEquals(expected_values[i][1], gle.debit)
|
||||
self.assertEquals(expected_values[i][2], gle.credit)
|
||||
self.assertEqual(expected_values[i][0], gle.account)
|
||||
self.assertEqual(expected_values[i][1], gle.debit)
|
||||
self.assertEqual(expected_values[i][2], gle.credit)
|
||||
set_perpetual_inventory(0, pi.company)
|
||||
|
||||
def test_purchase_invoice_calculation(self):
|
||||
@ -363,8 +363,8 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
}
|
||||
|
||||
for gle in gl_entries:
|
||||
self.assertEquals(expected_values[gle.account][0], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.credit)
|
||||
|
||||
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 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
|
||||
@ -437,9 +437,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
])
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_gl_entries[gle.account][0], gle.account)
|
||||
self.assertEquals(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][0], gle.account)
|
||||
self.assertEqual(expected_gl_entries[gle.account][1], gle.debit)
|
||||
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):
|
||||
set_perpetual_inventory()
|
||||
@ -461,9 +461,9 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
])
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_gl_entries[gle.account][0], gle.account)
|
||||
self.assertEquals(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][0], gle.account)
|
||||
self.assertEqual(expected_gl_entries[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_gl_entries[gle.account][2], gle.credit)
|
||||
|
||||
def test_auto_batch(self):
|
||||
item_code = frappe.db.get_value('Item',
|
||||
@ -493,20 +493,20 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
posting_time=frappe.utils.nowtime())
|
||||
|
||||
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
|
||||
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()
|
||||
self.assertEquals(actual_qty_1 - 2, actual_qty_2)
|
||||
self.assertEqual(actual_qty_1 - 2, actual_qty_2)
|
||||
|
||||
pi1.cancel()
|
||||
self.assertEquals(actual_qty_1, get_qty_after_transaction())
|
||||
self.assertEqual(actual_qty_1, get_qty_after_transaction())
|
||||
|
||||
pi.reload()
|
||||
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):
|
||||
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,
|
||||
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")])
|
||||
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):
|
||||
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_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)
|
||||
|
||||
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)
|
||||
|
||||
def test_outstanding_amount_after_advance_jv_cancelation(self):
|
||||
@ -643,10 +643,10 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
pi.append("taxes", shipping_charge)
|
||||
pi.save()
|
||||
|
||||
self.assertEquals(pi.net_total, 1250)
|
||||
self.assertEqual(pi.net_total, 1250)
|
||||
|
||||
self.assertEquals(pi.total_taxes_and_charges, 462.3)
|
||||
self.assertEquals(pi.grand_total, 1712.3)
|
||||
self.assertEqual(pi.total_taxes_and_charges, 462.3)
|
||||
self.assertEqual(pi.grand_total, 1712.3)
|
||||
|
||||
def test_make_pi_without_terms(self):
|
||||
pi = make_purchase_invoice(do_not_save=1)
|
||||
|
@ -101,6 +101,8 @@ class SalesInvoice(SellingController):
|
||||
self.set_billing_hours_and_amount()
|
||||
self.update_timesheet_billing_for_project()
|
||||
self.set_status()
|
||||
if self.is_pos and not self.is_return:
|
||||
self.verify_payment_amount_is_positive()
|
||||
|
||||
def before_save(self):
|
||||
set_account_for_mode_of_payment(self)
|
||||
@ -905,6 +907,11 @@ class SalesInvoice(SellingController):
|
||||
project.update_billed_amount()
|
||||
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):
|
||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||
list_context = get_list_context(context)
|
||||
|
@ -78,17 +78,17 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.get("items")),
|
||||
self.assertEqual(len(si.get("items")),
|
||||
len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.get("items"):
|
||||
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
|
||||
self.assertEquals(si.base_net_total, 1250)
|
||||
self.assertEquals(si.net_total, 1250)
|
||||
self.assertEqual(si.base_net_total, 1250)
|
||||
self.assertEqual(si.net_total, 1250)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
@ -105,10 +105,10 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
for d in si.get("taxes"):
|
||||
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.assertEquals(si.grand_total, 1627.05)
|
||||
self.assertEqual(si.base_grand_total, 1627.05)
|
||||
self.assertEqual(si.grand_total, 1627.05)
|
||||
|
||||
def test_payment_entry_unlink_against_invoice(self):
|
||||
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
|
||||
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
|
||||
for d in si.get("items"):
|
||||
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
|
||||
self.assertEquals(si.total, 25)
|
||||
self.assertEquals(si.base_total, 1250)
|
||||
self.assertEquals(si.net_total, 25)
|
||||
self.assertEquals(si.base_net_total, 1250)
|
||||
self.assertEqual(si.total, 25)
|
||||
self.assertEqual(si.base_total, 1250)
|
||||
self.assertEqual(si.net_total, 25)
|
||||
self.assertEqual(si.base_net_total, 1250)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
@ -181,10 +181,10 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
for d in si.get("taxes"):
|
||||
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.assertEquals(si.grand_total, 32.55)
|
||||
self.assertEqual(si.base_grand_total, 1627.5)
|
||||
self.assertEqual(si.grand_total, 32.55)
|
||||
|
||||
def test_sales_invoice_with_discount_and_inclusive_tax(self):
|
||||
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
|
||||
@ -199,8 +199,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.insert()
|
||||
|
||||
# with inclusive tax
|
||||
self.assertEquals(si.net_total, 4385.96)
|
||||
self.assertEquals(si.grand_total, 5000)
|
||||
self.assertEqual(si.net_total, 4385.96)
|
||||
self.assertEqual(si.grand_total, 5000)
|
||||
|
||||
si.reload()
|
||||
|
||||
@ -212,8 +212,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.save()
|
||||
|
||||
# with inclusive tax and additional discount
|
||||
self.assertEquals(si.net_total, 4285.96)
|
||||
self.assertEquals(si.grand_total, 4885.99)
|
||||
self.assertEqual(si.net_total, 4285.96)
|
||||
self.assertEqual(si.grand_total, 4885.99)
|
||||
|
||||
si.reload()
|
||||
|
||||
@ -225,8 +225,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.save()
|
||||
|
||||
# with inclusive tax and additional discount
|
||||
self.assertEquals(si.net_total, 4298.25)
|
||||
self.assertEquals(si.grand_total, 4900.00)
|
||||
self.assertEqual(si.net_total, 4298.25)
|
||||
self.assertEqual(si.grand_total, 4900.00)
|
||||
|
||||
def test_sales_invoice_discount_amount(self):
|
||||
si = frappe.copy_doc(test_records[3])
|
||||
@ -273,16 +273,16 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
]
|
||||
|
||||
# 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
|
||||
for i, d in enumerate(si.get("items")):
|
||||
for k, v in expected_values[i].items():
|
||||
self.assertEquals(d.get(k), v)
|
||||
self.assertEqual(d.get(k), v)
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.base_net_total, 1163.45)
|
||||
self.assertEquals(si.total, 1578.3)
|
||||
self.assertEqual(si.base_net_total, 1163.45)
|
||||
self.assertEqual(si.total, 1578.3)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
@ -300,11 +300,11 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
for d in si.get("taxes"):
|
||||
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.assertEquals(si.grand_total, 1500)
|
||||
self.assertEquals(si.rounding_adjustment, -0.01)
|
||||
self.assertEqual(si.base_grand_total, 1500)
|
||||
self.assertEqual(si.grand_total, 1500)
|
||||
self.assertEqual(si.rounding_adjustment, -0.01)
|
||||
|
||||
def test_discount_amount_gl_entry(self):
|
||||
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:
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
# cancel
|
||||
si.cancel()
|
||||
@ -374,12 +374,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
})
|
||||
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.assertEquals(si.get("taxes")[0].total, 5474.0)
|
||||
self.assertEqual(si.get("taxes")[0].tax_amount, 874.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):
|
||||
si = create_sales_invoice(qty=1, rate=75, do_not_save=True)
|
||||
@ -403,13 +403,13 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
})
|
||||
si.insert()
|
||||
|
||||
self.assertEquals(si.total, 975)
|
||||
self.assertEquals(si.net_total, 900)
|
||||
self.assertEqual(si.total, 975)
|
||||
self.assertEqual(si.net_total, 900)
|
||||
|
||||
self.assertEquals(si.get("taxes")[0].tax_amount, 216.0)
|
||||
self.assertEquals(si.get("taxes")[0].total, 1116.0)
|
||||
self.assertEqual(si.get("taxes")[0].tax_amount, 216.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):
|
||||
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 = 191
|
||||
for i in xrange(6):
|
||||
for i in range(6):
|
||||
si.get("taxes")[i].included_in_print_rate = 1
|
||||
|
||||
# tax type "Actual" cannot be inclusive
|
||||
@ -441,16 +441,16 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
}
|
||||
|
||||
# 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
|
||||
for d in si.get("items"):
|
||||
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
|
||||
self.assertEquals(si.net_total, 1249.97)
|
||||
self.assertEquals(si.total, 1578.3)
|
||||
self.assertEqual(si.net_total, 1249.97)
|
||||
self.assertEqual(si.total, 1578.3)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
@ -467,10 +467,10 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
for d in si.get("taxes"):
|
||||
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.assertEquals(si.grand_total, 1622.97)
|
||||
self.assertEqual(si.base_grand_total, 1622.97)
|
||||
self.assertEqual(si.grand_total, 1622.97)
|
||||
|
||||
def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
|
||||
# prepare
|
||||
@ -519,17 +519,17 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
]
|
||||
|
||||
# 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
|
||||
for i, d in enumerate(si.get("items")):
|
||||
for key, val in expected_values[i].items():
|
||||
self.assertEquals(d.get(key), val)
|
||||
self.assertEqual(d.get(key), val)
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.base_net_total, 49501.5)
|
||||
self.assertEquals(si.net_total, 990.03)
|
||||
self.assertEquals(si.total, 1250)
|
||||
self.assertEqual(si.base_net_total, 49501.5)
|
||||
self.assertEqual(si.net_total, 990.03)
|
||||
self.assertEqual(si.total, 1250)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
@ -546,17 +546,17 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
for d in si.get("taxes"):
|
||||
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.assertEquals(si.grand_total, 1215.90)
|
||||
self.assertEquals(si.rounding_adjustment, 0.01)
|
||||
self.assertEquals(si.base_rounding_adjustment, 0.50)
|
||||
self.assertEqual(si.base_grand_total, 60795)
|
||||
self.assertEqual(si.grand_total, 1215.90)
|
||||
self.assertEqual(si.rounding_adjustment, 0.01)
|
||||
self.assertEqual(si.base_rounding_adjustment, 0.50)
|
||||
|
||||
|
||||
def test_outstanding(self):
|
||||
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):
|
||||
w = self.make()
|
||||
@ -570,7 +570,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
jv.insert()
|
||||
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_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'))
|
||||
|
||||
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):
|
||||
si = frappe.copy_doc(test_records[1])
|
||||
@ -601,9 +601,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
])
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
# cancel
|
||||
si.cancel()
|
||||
@ -628,7 +628,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.insert()
|
||||
si.submit()
|
||||
|
||||
self.assertEquals(si.paid_amount, 600.0)
|
||||
self.assertEqual(si.paid_amount, 600.0)
|
||||
|
||||
self.pos_gl_entry(si, pos, 300)
|
||||
|
||||
@ -648,8 +648,8 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.insert()
|
||||
si.submit()
|
||||
|
||||
self.assertEquals(si.grand_total, 630.0)
|
||||
self.assertEquals(si.write_off_amount, -5)
|
||||
self.assertEqual(si.grand_total, 630.0)
|
||||
self.assertEqual(si.write_off_amount, -5)
|
||||
|
||||
def test_make_pos_invoice(self):
|
||||
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
|
||||
@ -667,11 +667,11 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
invoice_data = [{'09052016142': pos}]
|
||||
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})
|
||||
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)
|
||||
|
||||
@ -699,19 +699,19 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
invoice_data = [{timestamp: pos}]
|
||||
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})
|
||||
self.assertEquals(sales_invoice[0].docstatus, 0)
|
||||
self.assertEqual(sales_invoice[0].docstatus, 0)
|
||||
|
||||
timestamp = cint(time.time())
|
||||
pos["offline_pos_name"] = timestamp
|
||||
invoice_data = [{timestamp: pos}]
|
||||
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})
|
||||
self.assertEquals(sales_invoice1[0].docstatus, 0)
|
||||
self.assertEqual(sales_invoice1[0].docstatus, 0)
|
||||
|
||||
if allow_negative_stock:
|
||||
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""",
|
||||
si.name, as_dict=1)[0]
|
||||
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])
|
||||
|
||||
# check gl entries
|
||||
@ -747,9 +747,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
])
|
||||
|
||||
for i, gle in enumerate(sorted(gl_entries, key=lambda gle: gle.account)):
|
||||
self.assertEquals(expected_gl_entries[i][0], gle.account)
|
||||
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
||||
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
||||
self.assertEqual(expected_gl_entries[i][0], gle.account)
|
||||
self.assertEqual(expected_gl_entries[i][1], gle.debit)
|
||||
self.assertEqual(expected_gl_entries[i][2], gle.credit)
|
||||
|
||||
si.cancel()
|
||||
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],
|
||||
])
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
|
||||
@ -807,9 +807,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
[test_records[1]["taxes"][1]["account_head"], 0.0, 50.0],
|
||||
])
|
||||
for i, gle in enumerate(gl_entries):
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
set_perpetual_inventory(0)
|
||||
|
||||
@ -881,9 +881,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.submit()
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
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],
|
||||
"delivery_document_no"))
|
||||
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.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):
|
||||
set_perpetual_inventory()
|
||||
@ -951,7 +951,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si = create_sales_invoice(qty=5, rate=500, update_stock=1)
|
||||
|
||||
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 = 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()
|
||||
|
||||
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",
|
||||
{"voucher_type": "Sales Invoice", "voucher_no": si1.name},
|
||||
["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)
|
||||
|
||||
# Check gl entry
|
||||
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
|
||||
"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",
|
||||
"voucher_no": si1.name, "account": "Debtors - _TC", "party": "_Test Customer"}, "credit")
|
||||
@ -1003,19 +1003,19 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.get("items")),
|
||||
self.assertEqual(len(si.get("items")),
|
||||
len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.get("items"):
|
||||
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
|
||||
self.assertEquals(si.base_total, 1250)
|
||||
self.assertEquals(si.total, 1250)
|
||||
self.assertEquals(si.base_net_total, 625)
|
||||
self.assertEquals(si.net_total, 625)
|
||||
self.assertEqual(si.base_total, 1250)
|
||||
self.assertEqual(si.total, 1250)
|
||||
self.assertEqual(si.base_net_total, 625)
|
||||
self.assertEqual(si.net_total, 625)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
@ -1034,12 +1034,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
for d in si.get("taxes"):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
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.assertEquals(si.base_grand_total, 859.43)
|
||||
self.assertEquals(si.grand_total, 859.43)
|
||||
self.assertEqual(si.total_taxes_and_charges, 234.43)
|
||||
self.assertEqual(si.base_grand_total, 859.43)
|
||||
self.assertEqual(si.grand_total, 859.43)
|
||||
|
||||
def test_multi_currency_gle(self):
|
||||
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 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
|
||||
si.cancel()
|
||||
@ -1233,7 +1233,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
# check if the conversion_factor and price_list_rate is calculated according to uom
|
||||
for d in si.get("items"):
|
||||
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):
|
||||
frappe.flags.country = "India"
|
||||
@ -1363,9 +1363,9 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
order by account asc""", si.name, as_dict=1)
|
||||
|
||||
for gle in gl_entries:
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
def test_sales_invoice_with_shipping_rule(self):
|
||||
from erpnext.accounts.doctype.shipping_rule.test_shipping_rule \
|
||||
@ -1395,10 +1395,10 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.append("taxes", shipping_charge)
|
||||
si.save()
|
||||
|
||||
self.assertEquals(si.net_total, 1250)
|
||||
self.assertEqual(si.net_total, 1250)
|
||||
|
||||
self.assertEquals(si.total_taxes_and_charges, 577.05)
|
||||
self.assertEquals(si.grand_total, 1827.05)
|
||||
self.assertEqual(si.total_taxes_and_charges, 577.05)
|
||||
self.assertEqual(si.grand_total, 1827.05)
|
||||
|
||||
def test_create_invoice_without_terms(self):
|
||||
si = create_sales_invoice(do_not_save=1)
|
||||
|
@ -133,8 +133,8 @@ class ShippingRule(Document):
|
||||
return (not separate)
|
||||
|
||||
overlaps = []
|
||||
for i in xrange(0, len(self.conditions)):
|
||||
for j in xrange(i+1, len(self.conditions)):
|
||||
for i in range(0, len(self.conditions)):
|
||||
for j in range(i+1, len(self.conditions)):
|
||||
d1, d2 = self.conditions[i], self.conditions[j]
|
||||
if d1.as_dict() != d2.as_dict():
|
||||
# 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()
|
||||
|
||||
doc = make_subscription(reference_document=qo.name)
|
||||
self.assertEquals(doc.next_schedule_date, today())
|
||||
self.assertEqual(doc.next_schedule_date, today())
|
||||
make_subscription_entry()
|
||||
frappe.db.commit()
|
||||
|
||||
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',
|
||||
{'subscription': doc.name, 'name': ('!=', quotation.name)}, 'name')
|
||||
@ -31,10 +31,10 @@ class TestSubscription(unittest.TestCase):
|
||||
new_quotation = frappe.get_doc('Quotation', new_quotation)
|
||||
|
||||
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']:
|
||||
self.assertEquals(quotation.items[0].get(fieldname),
|
||||
self.assertEqual(quotation.items[0].get(fieldname),
|
||||
new_quotation.items[0].get(fieldname))
|
||||
|
||||
def test_monthly_subscription_for_so(self):
|
||||
@ -60,7 +60,7 @@ class TestSubscription(unittest.TestCase):
|
||||
|
||||
make_subscription_entry()
|
||||
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.disabled = 0
|
||||
@ -70,7 +70,7 @@ class TestSubscription(unittest.TestCase):
|
||||
make_subscription_entry()
|
||||
|
||||
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')
|
||||
|
||||
|
@ -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")
|
||||
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")
|
||||
|
||||
def test_conflict_with_overlapping_dates(self):
|
||||
@ -59,7 +59,7 @@ class TestTaxRule(unittest.TestCase):
|
||||
|
||||
def test_tax_template(self):
|
||||
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):
|
||||
@ -72,7 +72,7 @@ class TestTaxRule(unittest.TestCase):
|
||||
make_tax_rule(customer= "_Test Customer 2",
|
||||
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")
|
||||
|
||||
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",
|
||||
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")
|
||||
|
||||
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",
|
||||
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")
|
||||
|
||||
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",
|
||||
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")
|
||||
|
||||
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",
|
||||
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)
|
||||
|
||||
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",
|
||||
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")
|
||||
|
||||
|
||||
|
@ -1,10 +1,15 @@
|
||||
<style>
|
||||
@media screen {
|
||||
.print-format {
|
||||
padding: 8mm;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
<style>
|
||||
@media screen {
|
||||
.print-format {
|
||||
padding: 8mm;
|
||||
margin:4mm;
|
||||
font-size:10px;
|
||||
font-family: Tahoma, sans-serif;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% } %}
|
||||
|
||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
||||
@ -82,21 +87,24 @@
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<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: 10%">{%= __("Invoiced Amount") %}</th>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<th style="width: 10%">{%= __("Paid Amount") %}</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(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: 6%">{%= __("PDC/LC Ref") %}</th>
|
||||
<th style="width: 6%">{%= __("PDC/LC Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("PDC/LC Date") %}</th>
|
||||
<th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
|
||||
<th style="width: 10%">{%= __("PDC/LC Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<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>{%= data[i][__("Voucher Type")] %}
|
||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
@ -127,6 +136,7 @@
|
||||
<br>{%= __("Remarks") %}:
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= 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">{%= 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][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<td></td>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td></td>
|
||||
{% } %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= 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">{%= 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][__("Remaining Balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
|
@ -159,7 +159,7 @@ class ReceivablePayableReport(object):
|
||||
else:
|
||||
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"))
|
||||
row += [pdc.get("pdc_date"), pdc.get("pdc_ref"),
|
||||
flt(pdc.get("pdc_amount")), remaining_balance]
|
||||
@ -405,25 +405,33 @@ def get_pdc_details(party_type):
|
||||
on
|
||||
(pref.parent = pent.name)
|
||||
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
|
||||
group by pref.reference_name""", party_type, as_dict=1):
|
||||
pdc_details.setdefault(pdc.invoice_no, pdc)
|
||||
group by pent.party, pref.reference_name""", party_type, as_dict=1):
|
||||
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("""
|
||||
select
|
||||
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
|
||||
from
|
||||
`tabJournal Entry` as je inner join `tabJournal Entry Account` as jea
|
||||
on
|
||||
(jea.parent = je.name)
|
||||
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
|
||||
group by jea.reference_name""", party_type, as_dict=1):
|
||||
pdc_details.setdefault(pdc.invoice_no, pdc)
|
||||
group by jea.party, jea.reference_name""".format(amount_field), party_type, as_dict=1):
|
||||
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
|
||||
|
||||
|
@ -5,6 +5,8 @@ from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
import functools
|
||||
|
||||
import frappe
|
||||
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
|
||||
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
|
||||
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({
|
||||
"from_date": start_date
|
||||
})
|
||||
@ -325,7 +327,7 @@ def sort_root_accounts(roots):
|
||||
return -1
|
||||
return 1
|
||||
|
||||
roots.sort(compare_roots)
|
||||
roots.sort(key = functools.cmp_to_key(compare_roots))
|
||||
|
||||
|
||||
def set_gl_entries_by_account(
|
||||
|
@ -9,9 +9,9 @@
|
||||
{% } %}
|
||||
</h4>
|
||||
<h5 class="text-center">
|
||||
{%= dateutil.str_to_user(filters.from_date) %}
|
||||
{%= frappe.datetime.str_to_user(filters.from_date) %}
|
||||
{%= __("to") %}
|
||||
{%= dateutil.str_to_user(filters.to_date) %}
|
||||
{%= frappe.datetime.str_to_user(filters.to_date) %}
|
||||
</h5>
|
||||
<hr>
|
||||
<table class="table table-bordered">
|
||||
@ -29,7 +29,7 @@
|
||||
{% for(var i=0, l=data.length; i<l; i++) { %}
|
||||
<tr>
|
||||
{% 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 %}
|
||||
<br>{%= data[i].voucher_no %}</td>
|
||||
<td>
|
||||
@ -58,7 +58,7 @@
|
||||
<td style="text-align: right">
|
||||
{%= data[i].account && format_currency(data[i].credit, filters.presentation_currency) %}
|
||||
</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i].balance, filters.presentation_currency) %}
|
||||
</td>
|
||||
@ -66,4 +66,4 @@
|
||||
{% } %}
|
||||
</tbody>
|
||||
</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"):
|
||||
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)"""
|
||||
|
||||
return conditions
|
||||
|
@ -11,4 +11,4 @@ test_dependencies = ["Fertilizer"]
|
||||
class TestCrop(unittest.TestCase):
|
||||
def test_crop_period(self):
|
||||
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):
|
||||
def test_crop_cycle_creation(self):
|
||||
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
|
||||
self.assertEquals(check_task_creation(), True)
|
||||
self.assertEquals(check_project_creation(), True)
|
||||
self.assertEqual(check_task_creation(), True)
|
||||
self.assertEqual(check_project_creation(), True)
|
||||
|
||||
def check_task_creation():
|
||||
all_task_dict = {
|
||||
|
@ -9,4 +9,4 @@ import unittest
|
||||
class TestDisease(unittest.TestCase):
|
||||
def test_treatment_period(self):
|
||||
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):
|
||||
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_unit_string = str(formatted_land_units)
|
||||
test_land = frappe.get_doc('Land Unit', 'Test Land')
|
||||
self.assertEquals(formatted_land_unit_string, str(json.loads(test_land.get('location'))['features']))
|
||||
self.assertEquals(area, test_land.get('area'))
|
||||
self.assertEqual(formatted_land_unit_string, str(json.loads(test_land.get('location'))['features']))
|
||||
self.assertEqual(area, test_land.get('area'))
|
||||
|
@ -10,5 +10,5 @@ class TestSoilTexture(unittest.TestCase):
|
||||
def test_texture_selection(self):
|
||||
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)
|
||||
self.assertEquals(doc.silt_composition, 50)
|
||||
self.assertEquals(doc.soil_type, 'Silt Loam')
|
||||
self.assertEqual(doc.silt_composition, 50)
|
||||
self.assertEqual(doc.soil_type, 'Silt Loam')
|
@ -114,15 +114,15 @@ class Asset(Document):
|
||||
and getdate(self.next_depreciation_date) < next_depr_date):
|
||||
|
||||
number_of_pending_depreciations += 1
|
||||
for n in xrange(number_of_pending_depreciations):
|
||||
if n == xrange(number_of_pending_depreciations)[-1]:
|
||||
for n in range(number_of_pending_depreciations):
|
||||
if n == range(number_of_pending_depreciations)[-1]:
|
||||
schedule_date = add_months(self.available_for_use_date, n * 12)
|
||||
previous_scheduled_date = add_months(self.next_depreciation_date, (n-1) * 12)
|
||||
depreciation_amount = \
|
||||
self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
|
||||
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
|
||||
depreciation_amount = \
|
||||
self.get_depreciation_amount_prorata_temporis(value_after_depreciation,
|
||||
@ -141,7 +141,7 @@ class Asset(Document):
|
||||
"depreciation_amount": depreciation_amount
|
||||
})
|
||||
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,
|
||||
n * cint(self.frequency_of_depreciation))
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -71,6 +72,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -103,6 +105,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 1,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -136,6 +139,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -167,6 +171,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -198,6 +203,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -228,6 +234,40 @@
|
||||
"reqd": 0,
|
||||
"search_index": 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
|
||||
},
|
||||
{
|
||||
@ -258,6 +298,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -291,6 +332,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -322,6 +364,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -354,6 +397,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -387,6 +431,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -418,6 +463,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -450,6 +496,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -481,6 +528,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -510,6 +558,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -542,6 +591,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -572,6 +622,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -602,6 +653,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -633,6 +685,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -663,6 +716,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -693,6 +747,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -723,6 +778,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -753,6 +809,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -782,6 +839,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -811,6 +869,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -840,6 +899,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -869,6 +929,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -901,6 +962,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -931,6 +993,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -961,6 +1024,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -993,6 +1057,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1026,6 +1091,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1054,6 +1120,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1084,6 +1151,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1114,6 +1182,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1144,6 +1213,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1173,6 +1243,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1204,6 +1275,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1236,6 +1308,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1267,6 +1340,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1298,6 +1372,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1326,6 +1401,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1357,6 +1433,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1389,6 +1466,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1417,6 +1495,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1448,6 +1527,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1480,6 +1560,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1510,6 +1591,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1541,6 +1623,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1574,6 +1657,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1603,6 +1687,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1634,6 +1719,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1663,6 +1749,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1695,6 +1782,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1725,6 +1813,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1755,6 +1844,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1786,6 +1876,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1818,6 +1909,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1850,6 +1942,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1882,6 +1975,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1911,6 +2005,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1943,6 +2038,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1975,6 +2071,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2006,6 +2103,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2037,6 +2135,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2069,6 +2168,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2100,6 +2200,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2129,6 +2230,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2159,6 +2261,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2190,6 +2293,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2219,6 +2323,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2251,6 +2356,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2282,6 +2388,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2314,6 +2421,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2346,6 +2454,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2375,6 +2484,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2407,6 +2517,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2438,6 +2549,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2469,6 +2581,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2499,6 +2612,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2529,6 +2643,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2560,6 +2675,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2591,6 +2707,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2623,6 +2740,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2655,6 +2773,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2686,6 +2805,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2716,6 +2836,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2749,6 +2870,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2780,6 +2902,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2811,6 +2934,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2840,6 +2964,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2873,6 +2998,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2906,6 +3032,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -2937,6 +3064,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -2970,6 +3098,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3002,6 +3131,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3031,6 +3161,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3062,6 +3193,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3094,6 +3226,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3156,6 +3289,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3189,6 +3323,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3219,6 +3354,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3250,6 +3386,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3281,6 +3418,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3310,6 +3448,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -3341,6 +3480,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -3355,7 +3495,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-17 11:00:05.037716",
|
||||
"modified": "2018-02-21 14:26:17.099336",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
@ -332,7 +332,8 @@ def make_purchase_receipt(source_name, target_doc=None):
|
||||
"Purchase Order": {
|
||||
"doctype": "Purchase Receipt",
|
||||
"field_map": {
|
||||
"per_billed": "per_billed"
|
||||
"per_billed": "per_billed",
|
||||
"supplier_warehouse":"supplier_warehouse"
|
||||
},
|
||||
"validation": {
|
||||
"docstatus": ["=", 1],
|
||||
@ -377,7 +378,8 @@ def make_purchase_invoice(source_name, target_doc=None):
|
||||
"Purchase Order": {
|
||||
"doctype": "Purchase Invoice",
|
||||
"field_map": {
|
||||
"party_account_currency": "party_account_currency"
|
||||
"party_account_currency": "party_account_currency",
|
||||
"supplier_warehouse":"supplier_warehouse"
|
||||
},
|
||||
"validation": {
|
||||
"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.address_display = purchase_order.address_display
|
||||
stock_entry.company = purchase_order.company
|
||||
stock_entry.to_warehouse = purchase_order.supplier_warehouse
|
||||
stock_entry.from_bom = 1
|
||||
for item_code in item_code_list:
|
||||
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):
|
||||
po = frappe.get_doc("Purchase Order", name)
|
||||
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()
|
||||
|
||||
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):
|
||||
existing_ordered_qty = get_ordered_qty()
|
||||
@ -32,7 +32,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 6)
|
||||
|
||||
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)
|
||||
|
||||
@ -40,13 +40,13 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty)
|
||||
|
||||
po.load_from_db()
|
||||
self.assertEquals(po.get("items")[0].received_qty, 12)
|
||||
self.assertEqual(po.get("items")[0].received_qty, 12)
|
||||
|
||||
pr.cancel()
|
||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 6)
|
||||
|
||||
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):
|
||||
existing_ordered_qty = get_ordered_qty()
|
||||
@ -66,13 +66,13 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty)
|
||||
|
||||
po.load_from_db()
|
||||
self.assertEquals(po.get("items")[0].received_qty, 12)
|
||||
self.assertEqual(po.get("items")[0].received_qty, 12)
|
||||
|
||||
pi.cancel()
|
||||
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10)
|
||||
|
||||
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):
|
||||
po = create_purchase_order(do_not_submit=True)
|
||||
@ -82,8 +82,8 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
po.submit()
|
||||
pi = make_purchase_invoice(po.name)
|
||||
|
||||
self.assertEquals(pi.doctype, "Purchase Invoice")
|
||||
self.assertEquals(len(pi.get("items", [])), 1)
|
||||
self.assertEqual(pi.doctype, "Purchase Invoice")
|
||||
self.assertEqual(len(pi.get("items", [])), 1)
|
||||
|
||||
def test_make_purchase_invoice_with_terms(self):
|
||||
po = create_purchase_order(do_not_save=True)
|
||||
@ -104,8 +104,8 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
pi = make_purchase_invoice(po.name)
|
||||
pi.save()
|
||||
|
||||
self.assertEquals(pi.doctype, "Purchase Invoice")
|
||||
self.assertEquals(len(pi.get("items", [])), 1)
|
||||
self.assertEqual(pi.doctype, "Purchase Invoice")
|
||||
self.assertEqual(len(pi.get("items", [])), 1)
|
||||
|
||||
self.assertEqual(pi.payment_schedule[0].payment_amount, 2500.0)
|
||||
self.assertEqual(pi.payment_schedule[0].due_date, po.transaction_date)
|
||||
@ -114,7 +114,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
|
||||
def test_subcontracting(self):
|
||||
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):
|
||||
from erpnext.stock.utils import InvalidWarehouseCompany
|
||||
@ -134,11 +134,11 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
|
||||
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")
|
||||
|
||||
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):
|
||||
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",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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.assertEquals(bin2.projected_qty, bin1.projected_qty - 10)
|
||||
self.assertEqual(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10)
|
||||
self.assertEqual(bin2.projected_qty, bin1.projected_qty - 10)
|
||||
|
||||
# Create stock transfer
|
||||
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"},
|
||||
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
|
||||
po.update_status("Closed")
|
||||
@ -223,7 +223,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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
|
||||
po.update_status("Submitted")
|
||||
@ -231,7 +231,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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
|
||||
pr = make_purchase_receipt(po.name)
|
||||
@ -243,7 +243,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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
|
||||
pr.cancel()
|
||||
@ -251,7 +251,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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
|
||||
pi = make_purchase_invoice(po.name)
|
||||
@ -263,7 +263,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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
|
||||
pi.cancel()
|
||||
@ -271,14 +271,14 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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
|
||||
se.cancel()
|
||||
bin10 = frappe.db.get_value("Bin",
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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
|
||||
po.reload()
|
||||
@ -287,7 +287,7 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
|
||||
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():
|
||||
return [
|
||||
|
@ -14,8 +14,8 @@ class TestRequestforQuotation(unittest.TestCase):
|
||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import make_supplier_quotation
|
||||
rfq = make_request_for_quotation()
|
||||
|
||||
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Pending')
|
||||
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'Pending')
|
||||
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Pending')
|
||||
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'Pending')
|
||||
|
||||
# Submit the first supplier quotation
|
||||
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)
|
||||
|
||||
self.assertEquals(rfq.get('suppliers')[0].quote_status, 'Received')
|
||||
self.assertEquals(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
||||
self.assertEqual(rfq.get('suppliers')[0].quote_status, 'Received')
|
||||
self.assertEqual(rfq.get('suppliers')[1].quote_status, 'No Quote')
|
||||
|
||||
def test_make_supplier_quotation(self):
|
||||
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.submit()
|
||||
|
||||
self.assertEquals(sq.supplier, rfq.get('suppliers')[0].supplier)
|
||||
self.assertEquals(sq.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEquals(sq.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEquals(sq.get('items')[0].qty, 5)
|
||||
self.assertEqual(sq.supplier, rfq.get('suppliers')[0].supplier)
|
||||
self.assertEqual(sq.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEqual(sq.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEqual(sq.get('items')[0].qty, 5)
|
||||
|
||||
self.assertEquals(sq1.supplier, rfq.get('suppliers')[1].supplier)
|
||||
self.assertEquals(sq1.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEquals(sq1.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEquals(sq1.get('items')[0].qty, 5)
|
||||
self.assertEqual(sq1.supplier, rfq.get('suppliers')[1].supplier)
|
||||
self.assertEqual(sq1.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEqual(sq1.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEqual(sq1.get('items')[0].qty, 5)
|
||||
|
||||
def test_make_supplier_quotation_with_special_characters(self):
|
||||
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)
|
||||
|
||||
self.assertEquals(supplier_quotation_doc.supplier, rfq.get('suppliers')[0].supplier)
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].qty, 5)
|
||||
self.assertEquals(supplier_quotation_doc.get('items')[0].amount, 500)
|
||||
self.assertEqual(supplier_quotation_doc.supplier, rfq.get('suppliers')[0].supplier)
|
||||
self.assertEqual(supplier_quotation_doc.get('items')[0].request_for_quotation, rfq.name)
|
||||
self.assertEqual(supplier_quotation_doc.get('items')[0].item_code, "_Test Item")
|
||||
self.assertEqual(supplier_quotation_doc.get('items')[0].qty, 5)
|
||||
self.assertEqual(supplier_quotation_doc.get('items')[0].amount, 500)
|
||||
|
||||
|
||||
def make_request_for_quotation(supplier_data=None):
|
||||
|
@ -20,8 +20,8 @@ class TestPurchaseOrder(unittest.TestCase):
|
||||
sq.submit()
|
||||
po = make_purchase_order(sq.name)
|
||||
|
||||
self.assertEquals(po.doctype, "Purchase Order")
|
||||
self.assertEquals(len(po.get("items")), len(sq.get("items")))
|
||||
self.assertEqual(po.doctype, "Purchase Order")
|
||||
self.assertEqual(len(po.get("items")), len(sq.get("items")))
|
||||
|
||||
po.naming_series = "_T-Purchase Order-"
|
||||
|
||||
|
@ -13,9 +13,9 @@ class TestSupplierScorecardVariable(unittest.TestCase):
|
||||
def test_variable_exist(self):
|
||||
for d in test_existing_variables:
|
||||
my_doc = frappe.get_doc("Supplier Scorecard Variable", d.get("name"))
|
||||
self.assertEquals(my_doc.param_name, d.get('param_name'))
|
||||
self.assertEquals(my_doc.variable_label, d.get('variable_label'))
|
||||
self.assertEquals(my_doc.path, d.get('path'))
|
||||
self.assertEqual(my_doc.param_name, d.get('param_name'))
|
||||
self.assertEqual(my_doc.variable_label, d.get('variable_label'))
|
||||
self.assertEqual(my_doc.path, d.get('path'))
|
||||
|
||||
def test_path_exists(self):
|
||||
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)
|
||||
|
||||
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)
|
||||
if period_end_date > getdate(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")
|
||||
|
||||
customer = make_customer("_T-Lead-00001")
|
||||
self.assertEquals(customer.doctype, "Customer")
|
||||
self.assertEquals(customer.lead_name, "_T-Lead-00001")
|
||||
self.assertEqual(customer.doctype, "Customer")
|
||||
self.assertEqual(customer.lead_name, "_T-Lead-00001")
|
||||
|
||||
customer.company = "_Test Company"
|
||||
customer.customer_group = "_Test Customer Group"
|
||||
@ -26,8 +26,8 @@ class TestLead(unittest.TestCase):
|
||||
from erpnext.crm.doctype.lead.lead import make_customer
|
||||
|
||||
customer = make_customer("_T-Lead-00002")
|
||||
self.assertEquals(customer.doctype, "Customer")
|
||||
self.assertEquals(customer.lead_name, "_T-Lead-00002")
|
||||
self.assertEqual(customer.doctype, "Customer")
|
||||
self.assertEqual(customer.lead_name, "_T-Lead-00002")
|
||||
|
||||
customer.company = "_Test Company"
|
||||
customer.customer_group = "_Test Customer Group"
|
||||
|
@ -24,7 +24,7 @@ class TestOpportunity(unittest.TestCase):
|
||||
quotation.submit()
|
||||
|
||||
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):
|
||||
args = {
|
||||
@ -38,8 +38,8 @@ class TestOpportunity(unittest.TestCase):
|
||||
opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
|
||||
|
||||
self.assertTrue(opp_doc.lead)
|
||||
self.assertEquals(opp_doc.enquiry_from, "Lead")
|
||||
self.assertEquals(frappe.db.get_value("Lead", opp_doc.lead, "email_id"),
|
||||
self.assertEqual(opp_doc.enquiry_from, "Lead")
|
||||
self.assertEqual(frappe.db.get_value("Lead", opp_doc.lead, "email_id"),
|
||||
'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)
|
||||
self.assertTrue(opp_doc.customer)
|
||||
self.assertEquals(opp_doc.enquiry_from, "Customer")
|
||||
self.assertEquals(opp_doc.customer, customer.name)
|
||||
self.assertEqual(opp_doc.enquiry_from, "Customer")
|
||||
self.assertEqual(opp_doc.customer, customer.name)
|
||||
|
||||
def make_opportunity(**args):
|
||||
args = frappe._dict(args)
|
||||
|
@ -63,7 +63,7 @@ def simulate(domain='Manufacturing', days=100):
|
||||
# runs_for = 100
|
||||
|
||||
fixed_asset.work()
|
||||
for i in xrange(runs_for):
|
||||
for i in range(runs_for):
|
||||
sys.stdout.write("\rSimulating {0}: Day {1}".format(
|
||||
current_date.strftime("%Y-%m-%d"), i))
|
||||
sys.stdout.flush()
|
||||
|
@ -65,7 +65,7 @@ def make_appointment():
|
||||
i += 1
|
||||
|
||||
def make_consulation():
|
||||
for i in xrange(3):
|
||||
for i in range(3):
|
||||
physician = get_random("Physician")
|
||||
department = frappe.get_value("Physician", physician, "department")
|
||||
patient = get_random("Patient")
|
||||
@ -74,7 +74,7 @@ def make_consulation():
|
||||
consultation.save(ignore_permissions=True)
|
||||
|
||||
def consulation_on_appointment():
|
||||
for i in xrange(3):
|
||||
for i in range(3):
|
||||
appointment = get_random("Patient Appointment")
|
||||
appointment = frappe.get_doc("Patient Appointment",appointment)
|
||||
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():
|
||||
fiscal_year = None
|
||||
for year in xrange(2010, now_datetime().year + 1, 1):
|
||||
for year in range(2010, now_datetime().year + 1, 1):
|
||||
try:
|
||||
fiscal_year = frappe.get_doc({
|
||||
"doctype": "Fiscal Year",
|
||||
|
@ -15,7 +15,7 @@ from erpnext.education.api import get_student_group_students, make_attendance_re
|
||||
|
||||
def work():
|
||||
frappe.set_user(frappe.db.get_global('demo_education_user'))
|
||||
for d in xrange(20):
|
||||
for d in range(20):
|
||||
approve_random_student_applicant()
|
||||
enroll_random_student(frappe.flags.current_date)
|
||||
# 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_end_date = cstr(end_date)
|
||||
day = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
||||
for x in xrange(3):
|
||||
for x in range(3):
|
||||
random_day = random.choice(day)
|
||||
cs.day = random_day
|
||||
cs.from_time = timedelta(hours=(random.randrange(7, 17,1)))
|
||||
|
@ -116,7 +116,7 @@ def make_material_request(item_code, qty):
|
||||
return mr
|
||||
|
||||
def add_suppliers(rfq):
|
||||
for i in xrange(2):
|
||||
for i in range(2):
|
||||
supplier = get_random("Supplier")
|
||||
if supplier not in [d.supplier for d in rfq.get('suppliers')]:
|
||||
rfq.append("suppliers", { "supplier": supplier })
|
||||
|
@ -13,27 +13,27 @@ from erpnext.accounts.doctype.payment_request.payment_request import make_paymen
|
||||
def work():
|
||||
frappe.set_user(frappe.db.get_global('demo_sales_user_2'))
|
||||
if random.random() < 0.5:
|
||||
for i in xrange(random.randint(1,7)):
|
||||
for i in range(random.randint(1,7)):
|
||||
make_opportunity()
|
||||
|
||||
if random.random() < 0.5:
|
||||
for i in xrange(random.randint(1,3)):
|
||||
for i in range(random.randint(1,3)):
|
||||
make_quotation()
|
||||
|
||||
# lost quotations / inquiries
|
||||
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)
|
||||
if quotation and quotation.status == 'Submitted':
|
||||
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)
|
||||
if opportunity and opportunity.status in ('Open', 'Replied'):
|
||||
opportunity.declare_enquiry_lost('Did not ask')
|
||||
|
||||
if random.random() < 0.3:
|
||||
for i in xrange(random.randint(1,3)):
|
||||
for i in range(random.randint(1,3)):
|
||||
make_sales_order()
|
||||
|
||||
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):
|
||||
def test_grade(self):
|
||||
grade = get_grade("_Test Grading Scale", 80)
|
||||
self.assertEquals("A", grade)
|
||||
self.assertEqual("A", grade)
|
||||
|
||||
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)
|
||||
|
||||
if gl_entries[0].account == "_Test Receivable - _TC":
|
||||
self.assertEquals(gl_entries[0].debit, 50000)
|
||||
self.assertEquals(gl_entries[0].credit, 0)
|
||||
self.assertEquals(gl_entries[1].debit, 0)
|
||||
self.assertEquals(gl_entries[1].credit, 50000)
|
||||
self.assertEqual(gl_entries[0].debit, 50000)
|
||||
self.assertEqual(gl_entries[0].credit, 0)
|
||||
self.assertEqual(gl_entries[1].debit, 0)
|
||||
self.assertEqual(gl_entries[1].credit, 50000)
|
||||
else:
|
||||
self.assertEquals(gl_entries[0].credit, 50000)
|
||||
self.assertEquals(gl_entries[0].debit, 0)
|
||||
self.assertEquals(gl_entries[1].credit, 0)
|
||||
self.assertEquals(gl_entries[1].debit, 50000)
|
||||
self.assertEqual(gl_entries[0].credit, 50000)
|
||||
self.assertEqual(gl_entries[0].debit, 0)
|
||||
self.assertEqual(gl_entries[1].credit, 0)
|
||||
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.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)
|
||||
|
||||
if student_guardians:
|
||||
for i in xrange(2):
|
||||
for i in range(2):
|
||||
if i < len(student_guardians):
|
||||
g = student_guardians[i]
|
||||
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)"
|
||||
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"
|
||||
|
||||
|
@ -18,7 +18,7 @@ class HotelRoomReservation(Document):
|
||||
self.validate_availability()
|
||||
|
||||
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)
|
||||
self.rooms_booked = {}
|
||||
|
||||
@ -54,7 +54,7 @@ class HotelRoomReservation(Document):
|
||||
self.net_total = 0
|
||||
for d in self.items:
|
||||
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)
|
||||
if not d.item:
|
||||
continue
|
||||
|
@ -24,7 +24,7 @@ def get_data(filters):
|
||||
out = []
|
||||
for room_type in frappe.get_all('Hotel Room Type'):
|
||||
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)
|
||||
total_booked += get_rooms_booked(room_type.name, day)
|
||||
|
||||
|
@ -32,6 +32,19 @@ frappe.ui.form.on('Employee Advance', {
|
||||
frm.add_custom_button(__('Payment'),
|
||||
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) {
|
||||
@ -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):
|
||||
employee_loan = frappe.get_doc("Employee Loan", {"employee":self.employee})
|
||||
self.assertEquals(employee_loan.monthly_repayment_amount, 15052)
|
||||
self.assertEquals(employee_loan.total_interest_payable, 21034)
|
||||
self.assertEquals(employee_loan.total_payment, 301034)
|
||||
self.assertEqual(employee_loan.monthly_repayment_amount, 15052)
|
||||
self.assertEqual(employee_loan.total_interest_payable, 21034)
|
||||
self.assertEqual(employee_loan.total_payment, 301034)
|
||||
|
||||
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]]:
|
||||
self.assertEquals(schedule[idx].principal_amount, principal_amount)
|
||||
self.assertEquals(schedule[idx].interest_amount, interest_amount)
|
||||
self.assertEquals(schedule[idx].balance_loan_amount, balance_loan_amount)
|
||||
self.assertEqual(schedule[idx].principal_amount, principal_amount)
|
||||
self.assertEqual(schedule[idx].interest_amount, interest_amount)
|
||||
self.assertEqual(schedule[idx].balance_loan_amount, balance_loan_amount)
|
||||
|
||||
employee_loan.repayment_method = "Repay Fixed Amount per Period"
|
||||
employee_loan.monthly_repayment_amount = 14000
|
||||
employee_loan.save()
|
||||
|
||||
self.assertEquals(len(employee_loan.repayment_schedule), 22)
|
||||
self.assertEquals(employee_loan.total_interest_payable, 22712)
|
||||
self.assertEquals(employee_loan.total_payment, 302712)
|
||||
self.assertEqual(len(employee_loan.repayment_schedule), 22)
|
||||
self.assertEqual(employee_loan.total_interest_payable, 22712)
|
||||
self.assertEqual(employee_loan.total_payment, 302712)
|
||||
|
||||
def create_loan_type(loan_name, maximum_loan_amount, rate_of_interest):
|
||||
if not frappe.db.exists("Loan Type", loan_name):
|
||||
|
@ -38,14 +38,14 @@ class TestEmployeeLoanApplication(unittest.TestCase):
|
||||
|
||||
def test_loan_totals(self):
|
||||
loan_application = frappe.get_doc("Employee Loan Application", {"employee":self.employee})
|
||||
self.assertEquals(loan_application.repayment_amount, 11445)
|
||||
self.assertEquals(loan_application.total_payable_interest, 24657)
|
||||
self.assertEquals(loan_application.total_payable_amount, 274657)
|
||||
self.assertEqual(loan_application.repayment_amount, 11445)
|
||||
self.assertEqual(loan_application.total_payable_interest, 24657)
|
||||
self.assertEqual(loan_application.total_payable_amount, 274657)
|
||||
|
||||
loan_application.repayment_method = "Repay Fixed Amount per Period"
|
||||
loan_application.repayment_amount = 15000
|
||||
loan_application.save()
|
||||
|
||||
self.assertEquals(loan_application.repayment_periods, 18)
|
||||
self.assertEquals(loan_application.total_payable_interest, 18506)
|
||||
self.assertEquals(loan_application.total_payable_amount, 268506)
|
||||
self.assertEqual(loan_application.repayment_periods, 18)
|
||||
self.assertEqual(loan_application.total_payable_interest, 18506)
|
||||
self.assertEqual(loan_application.total_payable_amount, 268506)
|
@ -297,4 +297,30 @@ def get_advances(employee, advance_id=None):
|
||||
from
|
||||
`tabEmployee Advance`
|
||||
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:
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
def get_payable_account(company):
|
||||
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.db.set_value("Department", "_Test Department 1", "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):
|
||||
frappe.set_user("test1@example.com")
|
||||
|
@ -37,14 +37,14 @@ class TestSalarySlip(unittest.TestCase):
|
||||
ss = frappe.get_doc("Salary Slip",
|
||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||
|
||||
self.assertEquals(ss.total_working_days, no_of_days[0])
|
||||
self.assertEquals(ss.payment_days, no_of_days[0])
|
||||
self.assertEquals(ss.earnings[0].amount, 25000)
|
||||
self.assertEquals(ss.earnings[1].amount, 3000)
|
||||
self.assertEquals(ss.deductions[0].amount, 5000)
|
||||
self.assertEquals(ss.deductions[1].amount, 5000)
|
||||
self.assertEquals(ss.gross_pay, 40500)
|
||||
self.assertEquals(ss.net_pay, 29918)
|
||||
self.assertEqual(ss.total_working_days, no_of_days[0])
|
||||
self.assertEqual(ss.payment_days, no_of_days[0])
|
||||
self.assertEqual(ss.earnings[0].amount, 25000)
|
||||
self.assertEqual(ss.earnings[1].amount, 3000)
|
||||
self.assertEqual(ss.deductions[0].amount, 5000)
|
||||
self.assertEqual(ss.deductions[1].amount, 5000)
|
||||
self.assertEqual(ss.gross_pay, 40500)
|
||||
self.assertEqual(ss.net_pay, 29918)
|
||||
|
||||
def test_salary_slip_with_holidays_excluded(self):
|
||||
no_of_days = self.get_no_of_days()
|
||||
@ -55,15 +55,15 @@ class TestSalarySlip(unittest.TestCase):
|
||||
ss = frappe.get_doc("Salary Slip",
|
||||
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.assertEquals(ss.payment_days, no_of_days[0] - no_of_days[1])
|
||||
self.assertEquals(ss.earnings[0].amount, 25000)
|
||||
self.assertEquals(ss.earnings[0].default_amount, 25000)
|
||||
self.assertEquals(ss.earnings[1].amount, 3000)
|
||||
self.assertEquals(ss.deductions[0].amount, 5000)
|
||||
self.assertEquals(ss.deductions[1].amount, 5000)
|
||||
self.assertEquals(ss.gross_pay, 40500)
|
||||
self.assertEquals(ss.net_pay, 29918)
|
||||
self.assertEqual(ss.total_working_days, no_of_days[0] - no_of_days[1])
|
||||
self.assertEqual(ss.payment_days, no_of_days[0] - no_of_days[1])
|
||||
self.assertEqual(ss.earnings[0].amount, 25000)
|
||||
self.assertEqual(ss.earnings[0].default_amount, 25000)
|
||||
self.assertEqual(ss.earnings[1].amount, 3000)
|
||||
self.assertEqual(ss.deductions[0].amount, 5000)
|
||||
self.assertEqual(ss.deductions[1].amount, 5000)
|
||||
self.assertEqual(ss.gross_pay, 40500)
|
||||
self.assertEqual(ss.net_pay, 29918)
|
||||
|
||||
def test_payment_days(self):
|
||||
no_of_days = self.get_no_of_days()
|
||||
@ -95,8 +95,8 @@ class TestSalarySlip(unittest.TestCase):
|
||||
ss = frappe.get_doc("Salary Slip",
|
||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||
|
||||
self.assertEquals(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.total_working_days, no_of_days[0])
|
||||
self.assertEqual(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1))
|
||||
|
||||
# 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)))
|
||||
@ -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")
|
||||
ss.save()
|
||||
|
||||
self.assertEquals(ss.total_working_days, no_of_days[0])
|
||||
self.assertEquals(ss.payment_days, getdate(relieving_date).day)
|
||||
self.assertEqual(ss.total_working_days, no_of_days[0])
|
||||
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"), "status", "Active")
|
||||
@ -143,8 +143,8 @@ class TestSalarySlip(unittest.TestCase):
|
||||
ss = frappe.get_doc("Salary Slip",
|
||||
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
|
||||
ss.submit()
|
||||
self.assertEquals(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.total_loan_repayment, 582)
|
||||
self.assertEqual(ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.total_loan_repayment))))
|
||||
|
||||
def test_payroll_frequency(self):
|
||||
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"})
|
||||
if not sal_slip:
|
||||
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.assertEquals(sal_slip.get("earnings")[0].amount, 5000)
|
||||
self.assertEquals(sal_slip.get("deductions")[0].amount, 5000)
|
||||
self.assertEquals(sal_slip.get("deductions")[1].amount, 2500)
|
||||
self.assertEquals(sal_slip.get("total_deduction"), 7500)
|
||||
self.assertEquals(sal_slip.get("net_pay"), 7500)
|
||||
self.assertEqual(sal_slip.get("salary_structure"), 'Salary Structure Sample')
|
||||
self.assertEqual(sal_slip.get("earnings")[0].amount, 5000)
|
||||
self.assertEqual(sal_slip.get("deductions")[0].amount, 5000)
|
||||
self.assertEqual(sal_slip.get("deductions")[1].amount, 2500)
|
||||
self.assertEqual(sal_slip.get("total_deduction"), 7500)
|
||||
self.assertEqual(sal_slip.get("net_pay"), 7500)
|
||||
|
||||
def test_whitespaces_in_formula_conditions_fields(self):
|
||||
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:
|
||||
|
||||
# max iterations = len(holidays)
|
||||
for i in xrange(len(holidays)):
|
||||
for i in range(len(holidays)):
|
||||
if schedule_date in holidays:
|
||||
schedule_date = add_days(schedule_date, -1)
|
||||
else:
|
||||
|
@ -9,6 +9,8 @@ from erpnext.setup.utils import get_exchange_rate
|
||||
from frappe.website.website_generator import WebsiteGenerator
|
||||
from erpnext.stock.get_item_details import get_conversion_factor
|
||||
|
||||
import functools
|
||||
|
||||
from six import string_types
|
||||
|
||||
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()
|
||||
def get_bom_items(bom, company, qty=1, fetch_exploded=1):
|
||||
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
|
||||
|
||||
def validate_bom_no(item, bom_no):
|
||||
|
@ -18,7 +18,7 @@ class TestBOM(unittest.TestCase):
|
||||
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"][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):
|
||||
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.assertTrue(test_records[0]["items"][0]["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):
|
||||
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 _get_default_bom_in_item():
|
||||
|
@ -38,8 +38,11 @@ frappe.ui.form.on('Member', {
|
||||
]
|
||||
},
|
||||
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_import": 0,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:email",
|
||||
"autoname": "naming_series:",
|
||||
"beta": 0,
|
||||
"creation": "2017-09-11 09:24:52.898356",
|
||||
"custom": 0,
|
||||
@ -13,6 +13,38 @@
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"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_on_submit": 0,
|
||||
@ -41,6 +73,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -71,6 +104,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -100,6 +134,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -131,6 +166,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -162,6 +198,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -192,6 +229,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -222,6 +260,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -253,6 +292,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -284,6 +324,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -314,6 +355,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -345,6 +387,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -376,6 +419,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -406,6 +450,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -435,6 +480,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -465,6 +511,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -479,7 +526,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-15 05:08:48.561998",
|
||||
"modified": "2018-02-23 10:55:29.721224",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Non Profit",
|
||||
"name": "Member",
|
||||
|
@ -6,7 +6,6 @@ from __future__ import unicode_literals
|
||||
from frappe.model.document import Document
|
||||
from frappe.contacts.address_and_contact import load_address_and_contact
|
||||
|
||||
STANDARD_USERS = ("Guest", "Administrator")
|
||||
|
||||
class Member(Document):
|
||||
def onload(self):
|
||||
@ -15,10 +14,7 @@ class Member(Document):
|
||||
|
||||
|
||||
def validate(self):
|
||||
if self.name not in STANDARD_USERS:
|
||||
self.validate_email_type(self.email)
|
||||
self.validate_email_type(self.name)
|
||||
|
||||
self.validate_email_type(self.email)
|
||||
|
||||
def validate_email_type(self, email):
|
||||
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.add_default_cash_flow_mappers
|
||||
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():
|
||||
items_barcode = frappe.db.sql("""SELECT name, barcode FROM tabItem
|
||||
WHERE barcode IS NOT NULL and barcode != ''""", as_dict=1)
|
||||
items_barcode = frappe.get_list('Item', ['name', 'barcode'], { 'barcode': ('!=', '') })
|
||||
|
||||
frappe.reload_doc("stock", "doctype", "item")
|
||||
frappe.reload_doc("stock", "doctype", "item_barcode")
|
||||
|
||||
for item in items_barcode:
|
||||
doc = frappe.get_doc("Item", item.get("name"))
|
||||
if item.get("barcode"):
|
||||
doc.append("barcodes", {"barcode": item.get("barcode")})
|
||||
doc.flags.ignore_validate = True
|
||||
doc.flags.ignore_mandatory = True
|
||||
doc.save()
|
||||
barcode = item.barcode.strip()
|
||||
|
||||
if barcode and '<' not in barcode:
|
||||
frappe.get_doc({
|
||||
'idx': 0,
|
||||
'doctype': 'Item Barcode',
|
||||
'barcode': barcode,
|
||||
'parenttype': 'Item',
|
||||
'parent': item.name,
|
||||
'parentfield': 'barcodes'
|
||||
}).insert()
|
||||
|
@ -12,6 +12,7 @@ def execute():
|
||||
if not po_item:
|
||||
return
|
||||
|
||||
frappe.reload_doc("stock", "doctype", "bin")
|
||||
frappe.reload_doc("buying", "doctype", "purchase_order_item_supplied")
|
||||
company_warehouse = frappe._dict(frappe.db.sql("""select company, min(name) from `tabWarehouse`
|
||||
where is_group = 0 group by company"""))
|
||||
@ -30,7 +31,7 @@ def execute():
|
||||
|
||||
# Update bin
|
||||
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
|
||||
from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup
|
||||
where po.name = poitemsup.parent
|
||||
|
@ -1,13 +1,36 @@
|
||||
import frappe
|
||||
from frappe.model.rename_doc import update_linked_doctypes
|
||||
from frappe.model.rename_doc import get_fetch_fields
|
||||
|
||||
def execute():
|
||||
customers = frappe.get_all('Customer')
|
||||
for customer in customers:
|
||||
# Update Territory across all transaction
|
||||
terr = frappe.get_value('Customer', customer, 'territory')
|
||||
update_linked_doctypes("Customer", "Territory", customer.name, terr)
|
||||
ignore_doctypes = ["Lead", "Opportunity", "POS Profile", "Tax Rule", "Pricing Rule"]
|
||||
customers = frappe.get_all('Customer', fields=["name", "territory", "customer_group"])
|
||||
|
||||
# Update Territory across all transaction
|
||||
cust_group = frappe.get_value('Customer', customer, 'customer_group')
|
||||
update_linked_doctypes("Customer", "Customer Group", customer.name, cust_group)
|
||||
territory_fetch = get_fetch_fields('Customer', 'Territory', ignore_doctypes)
|
||||
customer_group_fetch = get_fetch_fields('Customer', 'Customer Group', ignore_doctypes)
|
||||
|
||||
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)
|
||||
|
||||
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."))
|
||||
|
||||
def update_depends_on(self):
|
||||
|
@ -78,16 +78,16 @@ class TestTask(unittest.TestCase):
|
||||
|
||||
assign()
|
||||
todo = get_owner_and_status()
|
||||
self.assertEquals(todo.owner, "test@example.com")
|
||||
self.assertEquals(todo.status, "Open")
|
||||
self.assertEqual(todo.owner, "test@example.com")
|
||||
self.assertEqual(todo.status, "Open")
|
||||
|
||||
# assignment should be
|
||||
task.load_from_db()
|
||||
task.status = "Closed"
|
||||
task.save()
|
||||
todo = get_owner_and_status()
|
||||
self.assertEquals(todo.owner, "test@example.com")
|
||||
self.assertEquals(todo.status, "Closed")
|
||||
self.assertEqual(todo.owner, "test@example.com")
|
||||
self.assertEqual(todo.status, "Closed")
|
||||
|
||||
def test_overdue(self):
|
||||
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
|
||||
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):
|
||||
if not frappe.db.exists("Task", subject):
|
||||
|
@ -17,21 +17,21 @@ class TestTimesheet(unittest.TestCase):
|
||||
make_salary_structure("_T-Employee-0001")
|
||||
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=1)
|
||||
|
||||
self.assertEquals(timesheet.total_hours, 2)
|
||||
self.assertEquals(timesheet.total_billable_hours, 2)
|
||||
self.assertEquals(timesheet.time_logs[0].billing_rate, 50)
|
||||
self.assertEquals(timesheet.time_logs[0].billing_amount, 100)
|
||||
self.assertEquals(timesheet.total_billable_amount, 100)
|
||||
self.assertEqual(timesheet.total_hours, 2)
|
||||
self.assertEqual(timesheet.total_billable_hours, 2)
|
||||
self.assertEqual(timesheet.time_logs[0].billing_rate, 50)
|
||||
self.assertEqual(timesheet.time_logs[0].billing_amount, 100)
|
||||
self.assertEqual(timesheet.total_billable_amount, 100)
|
||||
|
||||
def test_timesheet_billing_amount_not_billable(self):
|
||||
make_salary_structure("_T-Employee-0001")
|
||||
timesheet = make_timesheet("_T-Employee-0001", simulate=True, billable=0)
|
||||
|
||||
self.assertEquals(timesheet.total_hours, 2)
|
||||
self.assertEquals(timesheet.total_billable_hours, 0)
|
||||
self.assertEquals(timesheet.time_logs[0].billing_rate, 0)
|
||||
self.assertEquals(timesheet.time_logs[0].billing_amount, 0)
|
||||
self.assertEquals(timesheet.total_billable_amount, 0)
|
||||
self.assertEqual(timesheet.total_hours, 2)
|
||||
self.assertEqual(timesheet.total_billable_hours, 0)
|
||||
self.assertEqual(timesheet.time_logs[0].billing_rate, 0)
|
||||
self.assertEqual(timesheet.time_logs[0].billing_amount, 0)
|
||||
self.assertEqual(timesheet.total_billable_amount, 0)
|
||||
|
||||
def test_salary_slip_from_timesheet(self):
|
||||
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.submit()
|
||||
|
||||
self.assertEquals(salary_slip.total_working_hours, 2)
|
||||
self.assertEquals(salary_slip.hour_rate, 50)
|
||||
self.assertEquals(salary_slip.net_pay, 150)
|
||||
self.assertEquals(salary_slip.timesheets[0].time_sheet, timesheet.name)
|
||||
self.assertEquals(salary_slip.timesheets[0].working_hours, 2)
|
||||
self.assertEqual(salary_slip.total_working_hours, 2)
|
||||
self.assertEqual(salary_slip.hour_rate, 50)
|
||||
self.assertEqual(salary_slip.net_pay, 150)
|
||||
self.assertEqual(salary_slip.timesheets[0].time_sheet, timesheet.name)
|
||||
self.assertEqual(salary_slip.timesheets[0].working_hours, 2)
|
||||
|
||||
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
||||
self.assertEquals(timesheet.status, 'Payslip')
|
||||
self.assertEqual(timesheet.status, 'Payslip')
|
||||
salary_slip.cancel()
|
||||
|
||||
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
||||
self.assertEquals(timesheet.status, 'Submitted')
|
||||
self.assertEqual(timesheet.status, 'Submitted')
|
||||
|
||||
def test_sales_invoice_from_timesheet(self):
|
||||
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.submit()
|
||||
timesheet = frappe.get_doc('Timesheet', timesheet.name)
|
||||
self.assertEquals(sales_invoice.total_billing_amount, 100)
|
||||
self.assertEquals(timesheet.status, 'Billed')
|
||||
self.assertEquals(sales_invoice.customer, '_Test Customer')
|
||||
self.assertEqual(sales_invoice.total_billing_amount, 100)
|
||||
self.assertEqual(timesheet.status, 'Billed')
|
||||
self.assertEqual(sales_invoice.customer, '_Test Customer')
|
||||
|
||||
item = sales_invoice.items[0]
|
||||
self.assertEquals(item.item_code, '_Test Item')
|
||||
self.assertEquals(item.qty, 2.00)
|
||||
self.assertEquals(item.rate, 50.00)
|
||||
self.assertEqual(item.item_code, '_Test Item')
|
||||
self.assertEqual(item.qty, 2.00)
|
||||
self.assertEqual(item.rate, 50.00)
|
||||
|
||||
def test_timesheet_billing_based_on_project(self):
|
||||
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()
|
||||
|
||||
ts = frappe.get_doc('Timesheet', timesheet.name)
|
||||
self.assertEquals(ts.per_billed, 100)
|
||||
self.assertEquals(ts.time_logs[0].sales_invoice, sales_invoice.name)
|
||||
self.assertEqual(ts.per_billed, 100)
|
||||
self.assertEqual(ts.time_logs[0].sales_invoice, sales_invoice.name)
|
||||
|
||||
def test_timesheet_time_overlap(self):
|
||||
settings = frappe.get_single('Projects Settings')
|
||||
|
@ -292,7 +292,7 @@ def get_projectwise_timesheet_data(project, parent=None):
|
||||
cond = "and parent = %(parent)s"
|
||||
|
||||
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)
|
||||
|
||||
@frappe.whitelist()
|
||||
|
@ -38,15 +38,15 @@ class TestRestaurantMenu(unittest.TestCase):
|
||||
menu2.save()
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
menu1.items[0].rate = 401
|
||||
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)
|
||||
|
||||
menu1.items[0].rate = 400
|
||||
|
@ -15,8 +15,8 @@ frappe.ui.form.on('Restaurant Order Entry', {
|
||||
frm.set_query('add_item', get_item_query);
|
||||
},
|
||||
onload_post_render: function(frm) {
|
||||
if(!this.item_selector) {
|
||||
this.item_selector = new erpnext.ItemSelector({
|
||||
if(!frm.item_selector) {
|
||||
frm.item_selector = new erpnext.ItemSelector({
|
||||
frm: frm,
|
||||
item_field: 'item',
|
||||
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()
|
||||
|
||||
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 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'):
|
||||
frappe.flags.territory = True
|
||||
frappe.flags.territory_changed = True
|
||||
|
||||
def on_update(self):
|
||||
self.validate_name_with_customer_group()
|
||||
@ -76,10 +76,15 @@ class Customer(TransactionBase):
|
||||
if self.flags.is_new_doc:
|
||||
self.create_lead_address_contact()
|
||||
|
||||
if frappe.flags.territory:
|
||||
update_linked_doctypes("Customer", "Territory", self.name, self.territory)
|
||||
if frappe.flags.customer_group:
|
||||
update_linked_doctypes("Customer", "Customer Group", self.name, self.customer_group)
|
||||
self.update_territory_and_customer_groups()
|
||||
|
||||
def update_territory_and_customer_groups(self):
|
||||
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):
|
||||
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")
|
||||
|
||||
for key, value in iteritems(to_check):
|
||||
self.assertEquals(value, details.get(key))
|
||||
self.assertEqual(value, details.get(key))
|
||||
|
||||
def test_rename(self):
|
||||
# delete communication linked to these 2 customers
|
||||
@ -74,7 +74,7 @@ class TestCustomer(unittest.TestCase):
|
||||
self.assertFalse(frappe.db.exists("Customer", "_Test Customer 1"))
|
||||
|
||||
# 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",
|
||||
"reference_doctype": "Customer",
|
||||
"reference_name": "_Test Customer 1 Renamed"
|
||||
@ -125,9 +125,9 @@ class TestCustomer(unittest.TestCase):
|
||||
duplicate_customer = frappe.get_doc(
|
||||
get_customer_dict('_Test Customer 1')).insert(ignore_permissions=True)
|
||||
|
||||
self.assertEquals("_Test Customer 1", test_customer_1.name)
|
||||
self.assertEquals("_Test Customer 1 - 1", duplicate_customer.name)
|
||||
self.assertEquals(test_customer_1.customer_name, duplicate_customer.customer_name)
|
||||
self.assertEqual("_Test Customer 1", test_customer_1.name)
|
||||
self.assertEqual("_Test Customer 1 - 1", duplicate_customer.name)
|
||||
self.assertEqual(test_customer_1.customer_name, duplicate_customer.customer_name)
|
||||
|
||||
def get_customer_outstanding_amount(self):
|
||||
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;
|
||||
|
||||
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') {
|
||||
|
@ -44,11 +44,11 @@ class TestQuotation(unittest.TestCase):
|
||||
|
||||
sales_order = make_sales_order(quotation.name)
|
||||
|
||||
self.assertEquals(sales_order.doctype, "Sales Order")
|
||||
self.assertEquals(len(sales_order.get("items")), 1)
|
||||
self.assertEquals(sales_order.get("items")[0].doctype, "Sales Order Item")
|
||||
self.assertEquals(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
||||
self.assertEquals(sales_order.customer, "_Test Customer")
|
||||
self.assertEqual(sales_order.doctype, "Sales Order")
|
||||
self.assertEqual(len(sales_order.get("items")), 1)
|
||||
self.assertEqual(sales_order.get("items")[0].doctype, "Sales Order Item")
|
||||
self.assertEqual(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
||||
self.assertEqual(sales_order.customer, "_Test Customer")
|
||||
|
||||
sales_order.delivery_date = "2014-01-01"
|
||||
sales_order.naming_series = "_T-Quotation-"
|
||||
@ -77,11 +77,11 @@ class TestQuotation(unittest.TestCase):
|
||||
|
||||
sales_order = make_sales_order(quotation.name)
|
||||
|
||||
self.assertEquals(sales_order.doctype, "Sales Order")
|
||||
self.assertEquals(len(sales_order.get("items")), 1)
|
||||
self.assertEquals(sales_order.get("items")[0].doctype, "Sales Order Item")
|
||||
self.assertEquals(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
||||
self.assertEquals(sales_order.customer, "_Test Customer")
|
||||
self.assertEqual(sales_order.doctype, "Sales Order")
|
||||
self.assertEqual(len(sales_order.get("items")), 1)
|
||||
self.assertEqual(sales_order.get("items")[0].doctype, "Sales Order Item")
|
||||
self.assertEqual(sales_order.get("items")[0].prevdoc_docname, quotation.name)
|
||||
self.assertEqual(sales_order.customer, "_Test Customer")
|
||||
|
||||
sales_order.delivery_date = "2014-01-01"
|
||||
sales_order.naming_series = "_T-Quotation-"
|
||||
@ -123,7 +123,7 @@ class TestQuotation(unittest.TestCase):
|
||||
quotation.valid_till = add_months(quotation.transaction_date, 1)
|
||||
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)
|
||||
quotation.submit()
|
||||
|
||||
@ -134,16 +134,16 @@ class TestQuotation(unittest.TestCase):
|
||||
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
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()
|
||||
|
||||
def test_create_two_quotations(self):
|
||||
|
@ -104,8 +104,8 @@ class SalesOrder(SellingController):
|
||||
def validate_delivery_date(self):
|
||||
if self.order_type == 'Sales':
|
||||
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:
|
||||
for d in self.get("items"):
|
||||
if not d.delivery_date:
|
||||
|
@ -29,8 +29,8 @@ class TestSalesOrder(unittest.TestCase):
|
||||
so.submit()
|
||||
mr = make_material_request(so.name)
|
||||
|
||||
self.assertEquals(mr.material_request_type, "Purchase")
|
||||
self.assertEquals(len(mr.get("items")), len(so.get("items")))
|
||||
self.assertEqual(mr.material_request_type, "Purchase")
|
||||
self.assertEqual(len(mr.get("items")), len(so.get("items")))
|
||||
|
||||
def test_make_delivery_note(self):
|
||||
so = make_sales_order(do_not_submit=True)
|
||||
@ -40,8 +40,8 @@ class TestSalesOrder(unittest.TestCase):
|
||||
so.submit()
|
||||
dn = make_delivery_note(so.name)
|
||||
|
||||
self.assertEquals(dn.doctype, "Delivery Note")
|
||||
self.assertEquals(len(dn.get("items")), len(so.get("items")))
|
||||
self.assertEqual(dn.doctype, "Delivery Note")
|
||||
self.assertEqual(len(dn.get("items")), len(so.get("items")))
|
||||
|
||||
def test_make_sales_invoice(self):
|
||||
so = make_sales_order(do_not_submit=True)
|
||||
@ -51,14 +51,14 @@ class TestSalesOrder(unittest.TestCase):
|
||||
so.submit()
|
||||
si = make_sales_invoice(so.name)
|
||||
|
||||
self.assertEquals(len(si.get("items")), len(so.get("items")))
|
||||
self.assertEquals(len(si.get("items")), 1)
|
||||
self.assertEqual(len(si.get("items")), len(so.get("items")))
|
||||
self.assertEqual(len(si.get("items")), 1)
|
||||
|
||||
si.insert()
|
||||
si.submit()
|
||||
|
||||
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):
|
||||
so = make_sales_order(do_not_submit=True)
|
||||
@ -71,8 +71,8 @@ class TestSalesOrder(unittest.TestCase):
|
||||
so.submit()
|
||||
si = make_sales_invoice(so.name)
|
||||
|
||||
self.assertEquals(len(si.get("items")), len(so.get("items")))
|
||||
self.assertEquals(len(si.get("items")), 1)
|
||||
self.assertEqual(len(si.get("items")), len(so.get("items")))
|
||||
self.assertEqual(len(si.get("items")), 1)
|
||||
|
||||
si.insert()
|
||||
|
||||
@ -84,7 +84,7 @@ class TestSalesOrder(unittest.TestCase):
|
||||
si.submit()
|
||||
|
||||
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):
|
||||
so = make_sales_order()
|
||||
@ -92,7 +92,7 @@ class TestSalesOrder(unittest.TestCase):
|
||||
create_dn_against_so(so.name, 6)
|
||||
|
||||
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
|
||||
si1 = make_sales_invoice(so.name)
|
||||
@ -101,7 +101,7 @@ class TestSalesOrder(unittest.TestCase):
|
||||
si1.submit()
|
||||
|
||||
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
|
||||
si2 = make_sales_invoice(so.name)
|
||||
@ -111,7 +111,7 @@ class TestSalesOrder(unittest.TestCase):
|
||||
si2.submit()
|
||||
|
||||
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):
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
self.assertEquals(so.customer, po.customer)
|
||||
self.assertEquals(po.items[0].sales_order, so.name)
|
||||
self.assertEquals(po.items[0].item_code, po_item.item_code)
|
||||
self.assertEquals(dn.items[0].item_code, dn_item.item_code)
|
||||
self.assertEqual(so.customer, po.customer)
|
||||
self.assertEqual(po.items[0].sales_order, so.name)
|
||||
self.assertEqual(po.items[0].item_code, po_item.item_code)
|
||||
self.assertEqual(dn.items[0].item_code, dn_item.item_code)
|
||||
|
||||
#test ordered_qty and reserved_qty
|
||||
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
|
||||
reserved_qty = bin[0].reserved_qty if bin else 0.0
|
||||
|
||||
self.assertEquals(abs(flt(ordered_qty)), existing_ordered_qty)
|
||||
self.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty)
|
||||
self.assertEqual(abs(flt(ordered_qty)), existing_ordered_qty)
|
||||
self.assertEqual(abs(flt(reserved_qty)), existing_reserved_qty)
|
||||
|
||||
reserved_qty = frappe.db.get_value("Bin",
|
||||
{"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
|
||||
self.assertEquals(len(po.items), 1)
|
||||
self.assertEqual(len(po.items), 1)
|
||||
|
||||
#test per_delivered status
|
||||
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
|
||||
dn = create_dn_against_so(so.name, delivered_qty=1)
|
||||
reserved_qty = frappe.db.get_value("Bin",
|
||||
{"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
|
||||
so.db_set('status', "Closed")
|
||||
@ -463,13 +463,13 @@ class TestSalesOrder(unittest.TestCase):
|
||||
ordered_qty = bin[0].ordered_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.assertEquals(abs(flt(reserved_qty)), existing_reserved_qty)
|
||||
self.assertEqual(abs(flt(ordered_qty)), existing_ordered_qty)
|
||||
self.assertEqual(abs(flt(reserved_qty)), existing_reserved_qty)
|
||||
|
||||
reserved_qty = frappe.db.get_value("Bin",
|
||||
{"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):
|
||||
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)
|
||||
|
||||
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")
|
||||
|
||||
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):
|
||||
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.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.payment_schedule = []
|
||||
new_so.save()
|
||||
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):
|
||||
so = make_sales_order(do_not_save=1)
|
||||
@ -562,7 +562,7 @@ class TestSalesOrder(unittest.TestCase):
|
||||
# Check if Production Orders were raised
|
||||
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))
|
||||
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):
|
||||
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