diff --git a/.github/helper/install.sh b/.github/helper/install.sh index a6a6069d358..e7f46410e6c 100644 --- a/.github/helper/install.sh +++ b/.github/helper/install.sh @@ -4,11 +4,7 @@ set -e cd ~ || exit -sudo apt-get install redis-server - -sudo apt install nodejs - -sudo apt install npm +sudo apt-get install redis-server libcups2-dev pip install frappe-bench @@ -32,7 +28,6 @@ wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/w tar -xf /tmp/wkhtmltox.tar.xz -C /tmp sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf sudo chmod o+x /usr/local/bin/wkhtmltopdf -sudo apt-get install libcups2-dev cd ~/frappe-bench || exit diff --git a/.github/workflows/patch.yml b/.github/workflows/patch.yml index 0f28838d2bf..eaab24b9081 100644 --- a/.github/workflows/patch.yml +++ b/.github/workflows/patch.yml @@ -32,6 +32,12 @@ jobs: with: python-version: 3.6 + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: 12 + check-latest: true + - name: Add to Hosts run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts diff --git a/.github/workflows/server-tests.yml b/.github/workflows/server-tests.yml index 124ed7ad3e9..a008b638c3f 100644 --- a/.github/workflows/server-tests.yml +++ b/.github/workflows/server-tests.yml @@ -42,6 +42,12 @@ jobs: with: python-version: 3.7 + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: 12 + check-latest: true + - name: Add to Hosts run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index e3158ea97ee..cc3c5ceb7d1 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -94,7 +94,7 @@ jobs: run: cd ~/frappe-bench/ && bench --site test_site execute erpnext.setup.utils.before_tests - name: cypress pre-requisites - run: cd ~/frappe-bench/apps/frappe && yarn add cypress-file-upload@^5 --no-lockfile + run: cd ~/frappe-bench/apps/frappe && yarn add cypress-file-upload@^5 @testing-library/cypress@^8 --no-lockfile - name: Build Assets diff --git a/erpnext/accounts/custom/address.py b/erpnext/accounts/custom/address.py index c417a493c69..834227bb586 100644 --- a/erpnext/accounts/custom/address.py +++ b/erpnext/accounts/custom/address.py @@ -1,7 +1,7 @@ import frappe from frappe import _ from frappe.contacts.doctype.address.address import Address -from frappe.contacts.doctype.address.address import get_address_templates +from frappe.contacts.doctype.address.address import get_address_templates, get_address_display class ERPNextAddress(Address): def validate(self): @@ -22,6 +22,16 @@ class ERPNextAddress(Address): frappe.throw(_("Address needs to be linked to a Company. Please add a row for Company in the Links table."), title=_("Company Not Linked")) + def on_update(self): + """ + After Address is updated, update the related 'Primary Address' on Customer. + """ + address_display = get_address_display(self.as_dict()) + filters = { "customer_primary_address": self.name } + customers = frappe.db.get_all("Customer", filters=filters, as_list=True) + for customer_name in customers: + frappe.db.set_value("Customer", customer_name[0], "primary_address", address_display) + @frappe.whitelist() def get_shipping_address(company, address = None): filters = [ diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js index f7f1a5fb15a..7a1d7359488 100644 --- a/erpnext/accounts/doctype/account/account.js +++ b/erpnext/accounts/doctype/account/account.js @@ -74,7 +74,7 @@ frappe.ui.form.on('Account', { }); } else if (cint(frm.doc.is_group) == 0 && frappe.boot.user.can_read.indexOf("GL Entry") !== -1) { - cur_frm.add_custom_button(__('Ledger'), function () { + frm.add_custom_button(__('Ledger'), function () { frappe.route_options = { "account": frm.doc.name, "from_date": frappe.sys_defaults.year_start_date, diff --git a/erpnext/accounts/doctype/accounting_period/test_accounting_period.js b/erpnext/accounts/doctype/accounting_period/test_accounting_period.js deleted file mode 100644 index 71ce5b8d04f..00000000000 --- a/erpnext/accounts/doctype/accounting_period/test_accounting_period.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Accounting Period", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Accounting Period - () => frappe.tests.make('Accounting Period', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/bank/test_bank.js b/erpnext/accounts/doctype/bank/test_bank.js deleted file mode 100644 index 9ec264415a6..00000000000 --- a/erpnext/accounts/doctype/bank/test_bank.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Bank", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Bank - () => frappe.tests.make('Bank', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/bank_account/test_bank_account.js b/erpnext/accounts/doctype/bank_account/test_bank_account.js deleted file mode 100644 index c20a7990e8c..00000000000 --- a/erpnext/accounts/doctype/bank_account/test_bank_account.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Bank Account", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Bank Account - () => frappe.tests.make('Bank Account', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.js b/erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.js deleted file mode 100644 index f59999845af..00000000000 --- a/erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Bank Account Subtype", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Bank Account Subtype - () => frappe.tests.make('Bank Account Subtype', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/bank_guarantee/test_bank_guarantee.js b/erpnext/accounts/doctype/bank_guarantee/test_bank_guarantee.js deleted file mode 100644 index 0c60920cf98..00000000000 --- a/erpnext/accounts/doctype/bank_guarantee/test_bank_guarantee.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Bank Guarantee", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Bank Guarantee - () => frappe.tests.make('Bank Guarantee', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 0544a469d60..7ea71fc103a 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -55,6 +55,11 @@ class BankTransaction(StatusUpdater): self.clear_sales_invoice(payment_entry, for_cancel=for_cancel) def clear_simple_entry(self, payment_entry, for_cancel=False): + if payment_entry.payment_document == "Payment Entry": + if frappe.db.get_value("Payment Entry", payment_entry.payment_entry, "payment_type") == "Internal Transfer": + if len(get_reconciled_bank_transactions(payment_entry)) < 2: + return + clearance_date = self.date if not for_cancel else None frappe.db.set_value( payment_entry.payment_document, payment_entry.payment_entry, @@ -70,6 +75,17 @@ class BankTransaction(StatusUpdater): ), "clearance_date", clearance_date) +def get_reconciled_bank_transactions(payment_entry): + reconciled_bank_transactions = frappe.get_all( + 'Bank Transaction Payments', + filters = { + 'payment_entry': payment_entry.payment_entry + }, + fields = ['parent'] + ) + + return reconciled_bank_transactions + def get_total_allocated_amount(payment_entry): return frappe.db.sql(""" SELECT diff --git a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.js b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.js deleted file mode 100644 index 305119e1370..00000000000 --- a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Bank Transaction", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Bank Transaction - () => frappe.tests.make('Bank Transaction', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.js b/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.js deleted file mode 100644 index 12ca254c5ae..00000000000 --- a/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Cash Flow Mapper", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Cash Flow Mapper - () => frappe.tests.make('Cash Flow Mapper', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.js b/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.js deleted file mode 100644 index 1970ca806dc..00000000000 --- a/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Cash Flow Mapping", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Cash Flow Mapping - () => frappe.tests.make('Cash Flow Mapping', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.js b/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.js deleted file mode 100644 index 12546ce2e3a..00000000000 --- a/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Cash Flow Mapping Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Cash Flow Mapping Template - () => frappe.tests.make('Cash Flow Mapping Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.js b/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.js deleted file mode 100644 index eecabda751b..00000000000 --- a/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Cash Flow Mapping Template Details", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Cash Flow Mapping Template Details - () => frappe.tests.make('Cash Flow Mapping Template Details', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js b/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js deleted file mode 100644 index a7fcc8d8421..00000000000 --- a/erpnext/accounts/doctype/cashier_closing/test_cashier_closing.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Cashier Closing", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Cashier Closing - () => frappe.tests.make('Cashier Closing', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/test_chart_of_accounts_importer.js b/erpnext/accounts/doctype/chart_of_accounts_importer/test_chart_of_accounts_importer.js deleted file mode 100644 index b075a015d60..00000000000 --- a/erpnext/accounts/doctype/chart_of_accounts_importer/test_chart_of_accounts_importer.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Chart of Accounts Importer", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Chart of Accounts Importer - () => frappe.tests.make('Chart of Accounts Importer', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/coupon_code/test_coupon_code.js b/erpnext/accounts/doctype/coupon_code/test_coupon_code.js deleted file mode 100644 index 460fedc97f9..00000000000 --- a/erpnext/accounts/doctype/coupon_code/test_coupon_code.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Coupon Code", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Coupon Code - () => frappe.tests.make('Coupon Code', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.js b/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.js deleted file mode 100644 index 57c6a7871dc..00000000000 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Exchange Rate Revaluation", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Exchange Rate Revaluation - () => frappe.tests.make('Exchange Rate Revaluation', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/finance_book/test_finance_book.js b/erpnext/accounts/doctype/finance_book/test_finance_book.js deleted file mode 100644 index 9fb7d4fcc8e..00000000000 --- a/erpnext/accounts/doctype/finance_book/test_finance_book.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Finance Book", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Finance Book - () => frappe.tests.make('Finance Book', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/gl_entry/test_gl_entry.js b/erpnext/accounts/doctype/gl_entry/test_gl_entry.js deleted file mode 100644 index 2986e5e4e3b..00000000000 --- a/erpnext/accounts/doctype/gl_entry/test_gl_entry.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: GL Entry", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('GL Entry', [ - // insert a new GL Entry - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/item_tax_template/test_item_tax_template.js b/erpnext/accounts/doctype/item_tax_template/test_item_tax_template.js deleted file mode 100644 index 68934993914..00000000000 --- a/erpnext/accounts/doctype/item_tax_template/test_item_tax_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Item Tax Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Item Tax Template - () => frappe.tests.make('Item Tax Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 937597bc550..72648753a7a 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -643,7 +643,10 @@ class JournalEntry(AccountsController): for d in self.accounts: if d.reference_type=="Expense Claim" and d.reference_name: doc = frappe.get_doc("Expense Claim", d.reference_name) - update_reimbursed_amount(doc, jv=self.name) + if self.docstatus == 2: + update_reimbursed_amount(doc, -1 * d.debit) + else: + update_reimbursed_amount(doc, d.debit) def validate_expense_claim(self): diff --git a/erpnext/accounts/doctype/loyalty_point_entry/test_loyalty_point_entry.js b/erpnext/accounts/doctype/loyalty_point_entry/test_loyalty_point_entry.js deleted file mode 100644 index a916b67522c..00000000000 --- a/erpnext/accounts/doctype/loyalty_point_entry/test_loyalty_point_entry.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Loyalty Point Entry", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Loyalty Point Entry - () => frappe.tests.make('Loyalty Point Entry', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.js b/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.js deleted file mode 100644 index 9321c14e1f0..00000000000 --- a/erpnext/accounts/doctype/loyalty_program/test_loyalty_program.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Loyalty Program", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Loyalty Program - () => frappe.tests.make('Loyalty Program', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.js b/erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.js deleted file mode 100644 index f95d0d82138..00000000000 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Opening Invoice Creation Tool", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Opening Invoice Creation Tool - () => frappe.tests.make('Opening Invoice Creation Tool', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 91e89745f5d..e34d651f0c4 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -75,9 +75,9 @@ class PaymentEntry(AccountsController): if self.difference_amount: frappe.throw(_("Difference Amount must be zero")) self.make_gl_entries() + self.update_expense_claim() self.update_outstanding_amounts() self.update_advance_paid() - self.update_expense_claim() self.update_donation() self.update_payment_schedule() self.set_status() @@ -85,9 +85,9 @@ class PaymentEntry(AccountsController): def on_cancel(self): self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry') self.make_gl_entries(cancel=1) + self.update_expense_claim() self.update_outstanding_amounts() self.update_advance_paid() - self.update_expense_claim() self.update_donation(cancel=1) self.delink_advance_entry_references() self.update_payment_schedule(cancel=1) @@ -755,9 +755,11 @@ class PaymentEntry(AccountsController): if self.payment_type in ('Pay', 'Internal Transfer'): dr_or_cr = "debit" if d.add_deduct_tax == "Add" else "credit" + rev_dr_or_cr = "credit" if dr_or_cr == "debit" else "debit" against = self.party or self.paid_from elif self.payment_type == 'Receive': dr_or_cr = "credit" if d.add_deduct_tax == "Add" else "debit" + rev_dr_or_cr = "credit" if dr_or_cr == "debit" else "debit" against = self.party or self.paid_to payment_or_advance_account = self.get_party_account_for_taxes() @@ -779,14 +781,13 @@ class PaymentEntry(AccountsController): "cost_center": d.cost_center }, account_currency, item=d)) - #Intentionally use -1 to get net values in party account if not d.included_in_paid_amount or self.advance_tax_account: gl_entries.append( self.get_gl_dict({ "account": payment_or_advance_account, "against": against, - dr_or_cr: -1 * tax_amount, - dr_or_cr + "_in_account_currency": -1 * base_tax_amount + rev_dr_or_cr: tax_amount, + rev_dr_or_cr + "_in_account_currency": base_tax_amount if account_currency==self.company_currency else d.tax_amount, "cost_center": self.cost_center, @@ -830,7 +831,10 @@ class PaymentEntry(AccountsController): for d in self.get("references"): if d.reference_doctype=="Expense Claim" and d.reference_name: doc = frappe.get_doc("Expense Claim", d.reference_name) - update_reimbursed_amount(doc, self.name) + if self.docstatus == 2: + update_reimbursed_amount(doc, -1 * d.allocated_amount) + else: + update_reimbursed_amount(doc, d.allocated_amount) def update_donation(self, cancel=0): if self.payment_type == "Receive" and self.party_type == "Donor" and self.party: diff --git a/erpnext/accounts/doctype/payment_order/test_payment_order.js b/erpnext/accounts/doctype/payment_order/test_payment_order.js deleted file mode 100644 index f63fc54521c..00000000000 --- a/erpnext/accounts/doctype/payment_order/test_payment_order.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Payment Order", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Payment Order - () => frappe.tests.make('Payment Order', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/payment_request/test_payment_request.js b/erpnext/accounts/doctype/payment_request/test_payment_request.js deleted file mode 100644 index 070b595fc6a..00000000000 --- a/erpnext/accounts/doctype/payment_request/test_payment_request.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Payment Request", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Payment Request - () => frappe.tests.make('Payment Request', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/payment_term/test_payment_term.js b/erpnext/accounts/doctype/payment_term/test_payment_term.js deleted file mode 100644 index b26e42aa37d..00000000000 --- a/erpnext/accounts/doctype/payment_term/test_payment_term.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Payment Term", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Payment Term - () => frappe.tests.make('Payment Term', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/payment_terms_template/test_payment_terms_template.js b/erpnext/accounts/doctype/payment_terms_template/test_payment_terms_template.js deleted file mode 100644 index 494a0ed21fb..00000000000 --- a/erpnext/accounts/doctype/payment_terms_template/test_payment_terms_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Payment Terms Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Payment Terms Template - () => frappe.tests.make('Payment Terms Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py index 2d1939131c3..2a636bb3381 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py @@ -13,59 +13,49 @@ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sal class TestPeriodClosingVoucher(unittest.TestCase): def test_closing_entry(self): - year_start_date = get_fiscal_year(today(), company="_Test Company")[1] + frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") - make_journal_entry("_Test Bank - _TC", "Sales - _TC", 400, - "_Test Cost Center - _TC", posting_date=now(), submit=True) + company = create_company() + cost_center = create_cost_center('Test Cost Center 1') - make_journal_entry("_Test Account Cost for Goods Sold - _TC", - "_Test Bank - _TC", 600, "_Test Cost Center - _TC", posting_date=now(), submit=True) + jv1 = make_journal_entry( + amount=400, + account1="Cash - TPC", + account2="Sales - TPC", + cost_center=cost_center, + posting_date=now(), + save=False + ) + jv1.company = company + jv1.save() + jv1.submit() - random_expense_account = frappe.db.sql(""" - select t1.account, - sum(t1.debit) - sum(t1.credit) as balance, - sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) \ - as balance_in_account_currency - from `tabGL Entry` t1, `tabAccount` t2 - where t1.account = t2.name and t2.root_type = 'Expense' - and t2.docstatus < 2 and t2.company = '_Test Company' - and t1.posting_date between %s and %s - group by t1.account - having sum(t1.debit) > sum(t1.credit) - limit 1""", (year_start_date, today()), as_dict=True) - - profit_or_loss = frappe.db.sql("""select sum(t1.debit) - sum(t1.credit) as balance - from `tabGL Entry` t1, `tabAccount` t2 - where t1.account = t2.name and t2.report_type = 'Profit and Loss' - and t2.docstatus < 2 and t2.company = '_Test Company' - and t1.posting_date between %s and %s""", (year_start_date, today())) - - profit_or_loss = flt(profit_or_loss[0][0]) if profit_or_loss else 0 + jv2 = make_journal_entry( + amount=600, + account1="Cost of Goods Sold - TPC", + account2="Cash - TPC", + cost_center=cost_center, + posting_date=now(), + save=False + ) + jv2.company = company + jv2.save() + jv2.submit() pcv = self.make_period_closing_voucher() + surplus_account = pcv.closing_account_head - # Check value for closing account - gle_amount_for_closing_account = frappe.db.sql("""select debit - credit - from `tabGL Entry` where voucher_type='Period Closing Voucher' and voucher_no=%s - and account = '_Test Account Reserves and Surplus - _TC'""", pcv.name) + expected_gle = ( + ('Cost of Goods Sold - TPC', 0.0, 600.0), + (surplus_account, 600.0, 400.0), + ('Sales - TPC', 400.0, 0.0) + ) - gle_amount_for_closing_account = flt(gle_amount_for_closing_account[0][0]) \ - if gle_amount_for_closing_account else 0 + pcv_gle = frappe.db.sql(""" + select account, debit, credit from `tabGL Entry` where voucher_no=%s order by account + """, (pcv.name)) - self.assertEqual(gle_amount_for_closing_account, profit_or_loss) - - if random_expense_account: - # Check posted value for teh above random_expense_account - gle_for_random_expense_account = frappe.db.sql(""" - select sum(debit - credit) as amount, - sum(debit_in_account_currency - credit_in_account_currency) as amount_in_account_currency - from `tabGL Entry` - where voucher_type='Period Closing Voucher' and voucher_no=%s and account =%s""", - (pcv.name, random_expense_account[0].account), as_dict=True) - - self.assertEqual(gle_for_random_expense_account[0].amount, -1*random_expense_account[0].balance) - self.assertEqual(gle_for_random_expense_account[0].amount_in_account_currency, - -1*random_expense_account[0].balance_in_account_currency) + self.assertEqual(pcv_gle, expected_gle) def test_cost_center_wise_posting(self): frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") @@ -93,31 +83,23 @@ class TestPeriodClosingVoucher(unittest.TestCase): debit_to="Debtors - TPC" ) - pcv = frappe.get_doc({ - "transaction_date": today(), - "posting_date": today(), - "fiscal_year": get_fiscal_year(today())[0], - "company": "Test PCV Company", - "cost_center_wise_pnl": 1, - "closing_account_head": surplus_account, - "remarks": "Test", - "doctype": "Period Closing Voucher" - }) - pcv.insert() - pcv.submit() + pcv = self.make_period_closing_voucher() + surplus_account = pcv.closing_account_head expected_gle = ( - ('Sales - TPC', 200.0, 0.0, cost_center2), + (surplus_account, 0.0, 400.0, cost_center1), (surplus_account, 0.0, 200.0, cost_center2), ('Sales - TPC', 400.0, 0.0, cost_center1), - (surplus_account, 0.0, 400.0, cost_center1) + ('Sales - TPC', 200.0, 0.0, cost_center2), ) pcv_gle = frappe.db.sql(""" - select account, debit, credit, cost_center from `tabGL Entry` where voucher_no=%s + select account, debit, credit, cost_center + from `tabGL Entry` where voucher_no=%s + order by account, cost_center """, (pcv.name)) - self.assertTrue(pcv_gle, expected_gle) + self.assertEqual(pcv_gle, expected_gle) def test_period_closing_with_finance_book_entries(self): frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'") @@ -146,39 +128,35 @@ class TestPeriodClosingVoucher(unittest.TestCase): jv.save() jv.submit() - pcv = frappe.get_doc({ - "transaction_date": today(), - "posting_date": today(), - "fiscal_year": get_fiscal_year(today())[0], - "company": company, - "closing_account_head": surplus_account, - "remarks": "Test", - "doctype": "Period Closing Voucher" - }) - pcv.insert() - pcv.submit() + pcv = self.make_period_closing_voucher() + surplus_account = pcv.closing_account_head expected_gle = ( - (surplus_account, 0.0, 400.0, ''), + (surplus_account, 0.0, 400.0, None), (surplus_account, 0.0, 400.0, jv.finance_book), - ('Sales - TPC', 400.0, 0.0, ''), + ('Sales - TPC', 400.0, 0.0, None), ('Sales - TPC', 400.0, 0.0, jv.finance_book) ) pcv_gle = frappe.db.sql(""" - select account, debit, credit, finance_book from `tabGL Entry` where voucher_no=%s + select account, debit, credit, finance_book + from `tabGL Entry` where voucher_no=%s + order by account, finance_book """, (pcv.name)) - self.assertTrue(pcv_gle, expected_gle) + self.assertEqual(pcv_gle, expected_gle) def make_period_closing_voucher(self): + surplus_account = create_account() + cost_center = create_cost_center("Test Cost Center 1") pcv = frappe.get_doc({ "doctype": "Period Closing Voucher", - "closing_account_head": "_Test Account Reserves and Surplus - _TC", - "company": "_Test Company", - "fiscal_year": get_fiscal_year(today(), company="_Test Company")[0], + "transaction_date": today(), "posting_date": today(), - "cost_center": "_Test Cost Center - _TC", + "company": "Test PCV Company", + "fiscal_year": get_fiscal_year(today(), company="Test PCV Company")[0], + "cost_center": cost_center, + "closing_account_head": surplus_account, "remarks": "test" }) pcv.insert() diff --git a/erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.js b/erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.js deleted file mode 100644 index 48109b159c6..00000000000 --- a/erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: POS Closing Entry", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new POS Closing Entry - () => frappe.tests.make('POS Closing Entry', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/pos_profile/test_pos_profile.js b/erpnext/accounts/doctype/pos_profile/test_pos_profile.js deleted file mode 100644 index 42e5b7f92f1..00000000000 --- a/erpnext/accounts/doctype/pos_profile/test_pos_profile.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: POS Profile", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('POS Profile', [ - // insert a new POS Profile - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/pos_profile_user/test_pos_profile_user.js b/erpnext/accounts/doctype/pos_profile_user/test_pos_profile_user.js deleted file mode 100644 index 5449ab76a38..00000000000 --- a/erpnext/accounts/doctype/pos_profile_user/test_pos_profile_user.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: POS Profile User", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new POS Profile User - () => frappe.tests.make('POS Profile User', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/pos_settings/test_pos_settings.js b/erpnext/accounts/doctype/pos_settings/test_pos_settings.js deleted file mode 100644 index 639c94ed10d..00000000000 --- a/erpnext/accounts/doctype/pos_settings/test_pos_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: POS Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new POS Settings - () => frappe.tests.make('POS Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py index 94abf3b3c06..5467cb0bc5b 100644 --- a/erpnext/accounts/doctype/pricing_rule/utils.py +++ b/erpnext/accounts/doctype/pricing_rule/utils.py @@ -475,7 +475,20 @@ def apply_pricing_rule_on_transaction(doc): frappe.msgprint(_("User has not applied rule on the invoice {0}") .format(doc.name)) else: - doc.set(field, d.get(pr_field)) + if not d.coupon_code_based: + doc.set(field, d.get(pr_field)) + elif doc.get('coupon_code'): + # coupon code based pricing rule + coupon_code_pricing_rule = frappe.db.get_value('Coupon Code', doc.get('coupon_code'), 'pricing_rule') + if coupon_code_pricing_rule == d.name: + # if selected coupon code is linked with pricing rule + doc.set(field, d.get(pr_field)) + else: + # reset discount if not linked + doc.set(field, 0) + else: + # if coupon code based but no coupon code selected + doc.set(field, 0) doc.calculate_taxes_and_totals() elif d.price_or_product_discount == 'Product': diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index a98a83a0476..7427f381aba 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -719,19 +719,6 @@ frappe.ui.form.on('Sales Invoice', { } }, - project: function(frm){ - if (!frm.doc.is_return) { - frm.call({ - method: "add_timesheet_data", - doc: frm.doc, - callback: function(r, rt) { - refresh_field(['timesheets']) - } - }) - frm.refresh(); - } - }, - onload: function(frm) { frm.redemption_conversion_factor = null; }, @@ -842,25 +829,92 @@ frappe.ui.form.on('Sales Invoice', { } }, - add_timesheet_row: function(frm, row, exchange_rate) { - frm.add_child('timesheets', { - 'activity_type': row.activity_type, - 'description': row.description, - 'time_sheet': row.parent, - 'billing_hours': row.billing_hours, - 'billing_amount': flt(row.billing_amount) * flt(exchange_rate), - 'timesheet_detail': row.name, - 'project_name': row.project_name + project: function(frm) { + if (frm.doc.project) { + frm.events.add_timesheet_data(frm, { + project: frm.doc.project + }); + } + }, + + async add_timesheet_data(frm, kwargs) { + if (kwargs === "Sales Invoice") { + // called via frm.trigger() + kwargs = Object(); + } + + if (!kwargs.hasOwnProperty("project") && frm.doc.project) { + kwargs.project = frm.doc.project; + } + + const timesheets = await frm.events.get_timesheet_data(frm, kwargs); + return frm.events.set_timesheet_data(frm, timesheets); + }, + + async get_timesheet_data(frm, kwargs) { + return frappe.call({ + method: "erpnext.projects.doctype.timesheet.timesheet.get_projectwise_timesheet_data", + args: kwargs + }).then(r => { + if (!r.exc && r.message.length > 0) { + return r.message + } else { + return [] + } }); - frm.refresh_field('timesheets'); - calculate_total_billing_amount(frm); + }, + + set_timesheet_data: function(frm, timesheets) { + frm.clear_table("timesheets") + timesheets.forEach(timesheet => { + if (frm.doc.currency != timesheet.currency) { + frappe.call({ + method: "erpnext.setup.utils.get_exchange_rate", + args: { + from_currency: timesheet.currency, + to_currency: frm.doc.currency + }, + callback: function(r) { + if (r.message) { + exchange_rate = r.message; + frm.events.append_time_log(frm, timesheet, exchange_rate); + } + } + }); + } else { + frm.events.append_time_log(frm, timesheet, 1.0); + } + }); + }, + + append_time_log: function(frm, time_log, exchange_rate) { + const row = frm.add_child("timesheets"); + row.activity_type = time_log.activity_type; + row.description = time_log.description; + row.time_sheet = time_log.time_sheet; + row.from_time = time_log.from_time; + row.to_time = time_log.to_time; + row.billing_hours = time_log.billing_hours; + row.billing_amount = flt(time_log.billing_amount) * flt(exchange_rate); + row.timesheet_detail = time_log.name; + row.project_name = time_log.project_name; + + frm.refresh_field("timesheets"); + frm.trigger("calculate_timesheet_totals"); + }, + + calculate_timesheet_totals: function(frm) { + frm.set_value("total_billing_amount", + frm.doc.timesheets.reduce((a, b) => a + (b["billing_amount"] || 0.0), 0.0)); + frm.set_value("total_billing_hours", + frm.doc.timesheets.reduce((a, b) => a + (b["billing_hours"] || 0.0), 0.0)); }, refresh: function(frm) { if (frm.doc.docstatus===0 && !frm.doc.is_return) { - frm.add_custom_button(__('Fetch Timesheet'), function() { + frm.add_custom_button(__("Fetch Timesheet"), function() { let d = new frappe.ui.Dialog({ - title: __('Fetch Timesheet'), + title: __("Fetch Timesheet"), fields: [ { "label" : __("From"), @@ -869,8 +923,8 @@ frappe.ui.form.on('Sales Invoice', { "reqd": 1, }, { - fieldtype: 'Column Break', - fieldname: 'col_break_1', + fieldtype: "Column Break", + fieldname: "col_break_1", }, { "label" : __("To"), @@ -887,48 +941,18 @@ frappe.ui.form.on('Sales Invoice', { }, ], primary_action: function() { - let data = d.get_values(); - frappe.call({ - method: "erpnext.projects.doctype.timesheet.timesheet.get_projectwise_timesheet_data", - args: { - from_time: data.from_time, - to_time: data.to_time, - project: data.project - }, - callback: function(r) { - if (!r.exc && r.message.length > 0) { - frm.clear_table('timesheets') - r.message.forEach((d) => { - let exchange_rate = 1.0; - if (frm.doc.currency != d.currency) { - frappe.call({ - method: 'erpnext.setup.utils.get_exchange_rate', - args: { - from_currency: d.currency, - to_currency: frm.doc.currency - }, - callback: function(r) { - if (r.message) { - exchange_rate = r.message; - frm.events.add_timesheet_row(frm, d, exchange_rate); - } - } - }); - } else { - frm.events.add_timesheet_row(frm, d, exchange_rate); - } - }); - } else { - frappe.msgprint(__('No Timesheets found with the selected filters.')) - } - d.hide(); - } + const data = d.get_values(); + frm.events.add_timesheet_data(frm, { + from_time: data.from_time, + to_time: data.to_time, + project: data.project }); + d.hide(); }, - primary_action_label: __('Get Timesheets') + primary_action_label: __("Get Timesheets") }); d.show(); - }) + }); } if (frm.doc.is_debit_note) { @@ -961,26 +985,22 @@ frappe.ui.form.on('Sales Invoice', { frm: frm }); }, + create_dunning: function(frm) { frappe.model.open_mapped_doc({ method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.create_dunning", frm: frm }); } -}) +}); -var calculate_total_billing_amount = function(frm) { - var doc = frm.doc; - doc.total_billing_amount = 0.0 - if (doc.timesheets) { - $.each(doc.timesheets, function(index, data){ - doc.total_billing_amount += flt(data.billing_amount) - }) +frappe.ui.form.on("Sales Invoice Timesheet", { + timesheets_remove(frm, cdt, cdn) { + frm.trigger("calculate_timesheet_totals"); } +}); - refresh_field('total_billing_amount') -} var set_timesheet_detail_rate = function(cdt, cdn, currency, timelog) { frappe.call({ diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json index 99ecb8a4fea..2f8de068840 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json @@ -74,6 +74,7 @@ "time_sheet_list", "timesheets", "total_billing_amount", + "total_billing_hours", "section_break_30", "total_qty", "base_total", @@ -2011,6 +2012,13 @@ "fieldtype": "Small Text", "label": "Dispatch Address", "read_only": 1 + }, + { + "fieldname": "total_billing_hours", + "fieldtype": "Float", + "label": "Total Billing Hours", + "print_hide": 1, + "read_only": 1 } ], "icon": "fa fa-file-text", @@ -2023,7 +2031,7 @@ "link_fieldname": "consolidated_invoice" } ], - "modified": "2021-08-25 14:46:05.279588", + "modified": "2021-08-25 15:46:05.279588", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice", @@ -2077,4 +2085,4 @@ "title_field": "title", "track_changes": 1, "track_seen": 1 -} \ No newline at end of file +} diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 9e295d5ae54..0a7042fa47c 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe, erpnext import frappe.defaults -from frappe.utils import cint, flt, getdate, add_days, cstr, nowdate, get_link_to_form, formatdate +from frappe.utils import cint, flt, getdate, add_days, add_months, cstr, nowdate, get_link_to_form, formatdate from frappe import _, msgprint, throw from erpnext.accounts.party import get_party_account, get_due_date, get_party_details from frappe.model.mapper import get_mapped_doc @@ -13,7 +13,7 @@ from erpnext.accounts.utils import get_account_currency from erpnext.stock.doctype.delivery_note.delivery_note import update_billed_amount_based_on_so from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data from erpnext.assets.doctype.asset.depreciation \ - import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal + import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal, get_gl_entries_on_asset_regain, post_depreciation_entries from erpnext.stock.doctype.batch.batch import set_batch_nos from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no from erpnext.setup.doctype.company.company import update_company_current_month_sales @@ -149,7 +149,7 @@ class SalesInvoice(SellingController): if self.update_stock: frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale")) - elif asset.status in ("Scrapped", "Cancelled", "Sold"): + elif asset.status in ("Scrapped", "Cancelled") or (asset.status == "Sold" and not self.is_return): frappe.throw(_("Row #{0}: Asset {1} cannot be submitted, it is already {2}").format(d.idx, d.asset, asset.status)) def validate_item_cost_centers(self): @@ -757,7 +757,7 @@ class SalesInvoice(SellingController): if self.project: for data in get_projectwise_timesheet_data(self.project): self.append('timesheets', { - 'time_sheet': data.parent, + 'time_sheet': data.time_sheet, 'billing_hours': data.billing_hours, 'billing_amount': data.billing_amount, 'timesheet_detail': data.name, @@ -768,12 +768,11 @@ class SalesInvoice(SellingController): self.calculate_billing_amount_for_timesheet() def calculate_billing_amount_for_timesheet(self): - total_billing_amount = 0.0 - for data in self.timesheets: - if data.billing_amount: - total_billing_amount += data.billing_amount + def timesheet_sum(field): + return sum((ts.get(field) or 0.0) for ts in self.timesheets) - self.total_billing_amount = total_billing_amount + self.total_billing_amount = timesheet_sum("billing_amount") + self.total_billing_hours = timesheet_sum("billing_hours") def get_warehouse(self): user_pos_profile = frappe.db.sql("""select name, warehouse from `tabPOS Profile` @@ -925,22 +924,30 @@ class SalesInvoice(SellingController): for item in self.get("items"): if flt(item.base_net_amount, item.precision("base_net_amount")): if item.is_fixed_asset: - asset = frappe.get_doc("Asset", item.asset) + asset = self.get_asset(item) - if (len(asset.finance_books) > 1 and not item.finance_book - and asset.finance_books[0].finance_book): - frappe.throw(_("Select finance book for the item {0} at row {1}") - .format(item.item_code, item.idx)) + if self.is_return: + fixed_asset_gl_entries = get_gl_entries_on_asset_regain(asset, + item.base_net_amount, item.finance_book) + asset.db_set("disposal_date", None) - fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, - item.base_net_amount, item.finance_book) + if asset.calculate_depreciation: + self.reset_depreciation_schedule(asset) + + else: + fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, + item.base_net_amount, item.finance_book) + asset.db_set("disposal_date", self.posting_date) + + if asset.calculate_depreciation: + self.depreciate_asset(asset) for gle in fixed_asset_gl_entries: gle["against"] = self.customer gl_entries.append(self.get_gl_dict(gle, item=item)) - asset.db_set("disposal_date", self.posting_date) - asset.set_status("Sold" if self.docstatus==1 else None) + self.set_asset_status(asset) + else: # Do not book income for transfer within same company if not self.is_internal_transfer(): @@ -968,6 +975,89 @@ class SalesInvoice(SellingController): erpnext.is_perpetual_inventory_enabled(self.company): gl_entries += super(SalesInvoice, self).get_gl_entries() + def get_asset(self, item): + if item.get('asset'): + asset = frappe.get_doc("Asset", item.asset) + else: + frappe.throw(_( + "Row #{0}: You must select an Asset for Item {1}.").format(item.idx, item.item_name), + title=_("Missing Asset") + ) + + self.check_finance_books(item, asset) + return asset + + def check_finance_books(self, item, asset): + if (len(asset.finance_books) > 1 and not item.finance_book + and asset.finance_books[0].finance_book): + frappe.throw(_("Select finance book for the item {0} at row {1}") + .format(item.item_code, item.idx)) + + def depreciate_asset(self, asset): + asset.flags.ignore_validate_update_after_submit = True + asset.prepare_depreciation_data(self.posting_date) + asset.save() + + post_depreciation_entries(self.posting_date) + + def reset_depreciation_schedule(self, asset): + asset.flags.ignore_validate_update_after_submit = True + + # recreate original depreciation schedule of the asset + asset.prepare_depreciation_data() + + self.modify_depreciation_schedule_for_asset_repairs(asset) + asset.save() + + self.delete_depreciation_entry_made_after_sale(asset) + + def modify_depreciation_schedule_for_asset_repairs(self, asset): + asset_repairs = frappe.get_all( + 'Asset Repair', + filters = {'asset': asset.name}, + fields = ['name', 'increase_in_asset_life'] + ) + + for repair in asset_repairs: + if repair.increase_in_asset_life: + asset_repair = frappe.get_doc('Asset Repair', repair.name) + asset_repair.modify_depreciation_schedule() + asset.prepare_depreciation_data() + + def delete_depreciation_entry_made_after_sale(self, asset): + from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry + + posting_date_of_original_invoice = self.get_posting_date_of_sales_invoice() + + row = -1 + finance_book = asset.get('schedules')[0].get('finance_book') + for schedule in asset.get('schedules'): + if schedule.finance_book != finance_book: + row = 0 + finance_book = schedule.finance_book + else: + row += 1 + + if schedule.schedule_date == posting_date_of_original_invoice: + if not self.sale_was_made_on_original_schedule_date(asset, schedule, row, posting_date_of_original_invoice): + reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry) + reverse_journal_entry.posting_date = nowdate() + reverse_journal_entry.submit() + + def get_posting_date_of_sales_invoice(self): + return frappe.db.get_value('Sales Invoice', self.return_against, 'posting_date') + + # if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone + def sale_was_made_on_original_schedule_date(self, asset, schedule, row, posting_date_of_original_invoice): + for finance_book in asset.get('finance_books'): + if schedule.finance_book == finance_book.finance_book: + orginal_schedule_date = add_months(finance_book.depreciation_start_date, + row * cint(finance_book.frequency_of_depreciation)) + + if orginal_schedule_date == posting_date_of_original_invoice: + return True + return False + @property def enable_discount_accounting(self): if not hasattr(self, "_enable_discount_accounting"): diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 30e0db31f6c..8fa36509d21 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -10,6 +10,8 @@ from frappe.model.dynamic_links import get_dynamic_link_map from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile +from erpnext.assets.doctype.asset.test_asset import create_asset, create_asset_data +from erpnext.assets.doctype.asset.depreciation import post_depreciation_entries from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError from frappe.model.naming import make_autoname @@ -1106,6 +1108,45 @@ class TestSalesInvoice(unittest.TestCase): self.assertFalse(si1.outstanding_amount) self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 1500) + def test_gle_made_when_asset_is_returned(self): + create_asset_data() + + pi = frappe.new_doc('Purchase Invoice') + pi.supplier = '_Test Supplier' + pi.append('items', { + 'item_code': 'Macbook Pro', + 'qty': 1 + }) + pi.set_missing_values() + + asset = create_asset(item_code="Macbook Pro") + + si = create_sales_invoice(item_code="Macbook Pro", asset=asset.name, qty=1, rate=90000) + return_si = create_sales_invoice(is_return=1, return_against=si.name, item_code="Macbook Pro", asset=asset.name, qty=-1, rate=90000) + + disposal_account = frappe.get_cached_value("Company", "_Test Company", "disposal_account") + + # Asset value is 100,000 but it was sold for 90,000, so there should be a loss of 10,000 + loss_for_si = frappe.get_all( + "GL Entry", + filters = { + "voucher_no": si.name, + "account": disposal_account + }, + fields = ["credit", "debit"] + )[0] + + loss_for_return_si = frappe.get_all( + "GL Entry", + filters = { + "voucher_no": return_si.name, + "account": disposal_account + }, + fields = ["credit", "debit"] + )[0] + + self.assertEqual(loss_for_si['credit'], loss_for_return_si['debit']) + self.assertEqual(loss_for_si['debit'], loss_for_return_si['credit']) def test_incoming_rate_for_stand_alone_credit_note(self): return_si = create_sales_invoice(is_return=1, update_stock=1, qty=-1, rate=90000, incoming_rate=10, @@ -2108,6 +2149,30 @@ class TestSalesInvoice(unittest.TestCase): check_gl_entries(self, si.name, expected_gle, add_days(nowdate(), -1)) enable_discount_accounting(enable=0) + def test_asset_depreciation_on_sale(self): + """ + Tests if an Asset set to depreciate yearly on June 30, that gets sold on Sept 30, creates an additional depreciation entry on Sept 30. + """ + + create_asset_data() + asset = create_asset(item_code="Macbook Pro", calculate_depreciation=1, submit=1) + post_depreciation_entries(getdate("2021-09-30")) + + create_sales_invoice(item_code="Macbook Pro", asset=asset.name, qty=1, rate=90000, posting_date=getdate("2021-09-30")) + asset.load_from_db() + + expected_values = [ + ["2020-06-30", 1311.48, 1311.48], + ["2021-06-30", 20000.0, 21311.48], + ["2021-09-30", 3966.76, 25278.24] + ] + + for i, schedule in enumerate(asset.schedules): + self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date) + self.assertEqual(expected_values[i][1], schedule.depreciation_amount) + self.assertEqual(expected_values[i][2], schedule.accumulated_depreciation_amount) + self.assertTrue(schedule.journal_entry) + def test_sales_invoice_against_supplier(self): from erpnext.accounts.doctype.opening_invoice_creation_tool.test_opening_invoice_creation_tool import make_customer from erpnext.buying.doctype.supplier.test_supplier import create_supplier @@ -2360,6 +2425,7 @@ def create_sales_invoice(**args): "price_list_rate": args.price_list_rate if args.get("price_list_rate") is not None else 100, "income_account": args.income_account or "Sales - _TC", "expense_account": args.expense_account or "Cost of Goods Sold - _TC", + "asset": args.asset or None, "discount_account": args.discount_account or None, "discount_amount": args.discount_amount or 0, "cost_center": args.cost_center or "_Test Cost Center - _TC", diff --git a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json index c90297328ee..2cddbbfceee 100644 --- a/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json +++ b/erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json @@ -7,12 +7,19 @@ "field_order": [ "activity_type", "description", + "section_break_3", + "from_time", + "column_break_5", + "to_time", + "section_break_7", "billing_hours", + "column_break_9", "billing_amount", + "section_break_11", + "timesheet_detail", "column_break_5", "time_sheet", - "project_name", - "timesheet_detail" + "project_name" ], "fields": [ { @@ -64,10 +71,40 @@ "label": "Description", "read_only": 1 }, + { + "fieldname": "from_time", + "fieldtype": "Datetime", + "label": "From Time" + }, + { + "fieldname": "to_time", + "fieldtype": "Datetime", + "label": "To Time" + }, + { + "fieldname": "section_break_3", + "fieldtype": "Section Break", + "label": "Time" + }, { "fieldname": "column_break_5", "fieldtype": "Column Break" }, + { + + "fieldname": "section_break_7", + "fieldtype": "Section Break", + "label": "Totals" + }, + { + "fieldname": "column_break_9", + "fieldtype": "Column Break" + }, + { + "fieldname": "section_break_11", + "fieldtype": "Section Break", + "label": "Reference" + }, { "fieldname": "project_name", "fieldtype": "Data", @@ -77,7 +114,7 @@ ], "istable": 1, "links": [], - "modified": "2021-06-08 14:43:02.748981", + "modified": "2021-08-15 18:37:08.084930", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Timesheet", diff --git a/erpnext/accounts/doctype/share_transfer/test_share_transfer.js b/erpnext/accounts/doctype/share_transfer/test_share_transfer.js deleted file mode 100644 index e5530fa0aa6..00000000000 --- a/erpnext/accounts/doctype/share_transfer/test_share_transfer.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Share Transfer", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Share Transfer - () => frappe.tests.make('Share Transfer', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/share_type/test_share_type.js b/erpnext/accounts/doctype/share_type/test_share_type.js deleted file mode 100644 index 620afa2ba85..00000000000 --- a/erpnext/accounts/doctype/share_type/test_share_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Share Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Share Type - () => frappe.tests.make('Share Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/shareholder/test_shareholder.js b/erpnext/accounts/doctype/shareholder/test_shareholder.js deleted file mode 100644 index 61c53120ea6..00000000000 --- a/erpnext/accounts/doctype/shareholder/test_shareholder.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Shareholder", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Shareholder - () => frappe.tests.make('Shareholder', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/subscription_invoice/test_subscription_invoice.js b/erpnext/accounts/doctype/subscription_invoice/test_subscription_invoice.js deleted file mode 100644 index 15d3df2a633..00000000000 --- a/erpnext/accounts/doctype/subscription_invoice/test_subscription_invoice.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Subscription Invoice", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Subscription Invoice - () => frappe.tests.make('Subscription Invoice', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/subscription_plan/subscription_plan.json b/erpnext/accounts/doctype/subscription_plan/subscription_plan.json index 771611a7860..878ae098891 100644 --- a/erpnext/accounts/doctype/subscription_plan/subscription_plan.json +++ b/erpnext/accounts/doctype/subscription_plan/subscription_plan.json @@ -21,7 +21,7 @@ "column_break_13", "billing_interval_count", "payment_plan_section", - "payment_plan_id", + "product_price_id", "column_break_16", "payment_gateway", "accounting_dimensions_section", @@ -114,11 +114,6 @@ "fieldtype": "Section Break", "label": "Payment Plan" }, - { - "fieldname": "payment_plan_id", - "fieldtype": "Data", - "label": "Payment Plan" - }, { "fieldname": "column_break_16", "fieldtype": "Column Break" @@ -144,10 +139,15 @@ "fieldtype": "Link", "label": "Cost Center", "options": "Cost Center" + }, + { + "fieldname": "product_price_id", + "fieldtype": "Data", + "label": "Product Price ID" } ], "links": [], - "modified": "2021-08-09 10:53:44.205774", + "modified": "2021-08-13 10:53:44.205774", "modified_by": "Administrator", "module": "Accounts", "name": "Subscription Plan", diff --git a/erpnext/accounts/doctype/subscription_plan/test_subscription_plan.js b/erpnext/accounts/doctype/subscription_plan/test_subscription_plan.js deleted file mode 100644 index 3ceb9a60507..00000000000 --- a/erpnext/accounts/doctype/subscription_plan/test_subscription_plan.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Subscription Plan", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Subscription Plan - () => frappe.tests.make('Subscription Plan', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/subscription_settings/test_subscription_settings.js b/erpnext/accounts/doctype/subscription_settings/test_subscription_settings.js deleted file mode 100644 index 5a751ea99c3..00000000000 --- a/erpnext/accounts/doctype/subscription_settings/test_subscription_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Subscription Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Subscription Settings - () => frappe.tests.make('Subscription Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/tax_category/test_tax_category.js b/erpnext/accounts/doctype/tax_category/test_tax_category.js deleted file mode 100644 index 5142456d769..00000000000 --- a/erpnext/accounts/doctype/tax_category/test_tax_category.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Tax Category", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Tax Category - () => frappe.tests.make('Tax Category', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/tax_rule/test_tax_rule.js b/erpnext/accounts/doctype/tax_rule/test_tax_rule.js deleted file mode 100644 index 72d177deffe..00000000000 --- a/erpnext/accounts/doctype/tax_rule/test_tax_rule.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Tax Rule", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Tax Rule - () => frappe.tests.make('Tax Rule', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.js b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.js deleted file mode 100644 index eab98d43892..00000000000 --- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Tax Withholding Category", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Tax Withholding Category - () => frappe.tests.make('Tax Withholding Category', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 68355535c7e..9120602adf2 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -1086,3 +1086,14 @@ def get_journal_entry(account, stock_adjustment_account, amount): db_or_cr_stock_adjustment_account : abs(amount) }] } + +def check_and_delete_linked_reports(report): + """ Check if reports are referenced in Desktop Icon """ + icons = frappe.get_all("Desktop Icon", + fields = ['name'], + filters = { + "_report": report + }) + if icons: + for icon in icons: + frappe.delete_doc("Desktop Icon", icon) diff --git a/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.js b/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.js deleted file mode 100644 index f70dcd2f322..00000000000 --- a/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Agriculture Analysis Criteria", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Agriculture Analysis Criteria - () => frappe.tests.make('Agriculture Analysis Criteria', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.js b/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.js deleted file mode 100644 index a012c4b1ade..00000000000 --- a/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Agriculture Task", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Agriculture Task - () => frappe.tests.make('Agriculture Task', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.js b/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.js deleted file mode 100644 index 786c0471a47..00000000000 --- a/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Plant Analysis", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Plant Analysis - () => frappe.tests.make('Plant Analysis', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.js b/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.js deleted file mode 100644 index 29128eba27d..00000000000 --- a/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Soil Analysis", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Soil Analysis - () => frappe.tests.make('Soil Analysis', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/agriculture/doctype/weather/test_weather.js b/erpnext/agriculture/doctype/weather/test_weather.js deleted file mode 100644 index b5009a4ccd3..00000000000 --- a/erpnext/agriculture/doctype/weather/test_weather.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Weather", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Weather - () => frappe.tests.make('Weather', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index d955430f23c..6828c58960b 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -56,12 +56,12 @@ class Asset(AccountsController): if self.is_existing_asset and self.purchase_invoice: frappe.throw(_("Purchase Invoice cannot be made against an existing asset {0}").format(self.name)) - def prepare_depreciation_data(self): + def prepare_depreciation_data(self, date_of_sale=None): if self.calculate_depreciation: self.value_after_depreciation = 0 self.set_depreciation_rate() - self.make_depreciation_schedule() - self.set_accumulated_depreciation() + self.make_depreciation_schedule(date_of_sale) + self.set_accumulated_depreciation(date_of_sale) else: self.finance_books = [] self.value_after_depreciation = (flt(self.gross_purchase_amount) - @@ -167,7 +167,7 @@ class Asset(AccountsController): d.rate_of_depreciation = flt(self.get_depreciation_rate(d, on_validate=True), d.precision("rate_of_depreciation")) - def make_depreciation_schedule(self): + def make_depreciation_schedule(self, date_of_sale): if 'Manual' not in [d.depreciation_method for d in self.finance_books] and not self.schedules: self.schedules = [] @@ -212,6 +212,21 @@ class Asset(AccountsController): # so monthly schedule date is calculated by removing 11 months from it monthly_schedule_date = add_months(schedule_date, - d.frequency_of_depreciation + 1) + # if asset is being sold + if date_of_sale: + from_date = self.get_from_date(d.finance_book) + depreciation_amount, days, months = self.get_pro_rata_amt(d, depreciation_amount, + from_date, date_of_sale) + + self.append("schedules", { + "schedule_date": date_of_sale, + "depreciation_amount": depreciation_amount, + "depreciation_method": d.depreciation_method, + "finance_book": d.finance_book, + "finance_book_id": d.idx + }) + break + # For first row if has_pro_rata and n==0: depreciation_amount, days, months = self.get_pro_rata_amt(d, depreciation_amount, @@ -303,6 +318,21 @@ class Asset(AccountsController): break return start + def get_from_date(self, finance_book): + if not self.get('schedules'): + return self.available_for_use_date + + if len(self.finance_books) == 1: + return self.schedules[-1].schedule_date + + from_date = "" + for schedule in self.get('schedules'): + if schedule.finance_book == finance_book: + from_date = schedule.schedule_date + + if from_date: + return from_date + return self.available_for_use_date # if it returns True, depreciation_amount will not be equal for the first and last rows def check_is_pro_rata(self, row): @@ -357,7 +387,7 @@ class Asset(AccountsController): frappe.throw(_("Depreciation Row {0}: Next Depreciation Date cannot be before Available-for-use Date") .format(row.idx)) - def set_accumulated_depreciation(self, ignore_booked_entry = False): + def set_accumulated_depreciation(self, date_of_sale=None, ignore_booked_entry = False): straight_line_idx = [d.idx for d in self.get("schedules") if d.depreciation_method == 'Straight Line'] finance_books = [] @@ -365,7 +395,7 @@ class Asset(AccountsController): if ignore_booked_entry and d.journal_entry: continue - if d.finance_book_id not in finance_books: + if int(d.finance_book_id) not in finance_books: accumulated_depreciation = flt(self.opening_accumulated_depreciation) value_after_depreciation = flt(self.get_value_after_depreciation(d.finance_book_id)) finance_books.append(int(d.finance_book_id)) @@ -374,7 +404,7 @@ class Asset(AccountsController): value_after_depreciation -= flt(depreciation_amount) # for the last row, if depreciation method = Straight Line - if straight_line_idx and i == max(straight_line_idx) - 1: + if straight_line_idx and i == max(straight_line_idx) - 1 and not date_of_sale: book = self.get('finance_books')[cint(d.finance_book_id) - 1] depreciation_amount += flt(value_after_depreciation - flt(book.expected_value_after_useful_life), d.precision("depreciation_amount")) diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 251fe3fa493..9a61b79ed35 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -176,22 +176,34 @@ def restore_asset(asset_name): asset.set_status() -@frappe.whitelist() +def get_gl_entries_on_asset_regain(asset, selling_amount=0, finance_book=None): + fixed_asset_account, asset, depreciation_cost_center, accumulated_depr_account, accumulated_depr_amount, disposal_account, value_after_depreciation = \ + get_asset_details(asset, finance_book) + + gl_entries = [ + { + "account": fixed_asset_account, + "debit_in_account_currency": asset.gross_purchase_amount, + "debit": asset.gross_purchase_amount, + "cost_center": depreciation_cost_center + }, + { + "account": accumulated_depr_account, + "credit_in_account_currency": accumulated_depr_amount, + "credit": accumulated_depr_amount, + "cost_center": depreciation_cost_center + } + ] + + profit_amount = abs(flt(value_after_depreciation)) - abs(flt(selling_amount)) + if profit_amount: + get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center) + + return gl_entries + def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None): - fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset) - disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company) - depreciation_cost_center = asset.cost_center or depreciation_cost_center - - idx = 1 - if finance_book: - for d in asset.finance_books: - if d.finance_book == finance_book: - idx = d.idx - break - - value_after_depreciation = (asset.finance_books[idx - 1].value_after_depreciation - if asset.calculate_depreciation else asset.value_after_depreciation) - accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(value_after_depreciation) + fixed_asset_account, asset, depreciation_cost_center, accumulated_depr_account, accumulated_depr_amount, disposal_account, value_after_depreciation = \ + get_asset_details(asset, finance_book) gl_entries = [ { @@ -210,16 +222,37 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None) profit_amount = flt(selling_amount) - flt(value_after_depreciation) if profit_amount: - debit_or_credit = "debit" if profit_amount < 0 else "credit" - gl_entries.append({ - "account": disposal_account, - "cost_center": depreciation_cost_center, - debit_or_credit: abs(profit_amount), - debit_or_credit + "_in_account_currency": abs(profit_amount) - }) + get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center) return gl_entries +def get_asset_details(asset, finance_book=None): + fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset) + disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company) + depreciation_cost_center = asset.cost_center or depreciation_cost_center + + idx = 1 + if finance_book: + for d in asset.finance_books: + if d.finance_book == finance_book: + idx = d.idx + break + + value_after_depreciation = (asset.finance_books[idx - 1].value_after_depreciation + if asset.calculate_depreciation else asset.value_after_depreciation) + accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(value_after_depreciation) + + return fixed_asset_account, asset, depreciation_cost_center, accumulated_depr_account, accumulated_depr_amount, disposal_account, value_after_depreciation + +def get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center): + debit_or_credit = "debit" if profit_amount < 0 else "credit" + gl_entries.append({ + "account": disposal_account, + "cost_center": depreciation_cost_center, + debit_or_credit: abs(profit_amount), + debit_or_credit + "_in_account_currency": abs(profit_amount) + }) + @frappe.whitelist() def get_disposal_account_and_cost_center(company): disposal_account, depreciation_cost_center = frappe.get_cached_value('Company', company, diff --git a/erpnext/assets/doctype/asset/test_asset.js b/erpnext/assets/doctype/asset/test_asset.js deleted file mode 100644 index 6119e382174..00000000000 --- a/erpnext/assets/doctype/asset/test_asset.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset - () => frappe.tests.make('Asset', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset_category/test_asset_category.js b/erpnext/assets/doctype/asset_category/test_asset_category.js deleted file mode 100644 index 7e343b7519e..00000000000 --- a/erpnext/assets/doctype/asset_category/test_asset_category.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset Category", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset Category - () => frappe.tests.make('Asset Category', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.js deleted file mode 100644 index f9b38a1020e..00000000000 --- a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset Maintenance", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset Maintenance - () => frappe.tests.make('Asset Maintenance', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset_maintenance_log/test_asset_maintenance_log.js b/erpnext/assets/doctype/asset_maintenance_log/test_asset_maintenance_log.js deleted file mode 100644 index 4e80184ea7b..00000000000 --- a/erpnext/assets/doctype/asset_maintenance_log/test_asset_maintenance_log.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset Maintenance Log", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset Maintenance Log - () => frappe.tests.make('Asset Maintenance Log', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset_maintenance_team/test_asset_maintenance_team.js b/erpnext/assets/doctype/asset_maintenance_team/test_asset_maintenance_team.js deleted file mode 100644 index 41bf69623ec..00000000000 --- a/erpnext/assets/doctype/asset_maintenance_team/test_asset_maintenance_team.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset Maintenance Team", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset Maintenance Team - () => frappe.tests.make('Asset Maintenance Team', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset_movement/test_asset_movement.js b/erpnext/assets/doctype/asset_movement/test_asset_movement.js deleted file mode 100644 index b9515763c42..00000000000 --- a/erpnext/assets/doctype/asset_movement/test_asset_movement.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset Movement", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset Movement - () => frappe.tests.make('Asset Movement', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.js b/erpnext/assets/doctype/asset_repair/test_asset_repair.js deleted file mode 100644 index 7424ffe2b80..00000000000 --- a/erpnext/assets/doctype/asset_repair/test_asset_repair.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset Repair", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset Repair - () => frappe.tests.make('Asset Repair', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.js b/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.js deleted file mode 100644 index 32831c61d2e..00000000000 --- a/erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Asset Value Adjustment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Asset Value Adjustment - () => frappe.tests.make('Asset Value Adjustment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/location/test_location.js b/erpnext/assets/doctype/location/test_location.js deleted file mode 100644 index 3c06b63e820..00000000000 --- a/erpnext/assets/doctype/location/test_location.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Location", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Location - () => frappe.tests.make('Location', [ - // values to be set - { location_name: 'Basil Farm' } - ]), - () => { - assert.equal(cur_frm.doc.name, 'Basil Farm'); - }, - () => done() - ]); - -}); diff --git a/erpnext/assets/doctype/maintenance_team_member/test_maintenance_team_member.js b/erpnext/assets/doctype/maintenance_team_member/test_maintenance_team_member.js deleted file mode 100644 index d942e2a1566..00000000000 --- a/erpnext/assets/doctype/maintenance_team_member/test_maintenance_team_member.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Maintenance Team Member", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Maintenance Team Member - () => frappe.tests.make('Maintenance Team Member', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index 1766c2c80cc..7ee91961ca5 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -24,7 +24,26 @@ frappe.ui.form.on("Supplier", { } } }); + + frm.set_query("supplier_primary_contact", function(doc) { + return { + query: "erpnext.buying.doctype.supplier.supplier.get_supplier_primary_contact", + filters: { + "supplier": doc.name + } + }; + }); + + frm.set_query("supplier_primary_address", function(doc) { + return { + filters: { + "link_doctype": "Supplier", + "link_name": doc.name + } + }; + }); }, + refresh: function (frm) { frappe.dynamic_link = { doc: frm.doc, fieldname: 'name', doctype: 'Supplier' } @@ -78,6 +97,30 @@ frappe.ui.form.on("Supplier", { }); }, + supplier_primary_address: function(frm) { + if (frm.doc.supplier_primary_address) { + frappe.call({ + method: 'frappe.contacts.doctype.address.address.get_address_display', + args: { + "address_dict": frm.doc.supplier_primary_address + }, + callback: function(r) { + frm.set_value("primary_address", r.message); + } + }); + } + if (!frm.doc.supplier_primary_address) { + frm.set_value("primary_address", ""); + } + }, + + supplier_primary_contact: function(frm) { + if (!frm.doc.supplier_primary_contact) { + frm.set_value("mobile_no", ""); + frm.set_value("email_id", ""); + } + }, + is_internal_supplier: function(frm) { if (frm.doc.is_internal_supplier == 1) { frm.toggle_reqd("represents_company", true); diff --git a/erpnext/buying/doctype/supplier/supplier.json b/erpnext/buying/doctype/supplier/supplier.json index 38b8dfdf48d..c7a5db59941 100644 --- a/erpnext/buying/doctype/supplier/supplier.json +++ b/erpnext/buying/doctype/supplier/supplier.json @@ -49,6 +49,13 @@ "address_html", "column_break1", "contact_html", + "primary_address_and_contact_detail_section", + "supplier_primary_contact", + "mobile_no", + "email_id", + "column_break_44", + "supplier_primary_address", + "primary_address", "default_payable_accounts", "accounts", "default_tax_withholding_config", @@ -378,6 +385,47 @@ "fieldname": "allow_purchase_invoice_creation_without_purchase_receipt", "fieldtype": "Check", "label": "Allow Purchase Invoice Creation Without Purchase Receipt" + }, + { + "fieldname": "primary_address_and_contact_detail_section", + "fieldtype": "Section Break", + "label": "Primary Address and Contact Detail" + }, + { + "description": "Reselect, if the chosen contact is edited after save", + "fieldname": "supplier_primary_contact", + "fieldtype": "Link", + "label": "Supplier Primary Contact", + "options": "Contact" + }, + { + "fetch_from": "supplier_primary_contact.mobile_no", + "fieldname": "mobile_no", + "fieldtype": "Read Only", + "label": "Mobile No" + }, + { + "fetch_from": "supplier_primary_contact.email_id", + "fieldname": "email_id", + "fieldtype": "Read Only", + "label": "Email Id" + }, + { + "fieldname": "column_break_44", + "fieldtype": "Column Break" + }, + { + "fieldname": "primary_address", + "fieldtype": "Text", + "label": "Primary Address", + "read_only": 1 + }, + { + "description": "Reselect, if the chosen address is edited after save", + "fieldname": "supplier_primary_address", + "fieldtype": "Link", + "label": "Supplier Primary Address", + "options": "Address" } ], "icon": "fa fa-user", @@ -390,7 +438,7 @@ "link_fieldname": "supplier" } ], - "modified": "2021-05-18 15:10:11.087191", + "modified": "2021-08-27 18:02:44.314077", "modified_by": "Administrator", "module": "Buying", "name": "Supplier", diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index fd16b23c220..c9750caa65a 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -42,7 +42,12 @@ class Supplier(TransactionBase): if not self.naming_series: self.naming_series = '' + self.create_primary_contact() + self.create_primary_address() + def validate(self): + self.flags.is_new_doc = self.is_new() + # validation for Naming Series mandatory field... if frappe.defaults.get_global_default('supp_master_name') == 'Naming Series': if not self.naming_series: @@ -76,7 +81,39 @@ class Supplier(TransactionBase): frappe.throw(_("Internal Supplier for company {0} already exists").format( frappe.bold(self.represents_company))) + def create_primary_contact(self): + from erpnext.selling.doctype.customer.customer import make_contact + + if not self.supplier_primary_contact: + if self.mobile_no or self.email_id: + contact = make_contact(self) + self.db_set('supplier_primary_contact', contact.name) + self.db_set('mobile_no', self.mobile_no) + self.db_set('email_id', self.email_id) + + def create_primary_address(self): + from erpnext.selling.doctype.customer.customer import make_address + from frappe.contacts.doctype.address.address import get_address_display + + if self.flags.is_new_doc and self.get('address_line1'): + address = make_address(self) + address_display = get_address_display(address.name) + + self.db_set("supplier_primary_address", address.name) + self.db_set("primary_address", address_display) + def on_trash(self): + if self.supplier_primary_contact: + frappe.db.sql(""" + UPDATE `tabSupplier` + SET + supplier_primary_contact=null, + supplier_primary_address=null, + mobile_no=null, + email_id=null, + primary_address=null + WHERE name=%(name)s""", {"name": self.name}) + delete_contact_and_address('Supplier', self.name) def after_rename(self, olddn, newdn, merge=False): @@ -104,3 +141,21 @@ class Supplier(TransactionBase): doc.name, args.get('supplier_email_' + str(i))) except frappe.NameError: pass + +@frappe.whitelist() +@frappe.validate_and_sanitize_search_inputs +def get_supplier_primary_contact(doctype, txt, searchfield, start, page_len, filters): + supplier = filters.get("supplier") + return frappe.db.sql(""" + SELECT + `tabContact`.name from `tabContact`, + `tabDynamic Link` + WHERE + `tabContact`.name = `tabDynamic Link`.parent + and `tabDynamic Link`.link_name = %(supplier)s + and `tabDynamic Link`.link_doctype = 'Supplier' + and `tabContact`.name like %(txt)s + """, { + 'supplier': supplier, + 'txt': '%%%s%%' % txt + }) diff --git a/erpnext/crm/doctype/contract/test_contract.js b/erpnext/crm/doctype/contract/test_contract.js deleted file mode 100644 index 4c77c3d649f..00000000000 --- a/erpnext/crm/doctype/contract/test_contract.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Contract", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Contract - () => frappe.tests.make('Contract', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/crm/doctype/contract_fulfilment_checklist/test_contract_fulfilment_checklist.js b/erpnext/crm/doctype/contract_fulfilment_checklist/test_contract_fulfilment_checklist.js deleted file mode 100644 index 2a2d5e1bfc0..00000000000 --- a/erpnext/crm/doctype/contract_fulfilment_checklist/test_contract_fulfilment_checklist.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Contract Fulfilment Checklist", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Contract Fulfilment Checklist - () => frappe.tests.make('Contract Fulfilment Checklist', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/crm/doctype/contract_template/test_contract_template.js b/erpnext/crm/doctype/contract_template/test_contract_template.js deleted file mode 100644 index 6aaddd7df4d..00000000000 --- a/erpnext/crm/doctype/contract_template/test_contract_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Contract Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Contract Template - () => frappe.tests.make('Contract Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/crm/doctype/market_segment/test_market_segment.js b/erpnext/crm/doctype/market_segment/test_market_segment.js deleted file mode 100644 index aa4b868f932..00000000000 --- a/erpnext/crm/doctype/market_segment/test_market_segment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Market Segment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Market Segment - () => frappe.tests.make('Market Segment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/crm/doctype/opportunity_type/test_opportunity_type.js b/erpnext/crm/doctype/opportunity_type/test_opportunity_type.js deleted file mode 100644 index 3a1ede94dba..00000000000 --- a/erpnext/crm/doctype/opportunity_type/test_opportunity_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Opportunity Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Opportunity Type - () => frappe.tests.make('Opportunity Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/crm/doctype/sales_stage/test_sales_stage.js b/erpnext/crm/doctype/sales_stage/test_sales_stage.js deleted file mode 100644 index 807af1fd983..00000000000 --- a/erpnext/crm/doctype/sales_stage/test_sales_stage.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Sales Stage", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Sales Stage - () => frappe.tests.make('Sales Stage', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/academic_year/test_academic_year.js b/erpnext/education/doctype/academic_year/test_academic_year.js deleted file mode 100644 index 51e9cf307d8..00000000000 --- a/erpnext/education/doctype/academic_year/test_academic_year.js +++ /dev/null @@ -1,23 +0,0 @@ -// Testing Setup Module in Education -QUnit.module('education'); - -QUnit.test('Test: Academic Year', function(assert){ - assert.expect(3); - let done = assert.async(); - frappe.run_serially([ - () => { - return frappe.tests.make('Academic Year', [ - {academic_year_name: '2016-17'}, - {year_start_date: '2016-07-20'}, - {year_end_date:'2017-06-20'}, - ]); - }, - - () => { - assert.ok(cur_frm.doc.academic_year_name=='2016-17'); - assert.ok(cur_frm.doc.year_start_date=='2016-07-20'); - assert.ok(cur_frm.doc.year_end_date=='2017-06-20'); - }, - () => done() - ]); -}); diff --git a/erpnext/education/doctype/article/test_article.js b/erpnext/education/doctype/article/test_article.js deleted file mode 100644 index 9dbf063e844..00000000000 --- a/erpnext/education/doctype/article/test_article.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Article", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Article - () => frappe.tests.make('Article', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/content_question/test_content_question.js b/erpnext/education/doctype/content_question/test_content_question.js deleted file mode 100644 index cc869a87fcf..00000000000 --- a/erpnext/education/doctype/content_question/test_content_question.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Content Question", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Content Question - () => frappe.tests.make('Content Question', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/course_activity/test_course_activity.js b/erpnext/education/doctype/course_activity/test_course_activity.js deleted file mode 100644 index c89c89e5d3c..00000000000 --- a/erpnext/education/doctype/course_activity/test_course_activity.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Course Activity", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Course Activity - () => frappe.tests.make('Course Activity', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/course_content/test_course_content.js b/erpnext/education/doctype/course_content/test_course_content.js deleted file mode 100644 index 786e67e9a37..00000000000 --- a/erpnext/education/doctype/course_content/test_course_content.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Course Content", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Course Content - () => frappe.tests.make('Course Content', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/course_enrollment/test_course_enrollment.js b/erpnext/education/doctype/course_enrollment/test_course_enrollment.js deleted file mode 100644 index 216cc307991..00000000000 --- a/erpnext/education/doctype/course_enrollment/test_course_enrollment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Course Enrollment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Course Enrollment - () => frappe.tests.make('Course Enrollment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/course_schedule/test_course_schedule.js b/erpnext/education/doctype/course_schedule/test_course_schedule.js deleted file mode 100644 index 5cdb67be482..00000000000 --- a/erpnext/education/doctype/course_schedule/test_course_schedule.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Course Schedule", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Course Schedule - () => frappe.tests.make('Course Schedule', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/course_scheduling_tool/test_course_scheduling_tool.js b/erpnext/education/doctype/course_scheduling_tool/test_course_scheduling_tool.js deleted file mode 100644 index 4419d181167..00000000000 --- a/erpnext/education/doctype/course_scheduling_tool/test_course_scheduling_tool.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Course Scheduling Tool", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Course Scheduling Tool - () => frappe.tests.make('Course Scheduling Tool', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/course_topic/test_course_topic.js b/erpnext/education/doctype/course_topic/test_course_topic.js deleted file mode 100644 index d8d154fb9c8..00000000000 --- a/erpnext/education/doctype/course_topic/test_course_topic.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Course Topic", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Course Topic - () => frappe.tests.make('Course Topic', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/fee_category/test_fee_category.js b/erpnext/education/doctype/fee_category/test_fee_category.js deleted file mode 100644 index a08ed33e8b6..00000000000 --- a/erpnext/education/doctype/fee_category/test_fee_category.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Fee Category", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Fee Category - () => frappe.tests.make('Fee Category', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/fee_schedule/test_fee_schedule.js b/erpnext/education/doctype/fee_schedule/test_fee_schedule.js deleted file mode 100644 index d495b4ce7b1..00000000000 --- a/erpnext/education/doctype/fee_schedule/test_fee_schedule.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Fee Schedule", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('Fee Schedule', [ - // insert a new Fee Schedule - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/fee_structure/test_fee_structure.js b/erpnext/education/doctype/fee_structure/test_fee_structure.js deleted file mode 100644 index 61f41354c34..00000000000 --- a/erpnext/education/doctype/fee_structure/test_fee_structure.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Fee Structure", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Fee Structure - () => frappe.tests.make('Fee Structure', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/program_enrollment/test_program_enrollment.js b/erpnext/education/doctype/program_enrollment/test_program_enrollment.js deleted file mode 100644 index aea81a0714e..00000000000 --- a/erpnext/education/doctype/program_enrollment/test_program_enrollment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Program Enrollment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Program Enrollment - () => frappe.tests.make('Program Enrollment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/program_enrollment_tool/test_program_enrollment_tool.js b/erpnext/education/doctype/program_enrollment_tool/test_program_enrollment_tool.js deleted file mode 100644 index 8d55104a0f3..00000000000 --- a/erpnext/education/doctype/program_enrollment_tool/test_program_enrollment_tool.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Program Enrollment Tool", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Program Enrollment Tool - () => frappe.tests.make('Program Enrollment Tool', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/question/test_question.js b/erpnext/education/doctype/question/test_question.js deleted file mode 100644 index 509939c6b56..00000000000 --- a/erpnext/education/doctype/question/test_question.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Question", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Question - () => frappe.tests.make('Question', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/quiz/test_quiz.js b/erpnext/education/doctype/quiz/test_quiz.js deleted file mode 100644 index 147d13952ab..00000000000 --- a/erpnext/education/doctype/quiz/test_quiz.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Quiz", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Quiz - () => frappe.tests.make('Quiz', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/quiz_activity/test_quiz_activity.js b/erpnext/education/doctype/quiz_activity/test_quiz_activity.js deleted file mode 100644 index 94b5ab796ac..00000000000 --- a/erpnext/education/doctype/quiz_activity/test_quiz_activity.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Quiz Activity", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Quiz Activity - () => frappe.tests.make('Quiz Activity', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/quiz_result/test_quiz_result.js b/erpnext/education/doctype/quiz_result/test_quiz_result.js deleted file mode 100644 index 43f53a1dc77..00000000000 --- a/erpnext/education/doctype/quiz_result/test_quiz_result.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Quiz Result", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Quiz Result - () => frappe.tests.make('Quiz Result', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/school_house/test_school_house.js b/erpnext/education/doctype/school_house/test_school_house.js deleted file mode 100644 index dde63ecc4c6..00000000000 --- a/erpnext/education/doctype/school_house/test_school_house.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: School House", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new School House - () => frappe.tests.make('School House', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/student/test_student.js b/erpnext/education/doctype/student/test_student.js deleted file mode 100644 index e18d39aee07..00000000000 --- a/erpnext/education/doctype/student/test_student.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Student", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Student - () => frappe.tests.make('Student', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/student_language/test_student_language.js b/erpnext/education/doctype/student_language/test_student_language.js deleted file mode 100644 index 9b25569961a..00000000000 --- a/erpnext/education/doctype/student_language/test_student_language.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Student Language", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Student Language - () => frappe.tests.make('Student Language', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js deleted file mode 100644 index 10be092bb92..00000000000 --- a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Student Report Generation Tool", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Student Report Generation Tool - () => frappe.tests.make('Student Report Generation Tool', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/topic/test_topic.js b/erpnext/education/doctype/topic/test_topic.js deleted file mode 100644 index 4460b794786..00000000000 --- a/erpnext/education/doctype/topic/test_topic.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Topic", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Topic - () => frappe.tests.make('Topic', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/topic_content/test_topic_content.js b/erpnext/education/doctype/topic_content/test_topic_content.js deleted file mode 100644 index bf9a62d0376..00000000000 --- a/erpnext/education/doctype/topic_content/test_topic_content.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Topic Content", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Topic Content - () => frappe.tests.make('Topic Content', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/test_amazon_mws_settings.js b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/test_amazon_mws_settings.js deleted file mode 100644 index 9c8990986e2..00000000000 --- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/test_amazon_mws_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Amazon MWS Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Amazon MWS Settings - () => frappe.tests.make('Amazon MWS Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/erpnext_integrations/doctype/gocardless_mandate/test_gocardless_mandate.js b/erpnext/erpnext_integrations/doctype/gocardless_mandate/test_gocardless_mandate.js deleted file mode 100644 index caa9399eb6c..00000000000 --- a/erpnext/erpnext_integrations/doctype/gocardless_mandate/test_gocardless_mandate.js +++ /dev/null @@ -1,23 +0,0 @@ -/* 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() - ]); - -}); diff --git a/erpnext/erpnext_integrations/doctype/gocardless_settings/test_gocardless_settings.js b/erpnext/erpnext_integrations/doctype/gocardless_settings/test_gocardless_settings.js deleted file mode 100644 index b6daad8de48..00000000000 --- a/erpnext/erpnext_integrations/doctype/gocardless_settings/test_gocardless_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* 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() - ]); - -}); diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.js b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.js deleted file mode 100644 index dc91347336d..00000000000 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Plaid Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Plaid Settings - () => frappe.tests.make('Plaid Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/test_quickbooks_migrator.js b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/test_quickbooks_migrator.js deleted file mode 100644 index b71d7048076..00000000000 --- a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/test_quickbooks_migrator.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: QuickBooks Migrator", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new QuickBooks Migrator - () => frappe.tests.make('QuickBooks Migrator', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/test_tally_migration.js b/erpnext/erpnext_integrations/doctype/tally_migration/test_tally_migration.js deleted file mode 100644 index 433c5e2cda8..00000000000 --- a/erpnext/erpnext_integrations/doctype/tally_migration/test_tally_migration.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Tally Migration", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Tally Migration - () => frappe.tests.make('Tally Migration', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/erpnext_integrations/doctype/woocommerce_settings/test_woocommerce_settings.js b/erpnext/erpnext_integrations/doctype/woocommerce_settings/test_woocommerce_settings.js deleted file mode 100644 index ea06ab2dc4e..00000000000 --- a/erpnext/erpnext_integrations/doctype/woocommerce_settings/test_woocommerce_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Woocommerce Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Woocommerce Settings - () => frappe.tests.make('Woocommerce Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/erpnext_integrations/stripe_integration.py b/erpnext/erpnext_integrations/stripe_integration.py index 108b4c0dd81..820c7405328 100644 --- a/erpnext/erpnext_integrations/stripe_integration.py +++ b/erpnext/erpnext_integrations/stripe_integration.py @@ -2,11 +2,12 @@ # Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt -from __future__ import unicode_literals +import stripe + import frappe from frappe import _ from frappe.integrations.utils import create_request_log -import stripe + def create_stripe_subscription(gateway_controller, data): stripe_settings = frappe.get_doc("Stripe Settings", gateway_controller) @@ -23,31 +24,38 @@ def create_stripe_subscription(gateway_controller, data): except Exception: frappe.log_error(frappe.get_traceback()) return{ - "redirect_to": frappe.redirect_to_message(_('Server Error'), _("It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account.")), + "redirect_to": frappe.redirect_to_message( + _('Server Error'), + _("It seems that there is an issue with the server's stripe configuration. In case of failure, the amount will get refunded to your account.") + ), "status": 401 } def create_subscription_on_stripe(stripe_settings): - items = [] - for payment_plan in stripe_settings.payment_plans: - plan = frappe.db.get_value("Subscription Plan", payment_plan.plan, "payment_plan_id") - items.append({"plan": plan, "quantity": payment_plan.qty}) + items = [] + for payment_plan in stripe_settings.payment_plans: + plan = frappe.db.get_value("Subscription Plan", payment_plan.plan, "product_price_id") + items.append({"price": plan, "quantity": payment_plan.qty}) - try: - customer = stripe.Customer.create(description=stripe_settings.data.payer_name, email=stripe_settings.data.payer_email, source=stripe_settings.data.stripe_token_id) - subscription = stripe.Subscription.create(customer=customer, items=items) + try: + customer = stripe.Customer.create( + source=stripe_settings.data.stripe_token_id, + description=stripe_settings.data.payer_name, + email=stripe_settings.data.payer_email + ) - if subscription.status == "active": - stripe_settings.integration_request.db_set('status', 'Completed', update_modified=False) - stripe_settings.flags.status_changed_to = "Completed" + subscription = stripe.Subscription.create(customer=customer, items=items) - else: - stripe_settings.integration_request.db_set('status', 'Failed', update_modified=False) - frappe.log_error('Subscription N°: ' + subscription.id, 'Stripe Payment not completed') + if subscription.status == "active": + stripe_settings.integration_request.db_set('status', 'Completed', update_modified=False) + stripe_settings.flags.status_changed_to = "Completed" - except Exception: + else: stripe_settings.integration_request.db_set('status', 'Failed', update_modified=False) - frappe.log_error(frappe.get_traceback()) + frappe.log_error('Subscription N°: ' + subscription.id, 'Stripe Payment not completed') + except Exception: + stripe_settings.integration_request.db_set('status', 'Failed', update_modified=False) + frappe.log_error(frappe.get_traceback()) - return stripe_settings.finalize_request() + return stripe_settings.finalize_request() diff --git a/erpnext/healthcare/doctype/antibiotic/test_antibiotic.js b/erpnext/healthcare/doctype/antibiotic/test_antibiotic.js deleted file mode 100644 index b92103d7509..00000000000 --- a/erpnext/healthcare/doctype/antibiotic/test_antibiotic.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Antibiotic", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Antibiotic - () => frappe.tests.make('Antibiotic', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/appointment_type/test_appointment_type.js b/erpnext/healthcare/doctype/appointment_type/test_appointment_type.js deleted file mode 100644 index 93274e55c7b..00000000000 --- a/erpnext/healthcare/doctype/appointment_type/test_appointment_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Appointment Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Appointment Type - () => frappe.tests.make('Appointment Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.js deleted file mode 100644 index 80ef3d55f2a..00000000000 --- a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Clinical Procedure", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Clinical Procedure - () => frappe.tests.make('Clinical Procedure', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.js b/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.js deleted file mode 100644 index 1dde8b5d867..00000000000 --- a/erpnext/healthcare/doctype/clinical_procedure_template/test_clinical_procedure_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Clinical Procedure Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Clinical Procedure Template - () => frappe.tests.make('Clinical Procedure Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/complaint/test_complaint.js b/erpnext/healthcare/doctype/complaint/test_complaint.js deleted file mode 100644 index 9ff44d8da46..00000000000 --- a/erpnext/healthcare/doctype/complaint/test_complaint.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Complaint", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Complaint - () => frappe.tests.make('Complaint', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/diagnosis/test_diagnosis.js b/erpnext/healthcare/doctype/diagnosis/test_diagnosis.js deleted file mode 100644 index cacfef5b17d..00000000000 --- a/erpnext/healthcare/doctype/diagnosis/test_diagnosis.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Diagnosis", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Diagnosis - () => frappe.tests.make('Diagnosis', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/dosage_form/test_dosage_form.js b/erpnext/healthcare/doctype/dosage_form/test_dosage_form.js deleted file mode 100644 index ba54ab16faa..00000000000 --- a/erpnext/healthcare/doctype/dosage_form/test_dosage_form.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Dosage Form", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Dosage Form - () => frappe.tests.make('Dosage Form', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json index d91e6bf9dc6..a65c56694e7 100644 --- a/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json +++ b/erpnext/healthcare/doctype/drug_prescription/drug_prescription.json @@ -56,6 +56,7 @@ "reqd": 1 }, { + "allow_in_quick_entry": 1, "fieldname": "dosage_form", "fieldtype": "Link", "ignore_user_permissions": 1, @@ -109,7 +110,7 @@ ], "istable": 1, "links": [], - "modified": "2020-09-30 23:32:09.495288", + "modified": "2021-06-11 11:53:06.343704", "modified_by": "Administrator", "module": "Healthcare", "name": "Drug Prescription", diff --git a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.js b/erpnext/healthcare/doctype/fee_validity/test_fee_validity.js deleted file mode 100644 index 0ebb97438ca..00000000000 --- a/erpnext/healthcare/doctype/fee_validity/test_fee_validity.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Fee Validity", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Fee Validity - () => frappe.tests.make('Fee Validity', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.js b/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.js deleted file mode 100644 index 75aa208ec16..00000000000 --- a/erpnext/healthcare/doctype/healthcare_practitioner/test_healthcare_practitioner.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Healthcare Practitioner", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Healthcare Practitioner - () => frappe.tests.make('Healthcare Practitioner', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.js b/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.js deleted file mode 100644 index a67a4117073..00000000000 --- a/erpnext/healthcare/doctype/healthcare_service_unit/test_healthcare_service_unit.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Healthcare Service Unit", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Healthcare Service Unit - () => frappe.tests.make('Healthcare Service Unit', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js deleted file mode 100644 index 6db8f9e9c1a..00000000000 --- a/erpnext/healthcare/doctype/healthcare_service_unit_type/test_healthcare_service_unit_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Healthcare Service Unit Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Healthcare Service Unit Type - () => frappe.tests.make('Healthcare Service Unit Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/healthcare_settings/test_healthcare_settings.js b/erpnext/healthcare/doctype/healthcare_settings/test_healthcare_settings.js deleted file mode 100644 index ca10925e598..00000000000 --- a/erpnext/healthcare/doctype/healthcare_settings/test_healthcare_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Healthcare Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Healthcare Settings - () => frappe.tests.make('Healthcare Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js b/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js deleted file mode 100644 index 1ce9afa96d4..00000000000 --- a/erpnext/healthcare/doctype/inpatient_record/test_inpatient_record.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Inpatient Record", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Inpatient Record - () => frappe.tests.make('Inpatient Record', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/lab_test/test_lab_test.js b/erpnext/healthcare/doctype/lab_test/test_lab_test.js deleted file mode 100644 index 57cb22b2699..00000000000 --- a/erpnext/healthcare/doctype/lab_test/test_lab_test.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Lab Test", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Lab Test - () => frappe.tests.make('Lab Test', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/lab_test_sample/test_lab_test_sample.js b/erpnext/healthcare/doctype/lab_test_sample/test_lab_test_sample.js deleted file mode 100644 index ace60de752a..00000000000 --- a/erpnext/healthcare/doctype/lab_test_sample/test_lab_test_sample.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Lab Test Sample", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Lab Test Sample - () => frappe.tests.make('Lab Test Sample', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/lab_test_template/test_lab_test_template.js b/erpnext/healthcare/doctype/lab_test_template/test_lab_test_template.js deleted file mode 100644 index 7c2ec8c3483..00000000000 --- a/erpnext/healthcare/doctype/lab_test_template/test_lab_test_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Lab Test Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Lab Test Template - () => frappe.tests.make('Lab Test Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/lab_test_uom/test_lab_test_uom.js b/erpnext/healthcare/doctype/lab_test_uom/test_lab_test_uom.js deleted file mode 100644 index 1328dda2826..00000000000 --- a/erpnext/healthcare/doctype/lab_test_uom/test_lab_test_uom.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Lab Test UOM", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Lab Test UOM - () => frappe.tests.make('Lab Test UOM', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/medical_code/test_medical_code.js b/erpnext/healthcare/doctype/medical_code/test_medical_code.js deleted file mode 100644 index 8cc7c40025c..00000000000 --- a/erpnext/healthcare/doctype/medical_code/test_medical_code.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Medical Code", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Medical Code - () => frappe.tests.make('Medical Code', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/medical_code_standard/test_medical_code_standard.js b/erpnext/healthcare/doctype/medical_code_standard/test_medical_code_standard.js deleted file mode 100644 index 6ab6d531dfb..00000000000 --- a/erpnext/healthcare/doctype/medical_code_standard/test_medical_code_standard.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Medical Code Standard", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Medical Code Standard - () => frappe.tests.make('Medical Code Standard', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/medical_department/test_medical_department.js b/erpnext/healthcare/doctype/medical_department/test_medical_department.js deleted file mode 100644 index fdf49718dc8..00000000000 --- a/erpnext/healthcare/doctype/medical_department/test_medical_department.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Medical Department", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Medical Department - () => frappe.tests.make('Medical Department', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/organism/test_organism.js b/erpnext/healthcare/doctype/organism/test_organism.js deleted file mode 100644 index d57e5536c69..00000000000 --- a/erpnext/healthcare/doctype/organism/test_organism.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Organism", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Organism - () => frappe.tests.make('Organism', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py index 4c3da82a1ca..95cce73f231 100644 --- a/erpnext/healthcare/doctype/patient/patient.py +++ b/erpnext/healthcare/doctype/patient/patient.py @@ -122,13 +122,19 @@ class Patient(Document): return name - def get_age(self): - age_str = '' - if self.dob: - dob = getdate(self.dob) - age = dateutil.relativedelta.relativedelta(getdate(), dob) - age_str = f'{str(age.years)} {_("Years(s)")} {str(age.months)} {_("Month(s)")} {str(age.days)} {_("Day(s)")}' + @property + def age(self): + if not self.dob: + return + dob = getdate(self.dob) + age = dateutil.relativedelta.relativedelta(getdate(), dob) + return age + def get_age(self): + age = self.age + if not age: + return + age_str = str(age.years) + ' ' + _("Years(s)") + ' ' + str(age.months) + ' ' + _("Month(s)") + ' ' + str(age.days) + ' ' + _("Day(s)") return age_str @frappe.whitelist() diff --git a/erpnext/healthcare/doctype/patient/test_patient.js b/erpnext/healthcare/doctype/patient/test_patient.js deleted file mode 100644 index e1d9ecbd242..00000000000 --- a/erpnext/healthcare/doctype/patient/test_patient.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Patient", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('Patient', [ - // insert a new Patient - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.js deleted file mode 100644 index 71fc1778455..00000000000 --- a/erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Patient Appointment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Patient Appointment - () => frappe.tests.make('Patient Appointment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js index 5b950a8809e..9da9a6c13a2 100644 --- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js +++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js @@ -185,7 +185,42 @@ frappe.ui.form.on('Patient Encounter', { }; frm.set_value(values); } - } + }, + + get_applicable_treatment_plans: function(frm) { + frappe.call({ + method: 'get_applicable_treatment_plans', + doc: frm.doc, + args: {'encounter': frm.doc}, + freeze: true, + freeze_message: __('Fetching Treatment Plans'), + callback: function() { + new frappe.ui.form.MultiSelectDialog({ + doctype: "Treatment Plan Template", + target: this.cur_frm, + setters: { + medical_department: "", + }, + action(selections) { + frappe.call({ + method: 'set_treatment_plans', + doc: frm.doc, + args: selections, + }).then(() => { + frm.refresh_field('drug_prescription'); + frm.refresh_field('procedure_prescription'); + frm.refresh_field('lab_test_prescription'); + frm.refresh_field('therapies'); + }); + cur_dialog.hide(); + } + }); + + + } + }); + }, + }); var schedule_inpatient = function(frm) { diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json index b646ff9ebe6..994597dca7c 100644 --- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json +++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json @@ -31,6 +31,7 @@ "sb_symptoms", "symptoms", "symptoms_in_print", + "get_applicable_treatment_plans", "physical_examination", "diagnosis", "diagnosis_in_print", @@ -324,11 +325,17 @@ "no_copy": 1, "print_hide": 1, "read_only": 1 + }, + { + "depends_on": "eval:doc.patient", + "fieldname": "get_applicable_treatment_plans", + "fieldtype": "Button", + "label": "Get Applicable Treatment Plans" } ], "is_submittable": 1, "links": [], - "modified": "2020-11-30 10:39:00.783119", + "modified": "2021-07-27 11:39:12.347704", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient Encounter", @@ -358,4 +365,4 @@ "title_field": "title", "track_changes": 1, "track_seen": 1 -} \ No newline at end of file +} diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py index 2b3029efdeb..7a745ae468e 100644 --- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py +++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py @@ -10,6 +10,7 @@ from frappe.utils import cstr, getdate, add_days from frappe import _ from frappe.model.mapper import get_mapped_doc + class PatientEncounter(Document): def validate(self): self.set_title() @@ -33,6 +34,85 @@ class PatientEncounter(Document): self.title = _('{0} with {1}').format(self.patient_name or self.patient, self.practitioner_name or self.practitioner)[:100] + @frappe.whitelist() + @staticmethod + def get_applicable_treatment_plans(encounter): + patient = frappe.get_doc('Patient', encounter['patient']) + + plan_filters = {} + plan_filters['name'] = ['in', []] + + age = patient.age + if age: + plan_filters['patient_age_from'] = ['<=', age.years] + plan_filters['patient_age_to'] = ['>=', age.years] + + gender = patient.sex + if gender: + plan_filters['gender'] = ['in', [gender, None]] + + diagnosis = encounter.get('diagnosis') + if diagnosis: + diagnosis = [_diagnosis['diagnosis'] for _diagnosis in encounter['diagnosis']] + filters = [ + ['diagnosis', 'in', diagnosis], + ['parenttype', '=', 'Treatment Plan Template'], + ] + diagnosis = frappe.get_list('Patient Encounter Diagnosis', filters=filters, fields='*') + plan_names = [_diagnosis['parent'] for _diagnosis in diagnosis] + plan_filters['name'][1].extend(plan_names) + + symptoms = encounter.get('symptoms') + if symptoms: + symptoms = [symptom['complaint'] for symptom in encounter['symptoms']] + filters = [ + ['complaint', 'in', symptoms], + ['parenttype', '=', 'Treatment Plan Template'], + ] + symptoms = frappe.get_list('Patient Encounter Symptom', filters=filters, fields='*') + plan_names = [symptom['parent'] for symptom in symptoms] + plan_filters['name'][1].extend(plan_names) + + if not plan_filters['name'][1]: + plan_filters.pop('name') + + plans = frappe.get_list('Treatment Plan Template', fields='*', filters=plan_filters) + + return plans + + @frappe.whitelist() + def set_treatment_plans(self, treatment_plans=None): + for treatment_plan in treatment_plans: + self.set_treatment_plan(treatment_plan) + + def set_treatment_plan(self, plan): + plan_items = frappe.get_list('Treatment Plan Template Item', filters={'parent': plan}, fields='*') + for plan_item in plan_items: + self.set_treatment_plan_item(plan_item) + + drugs = frappe.get_list('Drug Prescription', filters={'parent': plan}, fields='*') + for drug in drugs: + self.append('drug_prescription', drug) + + self.save() + + def set_treatment_plan_item(self, plan_item): + if plan_item.type == 'Clinical Procedure Template': + self.append('procedure_prescription', { + 'procedure': plan_item.template + }) + + if plan_item.type == 'Lab Test Template': + self.append('lab_test_prescription', { + 'lab_test_code': plan_item.template + }) + + if plan_item.type == 'Therapy Type': + self.append('therapies', { + 'therapy_type': plan_item.template + }) + + @frappe.whitelist() def make_ip_medication_order(source_name, target_doc=None): def set_missing_values(source, target): diff --git a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.js deleted file mode 100644 index 1baabf7eef7..00000000000 --- a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Patient Encounter", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Patient Encounter - () => frappe.tests.make('Patient Encounter', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py index f5df152050f..96976821a71 100644 --- a/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py +++ b/erpnext/healthcare/doctype/patient_encounter/test_patient_encounter.py @@ -4,5 +4,82 @@ from __future__ import unicode_literals import unittest +import frappe +from erpnext.healthcare.doctype.patient_encounter.patient_encounter import PatientEncounter + + class TestPatientEncounter(unittest.TestCase): - pass + def setUp(self): + try: + gender_m = frappe.get_doc({ + 'doctype': 'Gender', + 'gender': 'MALE' + }).insert() + gender_f = frappe.get_doc({ + 'doctype': 'Gender', + 'gender': 'FEMALE' + }).insert() + except frappe.exceptions.DuplicateEntryError: + gender_m = frappe.get_doc({ + 'doctype': 'Gender', + 'gender': 'MALE' + }) + gender_f = frappe.get_doc({ + 'doctype': 'Gender', + 'gender': 'FEMALE' + }) + + self.patient_male = frappe.get_doc({ + 'doctype': 'Patient', + 'first_name': 'John', + 'sex': gender_m.gender, + }).insert() + self.patient_female = frappe.get_doc({ + 'doctype': 'Patient', + 'first_name': 'Curie', + 'sex': gender_f.gender, + }).insert() + self.practitioner = frappe.get_doc({ + 'doctype': 'Healthcare Practitioner', + 'first_name': 'Doc', + 'sex': 'MALE', + }).insert() + try: + self.care_plan_male = frappe.get_doc({ + 'doctype': 'Treatment Plan Template', + 'template_name': 'test plan - m', + 'gender': gender_m.gender, + }).insert() + self.care_plan_female = frappe.get_doc({ + 'doctype': 'Treatment Plan Template', + 'template_name': 'test plan - f', + 'gender': gender_f.gender, + }).insert() + except frappe.exceptions.DuplicateEntryError: + self.care_plan_male = frappe.get_doc({ + 'doctype': 'Treatment Plan Template', + 'template_name': 'test plan - m', + 'gender': gender_m.gender, + }) + self.care_plan_female = frappe.get_doc({ + 'doctype': 'Treatment Plan Template', + 'template_name': 'test plan - f', + 'gender': gender_f.gender, + }) + + def test_treatment_plan_template_filter(self): + encounter = frappe.get_doc({ + 'doctype': 'Patient Encounter', + 'patient': self.patient_male.name, + 'practitioner': self.practitioner.name, + }).insert() + plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict()) + self.assertEqual(plans[0]['name'], self.care_plan_male.template_name) + + encounter = frappe.get_doc({ + 'doctype': 'Patient Encounter', + 'patient': self.patient_female.name, + 'practitioner': self.practitioner.name, + }).insert() + plans = PatientEncounter.get_applicable_treatment_plans(encounter.as_dict()) + self.assertEqual(plans[0]['name'], self.care_plan_female.template_name) diff --git a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.js b/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.js deleted file mode 100644 index 66dda09e256..00000000000 --- a/erpnext/healthcare/doctype/patient_medical_record/test_patient_medical_record.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Patient Medical Record", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Patient Medical Record - () => frappe.tests.make('Patient Medical Record', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.js b/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.js deleted file mode 100644 index 32dac2c6526..00000000000 --- a/erpnext/healthcare/doctype/practitioner_schedule/test_practitioner_schedule.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Practitioner Schedule", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Practitioner Schedule - () => frappe.tests.make('Practitioner Schedule', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/prescription_dosage/test_prescription_dosage.js b/erpnext/healthcare/doctype/prescription_dosage/test_prescription_dosage.js deleted file mode 100644 index 009614ff5dd..00000000000 --- a/erpnext/healthcare/doctype/prescription_dosage/test_prescription_dosage.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Prescription Dosage", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Prescription Dosage - () => frappe.tests.make('Prescription Dosage', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/prescription_duration/test_prescription_duration.js b/erpnext/healthcare/doctype/prescription_duration/test_prescription_duration.js deleted file mode 100644 index 4971e79198c..00000000000 --- a/erpnext/healthcare/doctype/prescription_duration/test_prescription_duration.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Prescription Duration", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Prescription Duration - () => frappe.tests.make('Prescription Duration', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/sample_collection/test_sample_collection.js b/erpnext/healthcare/doctype/sample_collection/test_sample_collection.js deleted file mode 100644 index 2b4aed756bf..00000000000 --- a/erpnext/healthcare/doctype/sample_collection/test_sample_collection.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Sample Collection", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Sample Collection - () => frappe.tests.make('Sample Collection', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/sensitivity/test_sensitivity.js b/erpnext/healthcare/doctype/sensitivity/test_sensitivity.js deleted file mode 100644 index c2cf406f96d..00000000000 --- a/erpnext/healthcare/doctype/sensitivity/test_sensitivity.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Sensitivity", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Sensitivity - () => frappe.tests.make('Sensitivity', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/healthcare/doctype/treatment_plan_template/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/healthcare/doctype/treatment_plan_template/test_records.json b/erpnext/healthcare/doctype/treatment_plan_template/test_records.json new file mode 100644 index 00000000000..d661b4304f6 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template/test_records.json @@ -0,0 +1,7 @@ +[ + { + "doctype": "Treatment Plan Template", + "template_name": "Chemo", + "patient_age_from": 21 + } +] diff --git a/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py b/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py new file mode 100644 index 00000000000..21ede7129f1 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template/test_treatment_plan_template.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +import unittest + +class TestTreatmentPlanTemplate(unittest.TestCase): + pass diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js new file mode 100644 index 00000000000..986c3cb6e42 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.js @@ -0,0 +1,14 @@ +// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Treatment Plan Template', { + refresh: function (frm) { + frm.set_query('type', 'items', function () { + return { + filters: { + 'name': ['in', ['Lab Test Template', 'Clinical Procedure Template', 'Therapy Type']], + } + }; + }); + }, +}); diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json new file mode 100644 index 00000000000..85a312fb174 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.json @@ -0,0 +1,189 @@ +{ + "actions": [], + "autoname": "field:template_name", + "creation": "2021-06-10 10:14:17.901273", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "section_break_1", + "template_name", + "description", + "practitioners", + "disabled", + "column_break_1", + "medical_department", + "goal", + "order_group", + "section_break_8", + "patient_age_from", + "complaints", + "gender", + "column_break_12", + "patient_age_to", + "diagnosis", + "plan_items_section", + "items", + "drugs" + ], + "fields": [ + { + "fieldname": "section_break_1", + "fieldtype": "Section Break", + "label": "Plan Details" + }, + { + "fieldname": "medical_department", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Medical Department", + "options": "Medical Department" + }, + { + "fieldname": "description", + "fieldtype": "Small Text", + "label": "Description" + }, + { + "fieldname": "goal", + "fieldtype": "Small Text", + "label": "Goal" + }, + { + "fieldname": "practitioners", + "fieldtype": "Table MultiSelect", + "label": "Practitioners", + "options": "Treatment Plan Template Practitioner" + }, + { + "fieldname": "order_group", + "fieldtype": "Link", + "label": "Order Group", + "options": "Patient Encounter", + "read_only": 1 + }, + { + "fieldname": "section_break_8", + "fieldtype": "Section Break", + "label": "Plan Conditions" + }, + { + "fieldname": "template_name", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Template Name", + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "patient_age_from", + "fieldtype": "Int", + "label": "Patient Age From", + "non_negative": 1 + }, + { + "fieldname": "column_break_12", + "fieldtype": "Column Break" + }, + { + "fieldname": "patient_age_to", + "fieldtype": "Int", + "label": "Patient Age To", + "non_negative": 1 + }, + { + "fieldname": "gender", + "fieldtype": "Link", + "label": "Gender", + "options": "Gender" + }, + { + "fieldname": "complaints", + "fieldtype": "Table MultiSelect", + "label": "Complaints", + "options": "Patient Encounter Symptom" + }, + { + "fieldname": "diagnosis", + "fieldtype": "Table MultiSelect", + "label": "Diagnosis", + "options": "Patient Encounter Diagnosis" + }, + { + "fieldname": "plan_items_section", + "fieldtype": "Section Break", + "label": "Plan Items" + }, + { + "fieldname": "items", + "fieldtype": "Table", + "label": "Items", + "options": "Treatment Plan Template Item" + }, + { + "fieldname": "drugs", + "fieldtype": "Table", + "label": "Drugs", + "options": "Drug Prescription" + }, + { + "default": "0", + "fieldname": "disabled", + "fieldtype": "Check", + "label": "Disabled" + }, + { + "fieldname": "column_break_1", + "fieldtype": "Column Break" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-08-18 02:41:58.354296", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Treatment Plan Template", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Physician", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Healthcare Administrator", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "template_name", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py new file mode 100644 index 00000000000..a92e2668fe8 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template.py @@ -0,0 +1,19 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ +from frappe.model.document import Document + +class TreatmentPlanTemplate(Document): + def validate(self): + self.validate_age() + + def validate_age(self): + if self.patient_age_from and self.patient_age_from < 0: + frappe.throw(_('Patient Age From cannot be less than 0')) + if self.patient_age_to and self.patient_age_to < 0: + frappe.throw(_('Patient Age To cannot be less than 0')) + if self.patient_age_to and self.patient_age_from and \ + self.patient_age_to < self.patient_age_from: + frappe.throw(_('Patient Age To cannot be less than Patient Age From')) diff --git a/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js new file mode 100644 index 00000000000..7ab31dff791 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template/treatment_plan_template_list.js @@ -0,0 +1,10 @@ +frappe.listview_settings['Treatment Plan Template'] = { + get_indicator: function(doc) { + var colors = { + 1: 'gray', + 0: 'blue', + }; + let label = doc.disabled == 1 ? 'Disabled' : 'Enabled'; + return [__(label), colors[doc.disabled], 'disable,=,' + doc.disabled]; + } +}; diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template_item/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json new file mode 100644 index 00000000000..20a9d6793a5 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.json @@ -0,0 +1,55 @@ +{ + "actions": [], + "creation": "2021-06-10 11:47:29.194795", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "type", + "template", + "qty", + "instructions" + ], + "fields": [ + { + "fieldname": "type", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Type", + "options": "DocType", + "reqd": 1 + }, + { + "fieldname": "template", + "fieldtype": "Dynamic Link", + "in_list_view": 1, + "label": "Template", + "options": "type", + "reqd": 1 + }, + { + "default": "1", + "fieldname": "qty", + "fieldtype": "Int", + "label": "Qty" + }, + { + "fieldname": "instructions", + "fieldtype": "Small Text", + "in_list_view": 1, + "label": "Instructions" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-08-17 11:19:03.515441", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Treatment Plan Template Item", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py new file mode 100644 index 00000000000..5f58b06af60 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template_item/treatment_plan_template_item.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class TreatmentPlanTemplateItem(Document): + pass diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json new file mode 100644 index 00000000000..04da387f7b8 --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.json @@ -0,0 +1,32 @@ +{ + "actions": [], + "creation": "2021-06-10 10:37:56.669416", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "practitioner" + ], + "fields": [ + { + "fieldname": "practitioner", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Practitioner", + "options": "Healthcare Practitioner", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-06-11 16:05:06.733299", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Treatment Plan Template Practitioner", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py new file mode 100644 index 00000000000..6d34568e15c --- /dev/null +++ b/erpnext/healthcare/doctype/treatment_plan_template_practitioner/treatment_plan_template_practitioner.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class TreatmentPlanTemplatePractitioner(Document): + pass diff --git a/erpnext/healthcare/doctype/vital_signs/test_vital_signs.js b/erpnext/healthcare/doctype/vital_signs/test_vital_signs.js deleted file mode 100644 index f4ab4466be4..00000000000 --- a/erpnext/healthcare/doctype/vital_signs/test_vital_signs.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Vital Signs", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Vital Signs - () => frappe.tests.make('Vital Signs', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hooks.py b/erpnext/hooks.py index c997bf9b896..dc1b9113f81 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -441,7 +441,6 @@ regional_overrides = { 'erpnext.controllers.taxes_and_totals.get_regional_round_off_accounts': 'erpnext.regional.india.utils.get_regional_round_off_accounts', 'erpnext.hr.utils.calculate_annual_eligible_hra_exemption': 'erpnext.regional.india.utils.calculate_annual_eligible_hra_exemption', 'erpnext.hr.utils.calculate_hra_exemption_for_period': 'erpnext.regional.india.utils.calculate_hra_exemption_for_period', - 'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_regional_gl_entries': 'erpnext.regional.india.utils.make_regional_gl_entries', 'erpnext.controllers.accounts_controller.validate_einvoice_fields': 'erpnext.regional.india.e_invoice.utils.validate_einvoice_fields', 'erpnext.assets.doctype.asset.asset.get_depreciation_amount': 'erpnext.regional.india.utils.get_depreciation_amount', 'erpnext.stock.doctype.item.item.set_item_tax_from_hsn_code': 'erpnext.regional.india.utils.set_item_tax_from_hsn_code' diff --git a/erpnext/hotels/doctype/hotel_room/test_hotel_room.js b/erpnext/hotels/doctype/hotel_room/test_hotel_room.js deleted file mode 100644 index 8b2b83330f3..00000000000 --- a/erpnext/hotels/doctype/hotel_room/test_hotel_room.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Hotel Room", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Hotel Room - () => frappe.tests.make('Hotel Room', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.js b/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.js deleted file mode 100644 index f1ebad41d41..00000000000 --- a/erpnext/hotels/doctype/hotel_room_package/test_hotel_room_package.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Hotel Room Package", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Hotel Room Package - () => frappe.tests.make('Hotel Room Package', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.js b/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.js deleted file mode 100644 index ba0d1fd3e96..00000000000 --- a/erpnext/hotels/doctype/hotel_room_pricing/test_hotel_room_pricing.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Hotel Room Pricing", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Hotel Room Pricing - () => frappe.tests.make('Hotel Room Pricing', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.js b/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.js deleted file mode 100644 index 73a561c408c..00000000000 --- a/erpnext/hotels/doctype/hotel_room_pricing_package/test_hotel_room_pricing_package.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Hotel Room Pricing Package", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Hotel Room Pricing Package - () => frappe.tests.make('Hotel Room Pricing Package', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.js b/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.js deleted file mode 100644 index 2897139359b..00000000000 --- a/erpnext/hotels/doctype/hotel_room_reservation/test_hotel_room_reservation.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Hotel Room Reservation", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Hotel Room Reservation - () => frappe.tests.make('Hotel Room Reservation', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.js b/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.js deleted file mode 100644 index e2dd5780e3c..00000000000 --- a/erpnext/hotels/doctype/hotel_room_type/test_hotel_room_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Hotel Room Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Hotel Room Type - () => frappe.tests.make('Hotel Room Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.js b/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.js deleted file mode 100644 index bc0b7f8341d..00000000000 --- a/erpnext/hotels/doctype/hotel_settings/test_hotel_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Hotel Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Hotel Settings - () => frappe.tests.make('Hotel Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/attendance_request/test_attendance_request.js b/erpnext/hr/doctype/attendance_request/test_attendance_request.js deleted file mode 100644 index d40ec61b086..00000000000 --- a/erpnext/hr/doctype/attendance_request/test_attendance_request.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Attendance Request", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Attendance Request - () => frappe.tests.make('Attendance Request', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/branch/test_branch.js b/erpnext/hr/doctype/branch/test_branch.js deleted file mode 100644 index 82a6ae103ee..00000000000 --- a/erpnext/hr/doctype/branch/test_branch.js +++ /dev/null @@ -1,23 +0,0 @@ -QUnit.module('hr'); - -QUnit.test("Test: Branch [HR]", function (assert) { - assert.expect(1); - let done = assert.async(); - - frappe.run_serially([ - // test branch creation - () => frappe.set_route("List", "Branch", "List"), - () => frappe.new_doc("Branch"), - () => frappe.timeout(1), - () => frappe.quick_entry.dialog.$wrapper.find('.edit-full').click(), - () => frappe.timeout(1), - () => cur_frm.set_value("branch", "Test Branch"), - - // save form - () => cur_frm.save(), - () => frappe.timeout(1), - () => assert.equal("Test Branch", cur_frm.doc.branch, - 'name of branch correctly saved'), - () => done() - ]); -}); diff --git a/erpnext/hr/doctype/compensatory_leave_request/test_compensatory_leave_request.js b/erpnext/hr/doctype/compensatory_leave_request/test_compensatory_leave_request.js deleted file mode 100644 index bebcaac400e..00000000000 --- a/erpnext/hr/doctype/compensatory_leave_request/test_compensatory_leave_request.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Compensatory Leave Request", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Compensatory Leave Request - () => frappe.tests.make('Compensatory Leave Request', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/daily_work_summary/test_daily_work_summary.js b/erpnext/hr/doctype/daily_work_summary/test_daily_work_summary.js deleted file mode 100644 index 15335171473..00000000000 --- a/erpnext/hr/doctype/daily_work_summary/test_daily_work_summary.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Daily Work Summary", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Daily Work Summary - () => frappe.tests.make('Daily Work Summary', [ - // values to be set - { key: 'value' } - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/department/test_department.js b/erpnext/hr/doctype/department/test_department.js deleted file mode 100644 index e73779c97c6..00000000000 --- a/erpnext/hr/doctype/department/test_department.js +++ /dev/null @@ -1,23 +0,0 @@ -QUnit.module('hr'); - -QUnit.test("Test: Department [HR]", function (assert) { - assert.expect(1); - let done = assert.async(); - - frappe.run_serially([ - // test department creation - () => frappe.set_route("List", "Department", "List"), - () => frappe.new_doc("Department"), - () => frappe.timeout(1), - () => frappe.quick_entry.dialog.$wrapper.find('.edit-full').click(), - () => frappe.timeout(1), - () => cur_frm.set_value("department_name", "Test Department"), - () => cur_frm.set_value("leave_block_list", "Test Leave block list"), - // save form - () => cur_frm.save(), - () => frappe.timeout(1), - () => assert.equal("Test Department", cur_frm.doc.department_name, - 'name of department correctly saved'), - () => done() - ]); -}); diff --git a/erpnext/hr/doctype/designation/test_designation.js b/erpnext/hr/doctype/designation/test_designation.js deleted file mode 100644 index 00adf8293f7..00000000000 --- a/erpnext/hr/doctype/designation/test_designation.js +++ /dev/null @@ -1,23 +0,0 @@ -QUnit.module('hr'); - -QUnit.test("Test: Designation [HR]", function (assert) { - assert.expect(1); - let done = assert.async(); - - frappe.run_serially([ - // test designation creation - () => frappe.set_route("List", "Designation", "List"), - () => frappe.new_doc("Designation"), - () => frappe.timeout(1), - () => frappe.quick_entry.dialog.$wrapper.find('.edit-full').click(), - () => frappe.timeout(1), - () => cur_frm.set_value("designation_name", "Test Designation"), - () => cur_frm.set_value("description", "This designation is just for testing."), - // save form - () => cur_frm.save(), - () => frappe.timeout(1), - () => assert.equal("Test Designation", cur_frm.doc.designation_name, - 'name of designation correctly saved'), - () => done() - ]); -}); diff --git a/erpnext/hr/doctype/driver/test_driver.js b/erpnext/hr/doctype/driver/test_driver.js deleted file mode 100644 index ff9f61e66a6..00000000000 --- a/erpnext/hr/doctype/driver/test_driver.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Driver", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Driver - () => frappe.tests.make('Driver', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_advance/test_employee_advance.js b/erpnext/hr/doctype/employee_advance/test_employee_advance.js deleted file mode 100644 index 1b9ec6f6d0c..00000000000 --- a/erpnext/hr/doctype/employee_advance/test_employee_advance.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Advance", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Advance - () => frappe.tests.make('Employee Advance', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_grade/test_employee_grade.js b/erpnext/hr/doctype/employee_grade/test_employee_grade.js deleted file mode 100644 index d684fb2ad1b..00000000000 --- a/erpnext/hr/doctype/employee_grade/test_employee_grade.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Grade", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Grade - () => frappe.tests.make('Employee Grade', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_health_insurance/test_employee_health_insurance.js b/erpnext/hr/doctype/employee_health_insurance/test_employee_health_insurance.js deleted file mode 100644 index 245cb32971f..00000000000 --- a/erpnext/hr/doctype/employee_health_insurance/test_employee_health_insurance.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Health Insurance", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Health Insurance - () => frappe.tests.make('Employee Health Insurance', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.js b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.js deleted file mode 100644 index d15cef77dca..00000000000 --- a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Onboarding", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Onboarding - () => frappe.tests.make('Employee Onboarding', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_onboarding_template/test_employee_onboarding_template.js b/erpnext/hr/doctype/employee_onboarding_template/test_employee_onboarding_template.js deleted file mode 100644 index 10912edb6ac..00000000000 --- a/erpnext/hr/doctype/employee_onboarding_template/test_employee_onboarding_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Onboarding Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Onboarding Template - () => frappe.tests.make('Employee Onboarding Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_promotion/test_employee_promotion.js b/erpnext/hr/doctype/employee_promotion/test_employee_promotion.js deleted file mode 100644 index 5f0a5baf818..00000000000 --- a/erpnext/hr/doctype/employee_promotion/test_employee_promotion.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Promotion", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Promotion - () => frappe.tests.make('Employee Promotion', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_separation/test_employee_separation.js b/erpnext/hr/doctype/employee_separation/test_employee_separation.js deleted file mode 100644 index d6c635951f7..00000000000 --- a/erpnext/hr/doctype/employee_separation/test_employee_separation.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Separation", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Separation - () => frappe.tests.make('Employee Separation', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_separation_template/test_employee_separation_template.js b/erpnext/hr/doctype/employee_separation_template/test_employee_separation_template.js deleted file mode 100644 index 66fd4508046..00000000000 --- a/erpnext/hr/doctype/employee_separation_template/test_employee_separation_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Separation Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Separation Template - () => frappe.tests.make('Employee Separation Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_transfer/test_employee_transfer.js b/erpnext/hr/doctype/employee_transfer/test_employee_transfer.js deleted file mode 100644 index 05a3e1a5738..00000000000 --- a/erpnext/hr/doctype/employee_transfer/test_employee_transfer.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Transfer", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Transfer - () => frappe.tests.make('Employee Transfer', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/employee_transfer_property/test_employee_transfer_property.js b/erpnext/hr/doctype/employee_transfer_property/test_employee_transfer_property.js deleted file mode 100644 index 00a334a63d7..00000000000 --- a/erpnext/hr/doctype/employee_transfer_property/test_employee_transfer_property.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Transfer Property", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Transfer Property - () => frappe.tests.make('Employee Transfer Property', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index 95e2806aedc..4dc089cb1d2 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -77,7 +77,7 @@ class ExpenseClaim(AccountsController): self.make_gl_entries() if self.is_paid: - update_reimbursed_amount(self) + update_reimbursed_amount(self, self.grand_total) self.set_status(update=True) self.update_claimed_amount_in_employee_advance() @@ -89,7 +89,7 @@ class ExpenseClaim(AccountsController): self.make_gl_entries(cancel=True) if self.is_paid: - update_reimbursed_amount(self) + update_reimbursed_amount(self, -1 * self.grand_total) self.update_claimed_amount_in_employee_advance() @@ -270,20 +270,10 @@ class ExpenseClaim(AccountsController): if not expense.default_account or not validate: expense.default_account = get_expense_claim_account(expense.expense_type, self.company)["account"] -def update_reimbursed_amount(doc, jv=None): +def update_reimbursed_amount(doc, amount): - condition = "" - - if jv: - condition += "and voucher_no = '{0}'".format(jv) - - amt = frappe.db.sql("""select ifnull(sum(debit_in_account_currency), 0) - ifnull(sum(credit_in_account_currency), 0)as amt - from `tabGL Entry` where against_voucher_type = 'Expense Claim' and against_voucher = %s - and party = %s {condition}""".format(condition=condition), #nosec - (doc.name, doc.employee) ,as_dict=1)[0].amt - - doc.total_amount_reimbursed = amt - frappe.db.set_value("Expense Claim", doc.name , "total_amount_reimbursed", amt) + doc.total_amount_reimbursed += amount + frappe.db.set_value("Expense Claim", doc.name , "total_amount_reimbursed", doc.total_amount_reimbursed) doc.set_status() frappe.db.set_value("Expense Claim", doc.name , "status", doc.status) diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py index c2bd1e9f9f1..b5fc1fbe758 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe import unittest -from frappe.utils import random_string, nowdate +from frappe.utils import random_string, nowdate, flt from erpnext.hr.doctype.expense_claim.expense_claim import make_bank_entry from erpnext.accounts.doctype.account.test_account import create_account from erpnext.hr.doctype.employee.test_employee import make_employee @@ -138,6 +138,31 @@ class TestExpenseClaim(unittest.TestCase): expense_claim.submit() frappe.set_user("Administrator") + def test_multiple_payment_entries_against_expense(self): + # Creating expense claim + payable_account = get_payable_account("_Test Company") + expense_claim = make_expense_claim(payable_account, 5500, 5500, "_Test Company", "Travel Expenses - _TC") + expense_claim.save() + expense_claim.submit() + + # Payment entry 1: paying 500 + make_payment_entry(expense_claim, payable_account,500) + outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim) + self.assertEqual(outstanding_amount, 5000) + self.assertEqual(total_amount_reimbursed, 500) + + # Payment entry 1: paying 2000 + make_payment_entry(expense_claim, payable_account,2000) + outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim) + self.assertEqual(outstanding_amount, 3000) + self.assertEqual(total_amount_reimbursed, 2500) + + # Payment entry 1: paying 3000 + make_payment_entry(expense_claim, payable_account,3000) + outstanding_amount, total_amount_reimbursed = get_outstanding_and_total_reimbursed_amounts(expense_claim) + self.assertEqual(outstanding_amount, 0) + self.assertEqual(total_amount_reimbursed, 5500) + def get_payable_account(company): return frappe.get_cached_value('Company', company, 'default_payable_account') @@ -191,3 +216,23 @@ def make_expense_claim(payable_account, amount, sanctioned_amount, company, acco return expense_claim expense_claim.submit() return expense_claim + +def get_outstanding_and_total_reimbursed_amounts(expense_claim): + outstanding_amount = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_sanctioned_amount")) - \ + flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed")) + total_amount_reimbursed = flt(frappe.db.get_value("Expense Claim", expense_claim.name, "total_amount_reimbursed")) + + return outstanding_amount,total_amount_reimbursed + +def make_payment_entry(expense_claim, payable_account, amt): + from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry + + pe = get_payment_entry("Expense Claim", expense_claim.name, bank_account="_Test Bank USD - _TC", bank_amount=amt) + pe.reference_no = "1" + pe.reference_date = nowdate() + pe.source_exchange_rate = 1 + pe.paid_to = payable_account + pe.references[0].allocated_amount = amt + pe.insert() + pe.submit() + diff --git a/erpnext/hr/doctype/hr_settings/test_hr_settings.js b/erpnext/hr/doctype/hr_settings/test_hr_settings.js deleted file mode 100644 index f32640ba5c6..00000000000 --- a/erpnext/hr/doctype/hr_settings/test_hr_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: HR Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new HR Settings - () => frappe.tests.make('HR Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/identification_document_type/test_identification_document_type.js b/erpnext/hr/doctype/identification_document_type/test_identification_document_type.js deleted file mode 100644 index 65879098e87..00000000000 --- a/erpnext/hr/doctype/identification_document_type/test_identification_document_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Identification Document Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Identification Document Type - () => frappe.tests.make('Identification Document Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/job_applicant_source/test_job_applicant_source.js b/erpnext/hr/doctype/job_applicant_source/test_job_applicant_source.js deleted file mode 100644 index c093928f321..00000000000 --- a/erpnext/hr/doctype/job_applicant_source/test_job_applicant_source.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Job Applicant Source", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Job Applicant Source - () => frappe.tests.make('Job Applicant Source', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/leave_encashment/test_leave_encashment.js b/erpnext/hr/doctype/leave_encashment/test_leave_encashment.js deleted file mode 100644 index cafd9602cbe..00000000000 --- a/erpnext/hr/doctype/leave_encashment/test_leave_encashment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Leave Encashment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Leave Encashment - () => frappe.tests.make('Leave Encashment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/leave_period/test_leave_period.js b/erpnext/hr/doctype/leave_period/test_leave_period.js deleted file mode 100644 index ec0a8096890..00000000000 --- a/erpnext/hr/doctype/leave_period/test_leave_period.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Leave Period", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Leave Period - () => frappe.tests.make('Leave Period', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/leave_policy/test_leave_policy.js b/erpnext/hr/doctype/leave_policy/test_leave_policy.js deleted file mode 100644 index 5404a63bed1..00000000000 --- a/erpnext/hr/doctype/leave_policy/test_leave_policy.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Leave Policy", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Leave Policy - () => frappe.tests.make('Leave Policy', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/leave_policy_detail/test_leave_policy_detail.js b/erpnext/hr/doctype/leave_policy_detail/test_leave_policy_detail.js deleted file mode 100644 index 1c8995b7967..00000000000 --- a/erpnext/hr/doctype/leave_policy_detail/test_leave_policy_detail.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Leave Policy Detail", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Leave Policy Detail - () => frappe.tests.make('Leave Policy Detail', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/purpose_of_travel/test_purpose_of_travel.js b/erpnext/hr/doctype/purpose_of_travel/test_purpose_of_travel.js deleted file mode 100644 index 936c21ccf05..00000000000 --- a/erpnext/hr/doctype/purpose_of_travel/test_purpose_of_travel.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Purpose of Travel", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Purpose of Travel - () => frappe.tests.make('Purpose of Travel', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.js b/erpnext/hr/doctype/shift_assignment/test_shift_assignment.js deleted file mode 100644 index 77272877423..00000000000 --- a/erpnext/hr/doctype/shift_assignment/test_shift_assignment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Shift Assignment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Shift Assignment - () => frappe.tests.make('Shift Assignment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/shift_request/test_shift_request.js b/erpnext/hr/doctype/shift_request/test_shift_request.js deleted file mode 100644 index 9c8cd70020c..00000000000 --- a/erpnext/hr/doctype/shift_request/test_shift_request.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Shift Request", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Shift Request - () => frappe.tests.make('Shift Request', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/shift_type/test_shift_type.js b/erpnext/hr/doctype/shift_type/test_shift_type.js deleted file mode 100644 index 846f9316f58..00000000000 --- a/erpnext/hr/doctype/shift_type/test_shift_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Shift Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Shift Type - () => frappe.tests.make('Shift Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/staffing_plan/test_staffing_plan.js b/erpnext/hr/doctype/staffing_plan/test_staffing_plan.js deleted file mode 100644 index 64320bcd92b..00000000000 --- a/erpnext/hr/doctype/staffing_plan/test_staffing_plan.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Staffing Plan", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Staffing Plan - () => frappe.tests.make('Staffing Plan', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/training_program/test_training_program.js b/erpnext/hr/doctype/training_program/test_training_program.js deleted file mode 100644 index 3a62b2fa221..00000000000 --- a/erpnext/hr/doctype/training_program/test_training_program.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Training Program", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Training Program - () => frappe.tests.make('Training Program', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/training_result/test_training_result.js b/erpnext/hr/doctype/training_result/test_training_result.js deleted file mode 100644 index cb1d7fb27a3..00000000000 --- a/erpnext/hr/doctype/training_result/test_training_result.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Training Result", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Training Result - () => frappe.tests.make('Training Result', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/travel_request/test_travel_request.js b/erpnext/hr/doctype/travel_request/test_travel_request.js deleted file mode 100644 index 7e645918239..00000000000 --- a/erpnext/hr/doctype/travel_request/test_travel_request.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Travel Request", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Travel Request - () => frappe.tests.make('Travel Request', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hr/doctype/vehicle/test_vehicle.js b/erpnext/hr/doctype/vehicle/test_vehicle.js deleted file mode 100644 index 4d40cce086a..00000000000 --- a/erpnext/hr/doctype/vehicle/test_vehicle.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Vehicle", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Vehicle - () => frappe.tests.make('Vehicle', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.js b/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.js deleted file mode 100644 index fba3e098d4b..00000000000 --- a/erpnext/hub_node/doctype/marketplace_settings/test_marketplace_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Marketplace Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Marketplace Settings - () => frappe.tests.make('Marketplace Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.js b/erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.js deleted file mode 100644 index e0f05b1abbd..00000000000 --- a/erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Maintenance Schedule", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Maintenance Schedule - () => frappe.tests.make('Maintenance Schedule', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js index 8e488c1ce12..9a90f49d855 100644 --- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js +++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js @@ -73,12 +73,16 @@ erpnext.maintenance.MaintenanceVisit = frappe.ui.form.Controller.extend({ if (this.frm.doc.docstatus === 0) { this.frm.add_custom_button(__('Maintenance Schedule'), function () { + if (!me.frm.doc.customer) { + frappe.msgprint(__('Please select Customer first')); + return; + } erpnext.utils.map_current_doc({ method: "erpnext.maintenance.doctype.maintenance_schedule.maintenance_schedule.make_maintenance_visit", source_doctype: "Maintenance Schedule", target: me.frm, setters: { - customer: me.frm.doc.customer || undefined, + customer: me.frm.doc.customer, }, get_query_filters: { docstatus: 1, @@ -104,12 +108,16 @@ erpnext.maintenance.MaintenanceVisit = frappe.ui.form.Controller.extend({ }, __("Get Items From")); this.frm.add_custom_button(__('Sales Order'), function () { + if (!me.frm.doc.customer) { + frappe.msgprint(__('Please select Customer first')); + return; + } erpnext.utils.map_current_doc({ method: "erpnext.selling.doctype.sales_order.sales_order.make_maintenance_visit", source_doctype: "Sales Order", target: me.frm, setters: { - customer: me.frm.doc.customer || undefined, + customer: me.frm.doc.customer, }, get_query_filters: { docstatus: 1, diff --git a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.js b/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.js deleted file mode 100644 index 51a0d948419..00000000000 --- a/erpnext/manufacturing/doctype/blanket_order/test_blanket_order.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Blanket Order", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Blanket Order - () => frappe.tests.make('Blanket Order', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 70237f9147f..47d94fbce31 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -448,25 +448,29 @@ class BOM(WebsiteGenerator): frappe.throw(_("Quantity required for Item {0} in row {1}").format(m.item_code, m.idx)) check_list.append(m) - def check_recursion(self, bom_list=[]): + def check_recursion(self, bom_list=None): """ Check whether recursion occurs in any bom""" + def _throw_error(bom_name): + frappe.throw(_("BOM recursion: {0} cannot be parent or child of {0}").format(bom_name)) + bom_list = self.traverse_tree() - bom_nos = frappe.get_all('BOM Item', fields=["bom_no"], - filters={'parent': ('in', bom_list), 'parenttype': 'BOM'}) + child_items = frappe.get_all('BOM Item', fields=["bom_no", "item_code"], + filters={'parent': ('in', bom_list), 'parenttype': 'BOM'}) or [] - raise_exception = False - if bom_nos and self.name in [d.bom_no for d in bom_nos]: - raise_exception = True + child_bom = {d.bom_no for d in child_items} + child_items_codes = {d.item_code for d in child_items} - if not raise_exception: - bom_nos = frappe.get_all('BOM Item', fields=["parent"], - filters={'bom_no': self.name, 'parenttype': 'BOM'}) + if self.name in child_bom: + _throw_error(self.name) - if self.name in [d.parent for d in bom_nos]: - raise_exception = True + if self.item in child_items_codes: + _throw_error(self.item) - if raise_exception: - frappe.throw(_("BOM recursion: {0} cannot be parent or child of {1}").format(self.name, self.name)) + bom_nos = frappe.get_all('BOM Item', fields=["parent"], + filters={'bom_no': self.name, 'parenttype': 'BOM'}) or [] + + if self.name in {d.parent for d in bom_nos}: + _throw_error(self.name) def traverse_tree(self, bom_list=None): def _get_children(bom_no): @@ -514,17 +518,21 @@ class BOM(WebsiteGenerator): def update_rate_and_time(self, row, update_hour_rate = False): if not row.hour_rate or update_hour_rate: hour_rate = flt(frappe.get_cached_value("Workstation", row.workstation, "hour_rate")) - row.hour_rate = (hour_rate / flt(self.conversion_rate) - if self.conversion_rate and hour_rate else hour_rate) + + if hour_rate: + row.hour_rate = (hour_rate / flt(self.conversion_rate) + if self.conversion_rate and hour_rate else hour_rate) if self.routing: - row.time_in_mins = flt(frappe.db.get_value("BOM Operation", { + time_in_mins = flt(frappe.db.get_value("BOM Operation", { "workstation": row.workstation, "operation": row.operation, - "sequence_id": row.sequence_id, "parent": self.routing }, ["time_in_mins"])) + if time_in_mins: + row.time_in_mins = time_in_mins + if row.hour_rate and row.time_in_mins: row.base_hour_rate = flt(row.hour_rate) * flt(self.conversion_rate) row.operating_cost = flt(row.hour_rate) * flt(row.time_in_mins) / 60.0 diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py index 6a81ac33679..a904d7f7be0 100644 --- a/erpnext/manufacturing/doctype/bom/test_bom.py +++ b/erpnext/manufacturing/doctype/bom/test_bom.py @@ -227,6 +227,46 @@ class TestBOM(unittest.TestCase): self.assertEqual(bom_items, supplied_items) + def test_bom_recursion_1st_level(self): + """BOM should not allow BOM item again in child""" + item_code = "_Test BOM Recursion" + make_item(item_code, {'is_stock_item': 1}) + + bom = frappe.new_doc("BOM") + bom.item = item_code + bom.append("items", frappe._dict(item_code=item_code)) + with self.assertRaises(frappe.ValidationError) as err: + bom.save() + + self.assertTrue("recursion" in str(err.exception).lower()) + frappe.delete_doc("BOM", bom.name, ignore_missing=True) + + def test_bom_recursion_transitive(self): + item1 = "_Test BOM Recursion" + item2 = "_Test BOM Recursion 2" + make_item(item1, {'is_stock_item': 1}) + make_item(item2, {'is_stock_item': 1}) + + bom1 = frappe.new_doc("BOM") + bom1.item = item1 + bom1.append("items", frappe._dict(item_code=item2)) + bom1.save() + bom1.submit() + + bom2 = frappe.new_doc("BOM") + bom2.item = item2 + bom2.append("items", frappe._dict(item_code=item1)) + + with self.assertRaises(frappe.ValidationError) as err: + bom2.save() + bom2.submit() + + self.assertTrue("recursion" in str(err.exception).lower()) + + bom1.cancel() + frappe.delete_doc("BOM", bom1.name, ignore_missing=True, force=True) + frappe.delete_doc("BOM", bom2.name, ignore_missing=True, force=True) + def test_bom_with_process_loss_item(self): fg_item_non_whole, fg_item_whole, bom_item = create_process_loss_bom_items() diff --git a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.js b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.js deleted file mode 100644 index d220df2824f..00000000000 --- a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: BOM Update Tool", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('BOM Update Tool', [ - // insert a new BOM Update Tool - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/manufacturing/doctype/job_card/test_job_card.js b/erpnext/manufacturing/doctype/job_card/test_job_card.js deleted file mode 100644 index 5dc7805d226..00000000000 --- a/erpnext/manufacturing/doctype/job_card/test_job_card.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Job Card", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Job Card - () => frappe.tests.make('Job Card', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/manufacturing/doctype/manufacturing_settings/test_manufacturing_settings.js b/erpnext/manufacturing/doctype/manufacturing_settings/test_manufacturing_settings.js deleted file mode 100644 index 2b2589eddd8..00000000000 --- a/erpnext/manufacturing/doctype/manufacturing_settings/test_manufacturing_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Manufacturing Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('Manufacturing Settings', [ - // insert a new Manufacturing Settings - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/manufacturing/doctype/material_request_plan_item/test_material_request_plan_item.js b/erpnext/manufacturing/doctype/material_request_plan_item/test_material_request_plan_item.js deleted file mode 100644 index 14c6e393847..00000000000 --- a/erpnext/manufacturing/doctype/material_request_plan_item/test_material_request_plan_item.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Material Request Plan Item", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Material Request Plan Item - () => frappe.tests.make('Material Request Plan Item', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index b4c663507ce..6b61c6d330f 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -213,7 +213,6 @@ class ProductionPlan(Document): }) pi = self.append('po_items', { - 'include_exploded_items': 1, 'warehouse': data.warehouse, 'item_code': data.item_code, 'description': data.description or item_details.description, @@ -224,6 +223,7 @@ class ProductionPlan(Document): 'planned_start_date': now_datetime(), 'product_bundle_item': data.parent_item }) + pi._set_defaults() if self.get_items_from == "Sales Order": pi.sales_order = data.parent diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js index c2e3e6d7124..8f946866247 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js +++ b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js @@ -1,4 +1,5 @@ frappe.listview_settings['Production Plan'] = { + hide_name_column: true, add_fields: ["status"], filters: [["status", "!=", "Closed"]], get_indicator: function (doc) { diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.js b/erpnext/manufacturing/doctype/production_plan/test_production_plan.js deleted file mode 100644 index ef7d64c92da..00000000000 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Production Plan", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Production Plan - () => frappe.tests.make('Production Plan', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py index a5b9ff845fc..78028039c48 100644 --- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py @@ -288,6 +288,7 @@ class TestProductionPlan(unittest.TestCase): self.assertEqual(warehouses, expected_warehouses) def test_get_sales_order_with_variant(self): + rm_item = create_item('PIV_RM', valuation_rate = 100) if not frappe.db.exists('Item', {"item_code": 'PIV'}): item = create_item('PIV', valuation_rate = 100) variant_settings = { @@ -300,20 +301,20 @@ class TestProductionPlan(unittest.TestCase): } item.update(variant_settings) item.save() - parent_bom = make_bom(item = 'PIV', raw_materials = ['PIV']) + parent_bom = make_bom(item = 'PIV', raw_materials = [rm_item.item_code]) if not frappe.db.exists('BOM', {"item": 'PIV'}): - parent_bom = make_bom(item = 'PIV', raw_materials = ['PIV']) + parent_bom = make_bom(item = 'PIV', raw_materials = [rm_item.item_code]) else: parent_bom = frappe.get_doc('BOM', {"item": 'PIV'}) if not frappe.db.exists('Item', {"item_code": 'PIV-RED'}): variant = create_variant("PIV", {"Colour": "Red"}) variant.save() - variant_bom = make_bom(item = variant.item_code, raw_materials = [variant.item_code]) + variant_bom = make_bom(item = variant.item_code, raw_materials = [rm_item.item_code]) else: variant = frappe.get_doc('Item', 'PIV-RED') if not frappe.db.exists('BOM', {"item": 'PIV-RED'}): - variant_bom = make_bom(item = variant.item_code, raw_materials = [variant.item_code]) + variant_bom = make_bom(item = variant.item_code, raw_materials = [rm_item.item_code]) """Testing when item variant has a BOM""" so = make_sales_order(item_code="PIV-RED", qty=5) diff --git a/erpnext/manufacturing/doctype/routing/test_routing.js b/erpnext/manufacturing/doctype/routing/test_routing.js deleted file mode 100644 index 6cb65494af2..00000000000 --- a/erpnext/manufacturing/doctype/routing/test_routing.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Routing", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Routing - () => frappe.tests.make('Routing', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py index 3a334a530cd..c0ed6115340 100644 --- a/erpnext/manufacturing/doctype/work_order/test_work_order.py +++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py @@ -675,13 +675,18 @@ class TestWorkOrder(unittest.TestCase): def test_valuation_rate_missing_on_make_stock_entry(self): item_name = 'Test Valuation Rate Missing' + rm_item = '_Test raw material item' make_item(item_name, { "is_stock_item": 1, "include_item_in_manufacturing": 1, }) + make_item('_Test raw material item', { + "is_stock_item": 1, + "include_item_in_manufacturing": 1, + }) if not frappe.db.get_value('BOM', {'item': item_name}): - make_bom(item=item_name, raw_materials=[item_name], rm_qty=1) + make_bom(item=item_name, raw_materials=[rm_item], rm_qty=1) company = "_Test Company with perpetual inventory" source_warehouse = create_warehouse("Test Valuation Rate Missing Warehouse", company=company) diff --git a/erpnext/non_profit/doctype/certification_application/test_certification_application.js b/erpnext/non_profit/doctype/certification_application/test_certification_application.js deleted file mode 100644 index 40e94864d49..00000000000 --- a/erpnext/non_profit/doctype/certification_application/test_certification_application.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Certification Application", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Certification Application - () => frappe.tests.make('Certification Application', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/non_profit/doctype/certified_consultant/test_certified_consultant.js b/erpnext/non_profit/doctype/certified_consultant/test_certified_consultant.js deleted file mode 100644 index f6a72a43271..00000000000 --- a/erpnext/non_profit/doctype/certified_consultant/test_certified_consultant.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Certified Consultant", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Certified Consultant - () => frappe.tests.make('Certified Consultant', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/non_profit/doctype/chapter/test_chapter.js b/erpnext/non_profit/doctype/chapter/test_chapter.js deleted file mode 100644 index e30d6a5bf9b..00000000000 --- a/erpnext/non_profit/doctype/chapter/test_chapter.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Chapter", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Chapter - () => frappe.tests.make('Chapter', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/non_profit/doctype/donor_type/test_donor_type.js b/erpnext/non_profit/doctype/donor_type/test_donor_type.js deleted file mode 100644 index 22dc18ed76a..00000000000 --- a/erpnext/non_profit/doctype/donor_type/test_donor_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Donor Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Member - () => frappe.tests.make('Donor Type', [ - // values to be set - {donor_type: 'Test Organization'}, - ]), - () => { - assert.equal(cur_frm.doc.donor_type, 'Test Organization'); - }, - () => done() - ]); - -}); diff --git a/erpnext/non_profit/doctype/membership/test_membership.js b/erpnext/non_profit/doctype/membership/test_membership.js deleted file mode 100644 index 24c85c61576..00000000000 --- a/erpnext/non_profit/doctype/membership/test_membership.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Membership", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Membership - () => frappe.tests.make('Membership', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 0e1db3c7181..8f9295e75aa 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -217,6 +217,7 @@ execute:frappe.delete_doc_if_exists("DocType", "Bank Reconciliation") erpnext.patches.v13_0.move_doctype_reports_and_notification_from_hr_to_payroll #22-06-2020 erpnext.patches.v13_0.move_payroll_setting_separately_from_hr_settings #22-06-2020 execute:frappe.reload_doc("regional", "doctype", "e_invoice_settings") +erpnext.patches.v12_0.create_itc_reversal_custom_fields erpnext.patches.v13_0.check_is_income_tax_component #22-06-2020 erpnext.patches.v13_0.loyalty_points_entry_for_pos_invoice #22-07-2020 erpnext.patches.v12_0.add_taxjar_integration_field @@ -274,7 +275,6 @@ erpnext.patches.v13_0.rename_discharge_date_in_ip_record erpnext.patches.v12_0.create_taxable_value_field erpnext.patches.v12_0.add_gst_category_in_delivery_note erpnext.patches.v12_0.purchase_receipt_status -erpnext.patches.v12_0.create_itc_reversal_custom_fields erpnext.patches.v13_0.fix_non_unique_represents_company erpnext.patches.v12_0.add_document_type_field_for_italy_einvoicing erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021 @@ -303,6 +303,10 @@ erpnext.patches.v13_0.update_recipient_email_digest erpnext.patches.v13_0.shopify_deprecation_warning erpnext.patches.v13_0.add_custom_field_for_south_africa #2 erpnext.patches.v13_0.rename_discharge_ordered_date_in_ip_record +erpnext.patches.v13_0.migrate_stripe_api +erpnext.patches.v13_0.reset_clearance_date_for_intracompany_payment_entries +erpnext.patches.v13_0.set_operation_time_based_on_operating_cost +erpnext.patches.v13_0.validate_options_for_data_field erpnext.patches.v13_0.create_website_items erpnext.patches.v13_0.populate_e_commerce_settings erpnext.patches.v13_0.make_homepage_products_website_items diff --git a/erpnext/patches/v12_0/add_company_link_to_einvoice_settings.py b/erpnext/patches/v12_0/add_company_link_to_einvoice_settings.py index c2ed6c288fe..712eb4f61c2 100644 --- a/erpnext/patches/v12_0/add_company_link_to_einvoice_settings.py +++ b/erpnext/patches/v12_0/add_company_link_to_einvoice_settings.py @@ -3,10 +3,14 @@ import frappe def execute(): company = frappe.get_all('Company', filters = {'country': 'India'}) - if not company or not frappe.db.count('E Invoice User'): + + if not company: return frappe.reload_doc("regional", "doctype", "e_invoice_user") + if not frappe.db.count('E Invoice User'): + return + for creds in frappe.db.get_all('E Invoice User', fields=['name', 'gstin']): company_name = frappe.db.sql(""" select dl.link_name from `tabAddress` a, `tabDynamic Link` dl diff --git a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py index a6471eb53cd..5c3fa5991c9 100644 --- a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py +++ b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py @@ -91,8 +91,9 @@ def get_item_tax_template(item_tax_templates, item_tax_map, item_code, parenttyp item_tax_template.title = make_autoname("Item Tax Template-.####") for tax_type, tax_rate in iteritems(item_tax_map): - account_details = frappe.db.get_value("Account", tax_type, ['name', 'account_type'], as_dict=1) + account_details = frappe.db.get_value("Account", tax_type, ['name', 'account_type', 'company'], as_dict=1) if account_details: + item_tax_template.company = account_details.company if account_details.account_type not in ('Tax', 'Chargeable', 'Income Account', 'Expense Account', 'Expenses Included In Valuation'): frappe.db.set_value('Account', account_details.name, 'account_type', 'Chargeable') else: diff --git a/erpnext/patches/v13_0/check_is_income_tax_component.py b/erpnext/patches/v13_0/check_is_income_tax_component.py index ebae3ad7157..7a52dc88d21 100644 --- a/erpnext/patches/v13_0/check_is_income_tax_component.py +++ b/erpnext/patches/v13_0/check_is_income_tax_component.py @@ -19,10 +19,10 @@ def execute(): ] for doctype in doctypes: - frappe.reload_doc('Payroll', 'doctype', doctype) + frappe.reload_doc('Payroll', 'doctype', doctype, force=True) - reports = ['Professional Tax Deductions', 'Provident Fund Deductions'] + reports = ['Professional Tax Deductions', 'Provident Fund Deductions', 'E-Invoice Summary'] for report in reports: frappe.reload_doc('Regional', 'Report', report) frappe.reload_doc('Regional', 'Report', report) diff --git a/erpnext/patches/v13_0/delete_old_purchase_reports.py b/erpnext/patches/v13_0/delete_old_purchase_reports.py index c17aad06c7f..57620d3e986 100644 --- a/erpnext/patches/v13_0/delete_old_purchase_reports.py +++ b/erpnext/patches/v13_0/delete_old_purchase_reports.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe +from erpnext.accounts.utils import check_and_delete_linked_reports def execute(): reports_to_delete = ["Requested Items To Be Ordered", @@ -13,6 +14,7 @@ def execute(): for report in reports_to_delete: if frappe.db.exists("Report", report): delete_auto_email_reports(report) + check_and_delete_linked_reports(report) frappe.delete_doc("Report", report) diff --git a/erpnext/patches/v13_0/delete_old_sales_reports.py b/erpnext/patches/v13_0/delete_old_sales_reports.py index 671c012c8a0..905a42c0c4c 100644 --- a/erpnext/patches/v13_0/delete_old_sales_reports.py +++ b/erpnext/patches/v13_0/delete_old_sales_reports.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe +from erpnext.accounts.utils import check_and_delete_linked_reports def execute(): reports_to_delete = ["Ordered Items To Be Delivered", "Ordered Items To Be Billed"] @@ -11,6 +12,7 @@ def execute(): for report in reports_to_delete: if frappe.db.exists("Report", report): delete_auto_email_reports(report) + check_and_delete_linked_reports(report) frappe.delete_doc("Report", report) diff --git a/erpnext/patches/v13_0/migrate_stripe_api.py b/erpnext/patches/v13_0/migrate_stripe_api.py new file mode 100644 index 00000000000..355421a1f42 --- /dev/null +++ b/erpnext/patches/v13_0/migrate_stripe_api.py @@ -0,0 +1,7 @@ +import frappe +from frappe.model.utils.rename_field import rename_field + + +def execute(): + frappe.reload_doc("accounts", "doctype", "subscription_plan") + rename_field("Subscription Plan", "payment_plan_id", "product_price_id") diff --git a/erpnext/patches/v13_0/rename_issue_doctype_fields.py b/erpnext/patches/v13_0/rename_issue_doctype_fields.py index 41c51c36dcb..4885c0b7afa 100644 --- a/erpnext/patches/v13_0/rename_issue_doctype_fields.py +++ b/erpnext/patches/v13_0/rename_issue_doctype_fields.py @@ -41,6 +41,7 @@ def execute(): rename_field('Opportunity', 'mins_to_first_response', 'first_response_time') # change fieldtype to duration + frappe.reload_doc('crm', 'doctype', 'opportunity', force=True) count = 0 for entry in opportunities: mins_to_first_response = convert_to_seconds(entry.mins_to_first_response, 'Minutes') @@ -58,6 +59,8 @@ def execute(): def convert_to_seconds(value, unit): seconds = 0 + if value == 0: + return seconds if unit == 'Hours': seconds = value * 3600 if unit == 'Minutes': diff --git a/erpnext/patches/v13_0/reset_clearance_date_for_intracompany_payment_entries.py b/erpnext/patches/v13_0/reset_clearance_date_for_intracompany_payment_entries.py new file mode 100644 index 00000000000..1da5275761b --- /dev/null +++ b/erpnext/patches/v13_0/reset_clearance_date_for_intracompany_payment_entries.py @@ -0,0 +1,45 @@ +# Copyright (c) 2019, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe + +def execute(): + """ + Reset Clearance Date for Payment Entries of type Internal Transfer that have only been reconciled with one Bank Transaction. + This will allow the Payment Entries to be reconciled with the second Bank Transaction using the Bank Reconciliation Tool. + """ + + intra_company_pe = get_intra_company_payment_entries_with_clearance_dates() + reconciled_bank_transactions = get_reconciled_bank_transactions(intra_company_pe) + + for payment_entry in reconciled_bank_transactions: + if len(reconciled_bank_transactions[payment_entry]) == 1: + frappe.db.set_value('Payment Entry', payment_entry, 'clearance_date', None) + +def get_intra_company_payment_entries_with_clearance_dates(): + return frappe.get_all( + 'Payment Entry', + filters = { + 'payment_type': 'Internal Transfer', + 'clearance_date': ["not in", None] + }, + pluck = 'name' + ) + +def get_reconciled_bank_transactions(intra_company_pe): + """Returns dictionary where each key:value pair is Payment Entry : List of Bank Transactions reconciled with Payment Entry""" + + reconciled_bank_transactions = {} + + for payment_entry in intra_company_pe: + reconciled_bank_transactions[payment_entry] = frappe.get_all( + 'Bank Transaction Payments', + filters = { + 'payment_entry': payment_entry + }, + pluck='parent' + ) + + return reconciled_bank_transactions \ No newline at end of file diff --git a/erpnext/patches/v13_0/set_operation_time_based_on_operating_cost.py b/erpnext/patches/v13_0/set_operation_time_based_on_operating_cost.py new file mode 100644 index 00000000000..4acbdd63a00 --- /dev/null +++ b/erpnext/patches/v13_0/set_operation_time_based_on_operating_cost.py @@ -0,0 +1,15 @@ +import frappe + +def execute(): + frappe.reload_doc('manufacturing', 'doctype', 'bom') + frappe.reload_doc('manufacturing', 'doctype', 'bom_operation') + + frappe.db.sql(''' + UPDATE + `tabBOM Operation` + SET + time_in_mins = (operating_cost * 60) / hour_rate + WHERE + time_in_mins = 0 AND operating_cost > 0 + AND hour_rate > 0 AND docstatus = 1 AND parenttype = "BOM" + ''') \ No newline at end of file diff --git a/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py b/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py index e642547ef82..a5769d2957c 100644 --- a/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py +++ b/erpnext/patches/v13_0/update_returned_qty_in_pr_dn.py @@ -8,6 +8,7 @@ def execute(): frappe.reload_doc('stock', 'doctype', 'purchase_receipt_item') frappe.reload_doc('stock', 'doctype', 'delivery_note') frappe.reload_doc('stock', 'doctype', 'delivery_note_item') + frappe.reload_doc('stock', 'doctype', 'stock_settings') def update_from_return_docs(doctype): for return_doc in frappe.get_all(doctype, filters={'is_return' : 1, 'docstatus' : 1}): diff --git a/erpnext/patches/v13_0/validate_options_for_data_field.py b/erpnext/patches/v13_0/validate_options_for_data_field.py new file mode 100644 index 00000000000..568d1a4b0cb --- /dev/null +++ b/erpnext/patches/v13_0/validate_options_for_data_field.py @@ -0,0 +1,25 @@ +# Copyright (c) 2021, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model import data_field_options + +def execute(): + + for field in frappe.get_all('Custom Field', + fields = ['name'], + filters = { + 'fieldtype': 'Data', + 'options': ['!=', None] + }): + + if field not in data_field_options: + frappe.db.sql(""" + UPDATE + `tabCustom Field` + SET + options=NULL + WHERE + name=%s + """, (field)) diff --git a/erpnext/payroll/doctype/additional_salary/test_additional_salary.js b/erpnext/payroll/doctype/additional_salary/test_additional_salary.js deleted file mode 100644 index c18e1875854..00000000000 --- a/erpnext/payroll/doctype/additional_salary/test_additional_salary.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Additional Salary", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Additional Salary - () => frappe.tests.make('Additional Salary', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/employee_benefit_application/test_employee_benefit_application.js b/erpnext/payroll/doctype/employee_benefit_application/test_employee_benefit_application.js deleted file mode 100644 index b355e1c4366..00000000000 --- a/erpnext/payroll/doctype/employee_benefit_application/test_employee_benefit_application.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Benefit Application", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Benefit Application - () => frappe.tests.make('Employee Benefit Application', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/employee_benefit_claim/test_employee_benefit_claim.js b/erpnext/payroll/doctype/employee_benefit_claim/test_employee_benefit_claim.js deleted file mode 100644 index 3c808c0a560..00000000000 --- a/erpnext/payroll/doctype/employee_benefit_claim/test_employee_benefit_claim.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Benefit Claim", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Benefit Claim - () => frappe.tests.make('Employee Benefit Claim', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/employee_incentive/test_employee_incentive.js b/erpnext/payroll/doctype/employee_incentive/test_employee_incentive.js deleted file mode 100644 index 10bc03701fd..00000000000 --- a/erpnext/payroll/doctype/employee_incentive/test_employee_incentive.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Incentive", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Incentive - () => frappe.tests.make('Employee Incentive', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.js b/erpnext/payroll/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.js deleted file mode 100644 index e0e43c32e3b..00000000000 --- a/erpnext/payroll/doctype/employee_tax_exemption_category/test_employee_tax_exemption_category.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Tax Exemption Category", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Tax Exemption Category - () => frappe.tests.make('Employee Tax Exemption Category', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.js b/erpnext/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.js deleted file mode 100644 index 274a3a38603..00000000000 --- a/erpnext/payroll/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Tax Exemption Declaration", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Tax Exemption Declaration - () => frappe.tests.make('Employee Tax Exemption Declaration', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.js b/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.js deleted file mode 100644 index cec75087280..00000000000 --- a/erpnext/payroll/doctype/employee_tax_exemption_proof_submission/test_employee_tax_exemption_proof_submission.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Tax Exemption Proof Submission", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Tax Exemption Proof Submission - () => frappe.tests.make('Employee Tax Exemption Proof Submission', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.js b/erpnext/payroll/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.js deleted file mode 100644 index 8a1a6d151dd..00000000000 --- a/erpnext/payroll/doctype/employee_tax_exemption_sub_category/test_employee_tax_exemption_sub_category.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Employee Tax Exemption Sub Category", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Employee Tax Exemption Sub Category - () => frappe.tests.make('Employee Tax Exemption Sub Category', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/payroll_period/test_payroll_period.js b/erpnext/payroll/doctype/payroll_period/test_payroll_period.js deleted file mode 100644 index 8c4ded96f38..00000000000 --- a/erpnext/payroll/doctype/payroll_period/test_payroll_period.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Payroll Period", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Payroll Period - () => frappe.tests.make('Payroll Period', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/retention_bonus/test_retention_bonus.js b/erpnext/payroll/doctype/retention_bonus/test_retention_bonus.js deleted file mode 100644 index a4b95d3cb10..00000000000 --- a/erpnext/payroll/doctype/retention_bonus/test_retention_bonus.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Retention Bonus", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Retention Bonus - () => frappe.tests.make('Retention Bonus', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/salary_component/test_salary_component.js b/erpnext/payroll/doctype/salary_component/test_salary_component.js deleted file mode 100644 index c47d32d9965..00000000000 --- a/erpnext/payroll/doctype/salary_component/test_salary_component.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Salary Component", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Salary Component - () => frappe.tests.make('Salary Component', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/payroll/doctype/salary_structure_assignment/test_salary_structure_assignment.js b/erpnext/payroll/doctype/salary_structure_assignment/test_salary_structure_assignment.js deleted file mode 100644 index 2f52576c7a7..00000000000 --- a/erpnext/payroll/doctype/salary_structure_assignment/test_salary_structure_assignment.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Salary Structure Assignment", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Salary Structure Assignment - () => frappe.tests.make('Salary Structure Assignment', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/projects/doctype/project/test_project.js b/erpnext/projects/doctype/project/test_project.js deleted file mode 100644 index 16494f62b60..00000000000 --- a/erpnext/projects/doctype/project/test_project.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Project", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Project - () => frappe.tests.make('Project', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/projects/doctype/project_type/test_project_type.js b/erpnext/projects/doctype/project_type/test_project_type.js deleted file mode 100644 index c2198c452c0..00000000000 --- a/erpnext/projects/doctype/project_type/test_project_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Project Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('Project Type', [ - // insert a new Project Type - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/projects/doctype/project_update/test_project_update.js b/erpnext/projects/doctype/project_update/test_project_update.js deleted file mode 100644 index bda510b921a..00000000000 --- a/erpnext/projects/doctype/project_update/test_project_update.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Project Update", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Project Update - () => frappe.tests.make('Project Update', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/projects/doctype/projects_settings/test_projects_settings.js b/erpnext/projects/doctype/projects_settings/test_projects_settings.js deleted file mode 100644 index f6feaa48049..00000000000 --- a/erpnext/projects/doctype/projects_settings/test_projects_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Projects Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Projects Settings - () => frappe.tests.make('Projects Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.js b/erpnext/projects/doctype/timesheet/test_timesheet.js deleted file mode 100644 index c081d6f8ea4..00000000000 --- a/erpnext/projects/doctype/timesheet/test_timesheet.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Timesheet", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Timesheet - () => frappe.tests.make('Timesheet', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py index 5f569d6bcd4..3a3d9e2c2a5 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.py +++ b/erpnext/projects/doctype/timesheet/timesheet.py @@ -216,25 +216,53 @@ class Timesheet(Document): @frappe.whitelist() def get_projectwise_timesheet_data(project=None, parent=None, from_time=None, to_time=None): - condition = '' + condition = "" if project: - condition += "and tsd.project = %(project)s" + condition += "AND tsd.project = %(project)s " if parent: - condition += "AND tsd.parent = %(parent)s" + condition += "AND tsd.parent = %(parent)s " if from_time and to_time: condition += "AND CAST(tsd.from_time as DATE) BETWEEN %(from_time)s AND %(to_time)s" - return frappe.db.sql("""SELECT tsd.name as name, - tsd.parent as parent, tsd.billing_hours as billing_hours, - tsd.billing_amount as billing_amount, tsd.activity_type as activity_type, - tsd.description as description, ts.currency as currency, - tsd.project_name as project_name - FROM `tabTimesheet Detail` tsd - INNER JOIN `tabTimesheet` ts ON ts.name = tsd.parent - WHERE tsd.parenttype = 'Timesheet' - and tsd.docstatus=1 {0} - and tsd.is_billable = 1 - and tsd.sales_invoice is null""".format(condition), {'project': project, 'parent': parent, 'from_time': from_time, 'to_time': to_time}, as_dict=1) + query = f""" + SELECT + + tsd.name as name, + tsd.parent as time_sheet, + tsd.from_time as from_time, + tsd.to_time as to_time, + tsd.billing_hours as billing_hours, + tsd.billing_amount as billing_amount, + tsd.activity_type as activity_type, + tsd.description as description, + ts.currency as currency, + tsd.project_name as project_name + + FROM `tabTimesheet Detail` tsd + + INNER JOIN `tabTimesheet` ts + ON ts.name = tsd.parent + + WHERE + + tsd.parenttype = 'Timesheet' + AND tsd.docstatus = 1 + AND tsd.is_billable = 1 + AND tsd.sales_invoice is NULL + {condition} + + ORDER BY tsd.from_time ASC + """ + + filters = { + "project": project, + "parent": parent, + "from_time": from_time, + "to_time": to_time + } + + return frappe.db.sql(query, filters, as_dict=1) + @frappe.whitelist() def get_timesheet_detail_rate(timelog, currency): diff --git a/erpnext/public/build.json b/erpnext/public/build.json index b8ba5e2a267..4cf9bb11eff 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -39,6 +39,7 @@ "public/js/templates/item_quick_entry.html", "public/js/utils/item_quick_entry.js", "public/js/utils/customer_quick_entry.js", + "public/js/utils/supplier_quick_entry.js", "public/js/education/student_button.html", "public/js/education/assessment_result_tool.html", "public/js/hub/hub_factory.js", diff --git a/erpnext/public/js/utils/supplier_quick_entry.js b/erpnext/public/js/utils/supplier_quick_entry.js new file mode 100644 index 00000000000..8d591a96510 --- /dev/null +++ b/erpnext/public/js/utils/supplier_quick_entry.js @@ -0,0 +1,77 @@ +frappe.provide('frappe.ui.form'); + +frappe.ui.form.SupplierQuickEntryForm = class SupplierQuickEntryForm extends frappe.ui.form.QuickEntryForm { + constructor(doctype, after_insert, init_callback, doc, force) { + super(doctype, after_insert, init_callback, doc, force); + this.skip_redirect_on_error = true; + } + + render_dialog() { + this.mandatory = this.mandatory.concat(this.get_variant_fields()); + super.render_dialog(); + } + + get_variant_fields() { + var variant_fields = [ + { + fieldtype: "Section Break", + label: __("Primary Contact Details"), + collapsible: 1 + }, + { + label: __("Email Id"), + fieldname: "email_id", + fieldtype: "Data" + }, + { + fieldtype: "Column Break" + }, + { + label: __("Mobile Number"), + fieldname: "mobile_no", + fieldtype: "Data" + }, + { + fieldtype: "Section Break", + label: __("Primary Address Details"), + collapsible: 1 + }, + { + label: __("Address Line 1"), + fieldname: "address_line1", + fieldtype: "Data" + }, + { + label: __("Address Line 2"), + fieldname: "address_line2", + fieldtype: "Data" + }, + { + label: __("ZIP Code"), + fieldname: "pincode", + fieldtype: "Data" + }, + { + fieldtype: "Column Break" + }, + { + label: __("City"), + fieldname: "city", + fieldtype: "Data" + }, + { + label: __("State"), + fieldname: "state", + fieldtype: "Data" + }, + { + label: __("Country"), + fieldname: "country", + fieldtype: "Link", + options: "Country" + } + ]; + + return variant_fields; + } +}; diff --git a/erpnext/regional/doctype/gst_hsn_code/test_gst_hsn_code.js b/erpnext/regional/doctype/gst_hsn_code/test_gst_hsn_code.js deleted file mode 100644 index 24c5fd355ff..00000000000 --- a/erpnext/regional/doctype/gst_hsn_code/test_gst_hsn_code.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: GST HSN Code", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new GST HSN Code - () => frappe.tests.make('GST HSN Code', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/regional/doctype/gst_settings/test_gst_settings.js b/erpnext/regional/doctype/gst_settings/test_gst_settings.js deleted file mode 100644 index 00fcca6f326..00000000000 --- a/erpnext/regional/doctype/gst_settings/test_gst_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: GST Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new GST Settings - () => frappe.tests.make('GST Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 7076157d57f..737723bbfbe 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -150,8 +150,14 @@ class Customer(TransactionBase): self.db_set('email_id', self.email_id) def create_primary_address(self): + from frappe.contacts.doctype.address.address import get_address_display + if self.flags.is_new_doc and self.get('address_line1'): - make_address(self) + address = make_address(self) + address_display = get_address_display(address.name) + + self.db_set("customer_primary_address", address.name) + self.db_set("primary_address", address_display) def update_lead_status(self): '''If Customer created from Lead, update lead status to "Converted" @@ -246,9 +252,15 @@ class Customer(TransactionBase): def on_trash(self): if self.customer_primary_contact: - frappe.db.sql("""update `tabCustomer` - set customer_primary_contact=null, mobile_no=null, email_id=null - where name=%s""", self.name) + frappe.db.sql(""" + UPDATE `tabCustomer` + SET + customer_primary_contact=null, + customer_primary_address=null, + mobile_no=null, + email_id=null, + primary_address=null + WHERE name=%(name)s""", {"name": self.name}) delete_contact_and_address('Customer', self.name) if self.lead_name: diff --git a/erpnext/selling/doctype/customer/test_customer.js b/erpnext/selling/doctype/customer/test_customer.js deleted file mode 100644 index 65b81af32c1..00000000000 --- a/erpnext/selling/doctype/customer/test_customer.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Customer", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Customer - () => frappe.tests.make('Customer', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index bba54018aef..5d44582aab4 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -718,8 +718,7 @@ def make_maintenance_schedule(source_name, target_doc=None): "doctype": "Maintenance Schedule Item", "field_map": { "parent": "sales_order" - }, - "add_if_empty": True + } } }, target_doc) @@ -745,8 +744,7 @@ def make_maintenance_visit(source_name, target_doc=None): "field_map": { "parent": "prevdoc_docname", "parenttype": "prevdoc_doctype" - }, - "add_if_empty": True + } } }, target_doc) diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.js b/erpnext/selling/doctype/sales_order/test_sales_order.js deleted file mode 100644 index 57ed19b6965..00000000000 --- a/erpnext/selling/doctype/sales_order/test_sales_order.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Sales Order", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('Sales Order', [ - // insert a new Sales Order - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/selling/doctype/sales_partner_type/test_sales_partner_type.js b/erpnext/selling/doctype/sales_partner_type/test_sales_partner_type.js deleted file mode 100644 index 3ed7b46e1d9..00000000000 --- a/erpnext/selling/doctype/sales_partner_type/test_sales_partner_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Sales Partner Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Sales Partner Type - () => frappe.tests.make('Sales Partner Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.js b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.js deleted file mode 100644 index 19fde2e1481..00000000000 --- a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Currency Exchange", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Currency Exchange - () => frappe.tests.make('Currency Exchange', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/global_defaults/test_global_defaults.js b/erpnext/setup/doctype/global_defaults/test_global_defaults.js deleted file mode 100644 index 33634eb0f88..00000000000 --- a/erpnext/setup/doctype/global_defaults/test_global_defaults.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Global Defaults", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Global Defaults - () => frappe.tests.make('Global Defaults', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/item_group/test_item_group.js b/erpnext/setup/doctype/item_group/test_item_group.js deleted file mode 100644 index ea322e23d65..00000000000 --- a/erpnext/setup/doctype/item_group/test_item_group.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Item Group", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Item Group - () => frappe.tests.make('Item Group', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/naming_series/test_naming_series.js b/erpnext/setup/doctype/naming_series/test_naming_series.js deleted file mode 100644 index 22b664b2e6d..00000000000 --- a/erpnext/setup/doctype/naming_series/test_naming_series.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Naming Series", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Naming Series - () => frappe.tests.make('Naming Series', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/party_type/test_party_type.js b/erpnext/setup/doctype/party_type/test_party_type.js deleted file mode 100644 index c97dbc58c80..00000000000 --- a/erpnext/setup/doctype/party_type/test_party_type.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Party Type", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Party Type - () => frappe.tests.make('Party Type', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/supplier_group/test_supplier_group.js b/erpnext/setup/doctype/supplier_group/test_supplier_group.js deleted file mode 100644 index 976dd2cc4f3..00000000000 --- a/erpnext/setup/doctype/supplier_group/test_supplier_group.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Supplier Group", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Supplier Group - () => frappe.tests.make('Supplier Group', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/setup/doctype/uom_conversion_factor/test_uom_conversion_factor.js b/erpnext/setup/doctype/uom_conversion_factor/test_uom_conversion_factor.js deleted file mode 100644 index afcf74ccb47..00000000000 --- a/erpnext/setup/doctype/uom_conversion_factor/test_uom_conversion_factor.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: UOM Conversion Factor", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new UOM Conversion Factor - () => frappe.tests.make('UOM Conversion Factor', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/customs_tariff_number/test_customs_tariff_number.js b/erpnext/stock/doctype/customs_tariff_number/test_customs_tariff_number.js deleted file mode 100644 index 85812d69739..00000000000 --- a/erpnext/stock/doctype/customs_tariff_number/test_customs_tariff_number.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Customs Tariff Number", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Customs Tariff Number - () => frappe.tests.make('Customs Tariff Number', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/delivery_settings/test_delivery_settings.js b/erpnext/stock/doctype/delivery_settings/test_delivery_settings.js deleted file mode 100644 index 22977c08f75..00000000000 --- a/erpnext/stock/doctype/delivery_settings/test_delivery_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Delivery Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Delivery Settings - () => frappe.tests.make('Delivery Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.js b/erpnext/stock/doctype/delivery_trip/test_delivery_trip.js deleted file mode 100644 index b6d6d1af64f..00000000000 --- a/erpnext/stock/doctype/delivery_trip/test_delivery_trip.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Delivery Trip", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Delivery Trip - () => frappe.tests.make('Delivery Trip', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index b1972d0c8fe..e346ea87214 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -162,9 +162,8 @@ frappe.ui.form.on("Item", { is_fixed_asset: function(frm) { // set serial no to false & toggles its visibility frm.set_value('has_serial_no', 0); + frm.set_value('has_batch_no', 0); frm.toggle_enable(['has_serial_no', 'serial_no_series'], !frm.doc.is_fixed_asset); - frm.toggle_reqd(['asset_category'], frm.doc.is_fixed_asset); - frm.toggle_display(['has_serial_no', 'serial_no_series'], !frm.doc.is_fixed_asset); frm.call({ method: "set_asset_naming_series", diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json index af77e835eb4..3dcb2122c70 100644 --- a/erpnext/stock/doctype/item/item.json +++ b/erpnext/stock/doctype/item/item.json @@ -188,6 +188,7 @@ }, { "default": "0", + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "is_item_from_hub", "fieldtype": "Check", "label": "Is Item from Hub", @@ -222,6 +223,7 @@ { "bold": 1, "default": "1", + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "is_stock_item", "fieldtype": "Check", "label": "Maintain Stock", @@ -230,6 +232,7 @@ }, { "default": "1", + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "include_item_in_manufacturing", "fieldtype": "Check", "label": "Include Item In Manufacturing" @@ -266,6 +269,7 @@ "fieldname": "asset_category", "fieldtype": "Link", "label": "Asset Category", + "mandatory_depends_on": "is_fixed_asset", "options": "Asset Category" }, { @@ -418,8 +422,8 @@ }, { "collapsible": 1, - "collapsible_depends_on": "eval:doc.has_batch_no || doc.has_serial_no || doc.is_fixed_asset", - "depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset", + "collapsible_depends_on": "eval:doc.has_batch_no || doc.has_serial_no", + "depends_on": "eval:doc.is_stock_item", "fieldname": "serial_nos_and_batches", "fieldtype": "Section Break", "label": "Serial Nos and Batches" @@ -476,7 +480,7 @@ }, { "default": "0", - "depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset", + "depends_on": "eval:doc.is_stock_item", "fieldname": "has_serial_no", "fieldtype": "Check", "label": "Has Serial No", @@ -494,6 +498,7 @@ { "collapsible": 1, "collapsible_depends_on": "attributes", + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "variants_section", "fieldtype": "Section Break", "label": "Variants" @@ -524,6 +529,7 @@ "options": "Item Variant Attribute" }, { + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "defaults", "fieldtype": "Section Break", "label": "Sales, Purchase, Accounting Defaults" @@ -605,6 +611,7 @@ }, { "collapsible": 1, + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "supplier_details", "fieldtype": "Section Break", "label": "Supplier Details" @@ -652,6 +659,7 @@ }, { "collapsible": 1, + "default": "eval:!doc.is_fixed_asset", "fieldname": "sales_details", "fieldtype": "Section Break", "label": "Sales Details", @@ -745,6 +753,7 @@ }, { "collapsible": 1, + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "customer_details", "fieldtype": "Section Break", "label": "Customer Details" @@ -775,6 +784,7 @@ }, { "collapsible": 1, + "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "inspection_criteria", "fieldtype": "Section Break", "label": "Inspection Criteria", @@ -853,7 +863,7 @@ }, { "collapsible": 1, - "depends_on": "eval:(!doc.is_item_from_hub)", + "depends_on": "eval:(!doc.is_item_from_hub && !doc.is_fixed_asset)", "fieldname": "hub_publishing_sb", "fieldtype": "Section Break", "label": "Hub Publishing Details" @@ -887,7 +897,7 @@ "read_only": 1 }, { - "depends_on": "eval:!doc.__islocal", + "depends_on": "eval:!doc.__islocal && !doc.is_fixed_asset", "fieldname": "over_delivery_receipt_allowance", "fieldtype": "Float", "label": "Over Delivery/Receipt Allowance (%)", @@ -895,7 +905,7 @@ "oldfieldtype": "Currency" }, { - "depends_on": "eval:!doc.__islocal", + "depends_on": "eval:!doc.__islocal && !doc.is_fixed_asset", "fieldname": "over_billing_allowance", "fieldtype": "Float", "label": "Over Billing Allowance (%)" @@ -940,7 +950,7 @@ "index_web_pages_for_search": 1, "links": [], "max_attachments": 1, - "modified": "2021-07-16 15:32:12.806991", + "modified": "2021-08-26 12:23:07.277077", "modified_by": "Administrator", "module": "Stock", "name": "Item", diff --git a/erpnext/stock/doctype/item/test_item.js b/erpnext/stock/doctype/item/test_item.js deleted file mode 100644 index af44278a59a..00000000000 --- a/erpnext/stock/doctype/item/test_item.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Item", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Item - () => frappe.tests.make('Item', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 4d56851e0cb..d0bf2a5c665 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -577,8 +577,8 @@ def make_item_variant(): test_records = frappe.get_test_records('Item') def create_item(item_code, is_stock_item=1, valuation_rate=0, warehouse="_Test Warehouse - _TC", - is_customer_provided_item=None, customer=None, is_purchase_item=None, opening_stock=0, - company="_Test Company"): + is_customer_provided_item=None, customer=None, is_purchase_item=None, opening_stock=0, is_fixed_asset=0, + asset_category=None, company="_Test Company"): if not frappe.db.exists("Item", item_code): item = frappe.new_doc("Item") item.item_code = item_code @@ -586,6 +586,8 @@ def create_item(item_code, is_stock_item=1, valuation_rate=0, warehouse="_Test W item.description = item_code item.item_group = "All Item Groups" item.is_stock_item = is_stock_item + item.is_fixed_asset = is_fixed_asset + item.asset_category = asset_category item.opening_stock = opening_stock item.valuation_rate = valuation_rate item.is_purchase_item = is_purchase_item diff --git a/erpnext/stock/doctype/item_alternative/test_item_alternative.js b/erpnext/stock/doctype/item_alternative/test_item_alternative.js deleted file mode 100644 index 87318499fe4..00000000000 --- a/erpnext/stock/doctype/item_alternative/test_item_alternative.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Item Alternative", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Item Alternative - () => frappe.tests.make('Item Alternative', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/item_variant_settings/test_item_variant_settings.js b/erpnext/stock/doctype/item_variant_settings/test_item_variant_settings.js deleted file mode 100644 index 3b3bf94f375..00000000000 --- a/erpnext/stock/doctype/item_variant_settings/test_item_variant_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Item Variant Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Item Variant Settings - () => frappe.tests.make('Item Variant Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/manufacturer/test_manufacturer.js b/erpnext/stock/doctype/manufacturer/test_manufacturer.js deleted file mode 100644 index 0254a367ccb..00000000000 --- a/erpnext/stock/doctype/manufacturer/test_manufacturer.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Manufacturer", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('Manufacturer', [ - // insert a new Manufacturer - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/material_request/test_material_request.js b/erpnext/stock/doctype/material_request/test_material_request.js deleted file mode 100644 index 793cad0f3b6..00000000000 --- a/erpnext/stock/doctype/material_request/test_material_request.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Material Request", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially('Material Request', [ - // insert a new Material Request - () => frappe.tests.make([ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/price_list/test_price_list.js b/erpnext/stock/doctype/price_list/test_price_list.js deleted file mode 100644 index fe4e07b3bdd..00000000000 --- a/erpnext/stock/doctype/price_list/test_price_list.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Price List", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Price List - () => frappe.tests.make('Price List', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.js b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.js deleted file mode 100644 index 327484e6cc3..00000000000 --- a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Quality Inspection", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Quality Inspection - () => frappe.tests.make('Quality Inspection', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/quality_inspection_template/test_quality_inspection_template.js b/erpnext/stock/doctype/quality_inspection_template/test_quality_inspection_template.js deleted file mode 100644 index 879c262ed2a..00000000000 --- a/erpnext/stock/doctype/quality_inspection_template/test_quality_inspection_template.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Quality Inspection Template", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Quality Inspection Template - () => frappe.tests.make('Quality Inspection Template', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/serial_no/test_serial_no.js b/erpnext/stock/doctype/serial_no/test_serial_no.js deleted file mode 100644 index bf8293257c3..00000000000 --- a/erpnext/stock/doctype/serial_no/test_serial_no.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Serial No", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Serial No - () => frappe.tests.make('Serial No', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 324bb7a62d9..4531652a13c 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -390,7 +390,7 @@ class StockReconciliation(StockController): sl_entries = self.merge_similar_item_serial_nos(sl_entries) sl_entries.reverse() - allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock") + allow_negative_stock = cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock")) self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock) diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index 94b006c8944..e4381271ed2 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -15,6 +15,7 @@ from erpnext.stock.doctype.item.test_item import create_item from erpnext.stock.utils import get_incoming_rate, get_stock_value_on, get_valuation_method from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt +from erpnext.tests.utils import change_settings class TestStockReconciliation(unittest.TestCase): @@ -310,6 +311,7 @@ class TestStockReconciliation(unittest.TestCase): pr2.cancel() pr1.cancel() + @change_settings("Stock Settings", {"allow_negative_stock": 0}) def test_backdated_stock_reco_future_negative_stock(self): """ Test if a backdated stock reco causes future negative stock and is blocked. @@ -327,8 +329,6 @@ class TestStockReconciliation(unittest.TestCase): warehouse = "_Test Warehouse - _TC" create_item(item_code) - negative_stock_setting = frappe.db.get_single_value("Stock Settings", "allow_negative_stock") - frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 0) pr1 = make_purchase_receipt(item_code=item_code, warehouse=warehouse, qty=10, rate=100, posting_date=add_days(nowdate(), -2)) @@ -348,11 +348,50 @@ class TestStockReconciliation(unittest.TestCase): self.assertRaises(NegativeStockError, sr3.submit) # teardown - frappe.db.set_value("Stock Settings", None, "allow_negative_stock", negative_stock_setting) sr3.cancel() dn2.cancel() pr1.cancel() + + @change_settings("Stock Settings", {"allow_negative_stock": 0}) + def test_backdated_stock_reco_cancellation_future_negative_stock(self): + """ + Test if a backdated stock reco cancellation that causes future negative stock is blocked. + ------------------------------------------- + Var | Doc | Qty | Balance + ------------------------------------------- + SR | Reco | 100 | 100 (posting date: today-1) (shouldn't be cancelled after DN) + DN | DN | 100 | 0 (posting date: today) + """ + from erpnext.stock.stock_ledger import NegativeStockError + from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note + frappe.db.commit() + + item_code = "Backdated-Reco-Cancellation-Item" + warehouse = "_Test Warehouse - _TC" + create_item(item_code) + + + sr = create_stock_reconciliation(item_code=item_code, warehouse=warehouse, qty=100, rate=100, + posting_date=add_days(nowdate(), -1)) + + dn = create_delivery_note(item_code=item_code, warehouse=warehouse, qty=100, rate=120, + posting_date=nowdate()) + + dn_balance = frappe.db.get_value("Stock Ledger Entry", {"voucher_no": dn.name, "is_cancelled": 0}, + "qty_after_transaction") + self.assertEqual(dn_balance, 0) + + # check if cancellation of stock reco is blocked + self.assertRaises(NegativeStockError, sr.cancel) + + repost_exists = bool(frappe.db.exists("Repost Item Valuation", {"voucher_no": sr.name})) + self.assertFalse(repost_exists, msg="Negative stock validation not working on reco cancellation") + + # teardown + frappe.db.rollback() + + def test_valid_batch(self): create_batch_item_with_batch("Testing Batch Item 1", "001") create_batch_item_with_batch("Testing Batch Item 2", "002") diff --git a/erpnext/stock/doctype/stock_settings/test_stock_settings.js b/erpnext/stock/doctype/stock_settings/test_stock_settings.js deleted file mode 100644 index 57d9fc61aab..00000000000 --- a/erpnext/stock/doctype/stock_settings/test_stock_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Stock Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Stock Settings - () => frappe.tests.make('Stock Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/uom_category/test_uom_category.js b/erpnext/stock/doctype/uom_category/test_uom_category.js deleted file mode 100644 index 4b5972ea716..00000000000 --- a/erpnext/stock/doctype/uom_category/test_uom_category.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: UOM Category", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new UOM Category - () => frappe.tests.make('UOM Category', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/doctype/variant_field/test_variant_field.js b/erpnext/stock/doctype/variant_field/test_variant_field.js deleted file mode 100644 index 2600a10fe0d..00000000000 --- a/erpnext/stock/doctype/variant_field/test_variant_field.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Variant Field", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Variant Field - () => frappe.tests.make('Variant Field', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py index 623dc2ffd97..8a9f0a5e583 100644 --- a/erpnext/stock/report/stock_ageing/stock_ageing.py +++ b/erpnext/stock/report/stock_ageing/stock_ageing.py @@ -26,7 +26,7 @@ def execute(filters=None): average_age = get_average_age(fifo_queue, to_date) earliest_age = date_diff(to_date, fifo_queue[0][1]) latest_age = date_diff(to_date, fifo_queue[-1][1]) - range1, range2, range3, above_range3 = get_range_age(filters, fifo_queue, to_date) + range1, range2, range3, above_range3 = get_range_age(filters, fifo_queue, to_date, item_dict) row = [details.name, details.item_name, details.description, details.item_group, details.brand] @@ -58,19 +58,21 @@ def get_average_age(fifo_queue, to_date): return flt(age_qty / total_qty, 2) if total_qty else 0.0 -def get_range_age(filters, fifo_queue, to_date): +def get_range_age(filters, fifo_queue, to_date, item_dict): range1 = range2 = range3 = above_range3 = 0.0 + for item in fifo_queue: age = date_diff(to_date, item[1]) + qty = flt(item[0]) if not item_dict["has_serial_no"] else 1.0 if age <= filters.range1: - range1 += flt(item[0]) + range1 += qty elif age <= filters.range2: - range2 += flt(item[0]) + range2 += qty elif age <= filters.range3: - range3 += flt(item[0]) + range3 += qty else: - above_range3 += flt(item[0]) + above_range3 += qty return range1, range2, range3, above_range3 @@ -197,9 +199,7 @@ def get_fifo_queue(filters, sle=None): fifo_queue.append([d.actual_qty, d.posting_date]) else: if serial_no_list: - for serial_no in fifo_queue: - if serial_no[0] in serial_no_list: - fifo_queue.remove(serial_no) + fifo_queue[:] = [serial_no for serial_no in fifo_queue if serial_no[0] not in serial_no_list] else: qty_to_pop = abs(d.actual_qty) while qty_to_pop: @@ -222,14 +222,16 @@ def get_fifo_queue(filters, sle=None): else: item_details[key]["total_qty"] += d.actual_qty + item_details[key]["has_serial_no"] = d.has_serial_no + return item_details def get_stock_ledger_entries(filters): return frappe.db.sql("""select - item.name, item.item_name, item_group, brand, description, item.stock_uom, + item.name, item.item_name, item_group, brand, description, item.stock_uom, item.has_serial_no, actual_qty, posting_date, voucher_type, voucher_no, serial_no, batch_no, qty_after_transaction, warehouse from `tabStock Ledger Entry` sle, - (select name, item_name, description, stock_uom, brand, item_group + (select name, item_name, description, stock_uom, brand, item_group, has_serial_no from `tabItem` {item_conditions}) item where item_code = item.name and company = %(company)s and diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index b09b663c254..afd3ab2b5ae 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -947,7 +947,7 @@ def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no, return valuation_rate -def update_qty_in_future_sle(args, allow_negative_stock=None): +def update_qty_in_future_sle(args, allow_negative_stock=False): """Recalculate Qty after Transaction in future SLEs based on current SLE.""" datetime_limit_condition = "" qty_shift = args.actual_qty @@ -1036,8 +1036,8 @@ def get_datetime_limit_condition(detail): ) )""" -def validate_negative_qty_in_future_sle(args, allow_negative_stock=None): - allow_negative_stock = allow_negative_stock \ +def validate_negative_qty_in_future_sle(args, allow_negative_stock=False): + allow_negative_stock = cint(allow_negative_stock) \ or cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock")) if (args.actual_qty < 0 or args.voucher_type == "Stock Reconciliation") and not allow_negative_stock: diff --git a/erpnext/support/doctype/support_settings/test_support_settings.js b/erpnext/support/doctype/support_settings/test_support_settings.js deleted file mode 100644 index 0787306c3ea..00000000000 --- a/erpnext/support/doctype/support_settings/test_support_settings.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Support Settings", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Support Settings - () => frappe.tests.make('Support Settings', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -});