Merge branch 'develop' into ordered-qty-for-packed-items
This commit is contained in:
commit
89f87cee87
@ -120,6 +120,7 @@ def get_booking_dates(doc, item, posting_date=None):
|
||||
prev_gl_entry = frappe.db.sql('''
|
||||
select name, posting_date from `tabGL Entry` where company=%s and account=%s and
|
||||
voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
|
||||
and is_cancelled = 0
|
||||
order by posting_date desc limit 1
|
||||
''', (doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
||||
|
||||
@ -227,6 +228,7 @@ def get_already_booked_amount(doc, item):
|
||||
gl_entries_details = frappe.db.sql('''
|
||||
select sum({0}) as total_credit, sum({1}) as total_credit_in_account_currency, voucher_detail_no
|
||||
from `tabGL Entry` where company=%s and account=%s and voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
|
||||
and is_cancelled = 0
|
||||
group by voucher_detail_no
|
||||
'''.format(total_credit_debit, total_credit_debit_currency),
|
||||
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
||||
@ -282,7 +284,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
|
||||
return
|
||||
|
||||
# check if books nor frozen till endate:
|
||||
if getdate(end_date) >= getdate(accounts_frozen_upto):
|
||||
if accounts_frozen_upto and (end_date) <= getdate(accounts_frozen_upto):
|
||||
end_date = get_last_day(add_days(accounts_frozen_upto, 1))
|
||||
|
||||
if via_journal_entry:
|
||||
|
@ -2,6 +2,7 @@
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
|
||||
create_dimension,
|
||||
@ -10,11 +11,10 @@ from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension imp
|
||||
from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_creation_tool import (
|
||||
get_temporary_opening_account,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ["Customer", "Supplier", "Accounting Dimension"]
|
||||
|
||||
class TestOpeningInvoiceCreationTool(ERPNextTestCase):
|
||||
class TestOpeningInvoiceCreationTool(FrappeTestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
|
||||
|
@ -194,8 +194,14 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
||||
|
||||
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
|
||||
frm.toggle_display("base_total_taxes_and_charges", frm.doc.total_taxes_and_charges &&
|
||||
(frm.doc.paid_from_account_currency != company_currency));
|
||||
|
||||
if (frm.doc.payment_type == "Pay") {
|
||||
frm.toggle_display("base_total_taxes_and_charges", frm.doc.total_taxes_and_charges &&
|
||||
(frm.doc.paid_to_account_currency != company_currency));
|
||||
} else {
|
||||
frm.toggle_display("base_total_taxes_and_charges", frm.doc.total_taxes_and_charges &&
|
||||
(frm.doc.paid_from_account_currency != company_currency));
|
||||
}
|
||||
|
||||
frm.toggle_display("base_received_amount", (
|
||||
frm.doc.paid_to_account_currency != company_currency
|
||||
@ -230,7 +236,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
|
||||
|
||||
frm.set_currency_labels(["base_paid_amount", "base_received_amount", "base_total_allocated_amount",
|
||||
"difference_amount", "base_paid_amount_after_tax", "base_received_amount_after_tax"], company_currency);
|
||||
"difference_amount", "base_paid_amount_after_tax", "base_received_amount_after_tax",
|
||||
"base_total_taxes_and_charges"], company_currency);
|
||||
|
||||
frm.set_currency_labels(["paid_amount"], frm.doc.paid_from_account_currency);
|
||||
frm.set_currency_labels(["received_amount"], frm.doc.paid_to_account_currency);
|
||||
|
@ -66,7 +66,9 @@
|
||||
"tax_withholding_category",
|
||||
"section_break_56",
|
||||
"taxes",
|
||||
"section_break_60",
|
||||
"base_total_taxes_and_charges",
|
||||
"column_break_61",
|
||||
"total_taxes_and_charges",
|
||||
"deductions_or_loss_section",
|
||||
"deductions",
|
||||
@ -715,12 +717,21 @@
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Paid To Account Type"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_61",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_60",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_border": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-11-24 18:58:24.919764",
|
||||
"modified": "2022-02-23 20:08:39.559814",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
@ -763,6 +774,7 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"title_field": "title",
|
||||
"track_changes": 1
|
||||
}
|
@ -934,8 +934,12 @@ class PaymentEntry(AccountsController):
|
||||
|
||||
tax.base_total = tax.total * self.source_exchange_rate
|
||||
|
||||
self.total_taxes_and_charges += current_tax_amount
|
||||
self.base_total_taxes_and_charges += current_tax_amount * self.source_exchange_rate
|
||||
if self.payment_type == 'Pay':
|
||||
self.base_total_taxes_and_charges += flt(current_tax_amount / self.source_exchange_rate)
|
||||
self.total_taxes_and_charges += flt(current_tax_amount / self.target_exchange_rate)
|
||||
else:
|
||||
self.base_total_taxes_and_charges += flt(current_tax_amount / self.target_exchange_rate)
|
||||
self.total_taxes_and_charges += flt(current_tax_amount / self.source_exchange_rate)
|
||||
|
||||
if self.get('taxes'):
|
||||
self.paid_amount_after_tax = self.get('taxes')[-1].base_total
|
||||
|
@ -633,6 +633,45 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
self.assertEqual(flt(expected_party_balance), party_balance)
|
||||
self.assertEqual(flt(expected_party_account_balance), party_account_balance)
|
||||
|
||||
def test_multi_currency_payment_entry_with_taxes(self):
|
||||
payment_entry = create_payment_entry(party='_Test Supplier USD', paid_to = '_Test Payable USD - _TC',
|
||||
save=True)
|
||||
payment_entry.append('taxes', {
|
||||
'account_head': '_Test Account Service Tax - _TC',
|
||||
'charge_type': 'Actual',
|
||||
'tax_amount': 10,
|
||||
'add_deduct_tax': 'Add',
|
||||
'description': 'Test'
|
||||
})
|
||||
|
||||
payment_entry.save()
|
||||
self.assertEqual(payment_entry.base_total_taxes_and_charges, 10)
|
||||
self.assertEqual(flt(payment_entry.total_taxes_and_charges, 2), flt(10 / payment_entry.target_exchange_rate, 2))
|
||||
|
||||
def create_payment_entry(**args):
|
||||
payment_entry = frappe.new_doc('Payment Entry')
|
||||
payment_entry.company = args.get('company') or '_Test Company'
|
||||
payment_entry.payment_type = args.get('payment_type') or 'Pay'
|
||||
payment_entry.party_type = args.get('party_type') or 'Supplier'
|
||||
payment_entry.party = args.get('party') or '_Test Supplier'
|
||||
payment_entry.paid_from = args.get('paid_from') or '_Test Bank - _TC'
|
||||
payment_entry.paid_to = args.get('paid_to') or 'Creditors - _TC'
|
||||
payment_entry.paid_amount = args.get('paid_amount') or 1000
|
||||
|
||||
payment_entry.setup_party_account_field()
|
||||
payment_entry.set_missing_values()
|
||||
payment_entry.set_exchange_rate()
|
||||
payment_entry.received_amount = payment_entry.paid_amount / payment_entry.target_exchange_rate
|
||||
payment_entry.reference_no = 'Test001'
|
||||
payment_entry.reference_date = nowdate()
|
||||
|
||||
if args.get('save'):
|
||||
payment_entry.save()
|
||||
if args.get('submit'):
|
||||
payment_entry.submit()
|
||||
|
||||
return payment_entry
|
||||
|
||||
def create_payment_terms_template():
|
||||
|
||||
create_payment_term('Basic Amount Receivable')
|
||||
|
@ -73,7 +73,7 @@ def get_report_pdf(doc, consolidated=True):
|
||||
'to_date': doc.to_date,
|
||||
'company': doc.company,
|
||||
'finance_book': doc.finance_book if doc.finance_book else None,
|
||||
'account': doc.account if doc.account else None,
|
||||
'account': [doc.account] if doc.account else None,
|
||||
'party_type': 'Customer',
|
||||
'party': [entry.customer],
|
||||
'presentation_currency': presentation_currency,
|
||||
|
@ -1595,6 +1595,56 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
def test_rounding_adjustment_3(self):
|
||||
si = create_sales_invoice(do_not_save=True)
|
||||
si.items = []
|
||||
for d in [(1122, 2), (1122.01, 1), (1122.01, 1)]:
|
||||
si.append("items", {
|
||||
"item_code": "_Test Item",
|
||||
"gst_hsn_code": "999800",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"qty": d[1],
|
||||
"rate": d[0],
|
||||
"income_account": "Sales - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC"
|
||||
})
|
||||
for tax_account in ["_Test Account VAT - _TC", "_Test Account Service Tax - _TC"]:
|
||||
si.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": tax_account,
|
||||
"description": tax_account,
|
||||
"rate": 6,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"included_in_print_rate": 1
|
||||
})
|
||||
si.save()
|
||||
si.submit()
|
||||
self.assertEqual(si.net_total, 4007.16)
|
||||
self.assertEqual(si.grand_total, 4488.02)
|
||||
self.assertEqual(si.total_taxes_and_charges, 480.86)
|
||||
self.assertEqual(si.rounding_adjustment, -0.02)
|
||||
|
||||
expected_values = dict((d[0], d) for d in [
|
||||
[si.debit_to, 4488.0, 0.0],
|
||||
["_Test Account Service Tax - _TC", 0.0, 240.43],
|
||||
["_Test Account VAT - _TC", 0.0, 240.43],
|
||||
["Sales - _TC", 0.0, 4007.15],
|
||||
["Round Off - _TC", 0.01, 0]
|
||||
])
|
||||
|
||||
gl_entries = frappe.db.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
||||
order by account asc""", si.name, as_dict=1)
|
||||
|
||||
debit_credit_diff = 0
|
||||
for gle in gl_entries:
|
||||
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||
debit_credit_diff += (gle.debit - gle.credit)
|
||||
|
||||
self.assertEqual(debit_credit_diff, 0)
|
||||
|
||||
def test_sales_invoice_with_shipping_rule(self):
|
||||
from erpnext.accounts.doctype.shipping_rule.test_shipping_rule import create_shipping_rule
|
||||
|
||||
@ -2429,14 +2479,22 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
|
||||
def test_sales_commission(self):
|
||||
si = frappe.copy_doc(test_records[0])
|
||||
si = frappe.copy_doc(test_records[2])
|
||||
|
||||
frappe.db.set_value('Item', si.get('items')[0].item_code, 'grant_commission', 1)
|
||||
frappe.db.set_value('Item', si.get('items')[1].item_code, 'grant_commission', 0)
|
||||
|
||||
item = copy.deepcopy(si.get('items')[0])
|
||||
item.update({
|
||||
"qty": 1,
|
||||
"rate": 500,
|
||||
"grant_commission": 1
|
||||
})
|
||||
si.append("items", item)
|
||||
|
||||
item = copy.deepcopy(si.get('items')[1])
|
||||
item.update({
|
||||
"qty": 1,
|
||||
"rate": 500,
|
||||
})
|
||||
|
||||
# Test valid values
|
||||
for commission_rate, total_commission in ((0, 0), (10, 50), (100, 500)):
|
||||
|
@ -832,6 +832,7 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fetch_from": "item_code.grant_commission",
|
||||
"fieldname": "grant_commission",
|
||||
"fieldtype": "Check",
|
||||
"label": "Grant Commission",
|
||||
@ -841,7 +842,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-10-05 12:24:54.968907",
|
||||
"modified": "2022-02-24 14:41:36.392560",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
@ -849,5 +850,6 @@
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
}
|
@ -55,5 +55,8 @@ def validate_disabled(doc):
|
||||
frappe.throw(_("Disabled template must not be default template"))
|
||||
|
||||
def validate_for_tax_category(doc):
|
||||
if not doc.tax_category:
|
||||
return
|
||||
|
||||
if frappe.db.exists(doc.doctype, {"company": doc.company, "tax_category": doc.tax_category, "disabled": 0, "name": ["!=", doc.name]}):
|
||||
frappe.throw(_("A template with tax category {0} already exists. Only one template is allowed with each tax category").format(frappe.bold(doc.tax_category)))
|
||||
|
@ -274,7 +274,7 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision):
|
||||
debit_credit_diff += flt(d.credit)
|
||||
round_off_account_exists = True
|
||||
|
||||
if round_off_account_exists and abs(debit_credit_diff) <= (1.0 / (10**precision)):
|
||||
if round_off_account_exists and abs(debit_credit_diff) < (1.0 / (10**precision)):
|
||||
gl_map.remove(round_off_gle)
|
||||
return
|
||||
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_days, flt, getdate, nowdate
|
||||
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||
@ -27,7 +27,7 @@ from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
class TestPurchaseOrder(unittest.TestCase):
|
||||
class TestPurchaseOrder(FrappeTestCase):
|
||||
def test_make_purchase_receipt(self):
|
||||
po = create_purchase_order(do_not_submit=True)
|
||||
self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name)
|
||||
|
@ -1,9 +1,9 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import nowdate
|
||||
|
||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
||||
@ -16,7 +16,7 @@ from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||
|
||||
|
||||
class TestRequestforQuotation(unittest.TestCase):
|
||||
class TestRequestforQuotation(FrappeTestCase):
|
||||
def test_quote_status(self):
|
||||
rfq = make_request_for_quotation()
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
@ -12,8 +11,10 @@ from erpnext.exceptions import PartyDisabled
|
||||
test_dependencies = ['Payment Term', 'Payment Terms Template']
|
||||
test_records = frappe.get_test_records('Supplier')
|
||||
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
class TestSupplier(unittest.TestCase):
|
||||
|
||||
class TestSupplier(FrappeTestCase):
|
||||
def test_get_supplier_group_details(self):
|
||||
doc = frappe.new_doc("Supplier Group")
|
||||
doc.supplier_group_name = "_Testing Supplier Group"
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestPurchaseOrder(unittest.TestCase):
|
||||
class TestPurchaseOrder(FrappeTestCase):
|
||||
def test_make_purchase_order(self):
|
||||
from erpnext.buying.doctype.supplier_quotation.supplier_quotation import make_purchase_order
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestSupplierScorecard(unittest.TestCase):
|
||||
class TestSupplierScorecard(FrappeTestCase):
|
||||
|
||||
def test_create_scorecard(self):
|
||||
doc = make_supplier_scorecard().insert()
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestSupplierScorecardCriteria(unittest.TestCase):
|
||||
class TestSupplierScorecardCriteria(FrappeTestCase):
|
||||
def test_variables_exist(self):
|
||||
delete_test_scorecards()
|
||||
for d in test_good_criteria:
|
||||
|
@ -1,16 +1,16 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable import (
|
||||
VariablePathNotFound,
|
||||
)
|
||||
|
||||
|
||||
class TestSupplierScorecardVariable(unittest.TestCase):
|
||||
class TestSupplierScorecardVariable(FrappeTestCase):
|
||||
def test_variable_exist(self):
|
||||
for d in test_existing_variables:
|
||||
my_doc = frappe.get_doc("Supplier Scorecard Variable", d.get("name"))
|
||||
|
@ -2,10 +2,10 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
||||
from erpnext.buying.report.procurement_tracker.procurement_tracker import execute
|
||||
@ -14,7 +14,7 @@ from erpnext.stock.doctype.material_request.test_material_request import make_ma
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
|
||||
|
||||
class TestProcurementTracker(unittest.TestCase):
|
||||
class TestProcurementTracker(FrappeTestCase):
|
||||
def test_result_for_procurement_tracker(self):
|
||||
filters = {
|
||||
'company': '_Test Procurement Company',
|
||||
|
@ -3,9 +3,9 @@
|
||||
# Compiled at: 2019-05-06 09:51:46
|
||||
# Decompiled by https://python-decompiler.com
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
@ -15,7 +15,7 @@ from erpnext.buying.report.subcontracted_item_to_be_received.subcontracted_item_
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
class TestSubcontractedItemToBeReceived(unittest.TestCase):
|
||||
class TestSubcontractedItemToBeReceived(FrappeTestCase):
|
||||
|
||||
def test_pending_and_received_qty(self):
|
||||
po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes')
|
||||
|
@ -4,9 +4,9 @@
|
||||
# Decompiled by https://python-decompiler.com
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_rm_stock_entry
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
@ -16,7 +16,7 @@ from erpnext.buying.report.subcontracted_raw_materials_to_be_transferred.subcont
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
class TestSubcontractedItemToBeTransferred(unittest.TestCase):
|
||||
class TestSubcontractedItemToBeTransferred(FrappeTestCase):
|
||||
|
||||
def test_pending_and_transferred_qty(self):
|
||||
po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes', supplier_warehouse="_Test Warehouse 1 - _TC")
|
||||
|
@ -363,8 +363,6 @@ class Subcontracting():
|
||||
return
|
||||
|
||||
for row in self.get(self.raw_material_table):
|
||||
self.__validate_consumed_qty(row)
|
||||
|
||||
key = (row.rm_item_code, row.main_item_code, row.purchase_order)
|
||||
if not self.__transferred_items or not self.__transferred_items.get(key):
|
||||
return
|
||||
@ -372,12 +370,6 @@ class Subcontracting():
|
||||
self.__validate_batch_no(row, key)
|
||||
self.__validate_serial_no(row, key)
|
||||
|
||||
def __validate_consumed_qty(self, row):
|
||||
if self.backflush_based_on != 'BOM' and flt(row.consumed_qty) == 0.0:
|
||||
msg = f'Row {row.idx}: the consumed qty cannot be zero for the item {frappe.bold(row.rm_item_code)}'
|
||||
|
||||
frappe.throw(_(msg),title=_('Consumed Items Qty Check'))
|
||||
|
||||
def __validate_batch_no(self, row, key):
|
||||
if row.get('batch_no') and row.get('batch_no') not in self.__transferred_items.get(key).get('batch_no'):
|
||||
link = get_link_to_form('Purchase Order', row.purchase_order)
|
||||
|
@ -5,6 +5,7 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import change_settings
|
||||
from frappe.utils import add_months, nowdate
|
||||
|
||||
from erpnext.accounts.doctype.tax_rule.tax_rule import ConflictingTaxRule
|
||||
@ -15,7 +16,7 @@ from erpnext.e_commerce.shopping_cart.cart import (
|
||||
get_party,
|
||||
update_cart,
|
||||
)
|
||||
from erpnext.tests.utils import change_settings, create_test_contact_and_address
|
||||
from erpnext.tests.utils import create_test_contact_and_address
|
||||
|
||||
# test_dependencies = ['Payment Terms Template']
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.controllers.item_variant import create_variant
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import (
|
||||
@ -7,11 +8,10 @@ from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings imp
|
||||
from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
|
||||
from erpnext.e_commerce.variant_selector.utils import get_next_attribute_and_values
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ["Item"]
|
||||
|
||||
class TestVariantSelector(ERPNextTestCase):
|
||||
class TestVariantSelector(FrappeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@ -116,4 +116,4 @@ class TestVariantSelector(ERPNextTestCase):
|
||||
self.assertEqual(next_values["exact_match"][0],"Test-Tshirt-Temp-S-R")
|
||||
self.assertEqual(next_values["exact_match"][0],"Test-Tshirt-Temp-S-R")
|
||||
self.assertEqual(price_info["price_list_rate"], 100.0)
|
||||
self.assertEqual(price_info["formatted_price_sales_uom"], "₹ 100.00")
|
||||
self.assertEqual(price_info["formatted_price_sales_uom"], "₹ 100.00")
|
||||
|
@ -2,7 +2,7 @@
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2017-10-09 14:26:29.612365",
|
||||
"creation": "2022-01-17 18:36:51.450395",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
@ -121,7 +121,7 @@
|
||||
"fieldtype": "Select",
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"options": "Draft\nPaid\nUnpaid\nClaimed\nCancelled",
|
||||
"options": "Draft\nPaid\nUnpaid\nClaimed\nReturned\nPartly Claimed and Returned\nCancelled",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
@ -200,7 +200,7 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-09-11 18:38:38.617478",
|
||||
"modified": "2022-01-17 19:33:52.345823",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Employee Advance",
|
||||
@ -237,5 +237,41 @@
|
||||
"search_fields": "employee,employee_name",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [
|
||||
{
|
||||
"color": "Red",
|
||||
"custom": 1,
|
||||
"title": "Draft"
|
||||
},
|
||||
{
|
||||
"color": "Green",
|
||||
"custom": 1,
|
||||
"title": "Paid"
|
||||
},
|
||||
{
|
||||
"color": "Orange",
|
||||
"custom": 1,
|
||||
"title": "Unpaid"
|
||||
},
|
||||
{
|
||||
"color": "Blue",
|
||||
"custom": 1,
|
||||
"title": "Claimed"
|
||||
},
|
||||
{
|
||||
"color": "Gray",
|
||||
"title": "Returned"
|
||||
},
|
||||
{
|
||||
"color": "Yellow",
|
||||
"title": "Partly Claimed and Returned"
|
||||
},
|
||||
{
|
||||
"color": "Red",
|
||||
"custom": 1,
|
||||
"title": "Cancelled"
|
||||
}
|
||||
],
|
||||
"title_field": "employee_name",
|
||||
"track_changes": 1
|
||||
}
|
@ -27,19 +27,33 @@ class EmployeeAdvance(Document):
|
||||
|
||||
def on_cancel(self):
|
||||
self.ignore_linked_doctypes = ('GL Entry')
|
||||
self.set_status(update=True)
|
||||
|
||||
def set_status(self, update=False):
|
||||
precision = self.precision("paid_amount")
|
||||
total_amount = flt(flt(self.claimed_amount) + flt(self.return_amount), precision)
|
||||
status = None
|
||||
|
||||
def set_status(self):
|
||||
if self.docstatus == 0:
|
||||
self.status = "Draft"
|
||||
if self.docstatus == 1:
|
||||
if self.claimed_amount and flt(self.claimed_amount) == flt(self.paid_amount):
|
||||
self.status = "Claimed"
|
||||
elif self.paid_amount and self.advance_amount == flt(self.paid_amount):
|
||||
self.status = "Paid"
|
||||
status = "Draft"
|
||||
elif self.docstatus == 1:
|
||||
if flt(self.claimed_amount) > 0 and flt(self.claimed_amount, precision) == flt(self.paid_amount, precision):
|
||||
status = "Claimed"
|
||||
elif flt(self.return_amount) > 0 and flt(self.return_amount, precision) == flt(self.paid_amount, precision):
|
||||
status = "Returned"
|
||||
elif flt(self.claimed_amount) > 0 and (flt(self.return_amount) > 0) and total_amount == flt(self.paid_amount, precision):
|
||||
status = "Partly Claimed and Returned"
|
||||
elif flt(self.paid_amount) > 0 and flt(self.advance_amount, precision) == flt(self.paid_amount, precision):
|
||||
status = "Paid"
|
||||
else:
|
||||
self.status = "Unpaid"
|
||||
status = "Unpaid"
|
||||
elif self.docstatus == 2:
|
||||
self.status = "Cancelled"
|
||||
status = "Cancelled"
|
||||
|
||||
if update:
|
||||
self.db_set("status", status)
|
||||
else:
|
||||
self.status = status
|
||||
|
||||
def set_total_advance_paid(self):
|
||||
gle = frappe.qb.DocType("GL Entry")
|
||||
@ -85,9 +99,7 @@ class EmployeeAdvance(Document):
|
||||
|
||||
self.db_set("paid_amount", paid_amount)
|
||||
self.db_set("return_amount", return_amount)
|
||||
self.set_status()
|
||||
frappe.db.set_value("Employee Advance", self.name , "status", self.status)
|
||||
|
||||
self.set_status(update=True)
|
||||
|
||||
def update_claimed_amount(self):
|
||||
claimed_amount = frappe.db.sql("""
|
||||
@ -103,8 +115,8 @@ class EmployeeAdvance(Document):
|
||||
|
||||
frappe.db.set_value("Employee Advance", self.name, "claimed_amount", flt(claimed_amount))
|
||||
self.reload()
|
||||
self.set_status()
|
||||
frappe.db.set_value("Employee Advance", self.name, "status", self.status)
|
||||
self.set_status(update=True)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_pending_amount(employee, posting_date):
|
||||
@ -222,7 +234,8 @@ def make_return_entry(employee, company, employee_advance_name, return_amount,
|
||||
'reference_name': employee_advance_name,
|
||||
'party_type': 'Employee',
|
||||
'party': employee,
|
||||
'is_advance': 'Yes'
|
||||
'is_advance': 'Yes',
|
||||
'cost_center': erpnext.get_default_cost_center(company)
|
||||
})
|
||||
|
||||
bank_amount = flt(return_amount) if bank_cash_account.account_currency==currency \
|
||||
@ -233,7 +246,8 @@ def make_return_entry(employee, company, employee_advance_name, return_amount,
|
||||
"debit_in_account_currency": bank_amount,
|
||||
"account_currency": bank_cash_account.account_currency,
|
||||
"account_type": bank_cash_account.account_type,
|
||||
"exchange_rate": flt(exchange_rate) if bank_cash_account.account_currency == currency else 1
|
||||
"exchange_rate": flt(exchange_rate) if bank_cash_account.account_currency == currency else 1,
|
||||
"cost_center": erpnext.get_default_cost_center(company)
|
||||
})
|
||||
|
||||
return je.as_dict()
|
||||
|
@ -4,7 +4,7 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.utils import nowdate
|
||||
from frappe.utils import flt, nowdate
|
||||
|
||||
import erpnext
|
||||
from erpnext.hr.doctype.employee.test_employee import make_employee
|
||||
@ -12,12 +12,21 @@ from erpnext.hr.doctype.employee_advance.employee_advance import (
|
||||
EmployeeAdvanceOverPayment,
|
||||
create_return_through_additional_salary,
|
||||
make_bank_entry,
|
||||
make_return_entry,
|
||||
)
|
||||
from erpnext.hr.doctype.expense_claim.expense_claim import get_advances
|
||||
from erpnext.hr.doctype.expense_claim.test_expense_claim import (
|
||||
get_payable_account,
|
||||
make_expense_claim,
|
||||
)
|
||||
from erpnext.payroll.doctype.salary_component.test_salary_component import create_salary_component
|
||||
from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
|
||||
|
||||
|
||||
class TestEmployeeAdvance(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.db.delete("Employee Advance")
|
||||
|
||||
def test_paid_amount_and_status(self):
|
||||
employee_name = make_employee("_T@employe.advance")
|
||||
advance = make_employee_advance(employee_name)
|
||||
@ -52,9 +61,102 @@ class TestEmployeeAdvance(unittest.TestCase):
|
||||
self.assertEqual(advance.paid_amount, 0)
|
||||
self.assertEqual(advance.status, "Unpaid")
|
||||
|
||||
advance.cancel()
|
||||
advance.reload()
|
||||
self.assertEqual(advance.status, "Cancelled")
|
||||
|
||||
def test_claimed_status(self):
|
||||
# CLAIMED Status check, full amount claimed
|
||||
payable_account = get_payable_account("_Test Company")
|
||||
claim = make_expense_claim(payable_account, 1000, 1000, "_Test Company", "Travel Expenses - _TC", do_not_submit=True)
|
||||
|
||||
advance = make_employee_advance(claim.employee)
|
||||
pe = make_payment_entry(advance)
|
||||
pe.submit()
|
||||
|
||||
claim = get_advances_for_claim(claim, advance.name)
|
||||
claim.save()
|
||||
claim.submit()
|
||||
|
||||
advance.reload()
|
||||
self.assertEqual(advance.claimed_amount, 1000)
|
||||
self.assertEqual(advance.status, "Claimed")
|
||||
|
||||
# advance should not be shown in claims
|
||||
advances = get_advances(claim.employee)
|
||||
advances = [entry.name for entry in advances]
|
||||
self.assertTrue(advance.name not in advances)
|
||||
|
||||
# cancel claim; status should be Paid
|
||||
claim.cancel()
|
||||
advance.reload()
|
||||
self.assertEqual(advance.claimed_amount, 0)
|
||||
self.assertEqual(advance.status, "Paid")
|
||||
|
||||
def test_partly_claimed_and_returned_status(self):
|
||||
payable_account = get_payable_account("_Test Company")
|
||||
claim = make_expense_claim(payable_account, 1000, 1000, "_Test Company", "Travel Expenses - _TC", do_not_submit=True)
|
||||
|
||||
advance = make_employee_advance(claim.employee)
|
||||
pe = make_payment_entry(advance)
|
||||
pe.submit()
|
||||
|
||||
# PARTLY CLAIMED AND RETURNED status check
|
||||
# 500 Claimed, 500 Returned
|
||||
claim = make_expense_claim(payable_account, 500, 500, "_Test Company", "Travel Expenses - _TC", do_not_submit=True)
|
||||
|
||||
advance = make_employee_advance(claim.employee)
|
||||
pe = make_payment_entry(advance)
|
||||
pe.submit()
|
||||
|
||||
claim = get_advances_for_claim(claim, advance.name, amount=500)
|
||||
claim.save()
|
||||
claim.submit()
|
||||
|
||||
advance.reload()
|
||||
self.assertEqual(advance.claimed_amount, 500)
|
||||
self.assertEqual(advance.status, "Paid")
|
||||
|
||||
entry = make_return_entry(
|
||||
employee=advance.employee,
|
||||
company=advance.company,
|
||||
employee_advance_name=advance.name,
|
||||
return_amount=flt(advance.paid_amount - advance.claimed_amount),
|
||||
advance_account=advance.advance_account,
|
||||
mode_of_payment=advance.mode_of_payment,
|
||||
currency=advance.currency,
|
||||
exchange_rate=advance.exchange_rate
|
||||
)
|
||||
|
||||
entry = frappe.get_doc(entry)
|
||||
entry.insert()
|
||||
entry.submit()
|
||||
|
||||
advance.reload()
|
||||
self.assertEqual(advance.return_amount, 500)
|
||||
self.assertEqual(advance.status, "Partly Claimed and Returned")
|
||||
|
||||
# advance should not be shown in claims
|
||||
advances = get_advances(claim.employee)
|
||||
advances = [entry.name for entry in advances]
|
||||
self.assertTrue(advance.name not in advances)
|
||||
|
||||
# Cancel return entry; status should change to PAID
|
||||
entry.cancel()
|
||||
advance.reload()
|
||||
self.assertEqual(advance.return_amount, 0)
|
||||
self.assertEqual(advance.status, "Paid")
|
||||
|
||||
# advance should be shown in claims
|
||||
advances = get_advances(claim.employee)
|
||||
advances = [entry.name for entry in advances]
|
||||
self.assertTrue(advance.name in advances)
|
||||
|
||||
def test_repay_unclaimed_amount_from_salary(self):
|
||||
employee_name = make_employee("_T@employe.advance")
|
||||
advance = make_employee_advance(employee_name, {"repay_unclaimed_amount_from_salary": 1})
|
||||
pe = make_payment_entry(advance)
|
||||
pe.submit()
|
||||
|
||||
args = {"type": "Deduction"}
|
||||
create_salary_component("Advance Salary - Deduction", **args)
|
||||
@ -82,11 +184,13 @@ class TestEmployeeAdvance(unittest.TestCase):
|
||||
|
||||
advance.reload()
|
||||
self.assertEqual(advance.return_amount, 1000)
|
||||
self.assertEqual(advance.status, "Returned")
|
||||
|
||||
# update advance return amount on additional salary cancellation
|
||||
additional_salary.cancel()
|
||||
advance.reload()
|
||||
self.assertEqual(advance.return_amount, 700)
|
||||
self.assertEqual(advance.status, "Paid")
|
||||
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
@ -118,3 +222,24 @@ def make_employee_advance(employee_name, args=None):
|
||||
doc.submit()
|
||||
|
||||
return doc
|
||||
|
||||
|
||||
def get_advances_for_claim(claim, advance_name, amount=None):
|
||||
advances = get_advances(claim.employee, advance_name)
|
||||
|
||||
for entry in advances:
|
||||
if amount:
|
||||
allocated_amount = amount
|
||||
else:
|
||||
allocated_amount = flt(entry.paid_amount) - flt(entry.claimed_amount)
|
||||
|
||||
claim.append("advances", {
|
||||
"employee_advance": entry.name,
|
||||
"posting_date": entry.posting_date,
|
||||
"advance_account": entry.advance_account,
|
||||
"advance_paid": entry.paid_amount,
|
||||
"unclaimed_amount": allocated_amount,
|
||||
"allocated_amount": allocated_amount
|
||||
})
|
||||
|
||||
return claim
|
@ -171,7 +171,7 @@ frappe.ui.form.on("Expense Claim", {
|
||||
['docstatus', '=', 1],
|
||||
['employee', '=', frm.doc.employee],
|
||||
['paid_amount', '>', 0],
|
||||
['status', '!=', 'Claimed']
|
||||
['status', 'not in', ['Claimed', 'Returned', 'Partly Claimed and Returned']]
|
||||
]
|
||||
};
|
||||
});
|
||||
|
@ -23,10 +23,10 @@ class ExpenseClaim(AccountsController):
|
||||
|
||||
def validate(self):
|
||||
validate_active_employee(self.employee)
|
||||
self.validate_advances()
|
||||
set_employee_name(self)
|
||||
self.validate_sanctioned_amount()
|
||||
self.calculate_total_amount()
|
||||
set_employee_name(self)
|
||||
self.validate_advances()
|
||||
self.set_expense_account(validate=True)
|
||||
self.set_payable_account()
|
||||
self.set_cost_center()
|
||||
@ -341,18 +341,27 @@ def get_expense_claim_account(expense_claim_type, company):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_advances(employee, advance_id=None):
|
||||
if not advance_id:
|
||||
condition = 'docstatus=1 and employee={0} and paid_amount > 0 and paid_amount > claimed_amount + return_amount'.format(frappe.db.escape(employee))
|
||||
else:
|
||||
condition = 'name={0}'.format(frappe.db.escape(advance_id))
|
||||
advance = frappe.qb.DocType("Employee Advance")
|
||||
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
name, posting_date, paid_amount, claimed_amount, advance_account
|
||||
from
|
||||
`tabEmployee Advance`
|
||||
where {0}
|
||||
""".format(condition), as_dict=1)
|
||||
query = (
|
||||
frappe.qb.from_(advance)
|
||||
.select(
|
||||
advance.name, advance.posting_date, advance.paid_amount,
|
||||
advance.claimed_amount, advance.advance_account
|
||||
)
|
||||
)
|
||||
|
||||
if not advance_id:
|
||||
query = query.where(
|
||||
(advance.docstatus == 1)
|
||||
& (advance.employee == employee)
|
||||
& (advance.paid_amount > 0)
|
||||
& (advance.status.notin(["Claimed", "Returned", "Partly Claimed and Returned"]))
|
||||
)
|
||||
else:
|
||||
query = query.where(advance.name == advance_id)
|
||||
|
||||
return query.run(as_dict=True)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
@ -1,15 +1,15 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_months, today
|
||||
|
||||
from erpnext import get_company_currency
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
from .blanket_order import make_order
|
||||
|
||||
|
||||
class TestBlanketOrder(ERPNextTestCase):
|
||||
class TestBlanketOrder(FrappeTestCase):
|
||||
def setUp(self):
|
||||
frappe.flags.args = frappe._dict()
|
||||
|
||||
|
@ -918,7 +918,7 @@ def validate_bom_no(item, bom_no):
|
||||
frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_children(doctype, parent=None, is_root=False, **filters):
|
||||
def get_children(parent=None, is_root=False, **filters):
|
||||
if not parent or parent=="BOM":
|
||||
frappe.msgprint(_('Please select a BOM'))
|
||||
return
|
||||
|
@ -7,6 +7,7 @@ from functools import partial
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import cstr, flt
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
@ -17,11 +18,10 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import
|
||||
create_stock_reconciliation,
|
||||
)
|
||||
from erpnext.tests.test_subcontracting import set_backflush_based_on
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_records = frappe.get_test_records('BOM')
|
||||
|
||||
class TestBOM(ERPNextTestCase):
|
||||
class TestBOM(FrappeTestCase):
|
||||
def setUp(self):
|
||||
if not frappe.get_value('Item', '_Test Item'):
|
||||
make_test_records('Item')
|
||||
|
@ -2,15 +2,15 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool import update_cost
|
||||
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_records = frappe.get_test_records('BOM')
|
||||
|
||||
class TestBOMUpdateTool(ERPNextTestCase):
|
||||
class TestBOMUpdateTool(FrappeTestCase):
|
||||
def test_replace_bom(self):
|
||||
current_bom = "BOM-_Test Item Home Desktop Manufactured-001"
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import random_string
|
||||
|
||||
from erpnext.manufacturing.doctype.job_card.job_card import OperationMismatchError, OverlapError
|
||||
@ -11,10 +12,9 @@ from erpnext.manufacturing.doctype.job_card.job_card import (
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestJobCard(ERPNextTestCase):
|
||||
class TestJobCard(FrappeTestCase):
|
||||
def setUp(self):
|
||||
make_bom_for_jc_tests()
|
||||
|
||||
|
@ -49,7 +49,7 @@ frappe.ui.form.on('Production Plan', {
|
||||
if (d.item_code) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.bom",
|
||||
filters:{'item': cstr(d.item_code)}
|
||||
filters:{'item': cstr(d.item_code), 'docstatus': 1}
|
||||
}
|
||||
} else frappe.msgprint(__("Please enter Item first"));
|
||||
}
|
||||
@ -232,7 +232,7 @@ frappe.ui.form.on('Production Plan', {
|
||||
});
|
||||
},
|
||||
combine_items: function (frm) {
|
||||
frm.clear_table('prod_plan_references');
|
||||
frm.clear_table("prod_plan_references");
|
||||
|
||||
frappe.call({
|
||||
method: "get_items",
|
||||
@ -247,6 +247,13 @@ frappe.ui.form.on('Production Plan', {
|
||||
});
|
||||
},
|
||||
|
||||
combine_sub_items: (frm) => {
|
||||
if (frm.doc.sub_assembly_items.length > 0) {
|
||||
frm.clear_table("sub_assembly_items");
|
||||
frm.trigger("get_sub_assembly_items");
|
||||
}
|
||||
},
|
||||
|
||||
get_sub_assembly_items: function(frm) {
|
||||
frm.dirty();
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
"prod_plan_references",
|
||||
"section_break_24",
|
||||
"get_sub_assembly_items",
|
||||
"combine_sub_items",
|
||||
"sub_assembly_items",
|
||||
"material_request_planning",
|
||||
"include_non_stock_items",
|
||||
@ -340,7 +341,6 @@
|
||||
{
|
||||
"fieldname": "prod_plan_references",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 1,
|
||||
"label": "Production Plan Item Reference",
|
||||
"options": "Production Plan Item Reference"
|
||||
},
|
||||
@ -370,16 +370,23 @@
|
||||
"fieldname": "to_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Delivery Date"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "combine_sub_items",
|
||||
"fieldtype": "Check",
|
||||
"label": "Consolidate Sub Assembly Items"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-calendar",
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-09-06 18:35:59.642232",
|
||||
"modified": "2022-02-23 17:16:10.629378",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Plan",
|
||||
"naming_rule": "By \"Naming Series\" field",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
|
@ -21,7 +21,8 @@ from frappe.utils import (
|
||||
)
|
||||
from frappe.utils.csvutils import build_csv_response
|
||||
|
||||
from erpnext.manufacturing.doctype.bom.bom import get_children, validate_bom_no
|
||||
from erpnext.manufacturing.doctype.bom.bom import get_children as get_bom_children
|
||||
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
|
||||
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||
|
||||
@ -570,17 +571,28 @@ class ProductionPlan(Document):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_sub_assembly_items(self, manufacturing_type=None):
|
||||
"Fetch sub assembly items and optionally combine them."
|
||||
self.sub_assembly_items = []
|
||||
sub_assembly_items_store = [] # temporary store to process all subassembly items
|
||||
|
||||
for row in self.po_items:
|
||||
bom_data = []
|
||||
get_sub_assembly_items(row.bom_no, bom_data, row.planned_qty)
|
||||
self.set_sub_assembly_items_based_on_level(row, bom_data, manufacturing_type)
|
||||
sub_assembly_items_store.extend(bom_data)
|
||||
|
||||
self.sub_assembly_items.sort(key= lambda d: d.bom_level, reverse=True)
|
||||
for idx, row in enumerate(self.sub_assembly_items, start=1):
|
||||
row.idx = idx
|
||||
if self.combine_sub_items:
|
||||
# Combine subassembly items
|
||||
sub_assembly_items_store = self.combine_subassembly_items(sub_assembly_items_store)
|
||||
|
||||
sub_assembly_items_store.sort(key= lambda d: d.bom_level, reverse=True) # sort by bom level
|
||||
|
||||
for idx, row in enumerate(sub_assembly_items_store):
|
||||
row.idx = idx + 1
|
||||
self.append("sub_assembly_items", row)
|
||||
|
||||
def set_sub_assembly_items_based_on_level(self, row, bom_data, manufacturing_type=None):
|
||||
"Modify bom_data, set additional details."
|
||||
for data in bom_data:
|
||||
data.qty = data.stock_qty
|
||||
data.production_plan_item = row.name
|
||||
@ -589,7 +601,32 @@ class ProductionPlan(Document):
|
||||
data.type_of_manufacturing = manufacturing_type or ("Subcontract" if data.is_sub_contracted_item
|
||||
else "In House")
|
||||
|
||||
self.append("sub_assembly_items", data)
|
||||
def combine_subassembly_items(self, sub_assembly_items_store):
|
||||
"Aggregate if same: Item, Warehouse, Inhouse/Outhouse Manu.g, BOM No."
|
||||
key_wise_data = {}
|
||||
for row in sub_assembly_items_store:
|
||||
key = (
|
||||
row.get("production_item"), row.get("fg_warehouse"),
|
||||
row.get("bom_no"), row.get("type_of_manufacturing")
|
||||
)
|
||||
if key not in key_wise_data:
|
||||
# intialise (item, wh, bom no, man.g type) wise dict
|
||||
key_wise_data[key] = row
|
||||
continue
|
||||
|
||||
existing_row = key_wise_data[key]
|
||||
if existing_row:
|
||||
# if row with same (item, wh, bom no, man.g type) key, merge
|
||||
existing_row.qty += flt(row.qty)
|
||||
existing_row.stock_qty += flt(row.stock_qty)
|
||||
existing_row.bom_level = max(existing_row.bom_level, row.bom_level)
|
||||
continue
|
||||
else:
|
||||
# add row with key
|
||||
key_wise_data[key] = row
|
||||
|
||||
sub_assembly_items_store = [key_wise_data[key] for key in key_wise_data] # unpack into single level list
|
||||
return sub_assembly_items_store
|
||||
|
||||
def all_items_completed(self):
|
||||
all_items_produced = all(flt(d.planned_qty) - flt(d.produced_qty) < 0.000001
|
||||
@ -1031,7 +1068,7 @@ def get_item_data(item_code):
|
||||
}
|
||||
|
||||
def get_sub_assembly_items(bom_no, bom_data, to_produce_qty, indent=0):
|
||||
data = get_children('BOM', parent = bom_no)
|
||||
data = get_bom_children(parent=bom_no)
|
||||
for d in data:
|
||||
if d.expandable:
|
||||
parent_item_code = frappe.get_cached_value("BOM", bom_no, "item")
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_to_date, flt, now_datetime, nowdate
|
||||
|
||||
from erpnext.controllers.item_variant import create_variant
|
||||
@ -16,10 +17,9 @@ from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
|
||||
create_stock_reconciliation,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestProductionPlan(ERPNextTestCase):
|
||||
class TestProductionPlan(FrappeTestCase):
|
||||
def setUp(self):
|
||||
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
||||
'Raw Material Item 1', 'Raw Material Item 2']:
|
||||
@ -38,6 +38,9 @@ class TestProductionPlan(ERPNextTestCase):
|
||||
if not frappe.db.get_value('BOM', {'item': item}):
|
||||
make_bom(item = item, raw_materials = raw_materials)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
frappe.db.rollback()
|
||||
|
||||
def test_production_plan_mr_creation(self):
|
||||
"Test if MRs are created for unavailable raw materials."
|
||||
pln = create_production_plan(item_code='Test Production Item 1')
|
||||
@ -110,7 +113,7 @@ class TestProductionPlan(ERPNextTestCase):
|
||||
item_code='Test Production Item 1',
|
||||
ignore_existing_ordered_qty=1
|
||||
)
|
||||
self.assertTrue(len(pln.mr_items), 1)
|
||||
self.assertTrue(len(pln.mr_items))
|
||||
self.assertTrue(flt(pln.mr_items[0].quantity), 1.0)
|
||||
|
||||
sr1.cancel()
|
||||
@ -151,7 +154,7 @@ class TestProductionPlan(ERPNextTestCase):
|
||||
use_multi_level_bom=0,
|
||||
ignore_existing_ordered_qty=0
|
||||
)
|
||||
self.assertTrue(len(pln.mr_items), 0)
|
||||
self.assertFalse(len(pln.mr_items))
|
||||
|
||||
sr1.cancel()
|
||||
sr2.cancel()
|
||||
@ -258,6 +261,51 @@ class TestProductionPlan(ERPNextTestCase):
|
||||
pln.reload()
|
||||
pln.cancel()
|
||||
|
||||
def test_production_plan_combine_subassembly(self):
|
||||
"""
|
||||
Test combining Sub assembly items belonging to the same BOM in Prod Plan.
|
||||
1) Red-Car -> Wheel (sub assembly) > BOM-WHEEL-001
|
||||
2) Green-Car -> Wheel (sub assembly) > BOM-WHEEL-001
|
||||
"""
|
||||
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
||||
|
||||
bom_tree_1 = {
|
||||
"Red-Car": {"Wheel": {"Rubber": {}}}
|
||||
}
|
||||
bom_tree_2 = {
|
||||
"Green-Car": {"Wheel": {"Rubber": {}}}
|
||||
}
|
||||
|
||||
parent_bom_1 = create_nested_bom(bom_tree_1, prefix="")
|
||||
parent_bom_2 = create_nested_bom(bom_tree_2, prefix="")
|
||||
|
||||
# make sure both boms use same subassembly bom
|
||||
subassembly_bom = parent_bom_1.items[0].bom_no
|
||||
frappe.db.set_value("BOM Item", parent_bom_2.items[0].name, "bom_no", subassembly_bom)
|
||||
|
||||
plan = create_production_plan(item_code="Red-Car", use_multi_level_bom=1, do_not_save=True)
|
||||
plan.append("po_items", { # Add Green-Car to Prod Plan
|
||||
'use_multi_level_bom': 1,
|
||||
'item_code': "Green-Car",
|
||||
'bom_no': frappe.db.get_value('Item', "Green-Car", 'default_bom'),
|
||||
'planned_qty': 1,
|
||||
'planned_start_date': now_datetime()
|
||||
})
|
||||
plan.get_sub_assembly_items()
|
||||
self.assertTrue(len(plan.sub_assembly_items), 2)
|
||||
|
||||
plan.combine_sub_items = 1
|
||||
plan.get_sub_assembly_items()
|
||||
|
||||
self.assertTrue(len(plan.sub_assembly_items), 1) # check if sub-assembly items merged
|
||||
self.assertEqual(plan.sub_assembly_items[0].qty, 2.0)
|
||||
self.assertEqual(plan.sub_assembly_items[0].stock_qty, 2.0)
|
||||
|
||||
# change warehouse in one row, sub-assemblies should not merge
|
||||
plan.po_items[0].warehouse = "Finished Goods - _TC"
|
||||
plan.get_sub_assembly_items()
|
||||
self.assertTrue(len(plan.sub_assembly_items), 2)
|
||||
|
||||
def test_pp_to_mr_customer_provided(self):
|
||||
" Test Material Request from Production Plan for Customer Provided Item."
|
||||
create_item('CUST-0987', is_customer_provided_item = 1, customer = '_Test Customer', is_purchase_item = 0)
|
||||
@ -532,6 +580,7 @@ class TestProductionPlan(ERPNextTestCase):
|
||||
wip_warehouse='Work In Progress - _TC',
|
||||
fg_warehouse='Finished Goods - _TC',
|
||||
skip_transfer=1,
|
||||
use_multi_level_bom=1,
|
||||
do_not_submit=True
|
||||
)
|
||||
wo.production_plan = pln.name
|
||||
@ -576,6 +625,7 @@ class TestProductionPlan(ERPNextTestCase):
|
||||
wip_warehouse='Work In Progress - _TC',
|
||||
fg_warehouse='Finished Goods - _TC',
|
||||
skip_transfer=1,
|
||||
use_multi_level_bom=1,
|
||||
do_not_submit=True
|
||||
)
|
||||
wo.production_plan = pln.name
|
||||
|
@ -2,14 +2,14 @@
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.manufacturing.doctype.job_card.job_card import OperationSequenceError
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestRouting(ERPNextTestCase):
|
||||
class TestRouting(FrappeTestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.item_code = "Test Routing Item - A"
|
||||
|
@ -2,6 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase, timeout
|
||||
from frappe.utils import add_days, add_months, cint, flt, now, today
|
||||
|
||||
from erpnext.manufacturing.doctype.job_card.job_card import JobCardCancelError
|
||||
@ -21,10 +22,9 @@ from erpnext.stock.doctype.item.test_item import create_item, make_item
|
||||
from erpnext.stock.doctype.stock_entry import test_stock_entry
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
from erpnext.stock.utils import get_bin
|
||||
from erpnext.tests.utils import ERPNextTestCase, timeout
|
||||
|
||||
|
||||
class TestWorkOrder(ERPNextTestCase):
|
||||
class TestWorkOrder(FrappeTestCase):
|
||||
def setUp(self):
|
||||
self.warehouse = '_Test Warehouse 2 - _TC'
|
||||
self.item = '_Test Item'
|
||||
@ -1040,7 +1040,7 @@ def make_wo_order_test_record(**args):
|
||||
wo_order.scrap_warehouse = args.fg_warehouse or "_Test Scrap Warehouse - _TC"
|
||||
wo_order.company = args.company or "_Test Company"
|
||||
wo_order.stock_uom = args.stock_uom or "_Test UOM"
|
||||
wo_order.use_multi_level_bom=0
|
||||
wo_order.use_multi_level_bom= args.use_multi_level_bom or 0
|
||||
wo_order.skip_transfer=args.skip_transfer or 0
|
||||
wo_order.get_items_and_operations_from_bom()
|
||||
wo_order.sales_order = args.sales_order or None
|
||||
|
@ -854,7 +854,7 @@ def get_item_details(item, project = None, skip_bom_info=False):
|
||||
res = res[0]
|
||||
if skip_bom_info: return res
|
||||
|
||||
filters = {"item": item, "is_default": 1}
|
||||
filters = {"item": item, "is_default": 1, "docstatus": 1}
|
||||
|
||||
if project:
|
||||
filters = {"item": item, "project": project}
|
||||
|
@ -2,6 +2,7 @@
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.manufacturing.doctype.operation.test_operation import make_operation
|
||||
from erpnext.manufacturing.doctype.routing.test_routing import create_routing, setup_bom
|
||||
@ -10,13 +11,12 @@ from erpnext.manufacturing.doctype.workstation.workstation import (
|
||||
WorkstationHolidayError,
|
||||
check_if_within_operating_hours,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ["Warehouse"]
|
||||
test_records = frappe.get_test_records('Workstation')
|
||||
make_test_records('Workstation')
|
||||
|
||||
class TestWorkstation(ERPNextTestCase):
|
||||
class TestWorkstation(FrappeTestCase):
|
||||
def test_validate_timings(self):
|
||||
check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 11:00:00", "2013-02-02 19:00:00")
|
||||
check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 10:00:00", "2013-02-02 20:00:00")
|
||||
|
@ -356,4 +356,5 @@ erpnext.patches.v14_0.delete_amazon_mws_doctype
|
||||
erpnext.patches.v13_0.set_work_order_qty_in_so_from_mr
|
||||
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
||||
erpnext.patches.v14_0.update_batch_valuation_flag
|
||||
erpnext.patches.v14_0.delete_non_profit_doctypes
|
||||
erpnext.patches.v14_0.delete_non_profit_doctypes
|
||||
erpnext.patches.v14_0.update_employee_advance_status
|
26
erpnext/patches/v14_0/update_employee_advance_status.py
Normal file
26
erpnext/patches/v14_0/update_employee_advance_status.py
Normal file
@ -0,0 +1,26 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('hr', 'doctype', 'employee_advance')
|
||||
|
||||
advance = frappe.qb.DocType('Employee Advance')
|
||||
(frappe.qb
|
||||
.update(advance)
|
||||
.set(advance.status, 'Returned')
|
||||
.where(
|
||||
(advance.docstatus == 1)
|
||||
& ((advance.return_amount) & (advance.paid_amount == advance.return_amount))
|
||||
& (advance.status == 'Paid')
|
||||
)
|
||||
).run()
|
||||
|
||||
(frappe.qb
|
||||
.update(advance)
|
||||
.set(advance.status, 'Partly Claimed and Returned')
|
||||
.where(
|
||||
(advance.docstatus == 1)
|
||||
& ((advance.claimed_amount & advance.return_amount) & (advance.paid_amount == (advance.return_amount + advance.claimed_amount)))
|
||||
& (advance.status == 'Paid')
|
||||
)
|
||||
).run()
|
@ -105,6 +105,8 @@ class AdditionalSalary(Document):
|
||||
return_amount += self.amount
|
||||
|
||||
frappe.db.set_value("Employee Advance", self.ref_docname, "return_amount", return_amount)
|
||||
advance = frappe.get_doc("Employee Advance", self.ref_docname)
|
||||
advance.set_status(update=True)
|
||||
|
||||
def update_employee_referral(self, cancel=False):
|
||||
if self.ref_doctype == "Employee Referral":
|
||||
|
@ -4,12 +4,13 @@
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import flt
|
||||
|
||||
from erpnext.accounts.party import get_due_date
|
||||
from erpnext.exceptions import PartyDisabled, PartyFrozen
|
||||
from erpnext.selling.doctype.customer.customer import get_credit_limit, get_customer_outstanding
|
||||
from erpnext.tests.utils import ERPNextTestCase, create_test_contact_and_address
|
||||
from erpnext.tests.utils import create_test_contact_and_address
|
||||
|
||||
test_ignore = ["Price List"]
|
||||
test_dependencies = ['Payment Term', 'Payment Terms Template']
|
||||
@ -17,7 +18,7 @@ test_records = frappe.get_test_records('Customer')
|
||||
|
||||
|
||||
|
||||
class TestCustomer(ERPNextTestCase):
|
||||
class TestCustomer(FrappeTestCase):
|
||||
def setUp(self):
|
||||
if not frappe.get_value('Item', '_Test Item'):
|
||||
make_test_records('Item')
|
||||
|
@ -1,12 +1,10 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.controllers.queries import item_query
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ['Item', 'Customer', 'Supplier']
|
||||
|
||||
@ -18,7 +16,7 @@ def create_party_specific_item(**args):
|
||||
psi.based_on_value = args.get('based_on_value')
|
||||
psi.insert()
|
||||
|
||||
class TestPartySpecificItem(ERPNextTestCase):
|
||||
class TestPartySpecificItem(FrappeTestCase):
|
||||
def setUp(self):
|
||||
self.customer = frappe.get_last_doc("Customer")
|
||||
self.supplier = frappe.get_last_doc("Supplier")
|
||||
|
@ -2,14 +2,13 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_days, add_months, flt, getdate, nowdate
|
||||
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ["Product Bundle"]
|
||||
|
||||
|
||||
class TestQuotation(ERPNextTestCase):
|
||||
class TestQuotation(FrappeTestCase):
|
||||
def test_make_quotation_without_terms(self):
|
||||
quotation = make_quotation(do_not_save=1)
|
||||
self.assertFalse(quotation.get('payment_schedule'))
|
||||
|
@ -6,6 +6,7 @@ import json
|
||||
import frappe
|
||||
import frappe.permissions
|
||||
from frappe.core.doctype.user_permission.test_user_permission import create_user
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_days, flt, getdate, nowdate, today
|
||||
|
||||
from erpnext.controllers.accounts_controller import update_child_qty_rate
|
||||
@ -27,10 +28,9 @@ from erpnext.selling.doctype.sales_order.sales_order import (
|
||||
)
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestSalesOrder(ERPNextTestCase):
|
||||
class TestSalesOrder(FrappeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
@ -83,8 +83,8 @@
|
||||
"planned_qty",
|
||||
"column_break_69",
|
||||
"work_order_qty",
|
||||
"produced_qty",
|
||||
"delivered_qty",
|
||||
"produced_qty",
|
||||
"returned_qty",
|
||||
"shopping_cart_section",
|
||||
"additional_notes",
|
||||
@ -701,8 +701,10 @@
|
||||
"width": "50px"
|
||||
},
|
||||
{
|
||||
"description": "For Production",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 1,
|
||||
"label": "Produced Quantity",
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
@ -791,6 +793,7 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fetch_from": "item_code.grant_commission",
|
||||
"fieldname": "grant_commission",
|
||||
"fieldtype": "Check",
|
||||
"label": "Grant Commission",
|
||||
@ -800,7 +803,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-02-21 13:55:08.883104",
|
||||
"modified": "2022-02-24 14:41:57.325799",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order Item",
|
||||
|
@ -1,6 +1,7 @@
|
||||
import datetime
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_days
|
||||
|
||||
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
||||
@ -9,12 +10,11 @@ from erpnext.selling.report.payment_terms_status_for_sales_order.payment_terms_s
|
||||
execute,
|
||||
)
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ["Sales Order", "Item", "Sales Invoice", "Payment Terms Template"]
|
||||
|
||||
|
||||
class TestPaymentTermsStatusForSalesOrder(ERPNextTestCase):
|
||||
class TestPaymentTermsStatusForSalesOrder(FrappeTestCase):
|
||||
def create_payment_terms_template(self):
|
||||
# create template for 50-50 payments
|
||||
template = None
|
||||
|
@ -2,6 +2,7 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_months, nowdate
|
||||
|
||||
from erpnext.selling.doctype.sales_order.sales_order import make_material_request
|
||||
@ -9,10 +10,9 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde
|
||||
from erpnext.selling.report.pending_so_items_for_purchase_request.pending_so_items_for_purchase_request import (
|
||||
execute,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestPendingSOItemsForPurchaseRequest(ERPNextTestCase):
|
||||
class TestPendingSOItemsForPurchaseRequest(FrappeTestCase):
|
||||
def test_result_for_partial_material_request(self):
|
||||
so = make_sales_order()
|
||||
mr=make_material_request(so.name)
|
||||
|
@ -3,13 +3,13 @@
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.selling.report.sales_analytics.sales_analytics import execute
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestAnalytics(ERPNextTestCase):
|
||||
class TestAnalytics(FrappeTestCase):
|
||||
def test_sales_analytics(self):
|
||||
frappe.db.sql("delete from `tabSales Order` where company='_Test Company 2'")
|
||||
|
||||
|
@ -213,7 +213,14 @@ erpnext.stock.move_item = function (item, source, target, actual_qty, rate, call
|
||||
label: __('Target Warehouse'),
|
||||
fieldtype: 'Link',
|
||||
options: 'Warehouse',
|
||||
reqd: 1
|
||||
reqd: 1,
|
||||
get_query() {
|
||||
return {
|
||||
filters: {
|
||||
is_group: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldname: 'qty',
|
||||
@ -252,52 +259,21 @@ erpnext.stock.move_item = function (item, source, target, actual_qty, rate, call
|
||||
dialog.get_field('target').refresh();
|
||||
}
|
||||
|
||||
dialog.set_primary_action(__('Submit'), function () {
|
||||
var values = dialog.get_values();
|
||||
if (!values) {
|
||||
return;
|
||||
}
|
||||
if (source && values.qty > actual_qty) {
|
||||
frappe.msgprint(__('Quantity must be less than or equal to {0}', [actual_qty]));
|
||||
return;
|
||||
}
|
||||
if (values.source === values.target) {
|
||||
frappe.msgprint(__('Source and target warehouse must be different'));
|
||||
}
|
||||
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
|
||||
args: values,
|
||||
btn: dialog.get_primary_btn(),
|
||||
freeze: true,
|
||||
freeze_message: __('Creating Stock Entry'),
|
||||
callback: function (r) {
|
||||
frappe.show_alert(__('Stock Entry {0} created',
|
||||
['<a href="/app/stock-entry/' + r.message.name + '">' + r.message.name + '</a>']));
|
||||
dialog.hide();
|
||||
callback(r);
|
||||
},
|
||||
dialog.set_primary_action(__('Create Stock Entry'), function () {
|
||||
frappe.model.with_doctype('Stock Entry', function () {
|
||||
let doc = frappe.model.get_new_doc('Stock Entry');
|
||||
doc.from_warehouse = dialog.get_value('source');
|
||||
doc.to_warehouse = dialog.get_value('target');
|
||||
doc.stock_entry_type = doc.from_warehouse ? "Material Transfer" : "Material Receipt";
|
||||
let row = frappe.model.add_child(doc, 'items');
|
||||
row.item_code = dialog.get_value('item_code');
|
||||
row.s_warehouse = dialog.get_value('source');
|
||||
row.t_warehouse = dialog.get_value('target');
|
||||
row.qty = dialog.get_value('qty');
|
||||
row.conversion_factor = 1;
|
||||
row.transfer_qty = dialog.get_value('qty');
|
||||
row.basic_rate = dialog.get_value('rate');
|
||||
frappe.set_route('Form', doc.doctype, doc.name);
|
||||
});
|
||||
});
|
||||
|
||||
$('<p style="margin-left: 10px;"><a class="link-open text-muted small">' +
|
||||
__("Add more items or open full form") + '</a></p>')
|
||||
.appendTo(dialog.body)
|
||||
.find('.link-open')
|
||||
.on('click', function () {
|
||||
frappe.model.with_doctype('Stock Entry', function () {
|
||||
var doc = frappe.model.get_new_doc('Stock Entry');
|
||||
doc.from_warehouse = dialog.get_value('source');
|
||||
doc.to_warehouse = dialog.get_value('target');
|
||||
var row = frappe.model.add_child(doc, 'items');
|
||||
row.item_code = dialog.get_value('item_code');
|
||||
row.f_warehouse = dialog.get_value('target');
|
||||
row.t_warehouse = dialog.get_value('target');
|
||||
row.qty = dialog.get_value('qty');
|
||||
row.conversion_factor = 1;
|
||||
row.transfer_qty = dialog.get_value('qty');
|
||||
row.basic_rate = dialog.get_value('rate');
|
||||
frappe.set_route('Form', doc.doctype, doc.name);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ import json
|
||||
|
||||
import frappe
|
||||
from frappe.exceptions import ValidationError
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import cint, flt
|
||||
from frappe.utils.data import add_to_date, getdate
|
||||
|
||||
@ -16,10 +17,9 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import
|
||||
)
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
from erpnext.stock.stock_ledger import get_valuation_rate
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestBatch(ERPNextTestCase):
|
||||
class TestBatch(FrappeTestCase):
|
||||
def test_item_has_batch_enabled(self):
|
||||
self.assertRaises(ValidationError, frappe.get_doc({
|
||||
"doctype": "Batch",
|
||||
|
@ -2,13 +2,13 @@
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.stock.utils import _create_bin
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestBin(ERPNextTestCase):
|
||||
class TestBin(FrappeTestCase):
|
||||
|
||||
|
||||
def test_concurrent_inserts(self):
|
||||
|
@ -6,6 +6,7 @@
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import cstr, flt, nowdate, nowtime
|
||||
|
||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||
@ -35,10 +36,9 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import
|
||||
)
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import get_warehouse
|
||||
from erpnext.stock.stock_ledger import get_previous_sle
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestDeliveryNote(ERPNextTestCase):
|
||||
class TestDeliveryNote(FrappeTestCase):
|
||||
def test_over_billing_against_dn(self):
|
||||
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
|
||||
|
||||
|
@ -757,6 +757,7 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fetch_from": "item_code.grant_commission",
|
||||
"fieldname": "grant_commission",
|
||||
"fieldtype": "Check",
|
||||
"label": "Grant Commission",
|
||||
@ -767,12 +768,14 @@
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-10-06 12:12:44.018872",
|
||||
"modified": "2022-02-24 14:42:20.211085",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note Item",
|
||||
"naming_rule": "Random",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_days, flt, now_datetime, nowdate
|
||||
|
||||
import erpnext
|
||||
@ -12,10 +13,10 @@ from erpnext.stock.doctype.delivery_trip.delivery_trip import (
|
||||
make_expense_claim,
|
||||
notify_customers,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase, create_test_contact_and_address
|
||||
from erpnext.tests.utils import create_test_contact_and_address
|
||||
|
||||
|
||||
class TestDeliveryTrip(ERPNextTestCase):
|
||||
class TestDeliveryTrip(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
driver = create_driver()
|
||||
|
@ -6,6 +6,7 @@ import json
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_objects
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import add_days, today
|
||||
|
||||
from erpnext.controllers.item_variant import (
|
||||
@ -25,7 +26,6 @@ from erpnext.stock.doctype.item.item import (
|
||||
)
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
from erpnext.tests.utils import ERPNextTestCase, change_settings
|
||||
|
||||
test_ignore = ["BOM"]
|
||||
test_dependencies = ["Warehouse", "Item Group", "Item Tax Template", "Brand", "Item Attribute"]
|
||||
@ -53,7 +53,7 @@ def make_item(item_code, properties=None):
|
||||
|
||||
return item
|
||||
|
||||
class TestItem(ERPNextTestCase):
|
||||
class TestItem(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
frappe.flags.attribute_values = None
|
||||
|
@ -4,6 +4,7 @@
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import flt
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import (
|
||||
@ -18,10 +19,9 @@ from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
|
||||
create_stock_reconciliation,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestItemAlternative(ERPNextTestCase):
|
||||
class TestItemAlternative(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
make_items()
|
||||
|
@ -6,11 +6,12 @@ import frappe
|
||||
|
||||
test_records = frappe.get_test_records('Item Attribute')
|
||||
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.doctype.item_attribute.item_attribute import ItemAttributeIncrementError
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestItemAttribute(ERPNextTestCase):
|
||||
class TestItemAttribute(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
if frappe.db.exists("Item Attribute", "_Test_Length"):
|
||||
|
@ -4,13 +4,13 @@
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records_for_doctype
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.doctype.item_price.item_price import ItemPriceDuplicateItem
|
||||
from erpnext.stock.get_item_details import get_price_list_rate_for, process_args
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestItemPrice(ERPNextTestCase):
|
||||
class TestItemPrice(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
frappe.db.sql("delete from `tabItem Price`")
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_to_date, flt, now
|
||||
|
||||
from erpnext.accounts.doctype.account.test_account import create_account, get_inventory_account
|
||||
@ -14,10 +15,9 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import (
|
||||
get_gl_entries,
|
||||
make_purchase_receipt,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestLandedCostVoucher(ERPNextTestCase):
|
||||
class TestLandedCostVoucher(FrappeTestCase):
|
||||
def test_landed_cost_voucher(self):
|
||||
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import flt, today
|
||||
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
@ -15,10 +16,9 @@ from erpnext.stock.doctype.material_request.material_request import (
|
||||
make_supplier_quotation,
|
||||
raise_work_orders,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestMaterialRequest(ERPNextTestCase):
|
||||
class TestMaterialRequest(FrappeTestCase):
|
||||
def test_make_purchase_order(self):
|
||||
mr = frappe.copy_doc(test_records[0]).insert()
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import add_to_date, nowdate
|
||||
|
||||
from erpnext.selling.doctype.product_bundle.test_product_bundle import make_product_bundle
|
||||
@ -9,10 +10,9 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.tests.utils import ERPNextTestCase, change_settings
|
||||
|
||||
|
||||
class TestPackedItem(ERPNextTestCase):
|
||||
class TestPackedItem(FrappeTestCase):
|
||||
"Test impact on Packed Items table in various scenarios."
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
|
@ -4,7 +4,7 @@
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Packing Slip')
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestPackingSlip(unittest.TestCase):
|
||||
|
@ -6,16 +6,17 @@ from frappe import _dict
|
||||
|
||||
test_dependencies = ['Item', 'Sales Invoice', 'Stock Entry', 'Batch']
|
||||
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.pick_list.pick_list import create_delivery_note
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
||||
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import (
|
||||
EmptyStockReconciliationItemsError,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestPickList(ERPNextTestCase):
|
||||
class TestPickList(FrappeTestCase):
|
||||
|
||||
def test_pick_list_picks_warehouse_for_each_item(self):
|
||||
try:
|
||||
|
@ -7,6 +7,7 @@ import unittest
|
||||
from collections import defaultdict
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import add_days, cint, cstr, flt, today
|
||||
|
||||
import erpnext
|
||||
@ -17,10 +18,9 @@ from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchas
|
||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError, get_serial_nos
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
from erpnext.stock.stock_ledger import SerialNoExistsInFutureTransaction
|
||||
from erpnext.tests.utils import ERPNextTestCase, change_settings
|
||||
|
||||
|
||||
class TestPurchaseReceipt(ERPNextTestCase):
|
||||
class TestPurchaseReceipt(FrappeTestCase):
|
||||
def setUp(self):
|
||||
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.doctype.batch.test_batch import make_new_batch
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
@ -9,10 +10,9 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_pu
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
from erpnext.stock.get_item_details import get_conversion_factor
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestPutawayRule(ERPNextTestCase):
|
||||
class TestPutawayRule(FrappeTestCase):
|
||||
def setUp(self):
|
||||
if not frappe.db.exists("Item", "_Rice"):
|
||||
make_item("_Rice", {
|
||||
|
@ -2,6 +2,7 @@
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import nowdate
|
||||
|
||||
from erpnext.controllers.stock_controller import (
|
||||
@ -13,12 +14,11 @@ from erpnext.controllers.stock_controller import (
|
||||
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
# test_records = frappe.get_test_records('Quality Inspection')
|
||||
|
||||
|
||||
class TestQualityInspection(ERPNextTestCase):
|
||||
class TestQualityInspection(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
create_item("_Test Item with QA")
|
||||
|
@ -18,11 +18,12 @@ from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
test_dependencies = ["Item"]
|
||||
test_records = frappe.get_test_records('Serial No')
|
||||
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.doctype.serial_no.serial_no import *
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestSerialNo(ERPNextTestCase):
|
||||
class TestSerialNo(FrappeTestCase):
|
||||
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
|
@ -4,12 +4,12 @@
|
||||
from datetime import date, timedelta
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.doctype.delivery_note.delivery_note import make_shipment
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestShipment(ERPNextTestCase):
|
||||
class TestShipment(FrappeTestCase):
|
||||
def test_shipment_from_delivery_note(self):
|
||||
delivery_note = create_test_delivery_note()
|
||||
delivery_note.submit()
|
||||
|
@ -6,6 +6,7 @@ import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.permissions import add_user_permission, remove_user_permission
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import flt, nowdate, nowtime
|
||||
|
||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||
@ -28,7 +29,6 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import
|
||||
create_stock_reconciliation,
|
||||
)
|
||||
from erpnext.stock.stock_ledger import NegativeStockError, get_previous_sle
|
||||
from erpnext.tests.utils import ERPNextTestCase, change_settings
|
||||
|
||||
|
||||
def get_sle(**args):
|
||||
@ -42,7 +42,7 @@ def get_sle(**args):
|
||||
order by timestamp(posting_date, posting_time) desc, creation desc limit 1"""% condition,
|
||||
values, as_dict=1)
|
||||
|
||||
class TestStockEntry(ERPNextTestCase):
|
||||
class TestStockEntry(FrappeTestCase):
|
||||
def tearDown(self):
|
||||
frappe.db.rollback()
|
||||
frappe.set_user("Administrator")
|
||||
|
@ -7,6 +7,7 @@ from uuid import uuid4
|
||||
|
||||
import frappe
|
||||
from frappe.core.page.permission_manager.permission_manager import reset
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_days, today
|
||||
|
||||
from erpnext.stock.doctype.delivery_note.test_delivery_note import (
|
||||
@ -24,10 +25,9 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import
|
||||
create_stock_reconciliation,
|
||||
)
|
||||
from erpnext.stock.stock_ledger import get_previous_sle
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestStockLedgerEntry(ERPNextTestCase):
|
||||
class TestStockLedgerEntry(FrappeTestCase):
|
||||
def setUp(self):
|
||||
items = create_items()
|
||||
reset('Stock Entry')
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import add_days, cstr, flt, nowdate, nowtime, random_string
|
||||
|
||||
from erpnext.accounts.utils import get_stock_and_account_balance
|
||||
@ -19,10 +20,9 @@ from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import (
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
from erpnext.stock.stock_ledger import get_previous_sle, update_entries_after
|
||||
from erpnext.stock.utils import get_incoming_rate, get_stock_value_on, get_valuation_method
|
||||
from erpnext.tests.utils import ERPNextTestCase, change_settings
|
||||
|
||||
|
||||
class TestStockReconciliation(ERPNextTestCase):
|
||||
class TestStockReconciliation(FrappeTestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
create_batch_or_serial_no_items()
|
||||
|
@ -4,11 +4,10 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestStockSettings(ERPNextTestCase):
|
||||
class TestStockSettings(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
frappe.db.set_value("Stock Settings", None, "clean_description_html", 0)
|
||||
|
@ -3,17 +3,17 @@
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import cint
|
||||
|
||||
import erpnext
|
||||
from erpnext.accounts.doctype.account.test_account import create_account, get_inventory_account
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_records = frappe.get_test_records('Warehouse')
|
||||
|
||||
class TestWarehouse(ERPNextTestCase):
|
||||
class TestWarehouse(FrappeTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
if not frappe.get_value('Item', '_Test Item'):
|
||||
|
@ -244,7 +244,7 @@
|
||||
"idx": 1,
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2021-12-03 04:40:06.414630",
|
||||
"modified": "2022-03-01 02:37:48.034944",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Warehouse",
|
||||
@ -301,5 +301,7 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "warehouse_name"
|
||||
"states": [],
|
||||
"title_field": "warehouse_name",
|
||||
"track_changes": 1
|
||||
}
|
@ -2,12 +2,12 @@
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.stock.report.stock_ageing.stock_ageing import FIFOSlots, format_report_data
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestStockAgeing(ERPNextTestCase):
|
||||
class TestStockAgeing(FrappeTestCase):
|
||||
def setUp(self) -> None:
|
||||
self.filters = frappe._dict(
|
||||
company="_Test Company",
|
||||
@ -610,4 +610,4 @@ def generate_item_and_item_wh_wise_slots(filters, sle):
|
||||
item_wh_wise_slots = FIFOSlots(filters, sle).generate()
|
||||
filters.show_warehouse_wise_stock = False
|
||||
|
||||
return item_wise_slots, item_wh_wise_slots
|
||||
return item_wise_slots, item_wh_wise_slots
|
||||
|
@ -1,14 +1,13 @@
|
||||
import datetime
|
||||
import unittest
|
||||
|
||||
from frappe import _dict
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.stock.report.stock_analytics.stock_analytics import get_period_date_ranges
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestStockAnalyticsReport(ERPNextTestCase):
|
||||
class TestStockAnalyticsReport(FrappeTestCase):
|
||||
def test_get_period_date_ranges(self):
|
||||
|
||||
filters = _dict(range="Monthly", from_date="2020-12-28", to_date="2021-02-06")
|
||||
|
@ -2,13 +2,13 @@ import json
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from hypothesis import given
|
||||
from hypothesis import strategies as st
|
||||
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.stock.valuation import FIFOValuation, LIFOValuation, round_off_if_near_zero
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
qty_gen = st.floats(min_value=-1e6, max_value=1e6)
|
||||
value_gen = st.floats(min_value=1, max_value=1e6)
|
||||
@ -290,7 +290,7 @@ class TestLIFOValuation(unittest.TestCase):
|
||||
self.assertTotalQty(total_qty)
|
||||
self.assertTotalValue(total_value)
|
||||
|
||||
class TestLIFOValuationSLE(ERPNextTestCase):
|
||||
class TestLIFOValuationSLE(FrappeTestCase):
|
||||
ITEM_CODE = "_Test LIFO item"
|
||||
WAREHOUSE = "_Test Warehouse - _TC"
|
||||
|
||||
|
@ -1,27 +1 @@
|
||||
{% set domains = frappe.get_doc("Domain Settings").active_domains %}
|
||||
{% set links = {
|
||||
'Manufacturing': '/manufacturing',
|
||||
'Services': '/services',
|
||||
'Retail': '/retail',
|
||||
'Distribution': '/distribution',
|
||||
'Non Profit': '/non-profit',
|
||||
'Education': '/education',
|
||||
'Healthcare': '/healthcare',
|
||||
'Agriculture': '/agriculture',
|
||||
'Hospitality': ''
|
||||
} %}
|
||||
|
||||
{% set link = '' %}
|
||||
{% set label = '' %}
|
||||
{% if domains %}
|
||||
{% set label = domains[0].domain %}
|
||||
{% set link = links[label] %}
|
||||
{% endif %}
|
||||
|
||||
{% if label == "Services" %}
|
||||
{% set label = "Service" %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
<a href="https://erpnext.com{{ link }}?source=website_footer" target="_blank" class="text-muted">Powered by ERPNext - {{ '' if domains else 'Open Source' }} ERP Software {{ ('for ' + label + ' Companies') if domains else '' }}</a>
|
||||
<a href="https://erpnext.com?source=website_footer" target="_blank" class="text-muted">Powered by ERPNext</a>
|
||||
|
@ -25,7 +25,7 @@ class TestPointOfSale(unittest.TestCase):
|
||||
Test Stock and Service Item Search.
|
||||
"""
|
||||
|
||||
pos_profile = make_pos_profile()
|
||||
pos_profile = make_pos_profile(name="Test POS Profile for Search")
|
||||
item1 = make_item("Test Search Stock Item", {"is_stock_item": 1})
|
||||
make_stock_entry(
|
||||
item_code="Test Search Stock Item",
|
||||
|
@ -1,10 +1,6 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import copy
|
||||
import signal
|
||||
import unittest
|
||||
from contextlib import contextmanager
|
||||
from typing import Any, Dict, NewType, Optional
|
||||
|
||||
import frappe
|
||||
@ -13,22 +9,6 @@ from frappe.core.doctype.report.report import get_report_module_dotted_path
|
||||
ReportFilters = Dict[str, Any]
|
||||
ReportName = NewType("ReportName", str)
|
||||
|
||||
|
||||
class ERPNextTestCase(unittest.TestCase):
|
||||
"""A sane default test class for ERPNext tests."""
|
||||
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
frappe.db.commit()
|
||||
return super().setUpClass()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls) -> None:
|
||||
frappe.db.rollback()
|
||||
return super().tearDownClass()
|
||||
|
||||
|
||||
def create_test_contact_and_address():
|
||||
frappe.db.sql('delete from tabContact')
|
||||
frappe.db.sql('delete from `tabContact Email`')
|
||||
@ -81,43 +61,6 @@ def create_test_contact_and_address():
|
||||
contact_two.insert()
|
||||
|
||||
|
||||
@contextmanager
|
||||
def change_settings(doctype, settings_dict):
|
||||
""" A context manager to ensure that settings are changed before running
|
||||
function and restored after running it regardless of exceptions occured.
|
||||
This is useful in tests where you want to make changes in a function but
|
||||
don't retain those changes.
|
||||
import and use as decorator to cover full function or using `with` statement.
|
||||
|
||||
example:
|
||||
@change_settings("Stock Settings", {"item_naming_by": "Naming Series"})
|
||||
def test_case(self):
|
||||
...
|
||||
"""
|
||||
|
||||
try:
|
||||
settings = frappe.get_doc(doctype)
|
||||
# remember setting
|
||||
previous_settings = copy.deepcopy(settings_dict)
|
||||
for key in previous_settings:
|
||||
previous_settings[key] = getattr(settings, key)
|
||||
|
||||
# change setting
|
||||
for key, value in settings_dict.items():
|
||||
setattr(settings, key, value)
|
||||
settings.save()
|
||||
# singles are cached by default, clear to avoid flake
|
||||
frappe.db.value_cache[settings] = {}
|
||||
yield # yield control to calling function
|
||||
|
||||
finally:
|
||||
# restore settings
|
||||
settings = frappe.get_doc(doctype)
|
||||
for key, value in previous_settings.items():
|
||||
setattr(settings, key, value)
|
||||
settings.save()
|
||||
|
||||
|
||||
def execute_script_report(
|
||||
report_name: ReportName,
|
||||
module: str,
|
||||
@ -157,24 +100,3 @@ def execute_script_report(
|
||||
except Exception:
|
||||
print(f"Report failed to execute with filters: {test_filter}")
|
||||
raise
|
||||
|
||||
|
||||
|
||||
def timeout(seconds=30, error_message="Test timed out."):
|
||||
""" Timeout decorator to ensure a test doesn't run for too long.
|
||||
|
||||
adapted from https://stackoverflow.com/a/2282656"""
|
||||
def decorator(func):
|
||||
def _handle_timeout(signum, frame):
|
||||
raise Exception(error_message)
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
signal.signal(signal.SIGALRM, _handle_timeout)
|
||||
signal.alarm(seconds)
|
||||
try:
|
||||
result = func(*args, **kwargs)
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
return result
|
||||
return wrapper
|
||||
return decorator
|
||||
|
Loading…
x
Reference in New Issue
Block a user