diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 9d81a6318c0..8223ab55c57 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -13,6 +13,7 @@ from frappe.query_builder import Criterion, DocType from frappe.query_builder.custom import ConstantColumn from frappe.query_builder.functions import Abs, Sum from frappe.utils import ( + DateTimeLikeObject, add_days, add_months, cint, @@ -3113,12 +3114,14 @@ class AccountsController(TransactionBase): @frappe.whitelist() -def get_tax_rate(account_head): +def get_tax_rate(account_head: str): return frappe.get_cached_value("Account", account_head, ["tax_rate", "account_name"], as_dict=True) @frappe.whitelist() -def get_default_taxes_and_charges(master_doctype, tax_template=None, company=None): +def get_default_taxes_and_charges( + master_doctype: str, tax_template: str | None = None, company: str | None = None +): if not company: return {} @@ -3136,7 +3139,7 @@ def get_default_taxes_and_charges(master_doctype, tax_template=None, company=Non @frappe.whitelist() -def get_taxes_and_charges(master_doctype, master_name): +def get_taxes_and_charges(master_doctype: str, master_name: str | None = None): if not master_name: return from frappe.model import child_table_fields, default_fields @@ -3548,7 +3551,11 @@ def update_invoice_status(): @frappe.whitelist() def get_payment_terms( - terms_template, posting_date=None, grand_total=None, base_grand_total=None, bill_date=None + terms_template: str, + posting_date: DateTimeLikeObject | None = None, + grand_total: float | None = None, + base_grand_total: float | None = None, + bill_date: DateTimeLikeObject | None = None, ): if not terms_template: return @@ -3557,6 +3564,7 @@ def get_payment_terms( schedule = [] for d in terms_doc.get("terms"): + d = frappe._dict(d.as_dict()) term_details = get_payment_term_details(d, posting_date, grand_total, base_grand_total, bill_date) schedule.append(term_details) @@ -3565,7 +3573,11 @@ def get_payment_terms( @frappe.whitelist() def get_payment_term_details( - term, posting_date=None, grand_total=None, base_grand_total=None, bill_date=None + term: str | frappe._dict, + posting_date: DateTimeLikeObject | None = None, + grand_total: float | None = None, + base_grand_total: float | None = None, + bill_date: DateTimeLikeObject | None = None, ): term_details = frappe._dict() if isinstance(term, str): @@ -3601,7 +3613,7 @@ def get_payment_term_details( term_details.due_date = get_due_date(term, posting_date) term_details.discount_date = get_discount_date(term, posting_date) - if getdate(term_details.due_date) < getdate(posting_date): + if posting_date and getdate(term_details.due_date) < getdate(posting_date): term_details.due_date = posting_date return term_details @@ -3820,7 +3832,9 @@ def validate_and_delete_children(parent, data, ordered_item=None) -> bool: @frappe.whitelist() -def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"): +def update_child_qty_rate( + parent_doctype: str, trans_items: str, parent_doctype_name: str, child_docname: str = "items" +): from erpnext.buying.doctype.supplier_quotation.supplier_quotation import get_purchased_items from erpnext.selling.doctype.quotation.quotation import get_ordered_items @@ -4292,7 +4306,7 @@ def update_gl_dict_with_app_based_fields(doc, gl_dict): @frappe.whitelist() -def get_missing_company_details(doctype, docname): +def get_missing_company_details(doctype: str, docname: str): from frappe.contacts.doctype.address.address import get_address_display_list company = frappe.db.get_value(doctype, docname, "company") @@ -4348,7 +4362,7 @@ def get_missing_company_details(doctype, docname): @frappe.whitelist() -def update_company_master_and_address(current_doctype, name, company, details): +def update_company_master_and_address(current_doctype: str, name: str, company: str, details: dict | str): from frappe.utils import validate_email_address if isinstance(details, str): diff --git a/erpnext/controllers/item_variant.py b/erpnext/controllers/item_variant.py index 77599e3a009..f539ef15536 100644 --- a/erpnext/controllers/item_variant.py +++ b/erpnext/controllers/item_variant.py @@ -25,7 +25,13 @@ class ItemTemplateCannotHaveStock(frappe.ValidationError): @frappe.whitelist() -def get_variant(template, args=None, variant=None, manufacturer=None, manufacturer_part_no=None): +def get_variant( + template: str, + args: dict | str | None = None, + variant: str | None = None, + manufacturer: str | None = None, + manufacturer_part_no: str | None = None, +): """ Validates Attributes and their Values, then looks for an exactly matching Item Variant @@ -198,7 +204,7 @@ def find_variant(template, args, variant_item_code=None): @frappe.whitelist() -def create_variant(item, args, use_template_image=False): +def create_variant(item: str, args: dict | str, use_template_image: bool = False): use_template_image = frappe.parse_json(use_template_image) if isinstance(args, str): args = json.loads(args) @@ -223,7 +229,7 @@ def create_variant(item, args, use_template_image=False): @frappe.whitelist() -def enqueue_multiple_variant_creation(item, args, use_template_image=False): +def enqueue_multiple_variant_creation(item: str, args: dict | str, use_template_image: bool = False): use_template_image = frappe.parse_json(use_template_image) # There can be innumerable attribute combinations, enqueue if isinstance(args, str): @@ -403,7 +409,7 @@ def make_variant_item_code(template_item_code, template_item_name, variant): @frappe.whitelist() -def create_variant_doc_for_quick_entry(template, args): +def create_variant_doc_for_quick_entry(template: str, args: dict | str): variant_based_on = frappe.db.get_value("Item", template, "variant_based_on") args = json.loads(args) if variant_based_on == "Manufacturer": diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index e96d155701e..c3503da61a4 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -22,12 +22,12 @@ from erpnext.stock.get_item_details import ItemDetailsCtx, _get_item_tax_templat @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs def employee_query( - doctype, - txt, - searchfield, - start, - page_len, - filters, + doctype: str, + txt: str, + searchfield: str, + start: int, + page_len: int, + filters: dict | str | None = None, reference_doctype: str | None = None, ignore_user_permissions: bool = False, ): @@ -91,7 +91,9 @@ def has_ignored_field(reference_doctype, doctype): # searches for leads which are not converted @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def lead_query(doctype, txt, searchfield, start, page_len, filters): +def lead_query( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict | None = None +): doctype = "Lead" fields = get_fields(doctype, ["name", "lead_name", "company_name"]) @@ -127,7 +129,7 @@ def lead_query(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def tax_account_query(doctype, txt, searchfield, start, page_len, filters): +def tax_account_query(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): doctype = "Account" company_currency = erpnext.get_company_currency(filters.get("company")) @@ -174,7 +176,15 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False): +def item_query( + doctype: str, + txt: str, + searchfield: str, + start: int, + page_len: int, + filters: dict | str | None = None, + as_dict: bool = False, +): doctype = "Item" conditions = [] @@ -280,7 +290,9 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def bom(doctype, txt, searchfield, start, page_len, filters): +def bom( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict | str | None = None +): doctype = "BOM" conditions = [] fields = get_fields(doctype, ["name", "item"]) @@ -312,7 +324,9 @@ def bom(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_project_name(doctype, txt, searchfield, start, page_len, filters): +def get_project_name( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict | None = None +): proj = qb.DocType("Project") qb_filter_and_conditions = [] qb_filter_or_conditions = [] @@ -363,7 +377,9 @@ def get_project_name(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters, as_dict): +def get_delivery_notes_to_be_billed( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict, as_dict: bool +): doctype = "Delivery Note" fields = get_fields(doctype, ["name", "customer", "posting_date"]) @@ -399,7 +415,7 @@ def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_batch_no(doctype, txt, searchfield, start, page_len, filters): +def get_batch_no(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): doctype = "Batch" meta = frappe.get_meta(doctype, cached=True) searchfields = meta.get_search_fields() @@ -559,7 +575,9 @@ def get_batches_from_serial_and_batch_bundle(searchfields, txt, filters, start=0 @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_account_list(doctype, txt, searchfield, start, page_len, filters): +def get_account_list( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict | list +): doctype = "Account" filter_list = [] @@ -590,7 +608,7 @@ def get_account_list(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_blanket_orders(doctype, txt, searchfield, start, page_len, filters): +def get_blanket_orders(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): bo = frappe.qb.DocType("Blanket Order") bo_item = frappe.qb.DocType("Blanket Order Item") @@ -615,7 +633,7 @@ def get_blanket_orders(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_income_account(doctype, txt, searchfield, start, page_len, filters): +def get_income_account(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): from erpnext.controllers.queries import get_match_cond # income account can be any Credit account, @@ -649,7 +667,15 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters, reference_doctype=None): +def get_filtered_dimensions( + doctype: str, + txt: str, + searchfield: str, + start: int, + page_len: int, + filters: dict, + reference_doctype: str | None = None, +): from erpnext.accounts.doctype.accounting_dimension_filter.accounting_dimension_filter import ( get_dimension_filter_map, ) @@ -703,7 +729,7 @@ def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters, @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_expense_account(doctype, txt, searchfield, start, page_len, filters): +def get_expense_account(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): from erpnext.controllers.queries import get_match_cond if not filters: @@ -728,7 +754,7 @@ def get_expense_account(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def warehouse_query(doctype, txt, searchfield, start, page_len, filters): +def warehouse_query(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: list): # Should be used when item code is passed in filters. doctype = "Warehouse" conditions, bin_conditions = [], [] @@ -776,7 +802,7 @@ def get_doctype_wise_filters(filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_batch_numbers(doctype, txt, searchfield, start, page_len, filters): +def get_batch_numbers(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): query = """select batch_id from `tabBatch` where disabled = 0 and (expiry_date >= CURRENT_DATE or expiry_date IS NULL) @@ -790,7 +816,9 @@ def get_batch_numbers(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def item_manufacturer_query(doctype, txt, searchfield, start, page_len, filters): +def item_manufacturer_query( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict +): item_filters = [ ["manufacturer", "like", "%" + txt + "%"], ["item_code", "=", filters.get("item_code")], @@ -809,7 +837,7 @@ def item_manufacturer_query(doctype, txt, searchfield, start, page_len, filters) @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_purchase_receipts(doctype, txt, searchfield, start, page_len, filters): +def get_purchase_receipts(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): query = """ select pr.name from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pritem @@ -826,7 +854,7 @@ def get_purchase_receipts(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters): +def get_purchase_invoices(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): query = """ select pi.name from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` piitem @@ -843,7 +871,9 @@ def get_purchase_invoices(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_doctypes_for_closing(doctype, txt, searchfield, start, page_len, filters): +def get_doctypes_for_closing( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict +): doctypes = frappe.get_hooks("period_closing_doctypes") if txt: doctypes = [d for d in doctypes if txt.lower() in d.lower()] @@ -852,7 +882,7 @@ def get_doctypes_for_closing(doctype, txt, searchfield, start, page_len, filters @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_tax_template(doctype, txt, searchfield, start, page_len, filters): +def get_tax_template(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): item_doc = frappe.get_cached_doc("Item", filters.get("item_code")) item_group = filters.get("item_group") company = filters.get("company") @@ -918,7 +948,9 @@ def get_fields(doctype, fields=None): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_payment_terms_for_references(doctype, txt, searchfield, start, page_len, filters) -> list: +def get_payment_terms_for_references( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict +): terms = [] if filters: terms = frappe.db.get_all( @@ -933,7 +965,9 @@ def get_payment_terms_for_references(doctype, txt, searchfield, start, page_len, @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_filtered_child_rows(doctype, txt, searchfield, start, page_len, filters) -> list: +def get_filtered_child_rows( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict +): table = frappe.qb.DocType(doctype) query = ( frappe.qb.from_(table) @@ -961,7 +995,7 @@ def get_filtered_child_rows(doctype, txt, searchfield, start, page_len, filters) @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_item_uom_query(doctype, txt, searchfield, start, page_len, filters): +def get_item_uom_query(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): if frappe.get_single_value("Stock Settings", "allow_uom_with_conversion_rate_defined_in_item"): query_filters = {"parent": filters.get("item_code")} diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index f78ea1b48c8..6b947557a56 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -1269,20 +1269,20 @@ def get_available_serial_nos(serial_nos, warehouse): @frappe.whitelist() -def get_payment_data(invoice): +def get_payment_data(invoice: str): payment = frappe.db.get_all("Sales Invoice Payment", {"parent": invoice}, ["mode_of_payment", "amount"]) return payment @frappe.whitelist() -def get_invoice_item_returned_qty(doctype, invoice, customer, item_row_name): +def get_invoice_item_returned_qty(doctype: str, invoice: str, customer: str, item_row_name: str): is_return, docstatus = frappe.db.get_value(doctype, invoice, ["is_return", "docstatus"]) if not is_return and docstatus == 1: return get_returned_qty_map_for_row(invoice, customer, item_row_name, doctype) @frappe.whitelist() -def is_invoice_returnable(doctype, invoice): +def is_invoice_returnable(doctype: str, invoice: str): is_return, docstatus, customer = frappe.db.get_value( doctype, invoice, ["is_return", "docstatus", "customer"] ) diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 7ff2c4061f2..ea356f2a21e 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -1891,7 +1891,7 @@ class StockController(AccountsController): @frappe.whitelist() -def show_accounting_ledger_preview(company, doctype, docname): +def show_accounting_ledger_preview(company: str, doctype: str, docname: str): filters = frappe._dict(company=company, include_dimensions=1) doc = frappe.get_lazy_doc(doctype, docname) doc.run_method("before_gl_preview") @@ -1904,7 +1904,7 @@ def show_accounting_ledger_preview(company, doctype, docname): @frappe.whitelist() -def show_stock_ledger_preview(company, doctype, docname): +def show_stock_ledger_preview(company: str, doctype: str, docname: str): filters = frappe._dict(company=company) doc = frappe.get_lazy_doc(doctype, docname) doc.run_method("before_sl_preview") @@ -2065,7 +2065,7 @@ def repost_required_for_queue(doc: StockController) -> bool: @frappe.whitelist() -def check_item_quality_inspection(doctype, items): +def check_item_quality_inspection(doctype: str, items: str | list[dict]): if isinstance(items, str): items = json.loads(items) @@ -2087,7 +2087,7 @@ def check_item_quality_inspection(doctype, items): @frappe.whitelist() -def make_quality_inspections(doctype, docname, items, inspection_type): +def make_quality_inspections(doctype: str, docname: str, items: str | list, inspection_type: str): if isinstance(items, str): items = json.loads(items) diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index 11ad4f4d2ef..ddb2f590855 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -1368,7 +1368,10 @@ def get_pending_subcontracted_quantity(doctype, name): @frappe.whitelist() def make_rm_stock_entry( - subcontract_order, rm_items=None, order_doctype="Subcontracting Order", target_doc=None + subcontract_order: str, + rm_items: list | None = None, + order_doctype: str = "Subcontracting Order", + target_doc: dict | None = None, ): if subcontract_order: subcontract_order = frappe.get_doc(order_doctype, subcontract_order) @@ -1555,7 +1558,9 @@ def make_return_stock_entry_for_subcontract( @frappe.whitelist() -def get_materials_from_supplier(subcontract_order, rm_details, order_doctype="Subcontracting Order"): +def get_materials_from_supplier( + subcontract_order: str, rm_details: str | list, order_doctype: str = "Subcontracting Order" +): if isinstance(rm_details, str): rm_details = json.loads(rm_details) diff --git a/erpnext/controllers/subcontracting_inward_controller.py b/erpnext/controllers/subcontracting_inward_controller.py index 1a3ff66b825..1167cdcb59d 100644 --- a/erpnext/controllers/subcontracting_inward_controller.py +++ b/erpnext/controllers/subcontracting_inward_controller.py @@ -1104,7 +1104,9 @@ class SubcontractingInwardController: @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -def get_fg_reference_names(doctype, txt, searchfield, start, page_len, filters): +def get_fg_reference_names( + doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict +): return frappe.get_all( "Subcontracting Inward Order Item", limit_start=start, diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 773bd25ec4a..6ebcd8810bf 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -1184,7 +1184,7 @@ def get_itemised_tax_breakup_html(doc): @frappe.whitelist() -def get_round_off_applicable_accounts(company, account_list): +def get_round_off_applicable_accounts(company: str, account_list: list): # required to set correct region with temporary_flag("company", company): return get_regional_round_off_accounts(company, account_list) diff --git a/erpnext/controllers/trends.py b/erpnext/controllers/trends.py index 476bde248cc..752ec87d501 100644 --- a/erpnext/controllers/trends.py +++ b/erpnext/controllers/trends.py @@ -4,7 +4,7 @@ import frappe from frappe import _ -from frappe.utils import getdate +from frappe.utils import DateTimeLikeObject, getdate def get_columns(filters, trans): @@ -303,8 +303,10 @@ def get_period_wise_query(bet_dates, trans_date, query_details): return query_details -@frappe.whitelist(allow_guest=True) -def get_period_date_ranges(period, fiscal_year=None, year_start_date=None): +@frappe.whitelist() +def get_period_date_ranges( + period: str, fiscal_year: str | None = None, year_start_date: DateTimeLikeObject | None = None +): from dateutil.relativedelta import relativedelta if not year_start_date: