Files
schuetz3-erpnext/erpnext/controllers/buying_controller.py
venkat102 f94dffe568 fix: validate negative qty
(cherry picked from commit 329d14957b)

# Conflicts:
#	.editorconfig
#	.git-blame-ignore-revs
#	.github/helper/documentation.py
#	.github/helper/install.sh
#	.github/stale.yml
#	.github/workflows/linters.yml
#	.github/workflows/patch.yml
#	.github/workflows/release.yml
#	.github/workflows/release_notes.yml
#	.github/workflows/server-tests-mariadb.yml
#	.github/workflows/server-tests-postgres.yml
#	.gitignore
#	.mergify.yml
#	.releaserc
#	CODEOWNERS
#	README.md
#	erpnext/__init__.py
#	erpnext/accounts/deferred_revenue.py
#	erpnext/accounts/doctype/account/account.json
#	erpnext/accounts/doctype/account/account.py
#	erpnext/accounts/doctype/account/account_tree.js
#	erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
#	erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04.json
#	erpnext/accounts/doctype/account/chart_of_accounts/verified/hu_chart_of_accounts_for_microenterprises_with_account_number.json
#	erpnext/accounts/doctype/account/chart_of_accounts/verified/in_standard_chart_of_accounts.json
#	erpnext/accounts/doctype/account/chart_of_accounts/verified/ni_catalogo_de_cuentas.json
#	erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts.py
#	erpnext/accounts/doctype/account/chart_of_accounts/verified/standard_chart_of_accounts_with_account_number.py
#	erpnext/accounts/doctype/account/test_account.py
#	erpnext/accounts/doctype/account_closing_balance/account_closing_balance.json
#	erpnext/accounts/doctype/account_closing_balance/test_account_closing_balance.py
#	erpnext/accounts/doctype/accounting_dimension/accounting_dimension.json
#	erpnext/accounts/doctype/accounting_dimension/test_accounting_dimension.py
#	erpnext/accounts/doctype/accounting_dimension_detail/accounting_dimension_detail.json
#	erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.json
#	erpnext/accounts/doctype/accounting_dimension_filter/accounting_dimension_filter.py
#	erpnext/accounts/doctype/accounting_dimension_filter/test_accounting_dimension_filter.py
#	erpnext/accounts/doctype/accounting_period/accounting_period.json
#	erpnext/accounts/doctype/accounting_period/test_accounting_period.py
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
#	erpnext/accounts/doctype/accounts_settings/test_accounts_settings.py
#	erpnext/accounts/doctype/advance_payment_ledger_entry/test_advance_payment_ledger_entry.py
#	erpnext/accounts/doctype/advance_tax/advance_tax.json
#	erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.json
#	erpnext/accounts/doctype/advance_taxes_and_charges/advance_taxes_and_charges.py
#	erpnext/accounts/doctype/allowed_dimension/allowed_dimension.json
#	erpnext/accounts/doctype/allowed_to_transact_with/allowed_to_transact_with.json
#	erpnext/accounts/doctype/applicable_on_account/applicable_on_account.json
#	erpnext/accounts/doctype/bank/bank.json
#	erpnext/accounts/doctype/bank/test_bank.py
#	erpnext/accounts/doctype/bank_account/bank_account.json
#	erpnext/accounts/doctype/bank_account/bank_account.py
#	erpnext/accounts/doctype/bank_account/test_bank_account.py
#	erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.json
#	erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.py
#	erpnext/accounts/doctype/bank_account_type/bank_account_type.json
#	erpnext/accounts/doctype/bank_account_type/test_bank_account_type.py
#	erpnext/accounts/doctype/bank_clearance/bank_clearance.json
#	erpnext/accounts/doctype/bank_clearance/test_bank_clearance.py
#	erpnext/accounts/doctype/bank_clearance_detail/bank_clearance_detail.json
#	erpnext/accounts/doctype/bank_guarantee/bank_guarantee.json
#	erpnext/accounts/doctype/bank_guarantee/bank_guarantee.py
#	erpnext/accounts/doctype/bank_guarantee/test_bank_guarantee.py
#	erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.json
#	erpnext/accounts/doctype/bank_reconciliation_tool/test_bank_reconciliation_tool.py
#	erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js
#	erpnext/accounts/doctype/bank_statement_import/bank_statement_import.json
#	erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py
#	erpnext/accounts/doctype/bank_statement_import/test_bank_statement_import.py
#	erpnext/accounts/doctype/bank_transaction/auto_match_party.py
#	erpnext/accounts/doctype/bank_transaction/bank_transaction.py
#	erpnext/accounts/doctype/bank_transaction/test_auto_match_party.py
#	erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py
#	erpnext/accounts/doctype/bank_transaction_mapping/bank_transaction_mapping.json
#	erpnext/accounts/doctype/bank_transaction_payments/bank_transaction_payments.json
#	erpnext/accounts/doctype/bisect_accounting_statements/bisect_accounting_statements.json
#	erpnext/accounts/doctype/bisect_accounting_statements/bisect_accounting_statements.py
#	erpnext/accounts/doctype/bisect_accounting_statements/test_bisect_accounting_statements.py
#	erpnext/accounts/doctype/bisect_nodes/bisect_nodes.json
#	erpnext/accounts/doctype/bisect_nodes/test_bisect_nodes.py
#	erpnext/accounts/doctype/budget/budget.json
#	erpnext/accounts/doctype/budget/test_budget.py
#	erpnext/accounts/doctype/budget_account/budget_account.json
#	erpnext/accounts/doctype/campaign_item/campaign_item.json
#	erpnext/accounts/doctype/cashier_closing/cashier_closing.json
#	erpnext/accounts/doctype/cashier_closing/test_cashier_closing.py
#	erpnext/accounts/doctype/cashier_closing_payments/cashier_closing_payments.json
#	erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.json
#	erpnext/accounts/doctype/chart_of_accounts_importer/test_chart_of_accounts_importer.py
#	erpnext/accounts/doctype/cheque_print_template/cheque_print_template.json
#	erpnext/accounts/doctype/cheque_print_template/test_cheque_print_template.py
#	erpnext/accounts/doctype/closed_document/closed_document.json
#	erpnext/accounts/doctype/cost_center/cost_center.json
#	erpnext/accounts/doctype/cost_center/test_cost_center.py
#	erpnext/accounts/doctype/cost_center_allocation/cost_center_allocation.json
#	erpnext/accounts/doctype/cost_center_allocation/test_cost_center_allocation.py
#	erpnext/accounts/doctype/cost_center_allocation_percentage/cost_center_allocation_percentage.json
#	erpnext/accounts/doctype/coupon_code/coupon_code.json
#	erpnext/accounts/doctype/coupon_code/coupon_code.py
#	erpnext/accounts/doctype/coupon_code/test_coupon_code.py
#	erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json
#	erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py
#	erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json
#	erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json
#	erpnext/accounts/doctype/customer_group_item/customer_group_item.json
#	erpnext/accounts/doctype/customer_item/customer_item.json
#	erpnext/accounts/doctype/discounted_invoice/discounted_invoice.json
#	erpnext/accounts/doctype/dunning/dunning.json
#	erpnext/accounts/doctype/dunning/dunning.py
#	erpnext/accounts/doctype/dunning/test_dunning.py
#	erpnext/accounts/doctype/dunning_letter_text/dunning_letter_text.json
#	erpnext/accounts/doctype/dunning_type/dunning_type.json
#	erpnext/accounts/doctype/dunning_type/test_dunning_type.py
#	erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.js
#	erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.json
#	erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
#	erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py
#	erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json
#	erpnext/accounts/doctype/finance_book/finance_book.json
#	erpnext/accounts/doctype/finance_book/test_finance_book.py
#	erpnext/accounts/doctype/fiscal_year/fiscal_year.json
#	erpnext/accounts/doctype/fiscal_year/test_fiscal_year.py
#	erpnext/accounts/doctype/fiscal_year_company/fiscal_year_company.json
#	erpnext/accounts/doctype/gl_entry/test_gl_entry.py
#	erpnext/accounts/doctype/invoice_discounting/invoice_discounting.js
#	erpnext/accounts/doctype/invoice_discounting/invoice_discounting.json
#	erpnext/accounts/doctype/invoice_discounting/test_invoice_discounting.py
#	erpnext/accounts/doctype/item_tax_template/item_tax_template.json
#	erpnext/accounts/doctype/item_tax_template/test_item_tax_template.py
#	erpnext/accounts/doctype/item_tax_template_detail/item_tax_template_detail.json
#	erpnext/accounts/doctype/journal_entry/journal_entry.js
#	erpnext/accounts/doctype/journal_entry/journal_entry.json
#	erpnext/accounts/doctype/journal_entry/journal_entry.py
#	erpnext/accounts/doctype/journal_entry/journal_entry_list.js
#	erpnext/accounts/doctype/journal_entry/test_journal_entry.py
#	erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
#	erpnext/accounts/doctype/journal_entry_template/journal_entry_template.json
#	erpnext/accounts/doctype/journal_entry_template/test_journal_entry_template.py
#	erpnext/accounts/doctype/journal_entry_template_account/journal_entry_template_account.json
#	erpnext/accounts/doctype/ledger_health/test_ledger_health.py
#	erpnext/accounts/doctype/ledger_health_monitor/test_ledger_health_monitor.py
#	erpnext/accounts/doctype/ledger_merge/ledger_merge.json
#	erpnext/accounts/doctype/ledger_merge/test_ledger_merge.py
#	erpnext/accounts/doctype/ledger_merge_accounts/ledger_merge_accounts.json
#	erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.json
#	erpnext/accounts/doctype/loyalty_point_entry/loyalty_point_entry.py
#	erpnext/accounts/doctype/loyalty_point_entry/test_loyalty_point_entry.py
#	erpnext/accounts/doctype/loyalty_point_entry_redemption/loyalty_point_entry_redemption.json
#	erpnext/accounts/doctype/loyalty_program/loyalty_program.json
#	erpnext/accounts/doctype/loyalty_program/loyalty_program.py
#	erpnext/accounts/doctype/loyalty_program/test_loyalty_program.py
#	erpnext/accounts/doctype/loyalty_program_collection/loyalty_program_collection.json
#	erpnext/accounts/doctype/mode_of_payment/mode_of_payment.json
#	erpnext/accounts/doctype/mode_of_payment/test_mode_of_payment.py
#	erpnext/accounts/doctype/mode_of_payment_account/mode_of_payment_account.json
#	erpnext/accounts/doctype/monthly_distribution/monthly_distribution.json
#	erpnext/accounts/doctype/monthly_distribution/test_monthly_distribution.py
#	erpnext/accounts/doctype/monthly_distribution_percentage/monthly_distribution_percentage.json
#	erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.json
#	erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py
#	erpnext/accounts/doctype/opening_invoice_creation_tool/test_opening_invoice_creation_tool.py
#	erpnext/accounts/doctype/opening_invoice_creation_tool_item/opening_invoice_creation_tool_item.json
#	erpnext/accounts/doctype/overdue_payment/overdue_payment.json
#	erpnext/accounts/doctype/party_account/party_account.json
#	erpnext/accounts/doctype/party_link/party_link.json
#	erpnext/accounts/doctype/party_link/test_party_link.py
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
#	erpnext/accounts/doctype/payment_entry/payment_entry.json
#	erpnext/accounts/doctype/payment_entry/payment_entry.py
#	erpnext/accounts/doctype/payment_entry/test_payment_entry.py
#	erpnext/accounts/doctype/payment_entry_deduction/payment_entry_deduction.json
#	erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
#	erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.json
#	erpnext/accounts/doctype/payment_gateway_account/test_payment_gateway_account.py
#	erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.json
#	erpnext/accounts/doctype/payment_ledger_entry/test_payment_ledger_entry.py
#	erpnext/accounts/doctype/payment_order/payment_order.json
#	erpnext/accounts/doctype/payment_order/test_payment_order.py
#	erpnext/accounts/doctype/payment_order_reference/payment_order_reference.json
#	erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
#	erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
#	erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
#	erpnext/accounts/doctype/payment_reconciliation_allocation/payment_reconciliation_allocation.json
#	erpnext/accounts/doctype/payment_reconciliation_invoice/payment_reconciliation_invoice.json
#	erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
#	erpnext/accounts/doctype/payment_request/payment_request.js
#	erpnext/accounts/doctype/payment_request/payment_request.json
#	erpnext/accounts/doctype/payment_request/payment_request.py
#	erpnext/accounts/doctype/payment_request/payment_request_list.js
#	erpnext/accounts/doctype/payment_request/test_payment_request.py
#	erpnext/accounts/doctype/payment_schedule/payment_schedule.json
#	erpnext/accounts/doctype/payment_term/payment_term.json
#	erpnext/accounts/doctype/payment_term/test_payment_term.py
#	erpnext/accounts/doctype/payment_terms_template/payment_terms_template.json
#	erpnext/accounts/doctype/payment_terms_template/test_payment_terms_template.py
#	erpnext/accounts/doctype/payment_terms_template_detail/payment_terms_template_detail.json
#	erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.json
#	erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
#	erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.json
#	erpnext/accounts/doctype/pos_closing_entry/test_pos_closing_entry.py
#	erpnext/accounts/doctype/pos_closing_entry_detail/pos_closing_entry_detail.json
#	erpnext/accounts/doctype/pos_closing_entry_taxes/pos_closing_entry_taxes.json
#	erpnext/accounts/doctype/pos_customer_group/pos_customer_group.json
#	erpnext/accounts/doctype/pos_field/pos_field.json
#	erpnext/accounts/doctype/pos_invoice/pos_invoice.js
#	erpnext/accounts/doctype/pos_invoice/pos_invoice.json
#	erpnext/accounts/doctype/pos_invoice/pos_invoice.py
#	erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py
#	erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
#	erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.py
#	erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.json
#	erpnext/accounts/doctype/pos_invoice_merge_log/pos_invoice_merge_log.py
#	erpnext/accounts/doctype/pos_invoice_merge_log/test_pos_invoice_merge_log.py
#	erpnext/accounts/doctype/pos_invoice_reference/pos_invoice_reference.json
#	erpnext/accounts/doctype/pos_item_group/pos_item_group.json
#	erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.json
#	erpnext/accounts/doctype/pos_opening_entry/test_pos_opening_entry.py
#	erpnext/accounts/doctype/pos_opening_entry_detail/pos_opening_entry_detail.json
#	erpnext/accounts/doctype/pos_payment_method/pos_payment_method.json
#	erpnext/accounts/doctype/pos_profile/pos_profile.json
#	erpnext/accounts/doctype/pos_profile/pos_profile.py
#	erpnext/accounts/doctype/pos_profile/test_pos_profile.py
#	erpnext/accounts/doctype/pos_profile_user/pos_profile_user.json
#	erpnext/accounts/doctype/pos_profile_user/test_pos_profile_user.py
#	erpnext/accounts/doctype/pos_search_fields/pos_search_fields.json
#	erpnext/accounts/doctype/pos_settings/pos_settings.json
#	erpnext/accounts/doctype/pos_settings/test_pos_settings.py
#	erpnext/accounts/doctype/pricing_rule/pricing_rule.json
#	erpnext/accounts/doctype/pricing_rule/pricing_rule.py
#	erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
#	erpnext/accounts/doctype/pricing_rule/utils.py
#	erpnext/accounts/doctype/pricing_rule_brand/pricing_rule_brand.json
#	erpnext/accounts/doctype/pricing_rule_detail/pricing_rule_detail.json
#	erpnext/accounts/doctype/pricing_rule_item_code/pricing_rule_item_code.json
#	erpnext/accounts/doctype/pricing_rule_item_group/pricing_rule_item_group.json
#	erpnext/accounts/doctype/process_deferred_accounting/process_deferred_accounting.json
#	erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py
#	erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.json
#	erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py
#	erpnext/accounts/doctype/process_payment_reconciliation/test_process_payment_reconciliation.py
#	erpnext/accounts/doctype/process_payment_reconciliation_log/process_payment_reconciliation_log.json
#	erpnext/accounts/doctype/process_payment_reconciliation_log/test_process_payment_reconciliation_log.py
#	erpnext/accounts/doctype/process_payment_reconciliation_log_allocations/process_payment_reconciliation_log_allocations.json
#	erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.html
#	erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json
#	erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts_accounts_receivable.html
#	erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py
#	erpnext/accounts/doctype/process_statement_of_accounts_customer/process_statement_of_accounts_customer.json
#	erpnext/accounts/doctype/process_subscription/process_subscription.json
#	erpnext/accounts/doctype/process_subscription/test_process_subscription.py
#	erpnext/accounts/doctype/promotional_scheme/promotional_scheme.json
#	erpnext/accounts/doctype/promotional_scheme/test_promotional_scheme.py
#	erpnext/accounts/doctype/promotional_scheme_price_discount/promotional_scheme_price_discount.json
#	erpnext/accounts/doctype/promotional_scheme_product_discount/promotional_scheme_product_discount.json
#	erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json
#	erpnext/accounts/doctype/psoa_project/psoa_project.json
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
#	erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
#	erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json
#	erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
#	erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
#	erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
#	erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.py
#	erpnext/accounts/doctype/purchase_taxes_and_charges_template/purchase_taxes_and_charges_template.json
#	erpnext/accounts/doctype/purchase_taxes_and_charges_template/test_purchase_taxes_and_charges_template.py
#	erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json
#	erpnext/accounts/doctype/repost_accounting_ledger/test_repost_accounting_ledger.py
#	erpnext/accounts/doctype/repost_accounting_ledger_items/repost_accounting_ledger_items.json
#	erpnext/accounts/doctype/repost_accounting_ledger_settings/repost_accounting_ledger_settings.json
#	erpnext/accounts/doctype/repost_accounting_ledger_settings/test_repost_accounting_ledger_settings.py
#	erpnext/accounts/doctype/repost_allowed_types/repost_allowed_types.json
#	erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json
#	erpnext/accounts/doctype/repost_payment_ledger/test_repost_payment_ledger.py
#	erpnext/accounts/doctype/repost_payment_ledger_items/repost_payment_ledger_items.json
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.js
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.json
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.py
#	erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
#	erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
#	erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json
#	erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
#	erpnext/accounts/doctype/sales_partner_item/sales_partner_item.json
#	erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.json
#	erpnext/accounts/doctype/sales_taxes_and_charges/sales_taxes_and_charges.py
#	erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.json
#	erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
#	erpnext/accounts/doctype/sales_taxes_and_charges_template/test_sales_taxes_and_charges_template.py
#	erpnext/accounts/doctype/share_balance/share_balance.json
#	erpnext/accounts/doctype/share_transfer/share_transfer.json
#	erpnext/accounts/doctype/share_transfer/test_share_transfer.py
#	erpnext/accounts/doctype/share_type/share_type.json
#	erpnext/accounts/doctype/share_type/test_share_type.py
#	erpnext/accounts/doctype/shareholder/shareholder.json
#	erpnext/accounts/doctype/shareholder/test_shareholder.py
#	erpnext/accounts/doctype/shipping_rule/shipping_rule.json
#	erpnext/accounts/doctype/shipping_rule/shipping_rule.py
#	erpnext/accounts/doctype/shipping_rule/test_shipping_rule.py
#	erpnext/accounts/doctype/shipping_rule_condition/shipping_rule_condition.json
#	erpnext/accounts/doctype/shipping_rule_country/shipping_rule_country.json
#	erpnext/accounts/doctype/south_africa_vat_account/south_africa_vat_account.json
#	erpnext/accounts/doctype/subscription/subscription.json
#	erpnext/accounts/doctype/subscription/subscription.py
#	erpnext/accounts/doctype/subscription/subscription_list.js
#	erpnext/accounts/doctype/subscription/test_subscription.py
#	erpnext/accounts/doctype/subscription_invoice/subscription_invoice.json
#	erpnext/accounts/doctype/subscription_invoice/test_subscription_invoice.py
#	erpnext/accounts/doctype/subscription_plan/subscription_plan.json
#	erpnext/accounts/doctype/subscription_plan/test_subscription_plan.py
#	erpnext/accounts/doctype/subscription_plan_detail/subscription_plan_detail.json
#	erpnext/accounts/doctype/subscription_settings/subscription_settings.json
#	erpnext/accounts/doctype/subscription_settings/test_subscription_settings.py
#	erpnext/accounts/doctype/supplier_group_item/supplier_group_item.json
#	erpnext/accounts/doctype/supplier_item/supplier_item.json
#	erpnext/accounts/doctype/tax_category/tax_category.json
#	erpnext/accounts/doctype/tax_category/test_tax_category.py
#	erpnext/accounts/doctype/tax_rule/tax_rule.json
#	erpnext/accounts/doctype/tax_rule/tax_rule.py
#	erpnext/accounts/doctype/tax_rule/test_tax_rule.py
#	erpnext/accounts/doctype/tax_withheld_vouchers/tax_withheld_vouchers.json
#	erpnext/accounts/doctype/tax_withholding_account/tax_withholding_account.json
#	erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.json
#	erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
#	erpnext/accounts/doctype/tax_withholding_rate/tax_withholding_rate.json
#	erpnext/accounts/doctype/territory_item/territory_item.json
#	erpnext/accounts/doctype/transaction_deletion_record_details/transaction_deletion_record_details.json
#	erpnext/accounts/doctype/unreconcile_payment/test_unreconcile_payment.py
#	erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.json
#	erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.py
#	erpnext/accounts/doctype/unreconcile_payment_entries/unreconcile_payment_entries.json
#	erpnext/accounts/general_ledger.py
#	erpnext/accounts/notification/notification_for_new_fiscal_year/notification_for_new_fiscal_year.json
#	erpnext/accounts/party.py
#	erpnext/accounts/print_format/dunning_letter/dunning_letter.json
#	erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html
#	erpnext/accounts/report/account_balance/account_balance.js
#	erpnext/accounts/report/account_balance/account_balance.py
#	erpnext/accounts/report/account_balance/test_account_balance.py
#	erpnext/accounts/report/accounts_payable/accounts_payable.js
#	erpnext/accounts/report/accounts_payable/test_accounts_payable.py
#	erpnext/accounts/report/accounts_receivable/accounts_receivable.js
#	erpnext/accounts/report/accounts_receivable/accounts_receivable.py
#	erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
#	erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
#	erpnext/accounts/report/accounts_receivable_summary/test_accounts_receivable_summary.py
#	erpnext/accounts/report/balance_sheet/test_balance_sheet.py
#	erpnext/accounts/report/bank_reconciliation_statement/test_bank_reconciliation_statement.py
#	erpnext/accounts/report/cash_flow/cash_flow.py
#	erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
#	erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py
#	erpnext/accounts/report/deferred_revenue_and_expense/deferred_revenue_and_expense.py
#	erpnext/accounts/report/deferred_revenue_and_expense/test_deferred_revenue_and_expense.py
#	erpnext/accounts/report/general_and_payment_ledger_comparison/test_general_and_payment_ledger_comparison.py
#	erpnext/accounts/report/general_ledger/general_ledger.html
#	erpnext/accounts/report/general_ledger/general_ledger.py
#	erpnext/accounts/report/general_ledger/test_general_ledger.py
#	erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
#	erpnext/accounts/report/gross_profit/test_gross_profit.py
#	erpnext/accounts/report/item_wise_purchase_register/test_item_wise_purchase_register.py
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
#	erpnext/accounts/report/item_wise_sales_register/test_item_wise_sales_register.py
#	erpnext/accounts/report/payment_ledger/test_payment_ledger.py
#	erpnext/accounts/report/profit_and_loss_statement/test_profit_and_loss_statement.py
#	erpnext/accounts/report/purchase_register/test_purchase_register.py
#	erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py
#	erpnext/accounts/report/sales_register/test_sales_register.py
#	erpnext/accounts/report/tax_withholding_details/tax_withholding_details.py
#	erpnext/accounts/report/tax_withholding_details/test_tax_withholding_details.py
#	erpnext/accounts/report/trial_balance/test_trial_balance.py
#	erpnext/accounts/test/accounts_mixin.py
#	erpnext/accounts/test/test_reports.py
#	erpnext/accounts/test/test_utils.py
#	erpnext/accounts/test_party.py
#	erpnext/accounts/utils.py
#	erpnext/assets/doctype/asset/asset.js
#	erpnext/assets/doctype/asset/asset.json
#	erpnext/assets/doctype/asset/asset.py
#	erpnext/assets/doctype/asset/depreciation.py
#	erpnext/assets/doctype/asset/test_asset.py
#	erpnext/assets/doctype/asset_activity/asset_activity.json
#	erpnext/assets/doctype/asset_activity/test_asset_activity.py
#	erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
#	erpnext/assets/doctype/asset_capitalization/asset_capitalization.json
#	erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
#	erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
#	erpnext/assets/doctype/asset_capitalization_asset_item/asset_capitalization_asset_item.json
#	erpnext/assets/doctype/asset_capitalization_service_item/asset_capitalization_service_item.json
#	erpnext/assets/doctype/asset_capitalization_stock_item/asset_capitalization_stock_item.json
#	erpnext/assets/doctype/asset_category/asset_category.json
#	erpnext/assets/doctype/asset_category/test_asset_category.py
#	erpnext/assets/doctype/asset_category_account/asset_category_account.json
#	erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
#	erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py
#	erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
#	erpnext/assets/doctype/asset_maintenance/asset_maintenance.json
#	erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
#	erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
#	erpnext/assets/doctype/asset_maintenance_log/asset_maintenance_log.json
#	erpnext/assets/doctype/asset_maintenance_log/test_asset_maintenance_log.py
#	erpnext/assets/doctype/asset_maintenance_task/asset_maintenance_task.json
#	erpnext/assets/doctype/asset_maintenance_team/asset_maintenance_team.json
#	erpnext/assets/doctype/asset_maintenance_team/test_asset_maintenance_team.py
#	erpnext/assets/doctype/asset_movement/asset_movement.json
#	erpnext/assets/doctype/asset_movement/asset_movement.py
#	erpnext/assets/doctype/asset_movement/test_asset_movement.py
#	erpnext/assets/doctype/asset_movement_item/asset_movement_item.json
#	erpnext/assets/doctype/asset_repair/asset_repair.js
#	erpnext/assets/doctype/asset_repair/asset_repair.json
#	erpnext/assets/doctype/asset_repair/asset_repair.py
#	erpnext/assets/doctype/asset_repair/test_asset_repair.py
#	erpnext/assets/doctype/asset_repair_consumed_item/asset_repair_consumed_item.json
#	erpnext/assets/doctype/asset_shift_allocation/asset_shift_allocation.json
#	erpnext/assets/doctype/asset_shift_allocation/test_asset_shift_allocation.py
#	erpnext/assets/doctype/asset_shift_factor/asset_shift_factor.json
#	erpnext/assets/doctype/asset_shift_factor/test_asset_shift_factor.py
#	erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.js
#	erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.json
#	erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
#	erpnext/assets/doctype/asset_value_adjustment/test_asset_value_adjustment.py
#	erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json
#	erpnext/assets/doctype/linked_location/linked_location.json
#	erpnext/assets/doctype/location/location.json
#	erpnext/assets/doctype/location/test_location.py
#	erpnext/assets/doctype/maintenance_team_member/maintenance_team_member.json
#	erpnext/assets/doctype/maintenance_team_member/test_maintenance_team_member.py
#	erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
#	erpnext/bulk_transaction/doctype/bulk_transaction_log/bulk_transaction_log.json
#	erpnext/bulk_transaction/doctype/bulk_transaction_log/test_bulk_transaction_log.py
#	erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/bulk_transaction_log_detail.json
#	erpnext/bulk_transaction/doctype/bulk_transaction_log_detail/test_bulk_transaction_log_detail.py
#	erpnext/buying/doctype/buying_settings/buying_settings.json
#	erpnext/buying/doctype/buying_settings/test_buying_settings.py
#	erpnext/buying/doctype/purchase_order/purchase_order.js
#	erpnext/buying/doctype/purchase_order/purchase_order.json
#	erpnext/buying/doctype/purchase_order/purchase_order.py
#	erpnext/buying/doctype/purchase_order/purchase_order_list.js
#	erpnext/buying/doctype/purchase_order/test_purchase_order.py
#	erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
#	erpnext/buying/doctype/purchase_order_item/purchase_order_item.py
#	erpnext/buying/doctype/purchase_order_item_supplied/purchase_order_item_supplied.json
#	erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
#	erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
#	erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
#	erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
#	erpnext/buying/doctype/request_for_quotation/test_request_for_quotation.py
#	erpnext/buying/doctype/request_for_quotation_item/request_for_quotation_item.json
#	erpnext/buying/doctype/request_for_quotation_supplier/request_for_quotation_supplier.json
#	erpnext/buying/doctype/supplier/supplier.json
#	erpnext/buying/doctype/supplier/supplier_dashboard.py
#	erpnext/buying/doctype/supplier/test_supplier.py
#	erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
#	erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
#	erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
#	erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.py
#	erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.json
#	erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py
#	erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.json
#	erpnext/buying/doctype/supplier_scorecard/supplier_scorecard.py
#	erpnext/buying/doctype/supplier_scorecard/test_supplier_scorecard.py
#	erpnext/buying/doctype/supplier_scorecard_criteria/supplier_scorecard_criteria.json
#	erpnext/buying/doctype/supplier_scorecard_criteria/test_supplier_scorecard_criteria.py
#	erpnext/buying/doctype/supplier_scorecard_period/supplier_scorecard_period.json
#	erpnext/buying/doctype/supplier_scorecard_period/test_supplier_scorecard_period.py
#	erpnext/buying/doctype/supplier_scorecard_scoring_criteria/supplier_scorecard_scoring_criteria.json
#	erpnext/buying/doctype/supplier_scorecard_scoring_standing/supplier_scorecard_scoring_standing.json
#	erpnext/buying/doctype/supplier_scorecard_scoring_variable/supplier_scorecard_scoring_variable.json
#	erpnext/buying/doctype/supplier_scorecard_standing/supplier_scorecard_standing.json
#	erpnext/buying/doctype/supplier_scorecard_standing/test_supplier_scorecard_standing.py
#	erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.json
#	erpnext/buying/doctype/supplier_scorecard_variable/supplier_scorecard_variable.py
#	erpnext/buying/doctype/supplier_scorecard_variable/test_supplier_scorecard_variable.py
#	erpnext/buying/report/procurement_tracker/test_procurement_tracker.py
#	erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js
#	erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
#	erpnext/buying/report/requested_items_to_order_and_receive/test_requested_items_to_order_and_receive.py
#	erpnext/buying/report/subcontracted_item_to_be_received/test_subcontracted_item_to_be_received.py
#	erpnext/buying/report/subcontracted_raw_materials_to_be_transferred/test_subcontracted_raw_materials_to_be_transferred.py
#	erpnext/buying/utils.py
#	erpnext/communication/doctype/communication_medium/communication_medium.json
#	erpnext/communication/doctype/communication_medium_timeslot/communication_medium_timeslot.json
#	erpnext/controllers/accounts_controller.py
#	erpnext/controllers/buying_controller.py
#	erpnext/controllers/queries.py
#	erpnext/controllers/sales_and_purchase_return.py
#	erpnext/controllers/selling_controller.py
#	erpnext/controllers/status_updater.py
#	erpnext/controllers/stock_controller.py
#	erpnext/controllers/subcontracting_controller.py
#	erpnext/controllers/taxes_and_totals.py
#	erpnext/controllers/tests/test_accounts_controller.py
#	erpnext/controllers/tests/test_item_variant.py
#	erpnext/controllers/tests/test_mapper.py
#	erpnext/controllers/tests/test_qty_based_taxes.py
#	erpnext/controllers/tests/test_queries.py
#	erpnext/controllers/tests/test_subcontracting_controller.py
#	erpnext/controllers/tests/test_transaction_base.py
#	erpnext/controllers/website_list_for_contact.py
#	erpnext/crm/dashboard_chart/lead_source/lead_source.json
#	erpnext/crm/dashboard_chart/opportunities_via_campaigns/opportunities_via_campaigns.json
#	erpnext/crm/doctype/appointment/appointment.json
#	erpnext/crm/doctype/appointment/appointment.py
#	erpnext/crm/doctype/appointment/test_appointment.py
#	erpnext/crm/doctype/appointment_booking_settings/appointment_booking_settings.json
#	erpnext/crm/doctype/appointment_booking_settings/test_appointment_booking_settings.py
#	erpnext/crm/doctype/appointment_booking_slots/appointment_booking_slots.json
#	erpnext/crm/doctype/availability_of_slots/availability_of_slots.json
#	erpnext/crm/doctype/campaign/campaign.js
#	erpnext/crm/doctype/campaign/campaign.json
#	erpnext/crm/doctype/campaign/campaign.py
#	erpnext/crm/doctype/campaign/test_campaign.py
#	erpnext/crm/doctype/campaign_email_schedule/campaign_email_schedule.json
#	erpnext/crm/doctype/competitor/competitor.json
#	erpnext/crm/doctype/competitor/test_competitor.py
#	erpnext/crm/doctype/competitor_detail/competitor_detail.json
#	erpnext/crm/doctype/contract/contract.json
#	erpnext/crm/doctype/contract/test_contract.py
#	erpnext/crm/doctype/contract_fulfilment_checklist/contract_fulfilment_checklist.json
#	erpnext/crm/doctype/contract_fulfilment_checklist/test_contract_fulfilment_checklist.py
#	erpnext/crm/doctype/contract_template/contract_template.json
#	erpnext/crm/doctype/contract_template/test_contract_template.py
#	erpnext/crm/doctype/contract_template_fulfilment_terms/contract_template_fulfilment_terms.json
#	erpnext/crm/doctype/crm_note/crm_note.json
#	erpnext/crm/doctype/crm_settings/crm_settings.json
#	erpnext/crm/doctype/crm_settings/test_crm_settings.py
#	erpnext/crm/doctype/email_campaign/email_campaign.json
#	erpnext/crm/doctype/email_campaign/email_campaign.py
#	erpnext/crm/doctype/email_campaign/test_email_campaign.py
#	erpnext/crm/doctype/lead/lead.json
#	erpnext/crm/doctype/lead/lead.py
#	erpnext/crm/doctype/lead/test_lead.py
#	erpnext/crm/doctype/lost_reason_detail/lost_reason_detail.json
#	erpnext/crm/doctype/market_segment/market_segment.json
#	erpnext/crm/doctype/market_segment/test_market_segment.py
#	erpnext/crm/doctype/opportunity/opportunity.js
#	erpnext/crm/doctype/opportunity/opportunity.json
#	erpnext/crm/doctype/opportunity/opportunity.py
#	erpnext/crm/doctype/opportunity/test_opportunity.py
#	erpnext/crm/doctype/opportunity_item/opportunity_item.json
#	erpnext/crm/doctype/opportunity_lost_reason/opportunity_lost_reason.json
#	erpnext/crm/doctype/opportunity_lost_reason_detail/opportunity_lost_reason_detail.json
#	erpnext/crm/doctype/opportunity_type/opportunity_type.json
#	erpnext/crm/doctype/opportunity_type/test_opportunity_type.py
#	erpnext/crm/doctype/prospect/prospect.json
#	erpnext/crm/doctype/prospect/test_prospect.py
#	erpnext/crm/doctype/prospect_lead/prospect_lead.json
#	erpnext/crm/doctype/prospect_opportunity/prospect_opportunity.json
#	erpnext/crm/doctype/sales_stage/sales_stage.json
#	erpnext/crm/doctype/sales_stage/test_sales_stage.py
#	erpnext/crm/doctype/utils.py
#	erpnext/crm/report/campaign_efficiency/campaign_efficiency.py
#	erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.js
#	erpnext/crm/report/opportunity_summary_by_sales_stage/opportunity_summary_by_sales_stage.py
#	erpnext/crm/report/opportunity_summary_by_sales_stage/test_opportunity_summary_by_sales_stage.py
#	erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.js
#	erpnext/crm/report/sales_pipeline_analytics/sales_pipeline_analytics.py
#	erpnext/crm/report/sales_pipeline_analytics/test_sales_pipeline_analytics.py
#	erpnext/crm/workspace/crm/crm.json
#	erpnext/edi/doctype/code_list/code_list_import.py
#	erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json
#	erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
#	erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.json
#	erpnext/erpnext_integrations/doctype/quickbooks_migrator/test_quickbooks_migrator.py
#	erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.json
#	erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py
#	erpnext/erpnext_integrations/doctype/tally_migration/test_tally_migration.py
#	erpnext/erpnext_integrations/utils.py
#	erpnext/hooks.py
#	erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.json
#	erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py
#	erpnext/maintenance/doctype/maintenance_schedule/test_maintenance_schedule.py
#	erpnext/maintenance/doctype/maintenance_schedule_detail/maintenance_schedule_detail.json
#	erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json
#	erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.json
#	erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py
#	erpnext/maintenance/doctype/maintenance_visit/test_maintenance_visit.py
#	erpnext/maintenance/doctype/maintenance_visit_purpose/maintenance_visit_purpose.json
#	erpnext/manufacturing/doctype/blanket_order/blanket_order.json
#	erpnext/manufacturing/doctype/blanket_order/blanket_order.py
#	erpnext/manufacturing/doctype/blanket_order/test_blanket_order.py
#	erpnext/manufacturing/doctype/blanket_order_item/blanket_order_item.json
#	erpnext/manufacturing/doctype/bom/bom.js
#	erpnext/manufacturing/doctype/bom/bom.json
#	erpnext/manufacturing/doctype/bom/bom.py
#	erpnext/manufacturing/doctype/bom/test_bom.py
#	erpnext/manufacturing/doctype/bom_creator/bom_creator.js
#	erpnext/manufacturing/doctype/bom_creator/bom_creator.json
#	erpnext/manufacturing/doctype/bom_creator/bom_creator.py
#	erpnext/manufacturing/doctype/bom_creator/test_bom_creator.py
#	erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.json
#	erpnext/manufacturing/doctype/bom_creator_item/bom_creator_item.py
#	erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
#	erpnext/manufacturing/doctype/bom_item/bom_item.json
#	erpnext/manufacturing/doctype/bom_item/bom_item.py
#	erpnext/manufacturing/doctype/bom_operation/bom_operation.json
#	erpnext/manufacturing/doctype/bom_operation/bom_operation.py
#	erpnext/manufacturing/doctype/bom_scrap_item/bom_scrap_item.json
#	erpnext/manufacturing/doctype/bom_update_batch/bom_update_batch.json
#	erpnext/manufacturing/doctype/bom_update_log/bom_update_log.json
#	erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
#	erpnext/manufacturing/doctype/bom_update_log/test_bom_update_log.py
#	erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.json
#	erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
#	erpnext/manufacturing/doctype/bom_website_item/bom_website_item.json
#	erpnext/manufacturing/doctype/bom_website_operation/bom_website_operation.json
#	erpnext/manufacturing/doctype/downtime_entry/downtime_entry.json
#	erpnext/manufacturing/doctype/downtime_entry/test_downtime_entry.py
#	erpnext/manufacturing/doctype/job_card/job_card.js
#	erpnext/manufacturing/doctype/job_card/job_card.json
#	erpnext/manufacturing/doctype/job_card/job_card.py
#	erpnext/manufacturing/doctype/job_card/job_card_dashboard.py
#	erpnext/manufacturing/doctype/job_card/test_job_card.py
#	erpnext/manufacturing/doctype/job_card_item/job_card_item.json
#	erpnext/manufacturing/doctype/job_card_operation/job_card_operation.json
#	erpnext/manufacturing/doctype/job_card_scheduled_time/job_card_scheduled_time.json
#	erpnext/manufacturing/doctype/job_card_scrap_item/job_card_scrap_item.json
#	erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json
#	erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
#	erpnext/manufacturing/doctype/manufacturing_settings/test_manufacturing_settings.py
#	erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
#	erpnext/manufacturing/doctype/material_request_plan_item/test_material_request_plan_item.py
#	erpnext/manufacturing/doctype/operation/operation.json
#	erpnext/manufacturing/doctype/operation/test_operation.py
#	erpnext/manufacturing/doctype/plant_floor/plant_floor.js
#	erpnext/manufacturing/doctype/plant_floor/plant_floor.json
#	erpnext/manufacturing/doctype/plant_floor/test_plant_floor.py
#	erpnext/manufacturing/doctype/production_plan/production_plan.json
#	erpnext/manufacturing/doctype/production_plan/production_plan.py
#	erpnext/manufacturing/doctype/production_plan/test_production_plan.py
#	erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
#	erpnext/manufacturing/doctype/production_plan_item_reference/production_plan_item_reference.json
#	erpnext/manufacturing/doctype/production_plan_material_request/production_plan_material_request.json
#	erpnext/manufacturing/doctype/production_plan_material_request_warehouse/production_plan_material_request_warehouse.json
#	erpnext/manufacturing/doctype/production_plan_material_request_warehouse/test_production_plan_material_request_warehouse.py
#	erpnext/manufacturing/doctype/production_plan_sales_order/production_plan_sales_order.json
#	erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
#	erpnext/manufacturing/doctype/routing/routing.json
#	erpnext/manufacturing/doctype/routing/routing.py
#	erpnext/manufacturing/doctype/routing/test_routing.py
#	erpnext/manufacturing/doctype/sub_operation/sub_operation.json
#	erpnext/manufacturing/doctype/sub_operation/test_sub_operation.py
#	erpnext/manufacturing/doctype/work_order/test_work_order.py
#	erpnext/manufacturing/doctype/work_order/work_order.js
#	erpnext/manufacturing/doctype/work_order/work_order.json
#	erpnext/manufacturing/doctype/work_order/work_order.py
#	erpnext/manufacturing/doctype/work_order_item/work_order_item.json
#	erpnext/manufacturing/doctype/work_order_operation/work_order_operation.json
#	erpnext/manufacturing/doctype/work_order_operation/work_order_operation.py
#	erpnext/manufacturing/doctype/workstation/test_workstation.py
#	erpnext/manufacturing/doctype/workstation/workstation.js
#	erpnext/manufacturing/doctype/workstation/workstation.json
#	erpnext/manufacturing/doctype/workstation/workstation.py
#	erpnext/manufacturing/doctype/workstation/workstation_job_card.html
#	erpnext/manufacturing/doctype/workstation_type/test_workstation_type.py
#	erpnext/manufacturing/doctype/workstation_type/workstation_type.json
#	erpnext/manufacturing/doctype/workstation_working_hour/workstation_working_hour.json
#	erpnext/manufacturing/notification/material_request_receipt_notification/material_request_receipt_notification.json
#	erpnext/manufacturing/report/bom_stock_calculated/test_bom_stock_calculated.py
#	erpnext/manufacturing/report/bom_stock_report/test_bom_stock_report.py
#	erpnext/manufacturing/report/production_analytics/production_analytics.py
#	erpnext/manufacturing/report/quality_inspection_summary/quality_inspection_summary.py
#	erpnext/manufacturing/report/test_reports.py
#	erpnext/patches.txt
#	erpnext/patches/v11_0/create_department_records_for_each_company.py
#	erpnext/patches/v11_0/make_location_from_warehouse.py
#	erpnext/patches/v11_0/rebuild_tree_for_company.py
#	erpnext/patches/v11_0/rename_supplier_type_to_supplier_group.py
#	erpnext/patches/v11_0/update_department_lft_rgt.py
#	erpnext/patches/v13_0/modify_invalid_gain_loss_gl_entries.py
#	erpnext/patches/v14_0/migrate_crm_settings.py
#	erpnext/patches/v14_0/migrate_gl_to_payment_ledger.py
#	erpnext/patches/v15_0/create_advance_payment_ledger_records.py
#	erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
#	erpnext/patches/v15_0/update_gpa_and_ndb_for_assdeprsch.py
#	erpnext/portal/doctype/website_attribute/website_attribute.json
#	erpnext/portal/doctype/website_filter_field/website_filter_field.json
#	erpnext/portal/utils.py
#	erpnext/projects/doctype/activity_cost/activity_cost.json
#	erpnext/projects/doctype/activity_cost/test_activity_cost.py
#	erpnext/projects/doctype/activity_type/activity_type.json
#	erpnext/projects/doctype/activity_type/test_activity_type.py
#	erpnext/projects/doctype/dependent_task/dependent_task.json
#	erpnext/projects/doctype/project/project.json
#	erpnext/projects/doctype/project/project.py
#	erpnext/projects/doctype/project/test_project.py
#	erpnext/projects/doctype/project_template/project_template.json
#	erpnext/projects/doctype/project_template/test_project_template.py
#	erpnext/projects/doctype/project_template_task/project_template_task.json
#	erpnext/projects/doctype/project_type/project_type.json
#	erpnext/projects/doctype/project_type/test_project_type.py
#	erpnext/projects/doctype/project_update/project_update.json
#	erpnext/projects/doctype/project_update/test_project_update.py
#	erpnext/projects/doctype/project_user/project_user.json
#	erpnext/projects/doctype/projects_settings/projects_settings.json
#	erpnext/projects/doctype/projects_settings/test_projects_settings.py
#	erpnext/projects/doctype/task/task.js
#	erpnext/projects/doctype/task/task.json
#	erpnext/projects/doctype/task/task.py
#	erpnext/projects/doctype/task/test_task.py
#	erpnext/projects/doctype/task_depends_on/task_depends_on.json
#	erpnext/projects/doctype/task_type/task_type.json
#	erpnext/projects/doctype/task_type/test_task_type.py
#	erpnext/projects/doctype/timesheet/test_timesheet.py
#	erpnext/projects/doctype/timesheet/timesheet.js
#	erpnext/projects/doctype/timesheet/timesheet.json
#	erpnext/projects/doctype/timesheet/timesheet.py
#	erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
#	erpnext/projects/doctype/timesheet_detail/timesheet_detail.py
#	erpnext/projects/report/delayed_tasks_summary/delayed_tasks_summary.py
#	erpnext/projects/report/delayed_tasks_summary/test_delayed_tasks_summary.py
#	erpnext/projects/workspace/projects/projects.json
#	erpnext/public/images/erpnext-logo.svg
#	erpnext/public/js/bom_configurator/bom_configurator.bundle.js
#	erpnext/public/js/bulk_transaction_processing.js
#	erpnext/public/js/controllers/accounts.js
#	erpnext/public/js/controllers/taxes_and_totals.js
#	erpnext/public/js/controllers/transaction.js
#	erpnext/public/js/financial_statements.js
#	erpnext/public/js/plant_floor_visual/visual_plant.js
#	erpnext/public/js/projects/timer.js
#	erpnext/public/js/setup_wizard.js
#	erpnext/public/js/templates/visual_plant_floor_template.html
#	erpnext/public/js/utils.js
#	erpnext/public/js/utils/dimension_tree_filter.js
#	erpnext/public/scss/erpnext.scss
#	erpnext/quality_management/doctype/non_conformance/non_conformance.json
#	erpnext/quality_management/doctype/non_conformance/test_non_conformance.py
#	erpnext/quality_management/doctype/quality_action/quality_action.json
#	erpnext/quality_management/doctype/quality_action/test_quality_action.py
#	erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json
#	erpnext/quality_management/doctype/quality_feedback/quality_feedback.json
#	erpnext/quality_management/doctype/quality_feedback/test_quality_feedback.py
#	erpnext/quality_management/doctype/quality_feedback_parameter/quality_feedback_parameter.json
#	erpnext/quality_management/doctype/quality_feedback_template/quality_feedback_template.json
#	erpnext/quality_management/doctype/quality_feedback_template/test_quality_feedback_template.py
#	erpnext/quality_management/doctype/quality_feedback_template_parameter/quality_feedback_template_parameter.json
#	erpnext/quality_management/doctype/quality_goal/quality_goal.json
#	erpnext/quality_management/doctype/quality_goal/test_quality_goal.py
#	erpnext/quality_management/doctype/quality_goal_objective/quality_goal_objective.json
#	erpnext/quality_management/doctype/quality_meeting/quality_meeting.json
#	erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py
#	erpnext/quality_management/doctype/quality_meeting_agenda/quality_meeting_agenda.json
#	erpnext/quality_management/doctype/quality_meeting_agenda/test_quality_meeting_agenda.py
#	erpnext/quality_management/doctype/quality_meeting_minutes/quality_meeting_minutes.json
#	erpnext/quality_management/doctype/quality_procedure/quality_procedure.json
#	erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
#	erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
#	erpnext/quality_management/doctype/quality_review/quality_review.json
#	erpnext/quality_management/doctype/quality_review/test_quality_review.py
#	erpnext/quality_management/doctype/quality_review_objective/quality_review_objective.json
#	erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.json
#	erpnext/regional/doctype/import_supplier_invoice/import_supplier_invoice.py
#	erpnext/regional/doctype/import_supplier_invoice/test_import_supplier_invoice.py
#	erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.json
#	erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py
#	erpnext/regional/doctype/lower_deduction_certificate/test_lower_deduction_certificate.py
#	erpnext/regional/doctype/south_africa_vat_settings/south_africa_vat_settings.json
#	erpnext/regional/doctype/south_africa_vat_settings/test_south_africa_vat_settings.py
#	erpnext/regional/doctype/uae_vat_account/uae_vat_account.json
#	erpnext/regional/doctype/uae_vat_settings/test_uae_vat_settings.py
#	erpnext/regional/doctype/uae_vat_settings/uae_vat_settings.json
#	erpnext/regional/italy/utils.py
#	erpnext/regional/print_format/detailed_tax_invoice/detailed_tax_invoice.json
#	erpnext/regional/print_format/tax_invoice/tax_invoice.json
#	erpnext/regional/report/uae_vat_201/test_uae_vat_201.py
#	erpnext/regional/report/vat_audit_report/vat_audit_report.py
#	erpnext/regional/united_states/test_united_states.py
#	erpnext/selling/doctype/customer/customer.js
#	erpnext/selling/doctype/customer/customer.json
#	erpnext/selling/doctype/customer/customer.py
#	erpnext/selling/doctype/customer/customer_dashboard.py
#	erpnext/selling/doctype/customer/test_customer.py
#	erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.json
#	erpnext/selling/doctype/industry_type/industry_type.json
#	erpnext/selling/doctype/industry_type/test_industry_type.py
#	erpnext/selling/doctype/installation_note/installation_note.json
#	erpnext/selling/doctype/installation_note/installation_note.py
#	erpnext/selling/doctype/installation_note/test_installation_note.py
#	erpnext/selling/doctype/installation_note_item/installation_note_item.json
#	erpnext/selling/doctype/party_specific_item/party_specific_item.json
#	erpnext/selling/doctype/party_specific_item/test_party_specific_item.py
#	erpnext/selling/doctype/product_bundle/product_bundle.js
#	erpnext/selling/doctype/product_bundle/product_bundle.json
#	erpnext/selling/doctype/product_bundle/test_product_bundle.py
#	erpnext/selling/doctype/product_bundle_item/product_bundle_item.json
#	erpnext/selling/doctype/quotation/quotation.json
#	erpnext/selling/doctype/quotation/quotation.py
#	erpnext/selling/doctype/quotation/test_quotation.py
#	erpnext/selling/doctype/quotation_item/quotation_item.json
#	erpnext/selling/doctype/quotation_item/quotation_item.py
#	erpnext/selling/doctype/sales_order/sales_order.js
#	erpnext/selling/doctype/sales_order/sales_order.json
#	erpnext/selling/doctype/sales_order/sales_order.py
#	erpnext/selling/doctype/sales_order/sales_order_list.js
#	erpnext/selling/doctype/sales_order/test_sales_order.py
#	erpnext/selling/doctype/sales_order_item/sales_order_item.json
#	erpnext/selling/doctype/sales_order_item/sales_order_item.py
#	erpnext/selling/doctype/sales_partner_type/sales_partner_type.json
#	erpnext/selling/doctype/sales_partner_type/test_sales_partner_type.py
#	erpnext/selling/doctype/sales_team/sales_team.json
#	erpnext/selling/doctype/selling_settings/selling_settings.json
#	erpnext/selling/doctype/selling_settings/selling_settings.py
#	erpnext/selling/doctype/selling_settings/test_selling_settings.py
#	erpnext/selling/doctype/sms_center/sms_center.json
#	erpnext/selling/page/point_of_sale/pos_controller.js
#	erpnext/selling/page/point_of_sale/pos_item_cart.js
#	erpnext/selling/page/point_of_sale/pos_past_order_summary.js
#	erpnext/selling/page/point_of_sale/pos_payment.js
#	erpnext/selling/page/sales_funnel/sales_funnel.js
#	erpnext/selling/page/sales_funnel/sales_funnel.py
#	erpnext/selling/report/address_and_contacts/address_and_contacts.py
#	erpnext/selling/report/customer_credit_balance/customer_credit_balance.py
#	erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py
#	erpnext/selling/report/payment_terms_status_for_sales_order/test_payment_terms_status_for_sales_order.py
#	erpnext/selling/report/pending_so_items_for_purchase_request/test_pending_so_items_for_purchase_request.py
#	erpnext/selling/report/sales_analytics/sales_analytics.js
#	erpnext/selling/report/sales_analytics/sales_analytics.py
#	erpnext/selling/report/sales_analytics/test_analytics.py
#	erpnext/selling/report/sales_order_analysis/sales_order_analysis.js
#	erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
#	erpnext/selling/report/sales_order_analysis/test_sales_order_analysis.py
#	erpnext/selling/report/sales_partner_target_variance_based_on_item_group/test_sales_partner_target_variance_based_on_item_group.py
#	erpnext/selling/report/sales_person_target_variance_based_on_item_group/test_sales_person_target_variance_based_on_item_group.py
#	erpnext/selling/workspace/selling/selling.json
#	erpnext/setup/doctype/authorization_control/authorization_control.json
#	erpnext/setup/doctype/authorization_control/authorization_control.py
#	erpnext/setup/doctype/authorization_rule/authorization_rule.json
#	erpnext/setup/doctype/authorization_rule/test_authorization_rule.py
#	erpnext/setup/doctype/branch/branch.json
#	erpnext/setup/doctype/branch/test_branch.py
#	erpnext/setup/doctype/brand/brand.json
#	erpnext/setup/doctype/brand/test_brand.py
#	erpnext/setup/doctype/company/company.js
#	erpnext/setup/doctype/company/company.json
#	erpnext/setup/doctype/company/company.py
#	erpnext/setup/doctype/company/test_company.py
#	erpnext/setup/doctype/currency_exchange/test_currency_exchange.py
#	erpnext/setup/doctype/customer_group/customer_group.json
#	erpnext/setup/doctype/customer_group/customer_group.py
#	erpnext/setup/doctype/customer_group/test_customer_group.py
#	erpnext/setup/doctype/department/department.json
#	erpnext/setup/doctype/department/department.py
#	erpnext/setup/doctype/department/test_department.py
#	erpnext/setup/doctype/designation/designation.json
#	erpnext/setup/doctype/designation/test_designation.py
#	erpnext/setup/doctype/driver/driver.json
#	erpnext/setup/doctype/driver/driver.py
#	erpnext/setup/doctype/driver/test_driver.py
#	erpnext/setup/doctype/driving_license_category/driving_license_category.json
#	erpnext/setup/doctype/email_digest/email_digest.json
#	erpnext/setup/doctype/email_digest/email_digest.py
#	erpnext/setup/doctype/email_digest/test_email_digest.py
#	erpnext/setup/doctype/email_digest_recipient/email_digest_recipient.json
#	erpnext/setup/doctype/employee/employee.json
#	erpnext/setup/doctype/employee/employee.py
#	erpnext/setup/doctype/employee/test_employee.py
#	erpnext/setup/doctype/employee_education/employee_education.json
#	erpnext/setup/doctype/employee_external_work_history/employee_external_work_history.json
#	erpnext/setup/doctype/employee_group/employee_group.json
#	erpnext/setup/doctype/employee_group/test_employee_group.py
#	erpnext/setup/doctype/employee_group_table/employee_group_table.json
#	erpnext/setup/doctype/employee_internal_work_history/employee_internal_work_history.json
#	erpnext/setup/doctype/global_defaults/global_defaults.json
#	erpnext/setup/doctype/global_defaults/test_global_defaults.py
#	erpnext/setup/doctype/holiday/holiday.json
#	erpnext/setup/doctype/holiday_list/holiday_list.json
#	erpnext/setup/doctype/holiday_list/test_holiday_list.py
#	erpnext/setup/doctype/incoterm/test_incoterm.py
#	erpnext/setup/doctype/item_group/item_group.json
#	erpnext/setup/doctype/item_group/test_item_group.py
#	erpnext/setup/doctype/party_type/party_type.json
#	erpnext/setup/doctype/party_type/test_party_type.py
#	erpnext/setup/doctype/print_heading/print_heading.json
#	erpnext/setup/doctype/print_heading/test_print_heading.py
#	erpnext/setup/doctype/quotation_lost_reason/quotation_lost_reason.json
#	erpnext/setup/doctype/quotation_lost_reason/test_quotation_lost_reason.py
#	erpnext/setup/doctype/quotation_lost_reason_detail/quotation_lost_reason_detail.json
#	erpnext/setup/doctype/sales_partner/sales_partner.json
#	erpnext/setup/doctype/sales_partner/sales_partner.py
#	erpnext/setup/doctype/sales_partner/test_sales_partner.py
#	erpnext/setup/doctype/sales_person/sales_person.json
#	erpnext/setup/doctype/sales_person/test_sales_person.py
#	erpnext/setup/doctype/supplier_group/supplier_group.js
#	erpnext/setup/doctype/supplier_group/supplier_group.json
#	erpnext/setup/doctype/supplier_group/test_supplier_group.py
#	erpnext/setup/doctype/target_detail/target_detail.json
#	erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.json
#	erpnext/setup/doctype/terms_and_conditions/test_terms_and_conditions.py
#	erpnext/setup/doctype/territory/territory.json
#	erpnext/setup/doctype/territory/test_territory.py
#	erpnext/setup/doctype/transaction_deletion_record/test_transaction_deletion_record.py
#	erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.json
#	erpnext/setup/doctype/transaction_deletion_record_item/transaction_deletion_record_item.json
#	erpnext/setup/doctype/uom/test_uom.py
#	erpnext/setup/doctype/uom/uom.json
#	erpnext/setup/doctype/uom/uom.py
#	erpnext/setup/doctype/uom_conversion_factor/test_uom_conversion_factor.py
#	erpnext/setup/doctype/uom_conversion_factor/uom_conversion_factor.json
#	erpnext/setup/doctype/vehicle/test_vehicle.py
#	erpnext/setup/doctype/vehicle/vehicle.json
#	erpnext/setup/doctype/website_item_group/website_item_group.json
#	erpnext/setup/install.py
#	erpnext/setup/setup_wizard/data/country_wise_tax.json
#	erpnext/setup/setup_wizard/data/uom_data.json
#	erpnext/setup/setup_wizard/operations/defaults_setup.py
#	erpnext/setup/setup_wizard/operations/install_fixtures.py
#	erpnext/setup/utils.py
#	erpnext/startup/boot.py
#	erpnext/startup/leaderboard.py
#	erpnext/stock/__init__.py
#	erpnext/stock/deprecated_serial_batch.py
#	erpnext/stock/doctype/batch/batch.json
#	erpnext/stock/doctype/batch/test_batch.py
#	erpnext/stock/doctype/bin/bin.json
#	erpnext/stock/doctype/bin/test_bin.py
#	erpnext/stock/doctype/closing_stock_balance/closing_stock_balance.json
#	erpnext/stock/doctype/closing_stock_balance/test_closing_stock_balance.py
#	erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.json
#	erpnext/stock/doctype/customs_tariff_number/test_customs_tariff_number.py
#	erpnext/stock/doctype/delivery_note/delivery_note.json
#	erpnext/stock/doctype/delivery_note/delivery_note.py
#	erpnext/stock/doctype/delivery_note/delivery_note_list.js
#	erpnext/stock/doctype/delivery_note/test_delivery_note.py
#	erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
#	erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
#	erpnext/stock/doctype/delivery_settings/delivery_settings.json
#	erpnext/stock/doctype/delivery_settings/test_delivery_settings.py
#	erpnext/stock/doctype/delivery_stop/delivery_stop.json
#	erpnext/stock/doctype/delivery_trip/delivery_trip.js
#	erpnext/stock/doctype/delivery_trip/delivery_trip.json
#	erpnext/stock/doctype/delivery_trip/delivery_trip.py
#	erpnext/stock/doctype/delivery_trip/test_delivery_trip.py
#	erpnext/stock/doctype/inventory_dimension/inventory_dimension.json
#	erpnext/stock/doctype/inventory_dimension/inventory_dimension.py
#	erpnext/stock/doctype/inventory_dimension/test_inventory_dimension.py
#	erpnext/stock/doctype/item/item.js
#	erpnext/stock/doctype/item/item.json
#	erpnext/stock/doctype/item/item.py
#	erpnext/stock/doctype/item/item_list.js
#	erpnext/stock/doctype/item/test_item.py
#	erpnext/stock/doctype/item_alternative/item_alternative.json
#	erpnext/stock/doctype/item_alternative/test_item_alternative.py
#	erpnext/stock/doctype/item_attribute/item_attribute.json
#	erpnext/stock/doctype/item_attribute/item_attribute.py
#	erpnext/stock/doctype/item_attribute/test_item_attribute.py
#	erpnext/stock/doctype/item_attribute_value/item_attribute_value.json
#	erpnext/stock/doctype/item_barcode/item_barcode.json
#	erpnext/stock/doctype/item_customer_detail/item_customer_detail.json
#	erpnext/stock/doctype/item_default/item_default.json
#	erpnext/stock/doctype/item_manufacturer/item_manufacturer.json
#	erpnext/stock/doctype/item_manufacturer/test_item_manufacturer.py
#	erpnext/stock/doctype/item_price/item_price.json
#	erpnext/stock/doctype/item_price/item_price.py
#	erpnext/stock/doctype/item_price/test_item_price.py
#	erpnext/stock/doctype/item_quality_inspection_parameter/item_quality_inspection_parameter.json
#	erpnext/stock/doctype/item_reorder/item_reorder.json
#	erpnext/stock/doctype/item_supplier/item_supplier.json
#	erpnext/stock/doctype/item_tax/item_tax.json
#	erpnext/stock/doctype/item_variant/item_variant.json
#	erpnext/stock/doctype/item_variant_attribute/item_variant_attribute.json
#	erpnext/stock/doctype/item_variant_settings/item_variant_settings.js
#	erpnext/stock/doctype/item_variant_settings/item_variant_settings.json
#	erpnext/stock/doctype/item_variant_settings/test_item_variant_settings.py
#	erpnext/stock/doctype/item_website_specification/item_website_specification.json
#	erpnext/stock/doctype/landed_cost_item/landed_cost_item.json
#	erpnext/stock/doctype/landed_cost_purchase_receipt/landed_cost_purchase_receipt.json
#	erpnext/stock/doctype/landed_cost_taxes_and_charges/landed_cost_taxes_and_charges.json
#	erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.json
#	erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
#	erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
#	erpnext/stock/doctype/manufacturer/manufacturer.json
#	erpnext/stock/doctype/manufacturer/test_manufacturer.py
#	erpnext/stock/doctype/material_request/material_request.js
#	erpnext/stock/doctype/material_request/material_request.json
#	erpnext/stock/doctype/material_request/material_request.py
#	erpnext/stock/doctype/material_request/material_request_list.js
#	erpnext/stock/doctype/material_request/test_material_request.py
#	erpnext/stock/doctype/material_request_item/material_request_item.json
#	erpnext/stock/doctype/packed_item/packed_item.json
#	erpnext/stock/doctype/packed_item/packed_item.py
#	erpnext/stock/doctype/packed_item/test_packed_item.py
#	erpnext/stock/doctype/packing_slip/packing_slip.json
#	erpnext/stock/doctype/packing_slip/test_packing_slip.py
#	erpnext/stock/doctype/packing_slip_item/packing_slip_item.json
#	erpnext/stock/doctype/pick_list/pick_list.json
#	erpnext/stock/doctype/pick_list/pick_list_list.js
#	erpnext/stock/doctype/pick_list/test_pick_list.py
#	erpnext/stock/doctype/pick_list_item/pick_list_item.json
#	erpnext/stock/doctype/price_list/price_list.json
#	erpnext/stock/doctype/price_list/price_list.py
#	erpnext/stock/doctype/price_list/test_price_list.py
#	erpnext/stock/doctype/price_list_country/price_list_country.json
#	erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
#	erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
#	erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
#	erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
#	erpnext/stock/doctype/putaway_rule/putaway_rule.json
#	erpnext/stock/doctype/putaway_rule/putaway_rule.py
#	erpnext/stock/doctype/putaway_rule/test_putaway_rule.py
#	erpnext/stock/doctype/quality_inspection/quality_inspection.json
#	erpnext/stock/doctype/quality_inspection/test_quality_inspection.py
#	erpnext/stock/doctype/quality_inspection_parameter/quality_inspection_parameter.json
#	erpnext/stock/doctype/quality_inspection_parameter/test_quality_inspection_parameter.py
#	erpnext/stock/doctype/quality_inspection_parameter_group/quality_inspection_parameter_group.json
#	erpnext/stock/doctype/quality_inspection_parameter_group/test_quality_inspection_parameter_group.py
#	erpnext/stock/doctype/quality_inspection_reading/quality_inspection_reading.json
#	erpnext/stock/doctype/quality_inspection_template/quality_inspection_template.json
#	erpnext/stock/doctype/quality_inspection_template/test_quality_inspection_template.py
#	erpnext/stock/doctype/quick_stock_balance/quick_stock_balance.json
#	erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.json
#	erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
#	erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
#	erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.json
#	erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py
#	erpnext/stock/doctype/serial_and_batch_bundle/test_serial_and_batch_bundle.py
#	erpnext/stock/doctype/serial_and_batch_entry/serial_and_batch_entry.json
#	erpnext/stock/doctype/serial_no/serial_no.json
#	erpnext/stock/doctype/serial_no/test_serial_no.py
#	erpnext/stock/doctype/shipment/shipment.json
#	erpnext/stock/doctype/shipment/test_shipment.py
#	erpnext/stock/doctype/shipment_delivery_note/shipment_delivery_note.json
#	erpnext/stock/doctype/shipment_parcel/shipment_parcel.json
#	erpnext/stock/doctype/shipment_parcel_template/shipment_parcel_template.json
#	erpnext/stock/doctype/shipment_parcel_template/test_shipment_parcel_template.py
#	erpnext/stock/doctype/stock_entry/stock_entry.json
#	erpnext/stock/doctype/stock_entry/stock_entry.py
#	erpnext/stock/doctype/stock_entry/test_stock_entry.py
#	erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
#	erpnext/stock/doctype/stock_entry_type/stock_entry_type.json
#	erpnext/stock/doctype/stock_entry_type/stock_entry_type.py
#	erpnext/stock/doctype/stock_entry_type/test_stock_entry_type.py
#	erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.json
#	erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
#	erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
#	erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
#	erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
#	erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
#	erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
#	erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
#	erpnext/stock/doctype/stock_reposting_settings/test_stock_reposting_settings.py
#	erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.json
#	erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
#	erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py
#	erpnext/stock/doctype/stock_settings/stock_settings.json
#	erpnext/stock/doctype/stock_settings/stock_settings.py
#	erpnext/stock/doctype/stock_settings/test_stock_settings.py
#	erpnext/stock/doctype/uom_category/test_uom_category.py
#	erpnext/stock/doctype/uom_category/uom_category.json
#	erpnext/stock/doctype/uom_conversion_detail/uom_conversion_detail.json
#	erpnext/stock/doctype/variant_field/test_variant_field.py
#	erpnext/stock/doctype/variant_field/variant_field.json
#	erpnext/stock/doctype/warehouse/test_warehouse.py
#	erpnext/stock/doctype/warehouse/warehouse.json
#	erpnext/stock/doctype/warehouse/warehouse.py
#	erpnext/stock/doctype/warehouse_type/test_warehouse_type.py
#	erpnext/stock/doctype/warehouse_type/warehouse_type.json
#	erpnext/stock/get_item_details.py
#	erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary.js
#	erpnext/stock/page/warehouse_capacity_summary/warehouse_capacity_summary_header.html
#	erpnext/stock/print_format/purchase_receipt_serial_and_batch_bundle_print/purchase_receipt_serial_and_batch_bundle_print.json
#	erpnext/stock/reorder_item.py
#	erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
#	erpnext/stock/report/item_shortage_report/test_item_shortage_report.py
#	erpnext/stock/report/reserved_stock/test_reserved_stock.py
#	erpnext/stock/report/stock_ageing/test_stock_ageing.py
#	erpnext/stock/report/stock_analytics/test_stock_analytics.py
#	erpnext/stock/report/stock_balance/test_stock_balance.py
#	erpnext/stock/report/stock_ledger/test_stock_ledger_report.py
#	erpnext/stock/report/test_reports.py
#	erpnext/stock/serial_batch_bundle.py
#	erpnext/stock/stock_balance.py
#	erpnext/stock/stock_ledger.py
#	erpnext/stock/tests/test_get_item_details.py
#	erpnext/stock/tests/test_utils.py
#	erpnext/stock/tests/test_valuation.py
#	erpnext/stock/utils.py
#	erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.json
#	erpnext/subcontracting/doctype/subcontracting_bom/subcontracting_bom.py
#	erpnext/subcontracting/doctype/subcontracting_bom/test_subcontracting_bom.py
#	erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.json
#	erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
#	erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order_list.js
#	erpnext/subcontracting/doctype/subcontracting_order/test_subcontracting_order.py
#	erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
#	erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.py
#	erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.json
#	erpnext/subcontracting/doctype/subcontracting_order_supplied_item/subcontracting_order_supplied_item.json
#	erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.json
#	erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py
#	erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt_list.js
#	erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
#	erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json
#	erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.py
#	erpnext/subcontracting/doctype/subcontracting_receipt_supplied_item/subcontracting_receipt_supplied_item.json
#	erpnext/support/doctype/issue/issue.json
#	erpnext/support/doctype/issue/issue.py
#	erpnext/support/doctype/issue/test_issue.py
#	erpnext/support/doctype/issue_priority/issue_priority.json
#	erpnext/support/doctype/issue_priority/test_issue_priority.py
#	erpnext/support/doctype/issue_type/issue_type.json
#	erpnext/support/doctype/issue_type/test_issue_type.py
#	erpnext/support/doctype/pause_sla_on_status/pause_sla_on_status.json
#	erpnext/support/doctype/service_day/service_day.json
#	erpnext/support/doctype/service_level_agreement/service_level_agreement.json
#	erpnext/support/doctype/service_level_agreement/service_level_agreement.py
#	erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
#	erpnext/support/doctype/service_level_priority/service_level_priority.json
#	erpnext/support/doctype/sla_fulfilled_on_status/sla_fulfilled_on_status.json
#	erpnext/support/doctype/support_search_source/support_search_source.json
#	erpnext/support/doctype/support_settings/support_settings.json
#	erpnext/support/doctype/support_settings/test_support_settings.py
#	erpnext/support/doctype/warranty_claim/test_warranty_claim.py
#	erpnext/support/doctype/warranty_claim/warranty_claim.json
#	erpnext/support/doctype/warranty_claim/warranty_claim.py
#	erpnext/support/report/issue_analytics/test_issue_analytics.py
#	erpnext/telephony/doctype/call_log/test_call_log.py
#	erpnext/telephony/doctype/incoming_call_handling_schedule/incoming_call_handling_schedule.json
#	erpnext/telephony/doctype/incoming_call_settings/incoming_call_settings.json
#	erpnext/telephony/doctype/incoming_call_settings/test_incoming_call_settings.py
#	erpnext/telephony/doctype/telephony_call_type/telephony_call_type.json
#	erpnext/telephony/doctype/telephony_call_type/test_telephony_call_type.py
#	erpnext/telephony/doctype/voice_call_settings/test_voice_call_settings.py
#	erpnext/telephony/doctype/voice_call_settings/voice_call_settings.json
#	erpnext/templates/form_grid/includes/visible_cols.html
#	erpnext/templates/generators/sales_partner.html
#	erpnext/templates/includes/issue_row.html
#	erpnext/templates/includes/macros.html
#	erpnext/templates/includes/projects/project_row.html
#	erpnext/templates/includes/transaction_row.html
#	erpnext/templates/pages/order.html
#	erpnext/templates/pages/order.py
#	erpnext/templates/pages/timelog_info.html
#	erpnext/templates/print_formats/includes/total.html
#	erpnext/tests/test_activation.py
#	erpnext/tests/test_init.py
#	erpnext/tests/test_notifications.py
#	erpnext/tests/test_perf.py
#	erpnext/tests/test_point_of_sale.py
#	erpnext/tests/test_regional.py
#	erpnext/tests/test_webform.py
#	erpnext/tests/test_zform_loads.py
#	erpnext/utilities/activation.py
#	erpnext/utilities/bulk_transaction.py
#	erpnext/utilities/doctype/portal_user/portal_user.json
#	erpnext/utilities/doctype/rename_tool/rename_tool.json
#	erpnext/utilities/doctype/video/test_video.py
#	erpnext/utilities/doctype/video/video.json
#	erpnext/utilities/doctype/video/video.py
#	erpnext/utilities/doctype/video_settings/test_video_settings.py
#	erpnext/utilities/doctype/video_settings/video_settings.json
#	erpnext/www/support/index.py
#	pyproject.toml
2024-12-11 09:26:02 +00:00

