diff --git a/.travis.yml b/.travis.yml index 92c15e03197..80d979f602a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,6 @@ script: - bench run-tests - sleep 5 - bench reinstall --yes - - bench execute erpnext.setup.setup_wizard.utils.complete - - bench execute erpnext.setup.utils.enable_all_roles_and_domains - bench --verbose run-setup-wizard-ui-test + - bench execute erpnext.setup.utils.enable_all_roles_and_domains - bench run-ui-tests --app erpnext diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 12e46c42d3c..dc37574ea6a 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -644,16 +644,9 @@ frappe.ui.form.on('Payment Entry', { if(frm.doc.party) { var party_amount = frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount; - - var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [], - function(d) { return flt(d.amount) })); if(frm.doc.total_allocated_amount < party_amount) { - if(frm.doc.payment_type == "Receive") { - unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions); - } else { - unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions); - } + unallocated_amount = party_amount - frm.doc.total_allocated_amount; } } frm.set_value("unallocated_amount", unallocated_amount); @@ -672,11 +665,10 @@ frappe.ui.form.on('Payment Entry', { difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount); } - $.each(frm.doc.deductions || [], function(i, d) { - if(d.amount) difference_amount -= flt(d.amount); - }) + var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [], + function(d) { return flt(d.amount) })); - frm.set_value("difference_amount", difference_amount); + frm.set_value("difference_amount", difference_amount - total_deductions); frm.events.hide_unhide_fields(frm); }, diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index c6353d51d4e..7ae9bde4625 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -281,13 +281,8 @@ class PaymentEntry(AccountsController): if self.party: party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount - total_deductions = sum([flt(d.amount) for d in self.get("deductions")]) - if self.total_allocated_amount < party_amount: - if self.payment_type == "Receive": - self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions) - else: - self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions) + self.unallocated_amount = party_amount - self.total_allocated_amount def set_difference_amount(self): base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate) @@ -302,11 +297,10 @@ class PaymentEntry(AccountsController): else: self.difference_amount = self.base_paid_amount - flt(self.base_received_amount) - for d in self.get("deductions"): - if d.amount: - self.difference_amount -= flt(d.amount) + total_deductions = sum([flt(d.amount) for d in self.get("deductions")]) - self.difference_amount = flt(self.difference_amount, self.precision("difference_amount")) + self.difference_amount = flt(self.difference_amount - total_deductions, + self.precision("difference_amount")) def clear_unallocated_reference_document_rows(self): self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]})) diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index 0316ccafe24..60be20dd89a 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -267,3 +267,65 @@ class TestPaymentEntry(unittest.TestCase): return frappe.db.sql("""select account, debit, credit, against_voucher from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s order by account asc""", voucher_no, as_dict=1) + + def test_payment_entry_write_off_difference(self): + si = create_sales_invoice() + pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC") + pe.reference_no = "1" + pe.reference_date = "2016-01-01" + pe.received_amount = pe.paid_amount = 110 + pe.insert() + + self.assertEqual(pe.unallocated_amount, 10) + + pe.received_amount = pe.paid_amount = 95 + pe.append("deductions", { + "account": "_Test Write Off - _TC", + "cost_center": "_Test Cost Center - _TC", + "amount": 5 + }) + pe.save() + + self.assertEqual(pe.unallocated_amount, 0) + self.assertEqual(pe.difference_amount, 0) + + pe.submit() + + expected_gle = dict((d[0], d) for d in [ + ["Debtors - _TC", 0, 100, si.name], + ["_Test Cash - _TC", 95, 0, None], + ["_Test Write Off - _TC", 5, 0, None] + ]) + + self.validate_gl_entries(pe.name, expected_gle) + + def test_payment_entry_exchange_gain_loss(self): + si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + currency="USD", conversion_rate=50) + pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC") + pe.reference_no = "1" + pe.reference_date = "2016-01-01" + pe.target_exchange_rate = 55 + + pe.append("deductions", { + "account": "_Test Exchange Gain/Loss - _TC", + "cost_center": "_Test Cost Center - _TC", + "amount": -500 + }) + pe.save() + + self.assertEqual(pe.unallocated_amount, 0) + self.assertEqual(pe.difference_amount, 0) + + pe.submit() + + expected_gle = dict((d[0], d) for d in [ + ["_Test Receivable USD - _TC", 0, 5000, si.name], + ["_Test Bank USD - _TC", 5500, 0, None], + ["_Test Exchange Gain/Loss - _TC", 0, 500, None], + ]) + + self.validate_gl_entries(pe.name, expected_gle) + + outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount")) + self.assertEqual(outstanding_amount, 0) diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js new file mode 100644 index 00000000000..7dea76db800 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js @@ -0,0 +1,51 @@ +QUnit.module('Payment Entry'); + +QUnit.test("test payment entry", function(assert) { + assert.expect(6); + let done = assert.async(); + frappe.run_serially([ + () => { + return frappe.tests.make('Sales Invoice', [ + {customer: 'Test Customer 1'}, + {items: [ + [ + {'qty': 1}, + {'rate': 101}, + {'item_code': 'Test Product 1'}, + ] + ]} + ]); + }, + () => cur_frm.save(), + () => frappe.tests.click_button('Submit'), + () => frappe.tests.click_button('Yes'), + () => frappe.timeout(0.5), + () => frappe.tests.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.click_button('Make'), + () => frappe.click_link('Payment', 1), + () => frappe.timeout(2), + () => { + assert.equal(frappe.get_route()[1], 'Payment Entry', + 'made payment entry'); + assert.equal(cur_frm.doc.party, 'Test Customer 1', + 'customer set in payment entry'); + assert.equal(cur_frm.doc.paid_amount, 101, + 'paid amount set in payment entry'); + assert.equal(cur_frm.doc.references[0].allocated_amount, 101, + 'amount allocated against sales invoice'); + }, + () => cur_frm.set_value('paid_amount', 100), + () => { + cur_frm.doc.references[0].allocated_amount = 101; + }, + () => frappe.click_button('Write Off Difference Amount'), + () => { + assert.equal(cur_frm.doc.difference_amount, 0, + 'difference amount is zero'); + assert.equal(cur_frm.doc.deductions[0].amount, 1, + 'Write off amount = 1'); + }, + () => done() + ]); +}); diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js index a4ef0ca4eb3..0c76343fa90 100644 --- a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js @@ -25,5 +25,4 @@ QUnit.test("test payment entry", function(assert) { () => frappe.timeout(0.3), () => done() ]); -}); - +}); \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js new file mode 100644 index 00000000000..133f1362988 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js @@ -0,0 +1,67 @@ +QUnit.module('Payment Entry'); + +QUnit.test("test payment entry", function(assert) { + assert.expect(8); + let done = assert.async(); + frappe.run_serially([ + () => { + return frappe.tests.make('Sales Invoice', [ + {customer: 'Test Customer 1'}, + {company: '_Test Company'}, + {currency: 'INR'}, + {selling_price_list: '_Test Price List'}, + {items: [ + [ + {'qty': 1}, + {'item_code': 'Test Product 1'}, + ] + ]} + ]); + }, + () => frappe.timeout(1), + () => cur_frm.save(), + () => frappe.tests.click_button('Submit'), + () => frappe.tests.click_button('Yes'), + () => frappe.timeout(1.5), + () => frappe.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.click_button('Make'), + () => frappe.timeout(1), + () => frappe.click_link('Payment'), + () => frappe.timeout(2), + () => cur_frm.set_value("paid_to", "_Test Cash - _TC"), + () => frappe.timeout(0.5), + () => { + assert.equal(frappe.get_route()[1], 'Payment Entry', 'made payment entry'); + assert.equal(cur_frm.doc.party, 'Test Customer 1', 'customer set in payment entry'); + assert.equal(cur_frm.doc.paid_from, 'Debtors - _TC', 'customer account set in payment entry'); + assert.equal(cur_frm.doc.paid_amount, 100, 'paid amount set in payment entry'); + assert.equal(cur_frm.doc.references[0].allocated_amount, 100, + 'amount allocated against sales invoice'); + }, + () => cur_frm.set_value('paid_amount', 95), + () => frappe.timeout(1), + () => { + frappe.model.set_value("Payment Entry Reference", + cur_frm.doc.references[0].name, "allocated_amount", 100); + }, + () => frappe.timeout(.5), + () => { + assert.equal(cur_frm.doc.difference_amount, 5, 'difference amount is 5'); + }, + () => { + frappe.db.set_value("Company", "_Test Company", "write_off_account", "_Test Write Off - _TC"); + frappe.timeout(1); + frappe.db.set_value("Company", "_Test Company", + "exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC"); + }, + () => frappe.timeout(1), + () => frappe.click_button('Write Off Difference Amount'), + () => frappe.timeout(2), + () => { + assert.equal(cur_frm.doc.difference_amount, 0, 'difference amount is zero'); + assert.equal(cur_frm.doc.deductions[0].amount, 5, 'Write off amount = 5'); + }, + () => done() + ]); +}); \ No newline at end of file diff --git a/erpnext/hr/doctype/training_event/tests/test_training_event_attandance.js b/erpnext/hr/doctype/training_event/tests/test_training_event_attendance.js similarity index 100% rename from erpnext/hr/doctype/training_event/tests/test_training_event_attandance.js rename to erpnext/hr/doctype/training_event/tests/test_training_event_attendance.js diff --git a/erpnext/hr/doctype/training_feedback/training_feedback.py b/erpnext/hr/doctype/training_feedback/training_feedback.py index 20a3bc5652e..b7eae38ae48 100644 --- a/erpnext/hr/doctype/training_feedback/training_feedback.py +++ b/erpnext/hr/doctype/training_feedback/training_feedback.py @@ -20,4 +20,4 @@ class TrainingFeedback(Document): training_event.status = 'Feedback Submitted' break - training_event.update_after_submit() + training_event.save() diff --git a/erpnext/patches/v8_9/rename_company_sales_target_field.py b/erpnext/patches/v8_9/rename_company_sales_target_field.py index 8c54283ed7e..5433eb673e4 100644 --- a/erpnext/patches/v8_9/rename_company_sales_target_field.py +++ b/erpnext/patches/v8_9/rename_company_sales_target_field.py @@ -4,4 +4,5 @@ from frappe.model.utils.rename_field import rename_field def execute(): frappe.reload_doc("setup", "doctype", "company") - rename_field("Company", "sales_target", "monthly_sales_target") + if frappe.db.has_column('Company', 'sales_target'): + rename_field("Company", "sales_target", "monthly_sales_target") diff --git a/erpnext/setup/setup_wizard/test_setup_wizard.py b/erpnext/setup/setup_wizard/test_setup_wizard.py index aed6698bb43..2db63c1b44b 100644 --- a/erpnext/setup/setup_wizard/test_setup_wizard.py +++ b/erpnext/setup/setup_wizard/test_setup_wizard.py @@ -9,12 +9,13 @@ from frappe.utils.selenium_testdriver import TestDriver def run_setup_wizard_test(): driver = TestDriver() frappe.db.set_default('in_selenium', '1') + frappe.db.commit() driver.login('#page-setup-wizard') print('Running Setup Wizard Test...') # Language slide - driver.set_select("language", "English (United Kingdom)") + driver.set_select("language", "English (United States)") driver.wait_for_ajax(True) driver.wait_till_clickable(".next-btn").click() @@ -25,9 +26,9 @@ def run_setup_wizard_test(): driver.wait_till_clickable(".next-btn").click() # Profile slide - driver.set_field("full_name", "Joe Davis") - driver.set_field("email", "joe@example.com") - driver.set_field("password", "somethingrandom") + driver.set_field("full_name", "Great Tester") + driver.set_field("email", "great@example.com") + driver.set_field("password", "test") driver.wait_till_clickable(".next-btn").click() # Brand slide @@ -35,14 +36,14 @@ def run_setup_wizard_test(): driver.wait_till_clickable(".next-btn").click() # Org slide - driver.set_field("company_name", "Acme Corp") + driver.set_field("company_name", "For Testing") driver.wait_till_clickable(".next-btn").click() - driver.set_field("company_tagline", "Build Tools for Builders") - driver.set_field("bank_account", "BNL") + driver.set_field("company_tagline", "Just for GST") + driver.set_field("bank_account", "HDFC") driver.wait_till_clickable(".complete-btn").click() - # Wait for desk (Lock wait timeout error) - # driver.wait_for('#page-desktop', timeout=200) + # Wait for desktop + driver.wait_for('#page-desktop', timeout=600) console = driver.get_console() if frappe.flags.tests_verbose: @@ -52,6 +53,8 @@ def run_setup_wizard_test(): time.sleep(1) frappe.db.set_default('in_selenium', None) + frappe.db.commit() + driver.close() return True \ No newline at end of file diff --git a/erpnext/setup/setup_wizard/utils.py b/erpnext/setup/setup_wizard/utils.py index dc4abd4f502..d821a129899 100644 --- a/erpnext/setup/setup_wizard/utils.py +++ b/erpnext/setup/setup_wizard/utils.py @@ -10,6 +10,3 @@ def complete(): #setup_wizard.create_sales_tax(data) setup_complete(data) - - - diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 5dc97f623b3..f2ea1d88bca 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -488,6 +488,8 @@ class Item(WebsiteGenerator): def validate_warehouse_for_reorder(self): warehouse = [] for i in self.get("reorder_levels"): + if not i.warehouse_group: + i.warehouse_group = i.warehouse if i.get("warehouse") and i.get("warehouse") not in warehouse: warehouse += [i.get("warehouse")] else: diff --git a/erpnext/templates/print_formats/includes/taxes.html b/erpnext/templates/print_formats/includes/taxes.html index b180c1c923d..b7827635afa 100644 --- a/erpnext/templates/print_formats/includes/taxes.html +++ b/erpnext/templates/print_formats/includes/taxes.html @@ -19,7 +19,7 @@ {%- for charge in data -%} {%- if charge.tax_amount and not charge.included_in_print_rate -%}
-
+
{{ frappe.format_value(frappe.utils.flt(charge.tax_amount), diff --git a/erpnext/tests/ui/make_fixtures.js b/erpnext/tests/ui/make_fixtures.js index 0c5b4beebe1..f817c6549a8 100644 --- a/erpnext/tests/ui/make_fixtures.js +++ b/erpnext/tests/ui/make_fixtures.js @@ -205,6 +205,18 @@ $.extend(frappe.test_data, { {title: "Test Term 2"} ] }, + "Item Price": { + "ITEM-PRICE-00001": [ + {item_code: 'Test Product 1'}, + {price_list: '_Test Price List'}, + {price_list_rate: 100} + ], + "ITEM-PRICE-00002": [ + {item_code: 'Test Product 2'}, + {price_list: '_Test Price List'}, + {price_list_rate: 200} + ] + } }); diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt index 313554bd9ca..6017f6f67b6 100644 --- a/erpnext/tests/ui/tests.txt +++ b/erpnext/tests/ui/tests.txt @@ -125,4 +125,5 @@ erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_f erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_issue_with_serialize_item.js erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_repack.js -erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_serialize_item.js \ No newline at end of file +erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_serialize_item.js +erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js