996 lines
32 KiB
Python

# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
from frappe import ValidationError, _, msgprint
from frappe.contacts.doctype.address.address import render_address
from frappe.utils import cint, flt, getdate
from frappe.utils.data import nowtime
import erpnext
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
from erpnext.accounts.party import get_party_details
from erpnext.buying.utils import update_last_purchase_rate, validate_for_items
from erpnext.controllers.sales_and_purchase_return import get_rate_for_return
from erpnext.controllers.subcontracting_controller import SubcontractingController
from erpnext.stock.get_item_details import get_conversion_factor
from erpnext.stock.utils import get_incoming_rate
class QtyMismatchError(ValidationError):
pass
class BuyingController(SubcontractingController):
def __setup__(self):
self.flags.ignore_permlevel_for_fields = ["buying_price_list", "price_list_currency"]
def validate(self):
self.set_rate_for_standalone_debit_note()
super().validate()
if getattr(self, "supplier", None) and not self.supplier_name:
self.supplier_name = frappe.db.get_value("Supplier", self.supplier, "supplier_name")
self.validate_items()
self.set_qty_as_per_stock_uom()
self.validate_stock_or_nonstock_items()
self.validate_warehouse()
self.validate_from_warehouse()
self.set_supplier_address()
self.validate_asset_return()
self.validate_auto_repeat_subscription_dates()
self.create_package_for_transfer()
if self.doctype == "Purchase Invoice":
self.validate_purchase_receipt_if_update_stock()
if self.doctype == "Purchase Receipt" or (self.doctype == "Purchase Invoice" and self.update_stock):
# self.validate_purchase_return()
self.validate_rejected_warehouse()
self.validate_accepted_rejected_qty()
validate_for_items(self)
# sub-contracting
self.validate_for_subcontracting()
if self.get("is_old_subcontracting_flow"):
self.create_raw_materials_supplied()
self.set_landed_cost_voucher_amount()
if self.doctype in ("Purchase Receipt", "Purchase Invoice"):
self.update_valuation_rate()
self.set_serial_and_batch_bundle()
def onload(self):
super().onload()
self.set_onload(
"backflush_based_on",
frappe.db.get_single_value("Buying Settings", "backflush_raw_materials_of_subcontract_based_on"),
)
def create_package_for_transfer(self) -> None:
"""Create serial and batch package for Sourece Warehouse in case of inter transfer."""
if self.is_internal_transfer() and (
self.doctype == "Purchase Receipt" or (self.doctype == "Purchase Invoice" and self.update_stock)
):
field = "delivery_note_item" if self.doctype == "Purchase Receipt" else "sales_invoice_item"
doctype = "Delivery Note Item" if self.doctype == "Purchase Receipt" else "Sales Invoice Item"
ids = [d.get(field) for d in self.get("items") if d.get(field)]
bundle_ids = {}
if ids:
for bundle in frappe.get_all(
doctype, filters={"name": ("in", ids)}, fields=["serial_and_batch_bundle", "name"]
):
bundle_ids[bundle.name] = bundle.serial_and_batch_bundle
if not bundle_ids:
return
for item in self.get("items"):
if item.get(field) and not item.serial_and_batch_bundle and bundle_ids.get(item.get(field)):
item.serial_and_batch_bundle = self.make_package_for_transfer(
bundle_ids.get(item.get(field)),
item.from_warehouse,
type_of_transaction="Outward",
do_not_submit=True,
)
def set_rate_for_standalone_debit_note(self):
if self.get("is_return") and self.get("update_stock") and not self.return_against:
for row in self.items:
if row.rate <= 0:
# override the rate with valuation rate
row.rate = get_incoming_rate(
{
"item_code": row.item_code,
"warehouse": row.warehouse,
"posting_date": self.get("posting_date"),
"posting_time": self.get("posting_time"),
"qty": row.qty,
"serial_and_batch_bundle": row.get("serial_and_batch_bundle"),
"company": self.company,
"voucher_type": self.doctype,
"voucher_no": self.name,
"voucher_detail_no": row.name,
},
raise_error_if_no_rate=False,
)
row.discount_percentage = 0.0
row.discount_amount = 0.0
row.margin_rate_or_amount = 0.0
def set_missing_values(self, for_validate=False):
super().set_missing_values(for_validate)
self.set_supplier_from_item_default()
self.set_price_list_currency("Buying")
# set contact and address details for supplier, if they are not mentioned
if getattr(self, "supplier", None):
self.update_if_missing(
get_party_details(
self.supplier,
party_type="Supplier",
doctype=self.doctype,
company=self.company,
party_address=self.get("supplier_address"),
shipping_address=self.get("shipping_address"),
company_address=self.get("billing_address"),
fetch_payment_terms_template=not self.get("ignore_default_payment_terms_template"),
ignore_permissions=self.flags.ignore_permissions,
)
)
self.set_missing_item_details(for_validate)
def set_supplier_from_item_default(self):
if self.meta.get_field("supplier") and not self.supplier:
for d in self.get("items"):
supplier = frappe.db.get_value(
"Item Default", {"parent": d.item_code, "company": self.company}, "default_supplier"
)
if supplier:
self.supplier = supplier
else:
item_group = frappe.db.get_value("Item", d.item_code, "item_group")
supplier = frappe.db.get_value(
"Item Default", {"parent": item_group, "company": self.company}, "default_supplier"
)
if supplier:
self.supplier = supplier
break
def validate_stock_or_nonstock_items(self):
if self.meta.get_field("taxes") and not self.get_stock_items() and not self.get_asset_items():
msg = _('Tax Category has been changed to "Total" because all the Items are non-stock items')
self.update_tax_category(msg)
def update_tax_category(self, msg):
tax_for_valuation = [
d for d in self.get("taxes") if d.category in ["Valuation", "Valuation and Total"]
]
if tax_for_valuation:
for d in tax_for_valuation:
d.category = "Total"
msgprint(msg)
def validate_asset_return(self):
if self.doctype not in ["Purchase Receipt", "Purchase Invoice"] or not self.is_return:
return
purchase_doc_field = "purchase_receipt" if self.doctype == "Purchase Receipt" else "purchase_invoice"
not_cancelled_asset = []
if self.return_against:
not_cancelled_asset = [
d.name
for d in frappe.db.get_all("Asset", {purchase_doc_field: self.return_against, "docstatus": 1})
]
if self.is_return and len(not_cancelled_asset):
frappe.throw(
_(
"{} has submitted assets linked to it. You need to cancel the assets to create purchase return."
).format(self.return_against),
title=_("Not Allowed"),
)
def get_asset_items(self):
if self.doctype not in ["Purchase Order", "Purchase Invoice", "Purchase Receipt"]:
return []
return [d.item_code for d in self.items if d.is_fixed_asset]
def set_landed_cost_voucher_amount(self):
for d in self.get("items"):
lc_voucher_data = frappe.db.sql(
"""select sum(applicable_charges), cost_center
from `tabLanded Cost Item`
where docstatus = 1 and purchase_receipt_item = %s and receipt_document = %s""",
(d.name, self.name),
)
d.landed_cost_voucher_amount = lc_voucher_data[0][0] if lc_voucher_data else 0.0
if not d.cost_center and lc_voucher_data and lc_voucher_data[0][1]:
d.db_set("cost_center", lc_voucher_data[0][1])
def validate_from_warehouse(self):
for item in self.get("items"):
if item.get("from_warehouse") and (item.get("from_warehouse") == item.get("warehouse")):
frappe.throw(
_("Row #{0}: Accepted Warehouse and Supplier Warehouse cannot be same").format(item.idx)
)
if item.get("from_warehouse") and self.get("is_subcontracted"):
frappe.throw(
_(
"Row #{0}: Cannot select Supplier Warehouse while suppling raw materials to subcontractor"
).format(item.idx)
)
def set_supplier_address(self):
address_dict = {
"supplier_address": "address_display",
"shipping_address": "shipping_address_display",
"billing_address": "billing_address_display",
}
for address_field, address_display_field in address_dict.items():
if self.get(address_field):
self.set(
address_display_field, render_address(self.get(address_field), check_permissions=False)
)
def set_total_in_words(self):
from frappe.utils import money_in_words
if self.meta.get_field("base_in_words"):
if self.meta.get_field("base_rounded_total") and not self.is_rounded_total_disabled():
<<<<<<< HEAD
amount = abs(self.base_rounded_total)
else:
amount = abs(self.base_grand_total)
=======
amount = abs(flt(self.base_rounded_total))
else:
amount = abs(flt(self.base_grand_total))
>>>>>>> 329d14957b (fix: validate negative qty)
self.base_in_words = money_in_words(amount, self.company_currency)
if self.meta.get_field("in_words"):
if self.meta.get_field("rounded_total") and not self.is_rounded_total_disabled():
<<<<<<< HEAD
amount = abs(self.rounded_total)
else:
amount = abs(self.grand_total)
=======
amount = abs(flt(self.rounded_total))
else:
amount = abs(flt(self.grand_total))
>>>>>>> 329d14957b (fix: validate negative qty)
self.in_words = money_in_words(amount, self.currency)
# update valuation rate
def update_valuation_rate(self, reset_outgoing_rate=True):
"""
item_tax_amount is the total tax amount applied on that item
stored for valuation
TODO: rename item_tax_amount to valuation_tax_amount
"""
stock_and_asset_items = []
stock_and_asset_items = self.get_stock_items() + self.get_asset_items()
stock_and_asset_items_qty, stock_and_asset_items_amount = 0, 0
last_item_idx = 1
for d in self.get("items"):
if d.item_code and d.item_code in stock_and_asset_items:
stock_and_asset_items_qty += flt(d.qty)
stock_and_asset_items_amount += flt(d.base_net_amount)
last_item_idx = d.idx
total_valuation_amount = sum(
flt(d.base_tax_amount_after_discount_amount)
for d in self.get("taxes")
if d.category in ["Valuation", "Valuation and Total"]
)
valuation_amount_adjustment = total_valuation_amount
for i, item in enumerate(self.get("items")):
if item.item_code and item.qty and item.item_code in stock_and_asset_items:
item_proportion = (
flt(item.base_net_amount) / stock_and_asset_items_amount
if stock_and_asset_items_amount
else flt(item.qty) / stock_and_asset_items_qty
)
if i == (last_item_idx - 1):
item.item_tax_amount = flt(
valuation_amount_adjustment, self.precision("item_tax_amount", item)
)
else:
item.item_tax_amount = flt(
item_proportion * total_valuation_amount, self.precision("item_tax_amount", item)
)
valuation_amount_adjustment -= item.item_tax_amount
self.round_floats_in(item)
if flt(item.conversion_factor) == 0.0:
item.conversion_factor = (
get_conversion_factor(item.item_code, item.uom).get("conversion_factor") or 1.0
)
net_rate = item.base_net_amount
if item.sales_incoming_rate: # for internal transfer
net_rate = item.qty * item.sales_incoming_rate
qty_in_stock_uom = flt(item.qty * item.conversion_factor)
if self.get("is_old_subcontracting_flow"):
item.rm_supp_cost = self.get_supplied_items_cost(item.name, reset_outgoing_rate)
item.valuation_rate = (
net_rate
+ item.item_tax_amount
+ item.rm_supp_cost
+ flt(item.landed_cost_voucher_amount)
) / qty_in_stock_uom
else:
item.valuation_rate = (
net_rate
+ item.item_tax_amount
+ flt(item.landed_cost_voucher_amount)
+ flt(item.get("rate_difference_with_purchase_invoice"))
) / qty_in_stock_uom
else:
item.valuation_rate = 0.0
update_regional_item_valuation_rate(self)
def set_incoming_rate(self):
"""
Override item rate with incoming rate for internal stock transfer
"""
if self.doctype not in ("Purchase Receipt", "Purchase Invoice"):
return
if not (self.doctype == "Purchase Receipt" or self.get("update_stock")):
return
if cint(self.get("is_return")):
# Get outgoing rate based on original item cost based on valuation method
return
if not self.is_internal_transfer():
return
self.set_sales_incoming_rate_for_internal_transfer()
allow_at_arms_length_price = frappe.get_cached_value(
"Stock Settings", None, "allow_internal_transfer_at_arms_length_price"
)
if allow_at_arms_length_price:
return
for d in self.get("items"):
d.discount_percentage = 0.0
d.discount_amount = 0.0
d.margin_rate_or_amount = 0.0
if d.rate == d.sales_incoming_rate:
continue
d.rate = d.sales_incoming_rate
frappe.msgprint(
_(
"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
).format(d.idx),
alert=1,
)
def set_sales_incoming_rate_for_internal_transfer(self):
"""
Set incoming rate from the sales transaction against which the
purchase is made (internal transfer)
"""
ref_doctype_map = {
"Purchase Receipt": "Delivery Note Item",
"Purchase Invoice": "Sales Invoice Item",
}
ref_doctype = ref_doctype_map.get(self.doctype)
for d in self.get("items"):
if not d.get(frappe.scrub(ref_doctype)):
posting_time = self.get("posting_time")
if not posting_time:
posting_time = nowtime()
outgoing_rate = get_incoming_rate(
{
"item_code": d.item_code,
"warehouse": d.get("from_warehouse"),
"posting_date": self.get("posting_date") or self.get("transaction_date"),
"posting_time": posting_time,
"qty": -1 * flt(d.get("stock_qty")),
"serial_and_batch_bundle": d.get("serial_and_batch_bundle"),
"company": self.company,
"voucher_type": self.doctype,
"voucher_no": self.name,
"allow_zero_valuation": d.get("allow_zero_valuation"),
"voucher_detail_no": d.name,
},
raise_error_if_no_rate=False,
)
d.sales_incoming_rate = flt(outgoing_rate * (d.conversion_factor or 1), d.precision("rate"))
else:
field = "incoming_rate" if self.get("is_internal_supplier") else "rate"
d.sales_incoming_rate = flt(
frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), field)
* (d.conversion_factor or 1),
d.precision("rate"),
)
def validate_for_subcontracting(self):
if self.is_subcontracted and self.get("is_old_subcontracting_flow"):
if self.doctype in ["Purchase Receipt", "Purchase Invoice"] and not self.supplier_warehouse:
frappe.throw(_("Supplier Warehouse mandatory for sub-contracted {0}").format(self.doctype))
for item in self.get("items"):
if item in self.sub_contracted_items and not item.bom:
frappe.throw(_("Please select BOM in BOM field for Item {0}").format(item.item_code))
if self.doctype != "Purchase Order":
return
for row in self.get("supplied_items"):
if not row.reserve_warehouse:
msg = f"Reserved Warehouse is mandatory for the Item {frappe.bold(row.rm_item_code)} in Raw Materials supplied"
frappe.throw(_(msg))
else:
for item in self.get("items"):
if item.get("bom"):
item.bom = None
def set_qty_as_per_stock_uom(self):
allow_to_edit_stock_qty = frappe.db.get_single_value(
"Stock Settings", "allow_to_edit_stock_uom_qty_for_purchase"
)
for d in self.get("items"):
if d.meta.get_field("stock_qty"):
# Check if item code is present
# Conversion factor should not be mandatory for non itemized items
if not d.conversion_factor and d.item_code:
frappe.throw(_("Row {0}: Conversion Factor is mandatory").format(d.idx))
d.stock_qty = flt(d.qty) * flt(d.conversion_factor)
if self.doctype == "Purchase Receipt" and d.meta.get_field("received_stock_qty"):
# Set Received Qty in Stock UOM
d.received_stock_qty = flt(d.received_qty) * flt(
d.conversion_factor, d.precision("conversion_factor")
)
if allow_to_edit_stock_qty:
d.stock_qty = flt(d.stock_qty, d.precision("stock_qty"))
if d.get("received_stock_qty") and d.meta.get_field("received_stock_qty"):
d.received_stock_qty = flt(d.received_stock_qty, d.precision("received_stock_qty"))
def validate_purchase_return(self):
for d in self.get("items"):
if self.is_return and flt(d.rejected_qty) != 0:
frappe.throw(_("Row #{0}: Rejected Qty can not be entered in Purchase Return").format(d.idx))
# validate rate with ref PR
# validate accepted and rejected qty
def validate_accepted_rejected_qty(self):
for d in self.get("items"):
self.validate_negative_quantity(d, ["received_qty", "qty", "rejected_qty"])
if not flt(d.received_qty) and (flt(d.qty) or flt(d.rejected_qty)):
d.received_qty = flt(d.qty) + flt(d.rejected_qty)
# Check Received Qty = Accepted Qty + Rejected Qty
val = flt(d.qty) + flt(d.rejected_qty)
if flt(val, d.precision("received_qty")) != flt(d.received_qty, d.precision("received_qty")):
message = _(
"Row #{0}: Received Qty must be equal to Accepted + Rejected Qty for Item {1}"
).format(d.idx, d.item_code)
frappe.throw(msg=message, title=_("Mismatch"), exc=QtyMismatchError)
def validate_negative_quantity(self, item_row, field_list):
if self.is_return:
return
item_row = item_row.as_dict()
for fieldname in field_list:
if flt(item_row[fieldname]) < 0:
frappe.throw(
_("Row #{0}: {1} can not be negative for item {2}").format(
item_row["idx"],
frappe.get_meta(item_row.doctype).get_label(fieldname),
item_row["item_code"],
)
)
def check_for_on_hold_or_closed_status(self, ref_doctype, ref_fieldname):
for d in self.get("items"):
if d.get(ref_fieldname):
status = frappe.db.get_value(ref_doctype, d.get(ref_fieldname), "status")
if status in ("Closed", "On Hold"):
frappe.throw(_("{0} {1} is {2}").format(ref_doctype, d.get(ref_fieldname), status))
def update_stock_ledger(self, allow_negative_stock=False, via_landed_cost_voucher=False):
self.update_ordered_and_reserved_qty()
sl_entries = []
stock_items = self.get_stock_items()
for d in self.get("items"):
if d.item_code not in stock_items:
continue
if d.warehouse:
pr_qty = flt(flt(d.qty) * flt(d.conversion_factor), d.precision("stock_qty"))
if pr_qty:
if d.from_warehouse and (
(not cint(self.is_return) and self.docstatus == 1)
or (cint(self.is_return) and self.docstatus == 2)
):
serial_and_batch_bundle = d.get("serial_and_batch_bundle")
if self.is_internal_transfer() and self.is_return and self.docstatus == 2:
serial_and_batch_bundle = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_detail_no": d.name, "warehouse": d.from_warehouse},
"serial_and_batch_bundle",
)
from_warehouse_sle = self.get_sl_entries(
d,
{
"actual_qty": -1 * pr_qty,
"warehouse": d.from_warehouse,
"outgoing_rate": d.rate,
"recalculate_rate": 1,
"dependant_sle_voucher_detail_no": d.name,
"serial_and_batch_bundle": serial_and_batch_bundle,
},
)
sl_entries.append(from_warehouse_sle)
type_of_transaction = "Inward"
if self.docstatus == 2:
type_of_transaction = "Outward"
sle = self.get_sl_entries(
d,
{
"actual_qty": flt(pr_qty),
"serial_and_batch_bundle": (
d.serial_and_batch_bundle
if not self.is_internal_transfer()
or self.is_return
or (self.is_internal_transfer() and self.docstatus == 2)
else self.get_package_for_target_warehouse(
d, type_of_transaction=type_of_transaction
)
),
},
)
if self.is_return:
outgoing_rate = get_rate_for_return(
self.doctype, self.name, d.item_code, self.return_against, item_row=d
)
sle.update(
{
"outgoing_rate": outgoing_rate,
"recalculate_rate": 1,
"serial_and_batch_bundle": d.serial_and_batch_bundle,
}
)
if d.from_warehouse:
sle.dependant_sle_voucher_detail_no = d.name
else:
sle.update(
{
"incoming_rate": d.valuation_rate,
"recalculate_rate": 1
if (self.is_subcontracted and (d.bom or d.get("fg_item"))) or d.from_warehouse
else 0,
}
)
sl_entries.append(sle)
if d.from_warehouse and (
(not cint(self.is_return) and self.docstatus == 2)
or (cint(self.is_return) and self.docstatus == 1)
):
serial_and_batch_bundle = None
if self.is_internal_transfer() and self.docstatus == 2:
serial_and_batch_bundle = frappe.db.get_value(
"Stock Ledger Entry",
{"voucher_detail_no": d.name, "warehouse": d.warehouse},
"serial_and_batch_bundle",
)
from_warehouse_sle = self.get_sl_entries(
d,
{
"actual_qty": -1 * pr_qty,
"warehouse": d.from_warehouse,
"recalculate_rate": 1,
"serial_and_batch_bundle": (
self.get_package_for_target_warehouse(d, d.from_warehouse, "Inward")
if self.is_internal_transfer() and self.is_return
else serial_and_batch_bundle
),
},
)
sl_entries.append(from_warehouse_sle)
if flt(d.rejected_qty) != 0:
sl_entries.append(
self.get_sl_entries(
d,
{
"warehouse": d.rejected_warehouse,
"actual_qty": flt(
flt(d.rejected_qty) * flt(d.conversion_factor), d.precision("stock_qty")
),
"incoming_rate": 0.0,
"serial_and_batch_bundle": d.rejected_serial_and_batch_bundle,
},
)
)
if self.get("is_old_subcontracting_flow"):
self.make_sl_entries_for_supplier_warehouse(sl_entries)
self.make_sl_entries(
sl_entries,
allow_negative_stock=allow_negative_stock,
via_landed_cost_voucher=via_landed_cost_voucher,
)
def get_package_for_target_warehouse(self, item, warehouse=None, type_of_transaction=None) -> str:
if not item.serial_and_batch_bundle:
return ""
if not warehouse:
warehouse = item.warehouse
return self.make_package_for_transfer(
item.serial_and_batch_bundle, warehouse, type_of_transaction=type_of_transaction
)
def update_ordered_and_reserved_qty(self):
po_map = {}
for d in self.get("items"):
if self.doctype == "Purchase Receipt" and d.purchase_order:
po_map.setdefault(d.purchase_order, []).append(d.purchase_order_item)
elif self.doctype == "Purchase Invoice" and d.purchase_order and d.po_detail:
po_map.setdefault(d.purchase_order, []).append(d.po_detail)
for po, po_item_rows in po_map.items():
if po and po_item_rows:
po_obj = frappe.get_doc("Purchase Order", po)
if po_obj.status in ["Closed", "Cancelled"]:
frappe.throw(
_("{0} {1} is cancelled or closed").format(_("Purchase Order"), po),
frappe.InvalidStatusError,
)
po_obj.update_ordered_qty(po_item_rows)
if self.get("is_old_subcontracting_flow"):
po_obj.update_reserved_qty_for_subcontract()
def on_submit(self):
if self.get("is_return"):
return
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
self.process_fixed_asset()
if self.doctype in [
"Purchase Order",
"Purchase Receipt",
"Purchase Invoice",
] and not frappe.db.get_single_value("Buying Settings", "disable_last_purchase_rate"):
update_last_purchase_rate(self, is_submit=1)
def on_cancel(self):
super().on_cancel()
if self.get("is_return"):
return
if self.doctype in [
"Purchase Order",
"Purchase Receipt",
"Purchase Invoice",
] and not frappe.db.get_single_value("Buying Settings", "disable_last_purchase_rate"):
update_last_purchase_rate(self, is_submit=0)
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
field = "purchase_invoice" if self.doctype == "Purchase Invoice" else "purchase_receipt"
self.delete_linked_asset()
self.update_fixed_asset(field, delete_asset=True)
def validate_budget(self):
if self.docstatus == 1:
for data in self.get("items"):
args = data.as_dict()
args.update(
{
"doctype": self.doctype,
"company": self.company,
"posting_date": (
self.schedule_date
if self.doctype == "Material Request"
else self.transaction_date
),
}
)
validate_expense_against_budget(args)
def process_fixed_asset(self):
if self.doctype == "Purchase Invoice" and not self.update_stock:
return
asset_items = self.get_asset_items()
if asset_items:
self.auto_make_assets(asset_items)
def auto_make_assets(self, asset_items):
items_data = get_asset_item_details(asset_items)
messages = []
<<<<<<< HEAD
=======
alert = False
>>>>>>> 329d14957b (fix: validate negative qty)
for d in self.items:
if d.is_fixed_asset:
item_data = items_data.get(d.item_code)
if item_data.get("auto_create_assets"):
# If asset has to be auto created
# Check for asset naming series
if item_data.get("asset_naming_series"):
created_assets = []
if item_data.get("is_grouped_asset"):
asset = self.make_asset(d, is_grouped_asset=True)
created_assets.append(asset)
else:
for _qty in range(cint(d.qty)):
asset = self.make_asset(d)
created_assets.append(asset)
if len(created_assets) > 5:
# dont show asset form links if more than 5 assets are created
messages.append(
_("{} Assets created for {}").format(
len(created_assets), frappe.bold(d.item_code)
)
)
else:
assets_link = list(
map(lambda d: frappe.utils.get_link_to_form("Asset", d), created_assets)
)
assets_link = frappe.bold(",".join(assets_link))
is_plural = "s" if len(created_assets) != 1 else ""
messages.append(
_("Asset{} {assets_link} created for {}").format(
is_plural, frappe.bold(d.item_code), assets_link=assets_link
)
)
else:
frappe.throw(
_(
"Row {}: Asset Naming Series is mandatory for the auto creation for item {}"
).format(d.idx, frappe.bold(d.item_code))
)
else:
messages.append(
_("Assets not created for {0}. You will have to create asset manually.").format(
frappe.bold(d.item_code)
)
)
<<<<<<< HEAD
for message in messages:
frappe.msgprint(message, title="Success", indicator="green")
=======
alert = True
for message in messages:
frappe.msgprint(message, title="Success", indicator="green", alert=alert)
>>>>>>> 329d14957b (fix: validate negative qty)
def make_asset(self, row, is_grouped_asset=False):
if not row.asset_location:
frappe.throw(_("Row {0}: Enter location for the asset item {1}").format(row.idx, row.item_code))
item_data = frappe.get_cached_value(
"Item", row.item_code, ["asset_naming_series", "asset_category"], as_dict=1
)
asset_quantity = row.qty if is_grouped_asset else 1
purchase_amount = flt(row.valuation_rate) * asset_quantity
asset = frappe.get_doc(
{
"doctype": "Asset",
"item_code": row.item_code,
"asset_name": row.item_name,
"naming_series": item_data.get("asset_naming_series") or "AST",
"asset_category": item_data.get("asset_category"),
"location": row.asset_location,
"company": self.company,
"supplier": self.supplier,
"purchase_date": self.posting_date,
"calculate_depreciation": 0,
"purchase_amount": purchase_amount,
"gross_purchase_amount": purchase_amount,
"asset_quantity": asset_quantity,
"purchase_receipt": self.name if self.doctype == "Purchase Receipt" else None,
"purchase_invoice": self.name if self.doctype == "Purchase Invoice" else None,
"purchase_receipt_item": row.name if self.doctype == "Purchase Receipt" else None,
"purchase_invoice_item": row.name if self.doctype == "Purchase Invoice" else None,
}
)
asset.flags.ignore_validate = True
asset.flags.ignore_mandatory = True
asset.set_missing_values()
asset.db_insert()
return asset.name
def update_fixed_asset(self, field, delete_asset=False):
for d in self.get("items"):
if d.is_fixed_asset:
is_auto_create_enabled = frappe.db.get_value("Item", d.item_code, "auto_create_assets")
assets = frappe.db.get_all("Asset", filters={field: self.name, "item_code": d.item_code})
for asset in assets:
asset = frappe.get_doc("Asset", asset.name)
if delete_asset and is_auto_create_enabled:
# need to delete movements to delete assets otherwise throws link exists error
movements = frappe.db.sql(
"""SELECT asm.name
FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
WHERE asm_item.parent=asm.name and asm_item.asset=%s""",
asset.name,
as_dict=1,
)
for movement in movements:
frappe.delete_doc("Asset Movement", movement.name, force=1)
frappe.delete_doc("Asset", asset.name, force=1)
continue
if self.docstatus == 2:
if asset.docstatus == 2:
continue
if asset.docstatus == 0:
asset.set(field, None)
asset.supplier = None
if asset.docstatus == 1 and delete_asset:
frappe.throw(
_(
"Cannot cancel this document as it is linked with submitted asset {0}. Please cancel it to continue."
).format(frappe.utils.get_link_to_form("Asset", asset.name))
)
asset.flags.ignore_validate_update_after_submit = True
asset.flags.ignore_mandatory = True
if asset.docstatus == 0:
asset.flags.ignore_validate = True
asset.save()
def delete_linked_asset(self):
if self.doctype == "Purchase Invoice" and not self.get("update_stock"):
return
asset_movement = frappe.db.get_value("Asset Movement", {"reference_name": self.name}, "name")
frappe.delete_doc("Asset Movement", asset_movement, force=1)
def validate_schedule_date(self):
if not self.get("items"):
return
if any(d.schedule_date for d in self.get("items")):
# Select earliest schedule_date.
self.schedule_date = min(
d.schedule_date for d in self.get("items") if d.schedule_date is not None
)
if self.schedule_date:
for d in self.get("items"):
if not d.schedule_date:
d.schedule_date = self.schedule_date
if (
d.schedule_date
and self.transaction_date
and getdate(d.schedule_date) < getdate(self.transaction_date)
):
frappe.throw(_("Row #{0}: Reqd by Date cannot be before Transaction Date").format(d.idx))
else:
frappe.throw(_("Please enter Reqd by Date"))
def validate_items(self):
# validate items to see if they have is_purchase_item or is_subcontracted_item enabled
if self.doctype == "Material Request":
return
if self.get("is_old_subcontracting_flow"):
validate_item_type(self, "is_sub_contracted_item", "subcontracted")
else:
validate_item_type(self, "is_purchase_item", "purchase")
def get_asset_item_details(asset_items):
asset_items_data = {}
for d in frappe.get_all(
"Item",
fields=["name", "auto_create_assets", "asset_naming_series", "is_grouped_asset"],
filters={"name": ("in", asset_items)},
):
asset_items_data.setdefault(d.name, d)
return asset_items_data
def validate_item_type(doc, fieldname, message):
# iterate through items and check if they are valid sales or purchase items
items = [d.item_code for d in doc.items if d.item_code]
# No validation check inase of creating transaction using 'Opening Invoice Creation Tool'
if not items:
return
item_list = ", ".join(["%s" % frappe.db.escape(d) for d in items])
invalid_items = [
d[0]
for d in frappe.db.sql(
f"""
select item_code from tabItem where name in ({item_list}) and {fieldname}=0
""",
as_list=True,
)
]
if invalid_items:
items = ", ".join([d for d in invalid_items])
if len(invalid_items) > 1:
error_message = _(
"Following items {0} are not marked as {1} item. You can enable them as {1} item from its Item master"
).format(items, message)
else:
error_message = _(
"Following item {0} is not marked as {1} item. You can enable them as {1} item from its Item master"
).format(items, message)
frappe.throw(error_message)
@erpnext.allow_regional
def update_regional_item_valuation_rate(doc):
pass