From d6360755b913fae9fedc1852c968000db1b5040a Mon Sep 17 00:00:00 2001 From: Walstan Baptista <38958184+walstanb@users.noreply.github.com> Date: Wed, 31 Mar 2021 12:30:32 +0530 Subject: [PATCH] chore: frappe.whitelist for doc methods (#25068) * chore: frappe.whitelist for doc methods * fix: incorrect spelling * fix: sider issue Co-authored-by: Sagar Vora --- erpnext/accounts/doctype/account/account.py | 2 + .../accounting_period/accounting_period.py | 1 + .../doctype/bank_clearance/bank_clearance.py | 2 + .../bank_statement_import.js | 39 ------------------- erpnext/accounts/doctype/c_form/c_form.py | 1 + .../doctype/cost_center/cost_center.py | 2 + .../exchange_rate_revaluation.py | 2 + .../doctype/fiscal_year/fiscal_year.py | 3 +- .../invoice_discounting.py | 2 + .../doctype/journal_entry/journal_entry.py | 1 + .../monthly_distribution.py | 1 + .../opening_invoice_creation_tool.py | 1 + .../payment_reconciliation.py | 3 ++ .../pos_closing_entry/pos_closing_entry.py | 11 +++--- .../doctype/pos_invoice/pos_invoice.py | 3 ++ .../doctype/sales_invoice/sales_invoice.py | 3 ++ .../doctype/crop_cycle/crop_cycle.py | 2 + .../doctype/fertilizer/fertilizer.py | 1 + .../doctype/plant_analysis/plant_analysis.py | 1 + .../doctype/soil_analysis/soil_analysis.py | 1 + .../doctype/soil_texture/soil_texture.py | 8 ++-- .../doctype/water_analysis/water_analysis.py | 2 + .../agriculture/doctype/weather/weather.py | 1 + erpnext/assets/doctype/asset/asset.py | 1 + .../doctype/purchase_order/purchase_order.py | 1 + .../request_for_quotation.py | 1 + erpnext/controllers/accounts_controller.py | 2 + .../linkedin_settings/linkedin_settings.py | 5 ++- .../crm/doctype/opportunity/opportunity.py | 1 + .../twitter_settings/twitter_settings.py | 17 ++++---- .../course_scheduling_tool.py | 1 + .../doctype/fee_schedule/fee_schedule.py | 1 + .../program_enrollment/program_enrollment.py | 2 + .../program_enrollment_tool.py | 2 + .../student_group_creation_tool.py | 2 + .../doctype/mpesa_settings/mpesa_settings.py | 5 ++- .../doctype/plaid_settings/plaid_settings.py | 1 + .../quickbooks_migrator.py | 1 + .../tally_migration/tally_migration.py | 4 ++ .../clinical_procedure/clinical_procedure.py | 3 ++ .../inpatient_medication_entry.py | 1 + .../inpatient_medication_order.py | 1 + .../inpatient_record/inpatient_record.py | 3 ++ erpnext/healthcare/doctype/patient/patient.py | 1 + .../patient_appointment.py | 1 + .../patient_history_settings.py | 2 + .../doctype/therapy_plan/therapy_plan.py | 1 + .../hr/doctype/expense_claim/expense_claim.py | 1 + .../leave_allocation/leave_allocation.py | 1 + .../leave_encashment/leave_encashment.py | 1 + .../leave_policy_assignment.py | 1 + erpnext/hr/doctype/shift_type/shift_type.py | 1 + .../maintenance_schedule.py | 1 + erpnext/manufacturing/doctype/bom/bom.py | 3 ++ .../doctype/job_card/job_card.py | 1 + .../production_plan/production_plan.py | 6 +++ .../doctype/work_order/work_order.py | 2 + erpnext/non_profit/doctype/member/member.py | 1 + .../doctype/membership/membership.py | 2 + .../non_profit_settings.py | 2 + .../doctype/payroll_entry/payroll_entry.py | 3 ++ .../doctype/salary_slip/salary_slip.py | 3 ++ .../quality_feedback/quality_feedback.py | 1 + .../tax_exemption_80g_certificate.py | 2 + .../selling/doctype/quotation/quotation.py | 1 + .../doctype/sales_order/sales_order.py | 1 + erpnext/setup/doctype/company/company.py | 1 + .../doctype/email_digest/email_digest.py | 2 + .../global_defaults/global_defaults.py | 1 + .../doctype/naming_series/naming_series.py | 4 ++ .../doctype/delivery_trip/delivery_trip.py | 1 + erpnext/stock/doctype/item/item.py | 2 + .../landed_cost_voucher.py | 1 + .../doctype/packing_slip/packing_slip.py | 1 + erpnext/stock/doctype/pick_list/pick_list.py | 1 + .../quality_inspection/quality_inspection.py | 2 + .../repost_item_valuation.py | 1 + .../stock/doctype/stock_entry/stock_entry.py | 3 ++ erpnext/support/doctype/issue/issue.py | 2 + 79 files changed, 149 insertions(+), 60 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index c801cfcbba..0606823821 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -214,6 +214,7 @@ class Account(NestedSet): if parent_value_changed: doc.save() + @frappe.whitelist() def convert_group_to_ledger(self): if self.check_if_child_exists(): throw(_("Account with child nodes cannot be converted to ledger")) @@ -224,6 +225,7 @@ class Account(NestedSet): self.save() return 1 + @frappe.whitelist() def convert_ledger_to_group(self): if self.check_gle_exists(): throw(_("Account with existing transaction can not be converted to group.")) diff --git a/erpnext/accounts/doctype/accounting_period/accounting_period.py b/erpnext/accounts/doctype/accounting_period/accounting_period.py index df6cedd7cf..63b5dbbd3e 100644 --- a/erpnext/accounts/doctype/accounting_period/accounting_period.py +++ b/erpnext/accounts/doctype/accounting_period/accounting_period.py @@ -39,6 +39,7 @@ class AccountingPeriod(Document): frappe.throw(_("Accounting Period overlaps with {0}") .format(existing_accounting_period[0].get("name")), OverlapError) + @frappe.whitelist() def get_doctypes_for_closing(self): docs_for_closing = [] doctypes = ["Sales Invoice", "Purchase Invoice", "Journal Entry", "Payroll Entry", \ diff --git a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py index 76d82e7339..79f5596384 100644 --- a/erpnext/accounts/doctype/bank_clearance/bank_clearance.py +++ b/erpnext/accounts/doctype/bank_clearance/bank_clearance.py @@ -12,6 +12,7 @@ form_grid_templates = { } class BankClearance(Document): + @frappe.whitelist() def get_payment_entries(self): if not (self.from_date and self.to_date): frappe.throw(_("From Date and To Date are Mandatory")) @@ -108,6 +109,7 @@ class BankClearance(Document): row.update(d) self.total_amount += flt(amount) + @frappe.whitelist() def update_clearance_date(self): clearance_date_updated = False for d in self.get('payment_entries'): diff --git a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js index ad4ff9ee60..3dbd605344 100644 --- a/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js +++ b/erpnext/accounts/doctype/bank_statement_import/bank_statement_import.js @@ -532,43 +532,4 @@ frappe.ui.form.on("Bank Statement Import", { `); }, - - show_missing_link_values(frm, missing_link_values) { - let can_be_created_automatically = missing_link_values.every( - (d) => d.has_one_mandatory_field - ); - - let html = missing_link_values - .map((d) => { - let doctype = d.doctype; - let values = d.missing_values; - return ` -
${doctype}
- - `; - }) - .join(""); - - if (can_be_created_automatically) { - // prettier-ignore - let message = __('There are some linked records which needs to be created before we can import your file. Do you want to create the following missing records automatically?'); - frappe.confirm(message + html, () => { - frm.call("create_missing_link_values", { - missing_link_values, - }).then((r) => { - let records = r.message; - frappe.msgprint(__( - "Created {0} records successfully.", [ - records.length, - ] - )); - }); - }); - } else { - frappe.msgprint( - // prettier-ignore - __('The following records needs to be created before we can import your file.') + html - ); - } - }, }); diff --git a/erpnext/accounts/doctype/c_form/c_form.py b/erpnext/accounts/doctype/c_form/c_form.py index 9b64f8100f..fd86ed4c90 100644 --- a/erpnext/accounts/doctype/c_form/c_form.py +++ b/erpnext/accounts/doctype/c_form/c_form.py @@ -57,6 +57,7 @@ class CForm(Document): total = sum([flt(d.grand_total) for d in self.get('invoices')]) frappe.db.set(self, 'total_invoiced_amount', total) + @frappe.whitelist() def get_invoice_details(self, invoice_no): """ Pull details from invoices for referrence """ if invoice_no: diff --git a/erpnext/accounts/doctype/cost_center/cost_center.py b/erpnext/accounts/doctype/cost_center/cost_center.py index 12094d4f98..8a5473f3a1 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.py +++ b/erpnext/accounts/doctype/cost_center/cost_center.py @@ -50,6 +50,7 @@ class CostCenter(NestedSet): frappe.throw(_("{0} is not a group node. Please select a group node as parent cost center").format( frappe.bold(self.parent_cost_center))) + @frappe.whitelist() def convert_group_to_ledger(self): if self.check_if_child_exists(): frappe.throw(_("Cannot convert Cost Center to ledger as it has child nodes")) @@ -60,6 +61,7 @@ class CostCenter(NestedSet): self.save() return 1 + @frappe.whitelist() def convert_ledger_to_group(self): if cint(self.enable_distributed_cost_center): frappe.throw(_("Cost Center with enabled distributed cost center can not be converted to group")) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py index 9594706d0f..c1b8ba70ba 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py @@ -27,6 +27,7 @@ class ExchangeRateRevaluation(Document): if not (self.company and self.posting_date): frappe.throw(_("Please select Company and Posting Date to getting entries")) + @frappe.whitelist() def get_accounts_data(self, account=None): accounts = [] self.validate_mandatory() @@ -95,6 +96,7 @@ class ExchangeRateRevaluation(Document): message = _("No outstanding invoices found") frappe.msgprint(message) + @frappe.whitelist() def make_jv_entry(self): if self.total_gain_loss == 0: return diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py index da6a3fd2ef..42556269fd 100644 --- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py +++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py @@ -12,6 +12,7 @@ from frappe.model.document import Document class FiscalYearIncorrectDate(frappe.ValidationError): pass class FiscalYear(Document): + @frappe.whitelist() def set_as_default(self): frappe.db.set_value("Global Defaults", None, "current_fiscal_year", self.name) global_defaults = frappe.get_doc("Global Defaults") @@ -54,7 +55,7 @@ class FiscalYear(Document): def on_update(self): check_duplicate_fiscal_year(self) frappe.cache().delete_value("fiscal_years") - + def on_trash(self): global_defaults = frappe.get_doc("Global Defaults") if global_defaults.current_fiscal_year == self.name: diff --git a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py index af8940cde5..7b62b617f9 100644 --- a/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py +++ b/erpnext/accounts/doctype/invoice_discounting/invoice_discounting.py @@ -125,6 +125,7 @@ class InvoiceDiscounting(AccountsController): make_gl_entries(gl_entries, cancel=(self.docstatus == 2), update_outstanding='No') + @frappe.whitelist() def create_disbursement_entry(self): je = frappe.new_doc("Journal Entry") je.voucher_type = 'Journal Entry' @@ -174,6 +175,7 @@ class InvoiceDiscounting(AccountsController): return je + @frappe.whitelist() def close_loan(self): je = frappe.new_doc("Journal Entry") je.voucher_type = 'Journal Entry' diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 3419bb6c3e..ff2c8c29b4 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -564,6 +564,7 @@ class JournalEntry(AccountsController): if gl_map: make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj, update_outstanding=update_outstanding) + @frappe.whitelist() def get_balance(self): if not self.get('accounts'): msgprint(_("'Entries' cannot be empty"), raise_exception=True) diff --git a/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py b/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py index 18f853cadc..88667d7207 100644 --- a/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py +++ b/erpnext/accounts/doctype/monthly_distribution/monthly_distribution.py @@ -8,6 +8,7 @@ from frappe.utils import (flt, add_months) from frappe.model.document import Document class MonthlyDistribution(Document): + @frappe.whitelist() def get_months(self): month_list = ['January','February','March','April','May','June','July','August','September', 'October','November','December'] diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py index e6449b7831..29dc96e8c6 100644 --- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py +++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py @@ -167,6 +167,7 @@ class OpeningInvoiceCreationTool(Document): return invoice + @frappe.whitelist() def make_invoices(self): self.validate_company() invoices = self.get_invoices() diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py index f7a15c04fa..cf6ec18f3b 100644 --- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py +++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py @@ -11,6 +11,7 @@ from erpnext.accounts.utils import (get_outstanding_invoices, from erpnext.controllers.accounts_controller import get_advance_payment_entries class PaymentReconciliation(Document): + @frappe.whitelist() def get_unreconciled_entries(self): self.get_nonreconciled_payment_entries() self.get_invoice_entries() @@ -147,6 +148,7 @@ class PaymentReconciliation(Document): ent.currency = e.get('currency') ent.outstanding_amount = e.get('outstanding_amount') + @frappe.whitelist() def reconcile(self, args): for e in self.get('payments'): e.invoice_type = None @@ -197,6 +199,7 @@ class PaymentReconciliation(Document): 'difference_account': row.difference_account }) + @frappe.whitelist() def get_difference_amount(self, child_row): if child_row.get("reference_type") != 'Payment Entry': return diff --git a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py index f5224a269e..a05e5984f5 100644 --- a/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py +++ b/erpnext/accounts/doctype/pos_closing_entry/pos_closing_entry.py @@ -18,7 +18,7 @@ class POSClosingEntry(StatusUpdater): self.validate_pos_closing() self.validate_pos_invoices() - + def validate_pos_closing(self): user = frappe.db.sql(""" SELECT name FROM `tabPOS Closing Entry` @@ -37,12 +37,12 @@ class POSClosingEntry(StatusUpdater): bold_user = frappe.bold(self.user) frappe.throw(_("POS Closing Entry {} against {} between selected period") .format(bold_already_exists, bold_user), title=_("Invalid Period")) - + def validate_pos_invoices(self): invalid_rows = [] for d in self.pos_transactions: invalid_row = {'idx': d.idx} - pos_invoice = frappe.db.get_values("POS Invoice", d.pos_invoice, + pos_invoice = frappe.db.get_values("POS Invoice", d.pos_invoice, ["consolidated_invoice", "pos_profile", "docstatus", "owner"], as_dict=1)[0] if pos_invoice.consolidated_invoice: invalid_row.setdefault('msg', []).append(_('POS Invoice is {}').format(frappe.bold("already consolidated"))) @@ -68,14 +68,15 @@ class POSClosingEntry(StatusUpdater): frappe.throw(error_list, title=_("Invalid POS Invoices"), as_list=True) + @frappe.whitelist() def get_payment_reconciliation_details(self): currency = frappe.get_cached_value('Company', self.company, "default_currency") return frappe.render_template("erpnext/accounts/doctype/pos_closing_entry/closing_voucher_details.html", {"data": self, "currency": currency}) - + def on_submit(self): consolidate_pos_invoices(closing_entry=self) - + def on_cancel(self): unconsolidate_pos_invoices(closing_entry=self) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index 402d157009..832fb8069a 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -355,6 +355,7 @@ class POSInvoice(SalesInvoice): return profile + @frappe.whitelist() def set_missing_values(self, for_validate=False): profile = self.set_pos_fields(for_validate) @@ -377,6 +378,7 @@ class POSInvoice(SalesInvoice): "allow_print_before_pay": profile.get("allow_print_before_pay") } + @frappe.whitelist() def reset_mode_of_payments(self): if self.pos_profile: pos_profile = frappe.get_cached_doc('POS Profile', self.pos_profile) @@ -389,6 +391,7 @@ class POSInvoice(SalesInvoice): if not pay.account: pay.account = get_bank_cash_account(pay.mode_of_payment, self.company).get("account") + @frappe.whitelist() def create_payment_request(self): for pay in self.payments: if pay.type == "Phone": diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index a1bf66b03e..21d550a4d3 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -390,6 +390,7 @@ class SalesInvoice(SellingController): if validate_against_credit_limit: check_credit_limit(self.customer, self.company, bypass_credit_limit_check_at_sales_order) + @frappe.whitelist() def set_missing_values(self, for_validate=False): pos = self.set_pos_fields(for_validate) @@ -729,6 +730,7 @@ class SalesInvoice(SellingController): else: self.calculate_billing_amount_for_timesheet() + @frappe.whitelist() def add_timesheet_data(self): self.set('timesheets', []) if self.project: @@ -1286,6 +1288,7 @@ class SalesInvoice(SellingController): break # Healthcare + @frappe.whitelist() def set_healthcare_services(self, checked_values): self.set("items", []) from erpnext.stock.get_item_details import get_item_details diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py index afbd9b4e6e..9000dea913 100644 --- a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py +++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py @@ -71,6 +71,7 @@ class CropCycle(Document): "exp_end_date": add_days(start_date, crop_task.get("end_day") - 1) }).insert() + @frappe.whitelist() def reload_linked_analysis(self): linked_doctypes = ['Soil Texture', 'Soil Analysis', 'Plant Analysis'] required_fields = ['location', 'name', 'collection_datetime'] @@ -87,6 +88,7 @@ class CropCycle(Document): frappe.publish_realtime("List of Linked Docs", output, user=frappe.session.user) + @frappe.whitelist() def append_to_child(self, obj_to_append): for doctype in obj_to_append: for doc_name in set(obj_to_append[doctype]): diff --git a/erpnext/agriculture/doctype/fertilizer/fertilizer.py b/erpnext/agriculture/doctype/fertilizer/fertilizer.py index dc2781cf00..9cb492aff1 100644 --- a/erpnext/agriculture/doctype/fertilizer/fertilizer.py +++ b/erpnext/agriculture/doctype/fertilizer/fertilizer.py @@ -7,6 +7,7 @@ import frappe from frappe.model.document import Document class Fertilizer(Document): + @frappe.whitelist() def load_contents(self): docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Fertilizer'}) for doc in docs: diff --git a/erpnext/agriculture/doctype/plant_analysis/plant_analysis.py b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.py index 304727e04f..2806cc6523 100644 --- a/erpnext/agriculture/doctype/plant_analysis/plant_analysis.py +++ b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.py @@ -8,6 +8,7 @@ from frappe.model.naming import make_autoname from frappe.model.document import Document class PlantAnalysis(Document): + @frappe.whitelist() def load_contents(self): docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Plant Analysis'}) for doc in docs: diff --git a/erpnext/agriculture/doctype/soil_analysis/soil_analysis.py b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.py index 17b96a0ac1..37835f8c7b 100644 --- a/erpnext/agriculture/doctype/soil_analysis/soil_analysis.py +++ b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.py @@ -7,6 +7,7 @@ import frappe from frappe.model.document import Document class SoilAnalysis(Document): + @frappe.whitelist() def load_contents(self): docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Soil Analysis'}) for doc in docs: diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.py b/erpnext/agriculture/doctype/soil_texture/soil_texture.py index 8c1d7ed5ac..209b2c8598 100644 --- a/erpnext/agriculture/doctype/soil_texture/soil_texture.py +++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.py @@ -13,6 +13,7 @@ class SoilTexture(Document): soil_edit_order = [2, 1, 0] soil_types = ['clay_composition', 'sand_composition', 'silt_composition'] + @frappe.whitelist() def load_contents(self): docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Soil Texture'}) for doc in docs: @@ -26,6 +27,7 @@ class SoilTexture(Document): if sum(self.get(soil_type) for soil_type in self.soil_types) != 100: frappe.throw(_('Soil compositions do not add up to 100')) + @frappe.whitelist() def update_soil_edit(self, soil_type): self.soil_edit_order[self.soil_types.index(soil_type)] = max(self.soil_edit_order)+1 self.soil_type = self.get_soil_type() @@ -35,8 +37,8 @@ class SoilTexture(Document): if sum(self.soil_edit_order) < 5: return last_edit_index = self.soil_edit_order.index(min(self.soil_edit_order)) - # set composition of the last edited soil - self.set( self.soil_types[last_edit_index], + # set composition of the last edited soil + self.set(self.soil_types[last_edit_index], 100 - sum(cint(self.get(soil_type)) for soil_type in self.soil_types) + cint(self.get(self.soil_types[last_edit_index]))) # calculate soil type @@ -67,4 +69,4 @@ class SoilTexture(Document): elif (c >= 40 and sa <= 45 and si < 40): return 'Clay' else: - return 'Select' \ No newline at end of file + return 'Select' diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.py b/erpnext/agriculture/doctype/water_analysis/water_analysis.py index 88f1fbd9cc..d9f007cea1 100644 --- a/erpnext/agriculture/doctype/water_analysis/water_analysis.py +++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.py @@ -9,11 +9,13 @@ from frappe.model.document import Document from frappe import _ class WaterAnalysis(Document): + @frappe.whitelist() def load_contents(self): docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Water Analysis'}) for doc in docs: self.append('water_analysis_criteria', {'title': str(doc.name)}) + @frappe.whitelist() def update_lab_result_date(self): if not self.result_datetime: self.result_datetime = self.laboratory_testing_datetime diff --git a/erpnext/agriculture/doctype/weather/weather.py b/erpnext/agriculture/doctype/weather/weather.py index 938daa207e..235e684e51 100644 --- a/erpnext/agriculture/doctype/weather/weather.py +++ b/erpnext/agriculture/doctype/weather/weather.py @@ -7,6 +7,7 @@ import frappe from frappe.model.document import Document class Weather(Document): + @frappe.whitelist() def load_contents(self): docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Weather'}) for doc in docs: diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index e8e8ec6cc0..9aff1440d6 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -553,6 +553,7 @@ class Asset(AccountsController): make_gl_entries(gl_entries) self.db_set('booked_fixed_asset', 1) + @frappe.whitelist() def get_depreciation_rate(self, args, on_validate=False): if isinstance(args, string_types): args = json.loads(args) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index d32e98e8d9..735c31c423 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -133,6 +133,7 @@ class PurchaseOrder(BuyingController): d.material_request_item, "schedule_date") + @frappe.whitelist() def get_last_purchase_rate(self): """get last purchase rates for all items""" diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py index 7cf22f87e4..b530d1ab24 100644 --- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py +++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py @@ -66,6 +66,7 @@ class RequestforQuotation(BuyingController): def on_cancel(self): frappe.db.set(self, 'status', 'Cancelled') + @frappe.whitelist() def get_supplier_email_preview(self, supplier): """Returns formatted email preview as string.""" rfq_suppliers = list(filter(lambda row: row.supplier == supplier, self.suppliers)) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 73276f3646..6cae69676f 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -517,6 +517,7 @@ class AccountsController(TransactionBase): frappe.db.sql("""delete from `tab%s` where parentfield=%s and parent = %s and allocated_amount = 0""" % (childtype, '%s', '%s'), (parentfield, self.name)) + @frappe.whitelist() def apply_shipping_rule(self): if self.shipping_rule: shipping_rule = frappe.get_doc("Shipping Rule", self.shipping_rule) @@ -537,6 +538,7 @@ class AccountsController(TransactionBase): return {} + @frappe.whitelist() def set_advances(self): """Returns list of advances against Account, Party, Reference""" diff --git a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py index 377e061fdf..d8c6fb4f90 100644 --- a/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py +++ b/erpnext/crm/doctype/linkedin_settings/linkedin_settings.py @@ -11,7 +11,8 @@ from frappe.utils.file_manager import get_file, get_file_path from six.moves.urllib.parse import urlencode class LinkedInSettings(Document): - def get_authorization_url(self): + @frappe.whitelist() + def get_authorization_url(self): params = urlencode({ "response_type":"code", "client_id": self.consumer_key, @@ -35,7 +36,7 @@ class LinkedInSettings(Document): headers = { "Content-Type": "application/x-www-form-urlencoded" } - + response = self.http_post(url=url, data=body, headers=headers) response = frappe.parse_json(response.content.decode()) self.db_set("access_token", response["access_token"]) diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py index 0522ace1e5..23ad98a282 100644 --- a/erpnext/crm/doctype/opportunity/opportunity.py +++ b/erpnext/crm/doctype/opportunity/opportunity.py @@ -85,6 +85,7 @@ class Opportunity(TransactionBase): self.opportunity_from = "Lead" self.party_name = lead_name + @frappe.whitelist() def declare_enquiry_lost(self, lost_reasons_list, detailed_reason=None): if not self.has_active_quotation(): frappe.db.set(self, 'status', 'Lost') diff --git a/erpnext/crm/doctype/twitter_settings/twitter_settings.py b/erpnext/crm/doctype/twitter_settings/twitter_settings.py index 976a23dfc7..1e1beab2d2 100644 --- a/erpnext/crm/doctype/twitter_settings/twitter_settings.py +++ b/erpnext/crm/doctype/twitter_settings/twitter_settings.py @@ -11,6 +11,7 @@ from frappe.utils import get_url_to_form, get_link_to_form from tweepy.error import TweepError class TwitterSettings(Document): + @frappe.whitelist() def get_authorize_url(self): callback_url = "{0}/api/method/erpnext.crm.doctype.twitter_settings.twitter_settings.callback?".format(frappe.utils.get_url()) auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret"), callback_url) @@ -21,12 +22,12 @@ class TwitterSettings(Document): frappe.msgprint(_("Error! Failed to get request token.")) frappe.throw(_('Invalid {0} or {1}').format(frappe.bold("Consumer Key"), frappe.bold("Consumer Secret Key"))) - + def get_access_token(self, oauth_token, oauth_verifier): auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret")) - auth.request_token = { + auth.request_token = { 'oauth_token' : oauth_token, - 'oauth_token_secret' : oauth_verifier + 'oauth_token_secret' : oauth_verifier } try: @@ -50,10 +51,10 @@ class TwitterSettings(Document): frappe.throw(_('Invalid Consumer Key or Consumer Secret Key')) def get_api(self, access_token, access_token_secret): - # authentication of consumer key and secret - auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret")) - # authentication of access token and secret - auth.set_access_token(access_token, access_token_secret) + # authentication of consumer key and secret + auth = tweepy.OAuthHandler(self.consumer_key, self.get_password(fieldname="consumer_secret")) + # authentication of access token and secret + auth.set_access_token(access_token, access_token_secret) return tweepy.API(auth) @@ -64,7 +65,7 @@ class TwitterSettings(Document): if media: media_id = self.upload_image(media) return self.send_tweet(text, media_id) - + def upload_image(self, media): media = get_file_path(media) api = self.get_api(self.access_token, self.access_token_secret) diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py index 97c29ab667..6a0dcf460a 100644 --- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py +++ b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.py @@ -13,6 +13,7 @@ from erpnext.education.utils import OverlapError class CourseSchedulingTool(Document): + @frappe.whitelist() def schedule_course(self): """Creates course schedules as per specified parameters""" diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.py b/erpnext/education/doctype/fee_schedule/fee_schedule.py index 1543acdca9..0b025c7534 100644 --- a/erpnext/education/doctype/fee_schedule/fee_schedule.py +++ b/erpnext/education/doctype/fee_schedule/fee_schedule.py @@ -52,6 +52,7 @@ class FeeSchedule(Document): self.grand_total = no_of_students*self.total_amount self.grand_total_in_words = money_in_words(self.grand_total) + @frappe.whitelist() def create_fees(self): self.db_set("fee_creation_status", "In Process") frappe.publish_realtime("fee_schedule_progress", diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.py b/erpnext/education/doctype/program_enrollment/program_enrollment.py index d18c0f9625..b282babd0f 100644 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.py +++ b/erpnext/education/doctype/program_enrollment/program_enrollment.py @@ -91,6 +91,8 @@ class ProgramEnrollment(Document): (fee, fee) for fee in fee_list] msgprint(_("Fee Records Created - {0}").format(comma_and(fee_list))) + + @frappe.whitelist() def get_courses(self): return frappe.db.sql('''select course from `tabProgram Course` where parent = %s and required = 1''', (self.program), as_dict=1) diff --git a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py b/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py index 8180102c58..5833b67f9b 100644 --- a/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py +++ b/erpnext/education/doctype/program_enrollment_tool/program_enrollment_tool.py @@ -14,6 +14,7 @@ class ProgramEnrollmentTool(Document): academic_term_reqd = cint(frappe.db.get_single_value('Education Settings', 'academic_term_reqd')) self.set_onload("academic_term_reqd", academic_term_reqd) + @frappe.whitelist() def get_students(self): students = [] if not self.get_students_from: @@ -49,6 +50,7 @@ class ProgramEnrollmentTool(Document): else: frappe.throw(_("No students Found")) + @frappe.whitelist() def enroll_students(self): total = len(self.students) for i, stud in enumerate(self.students): diff --git a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py b/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py index d7645e30cd..dc8667ec06 100644 --- a/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py +++ b/erpnext/education/doctype/student_group_creation_tool/student_group_creation_tool.py @@ -9,6 +9,7 @@ from frappe.model.document import Document from erpnext.education.doctype.student_group.student_group import get_students class StudentGroupCreationTool(Document): + @frappe.whitelist() def get_courses(self): group_list = [] @@ -42,6 +43,7 @@ class StudentGroupCreationTool(Document): return group_list + @frappe.whitelist() def create_student_groups(self): if not self.courses: frappe.throw(_("""No Student Groups created.""")) diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py index b5718026c1..fdfaa1b054 100644 --- a/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py +++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/mpesa_settings.py @@ -59,9 +59,10 @@ class MpesaSettings(Document): request_amounts.append(amount) else: request_amounts = [request_amount] - + return request_amounts + @frappe.whitelist() def get_account_balance_info(self): payload = dict( reference_doctype="Mpesa Settings", @@ -198,7 +199,7 @@ def get_completed_integration_requests_info(reference_doctype, reference_docname completed_mpesa_receipt = fetch_param_value(item_response, "MpesaReceiptNumber", "Name") completed_payments.append(completed_amount) mpesa_receipts.append(completed_mpesa_receipt) - + return mpesa_receipts, completed_payments def get_account_balance(request_payload): diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index 21f6fee79c..16c65733f0 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -15,6 +15,7 @@ from frappe.utils import add_months, formatdate, getdate, today class PlaidSettings(Document): @staticmethod + @frappe.whitelist() def get_link_token(): plaid = PlaidConnector() return plaid.get_link_token() diff --git a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py index 96a533ee10..866ea66278 100644 --- a/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py +++ b/erpnext/erpnext_integrations/doctype/quickbooks_migrator/quickbooks_migrator.py @@ -54,6 +54,7 @@ class QuickBooksMigrator(Document): self.authorization_url = self.oauth.authorization_url(self.authorization_endpoint)[0] + @frappe.whitelist() def migrate(self): frappe.enqueue_doc("QuickBooks Migrator", "QuickBooks Migrator", "_migrate", queue="long") diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py index 462685f5e7..907a22333b 100644 --- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py +++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.py @@ -594,18 +594,22 @@ class TallyMigration(Document): frappe.db.set_value("Price List", "Tally Price List", "enabled", 0) frappe.flags.in_migrate = False + @frappe.whitelist() def process_master_data(self): self.set_status("Processing Master Data") frappe.enqueue_doc(self.doctype, self.name, "_process_master_data", queue="long", timeout=3600) + @frappe.whitelist() def import_master_data(self): self.set_status("Importing Master Data") frappe.enqueue_doc(self.doctype, self.name, "_import_master_data", queue="long", timeout=3600) + @frappe.whitelist() def process_day_book_data(self): self.set_status("Processing Day Book Data") frappe.enqueue_doc(self.doctype, self.name, "_process_day_book_data", queue="long", timeout=3600) + @frappe.whitelist() def import_day_book_data(self): self.set_status("Importing Day Book Data") frappe.enqueue_doc(self.doctype, self.name, "_import_day_book_data", queue="long", timeout=3600) diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py index 325c2094fb..cbf89ee3bd 100644 --- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py +++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py @@ -54,6 +54,7 @@ class ClinicalProcedure(Document): def set_title(self): self.title = _('{0} - {1}').format(self.patient_name or self.patient, self.procedure_template)[:100] + @frappe.whitelist() def complete_procedure(self): if self.consume_stock and self.items: stock_entry = make_stock_entry(self) @@ -96,6 +97,7 @@ class ClinicalProcedure(Document): if self.consume_stock and self.items: return stock_entry + @frappe.whitelist() def start_procedure(self): allow_start = self.set_actual_qty() if allow_start: @@ -116,6 +118,7 @@ class ClinicalProcedure(Document): return allow_start + @frappe.whitelist() def make_material_receipt(self, submit=False): stock_entry = frappe.new_doc('Stock Entry') diff --git a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py index e7319085e4..3a299eda26 100644 --- a/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py +++ b/erpnext/healthcare/doctype/inpatient_medication_entry/inpatient_medication_entry.py @@ -14,6 +14,7 @@ class InpatientMedicationEntry(Document): def validate(self): self.validate_medication_orders() + @frappe.whitelist() def get_medication_orders(self): # pull inpatient medication orders based on selected filters orders = get_pending_medication_orders(self) diff --git a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.py b/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.py index 33cbbec812..b379e98fe1 100644 --- a/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.py +++ b/erpnext/healthcare/doctype/inpatient_medication_order/inpatient_medication_order.py @@ -57,6 +57,7 @@ class InpatientMedicationOrder(Document): self.db_set('status', status) + @frappe.whitelist() def add_order_entries(self, order): if order.get('drug_code'): dosage = frappe.get_doc('Prescription Dosage', order.get('dosage')) diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py index 2934316c06..f4d1eaf2e3 100644 --- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py +++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py @@ -53,12 +53,15 @@ class InpatientRecord(Document): + """ {0}""".format(ip_record[0].name)) frappe.throw(msg) + @frappe.whitelist() def admit(self, service_unit, check_in, expected_discharge=None): admit_patient(self, service_unit, check_in, expected_discharge) + @frappe.whitelist() def discharge(self): discharge_patient(self) + @frappe.whitelist() def transfer(self, service_unit, check_in, leave_from): if leave_from: patient_leave_service_unit(self, check_in, leave_from) diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py index 8603f974c3..789d452c07 100644 --- a/erpnext/healthcare/doctype/patient/patient.py +++ b/erpnext/healthcare/doctype/patient/patient.py @@ -111,6 +111,7 @@ class Patient(Document): age_str = str(age.years) + ' ' + _("Years(s)") + ' ' + str(age.months) + ' ' + _("Month(s)") + ' ' + str(age.days) + ' ' + _("Day(s)") return age_str + @frappe.whitelist() def invoice_patient_registration(self): if frappe.db.get_single_value('Healthcare Settings', 'registration_fee'): company = frappe.defaults.get_user_default('company') diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py index 1f76cd624c..cdd4ad39c8 100755 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py @@ -113,6 +113,7 @@ class PatientAppointment(Document): if fee_validity: frappe.msgprint(_('{0} has fee validity till {1}').format(self.patient, fee_validity.valid_till)) + @frappe.whitelist() def get_therapy_types(self): if not self.therapy_plan: return diff --git a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py index 2e8c994c3d..887d58a2e0 100644 --- a/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py +++ b/erpnext/healthcare/doctype/patient_history_settings/patient_history_settings.py @@ -34,6 +34,7 @@ class PatientHistorySettings(Document): frappe.throw(_('Row #{0}: Field {1} in Document Type {2} is not a Date / Datetime field.').format( entry.idx, frappe.bold(entry.date_fieldname), frappe.bold(entry.document_type))) + @frappe.whitelist() def get_doctype_fields(self, document_type, fields): multicheck_fields = [] doc_fields = frappe.get_meta(document_type).fields @@ -49,6 +50,7 @@ class PatientHistorySettings(Document): return multicheck_fields + @frappe.whitelist() def get_date_field_for_dt(self, document_type): meta = frappe.get_meta(document_type) date_fields = meta.get('fields', { diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py index ac01c604dd..e209660434 100644 --- a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py +++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py @@ -33,6 +33,7 @@ class TherapyPlan(Document): self.db_set('total_sessions', total_sessions) self.db_set('total_sessions_completed', total_sessions_completed) + @frappe.whitelist() def set_therapy_details_from_template(self): # Add therapy types in the child table self.set('therapy_plan_details', []) diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py index bf893d5fab..e7bb6dcd48 100644 --- a/erpnext/hr/doctype/expense_claim/expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/expense_claim.py @@ -211,6 +211,7 @@ class ExpenseClaim(AccountsController): self.total_claimed_amount += flt(d.amount) self.total_sanctioned_amount += flt(d.sanctioned_amount) + @frappe.whitelist() def calculate_taxes(self): self.total_taxes_and_charges = 0 for tax in self.taxes: diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py index 69d605d063..11302cad75 100755 --- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py +++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py @@ -99,6 +99,7 @@ class LeaveAllocation(Document): .format(formatdate(future_allocation[0].from_date), future_allocation[0].name), BackDatedAllocationError) + @frappe.whitelist() def set_total_leaves_allocated(self): self.unused_leaves = get_carry_forwarded_leaves(self.employee, self.leave_type, self.from_date, self.carry_forward) diff --git a/erpnext/hr/doctype/leave_encashment/leave_encashment.py b/erpnext/hr/doctype/leave_encashment/leave_encashment.py index 4c1a46522f..e041b7fb8f 100644 --- a/erpnext/hr/doctype/leave_encashment/leave_encashment.py +++ b/erpnext/hr/doctype/leave_encashment/leave_encashment.py @@ -63,6 +63,7 @@ class LeaveEncashment(Document): frappe.db.get_value('Leave Allocation', self.leave_allocation, 'total_leaves_encashed') - self.encashable_days) self.create_leave_ledger_entry(submit=False) + @frappe.whitelist() def get_leave_details_for_encashment(self): salary_structure = get_assigned_salary_structure(self.employee, self.encashment_date or getdate(nowdate())) if not salary_structure: diff --git a/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py b/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py index 4064c56e44..462b81df1d 100644 --- a/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py +++ b/erpnext/hr/doctype/leave_policy_assignment/leave_policy_assignment.py @@ -36,6 +36,7 @@ class LeavePolicyAssignment(Document): frappe.throw(_("Leave Policy: {0} already assigned for Employee {1} for period {2} to {3}") .format(bold(self.leave_policy), bold(self.employee), bold(formatdate(self.effective_from)), bold(formatdate(self.effective_to)))) + @frappe.whitelist() def grant_leave_alloc_for_employee(self): if self.leaves_allocated: frappe.throw(_("Leave already have been assigned for this Leave Policy Assignment")) diff --git a/erpnext/hr/doctype/shift_type/shift_type.py b/erpnext/hr/doctype/shift_type/shift_type.py index 054e7e3688..d5fdda8094 100644 --- a/erpnext/hr/doctype/shift_type/shift_type.py +++ b/erpnext/hr/doctype/shift_type/shift_type.py @@ -15,6 +15,7 @@ from erpnext.hr.doctype.attendance.attendance import mark_attendance from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee class ShiftType(Document): + @frappe.whitelist() def process_auto_attendance(self): if not cint(self.enable_auto_attendance) or not self.process_attendance_after or not self.last_sync_of_checkin: return diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py index cba6a2d014..0aefe19c8d 100644 --- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py @@ -12,6 +12,7 @@ from erpnext.stock.utils import get_valid_serial_nos from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee class MaintenanceSchedule(TransactionBase): + @frappe.whitelist() def generate_schedule(self): self.set('schedules', []) frappe.db.sql("""delete from `tabMaintenance Schedule Detail` diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 03beedb663..979f7ca312 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -113,6 +113,7 @@ class BOM(WebsiteGenerator): return item + @frappe.whitelist() def get_routing(self): if self.routing: self.set("operations", []) @@ -145,6 +146,7 @@ class BOM(WebsiteGenerator): if not item.get(r): item.set(r, ret[r]) + @frappe.whitelist() def get_bom_material_detail(self, args=None): """ Get raw material details like uom, desc and rate""" if not args: @@ -210,6 +212,7 @@ class BOM(WebsiteGenerator): .format(self.rm_cost_as_per, arg["item_code"]), alert=True) return flt(rate) * flt(self.plc_conversion_rate or 1) / (self.conversion_rate or 1) + @frappe.whitelist() def update_cost(self, update_parent=True, from_child_bom=False, save=True): if self.docstatus == 2: return diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py index 7aaf2a08ec..8aa0ffd774 100644 --- a/erpnext/manufacturing/doctype/job_card/job_card.py +++ b/erpnext/manufacturing/doctype/job_card/job_card.py @@ -164,6 +164,7 @@ class JobCard(Document): "time_in_mins": time_diff_in_minutes(row.planned_end_time, row.planned_start_time), }) + @frappe.whitelist() def get_required_items(self): if not self.get('work_order'): return diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 109c8b5647..05b328c9e8 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -29,6 +29,7 @@ class ProductionPlan(Document): if not flt(d.planned_qty): frappe.throw(_("Please enter Planned Qty for Item {0} at row {1}").format(d.item_code, d.idx)) + @frappe.whitelist() def get_open_sales_orders(self): """ Pull sales orders which are pending to deliver based on criteria selected""" open_so = get_sales_orders(self) @@ -50,6 +51,7 @@ class ProductionPlan(Document): 'grand_total': data.base_grand_total }) + @frappe.whitelist() def get_pending_material_requests(self): """ Pull Material Requests that are pending based on criteria selected""" mr_filter = item_filter = "" @@ -92,6 +94,7 @@ class ProductionPlan(Document): 'material_request_date': data.transaction_date }) + @frappe.whitelist() def get_items(self): if self.get_items_from == "Sales Order": self.get_so_items() @@ -219,6 +222,7 @@ class ProductionPlan(Document): filters = {'docstatus': 0, 'production_plan': ("=", self.name)}): frappe.delete_doc('Work Order', d.name) + @frappe.whitelist() def set_status(self, close=None): self.status = { 0: 'Draft', @@ -302,6 +306,7 @@ class ProductionPlan(Document): return item_dict + @frappe.whitelist() def make_work_order(self): wo_list = [] self.validate_data() @@ -367,6 +372,7 @@ class ProductionPlan(Document): except OverProductionError: pass + @frappe.whitelist() def make_material_request(self): '''Create Material Requests grouped by Sales Order and Material Request Type''' material_request_list = [] diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py index 3d64ad4318..8507f5eb34 100644 --- a/erpnext/manufacturing/doctype/work_order/work_order.py +++ b/erpnext/manufacturing/doctype/work_order/work_order.py @@ -509,6 +509,7 @@ class WorkOrder(Document): stock_bin = get_bin(d.item_code, d.source_warehouse) stock_bin.update_reserved_qty_for_production() + @frappe.whitelist() def get_items_and_operations_from_bom(self): self.set_required_items() self.set_work_order_operations() @@ -613,6 +614,7 @@ class WorkOrder(Document): item.db_set('consumed_qty', flt(consumed_qty), update_modified=False) + @frappe.whitelist() def make_bom(self): data = frappe.db.sql(""" select sed.item_code, sed.qty, sed.s_warehouse from `tabStock Entry Detail` sed, `tabStock Entry` se diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py index 3ba2ee71c6..efc072ee97 100644 --- a/erpnext/non_profit/doctype/member/member.py +++ b/erpnext/non_profit/doctype/member/member.py @@ -53,6 +53,7 @@ class Member(Document): return subscription + @frappe.whitelist() def make_customer_and_link(self): if self.customer: frappe.msgprint(_("A customer is already linked to this Member")) diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py index 52447e4386..e8ae6187b7 100644 --- a/erpnext/non_profit/doctype/membership/membership.py +++ b/erpnext/non_profit/doctype/membership/membership.py @@ -74,6 +74,7 @@ class Membership(Document): self.generate_invoice(with_payment_entry=settings.automate_membership_payment_entries, save=True) + @frappe.whitelist() def generate_invoice(self, save=True, with_payment_entry=False): if not (self.paid or self.currency or self.amount): frappe.throw(_("The payment for this membership is not paid. To generate invoice fill the payment details")) @@ -130,6 +131,7 @@ class Membership(Document): pe.save() pe.submit() + @frappe.whitelist() def send_acknowlement(self): settings = frappe.get_doc("Non Profit Settings") if not settings.send_email: diff --git a/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.py b/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.py index 108554c6a0..a84cc2cdb5 100644 --- a/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.py +++ b/erpnext/non_profit/doctype/non_profit_settings/non_profit_settings.py @@ -9,6 +9,7 @@ from frappe.integrations.utils import get_payment_gateway_controller from frappe.model.document import Document class NonProfitSettings(Document): + @frappe.whitelist() def generate_webhook_secret(self, field="membership_webhook_secret"): key = frappe.generate_hash(length=20) self.set(field, key) @@ -21,6 +22,7 @@ class NonProfitSettings(Document): _("Webhook Secret") ) + @frappe.whitelist() def revoke_key(self, key): self.set(key, None) self.save() diff --git a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py index 6bcd4e0c00..78904710a8 100644 --- a/erpnext/payroll/doctype/payroll_entry/payroll_entry.py +++ b/erpnext/payroll/doctype/payroll_entry/payroll_entry.py @@ -95,6 +95,7 @@ class PayrollEntry(Document): return emp_list + @frappe.whitelist() def fill_employee_details(self): self.set('employees', []) employees = self.get_emp_list() @@ -142,6 +143,7 @@ class PayrollEntry(Document): if not self.get(fieldname): frappe.throw(_("Please set {0}").format(self.meta.get_label(fieldname))) + @frappe.whitelist() def create_salary_slips(self): """ Creates salary slip for selected employees if already not created @@ -329,6 +331,7 @@ class PayrollEntry(Document): amount = flt(amount) * flt(conversion_rate) return exchange_rate, amount + @frappe.whitelist() def make_payment_entry(self): self.check_permission('write') diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py index a04a635807..9abe57cd65 100644 --- a/erpnext/payroll/doctype/salary_slip/salary_slip.py +++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py @@ -142,6 +142,7 @@ class SalarySlip(TransactionBase): self.start_date = date_details.start_date self.end_date = date_details.end_date + @frappe.whitelist() def get_emp_and_working_day_details(self): '''First time, load all the components from salary structure''' if self.employee: @@ -1114,10 +1115,12 @@ class SalarySlip(TransactionBase): self.bank_name = emp.bank_name self.bank_account_no = emp.bank_ac_no + @frappe.whitelist() def process_salary_based_on_working_days(self): self.get_working_days_details(lwp=self.leave_without_pay) self.calculate_net_pay() + @frappe.whitelist() def set_totals(self): self.gross_pay = 0.0 if self.salary_slip_based_on_timesheet == 1: diff --git a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py index bf82cc080a..5a8ec73cfe 100644 --- a/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py +++ b/erpnext/quality_management/doctype/quality_feedback/quality_feedback.py @@ -7,6 +7,7 @@ import frappe from frappe.model.document import Document class QualityFeedback(Document): + @frappe.whitelist() def set_parameters(self): if self.template and not getattr(self, 'parameters', []): for d in frappe.get_doc('Quality Feedback Template', self.template).parameters: diff --git a/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py b/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py index 41c7b23146..41a0f1193b 100644 --- a/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py +++ b/erpnext/regional/doctype/tax_exemption_80g_certificate/tax_exemption_80g_certificate.py @@ -50,6 +50,7 @@ class TaxExemption80GCertificate(Document): frappe.throw(_('Please set the {0} for company {1}').format(frappe.bold('PAN Number'), get_link_to_form('Company', self.company))) + @frappe.whitelist() def set_company_address(self): address = get_company_address(self.company) self.company_address = address.company_address @@ -70,6 +71,7 @@ class TaxExemption80GCertificate(Document): else: self.title = self.donor_name + @frappe.whitelist() def get_payments(self): if not self.member: frappe.throw(_('Please select a Member first.')) diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 5da248c1b5..246f9234a4 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -64,6 +64,7 @@ class Quotation(SellingController): opp = frappe.get_doc("Opportunity", opportunity) opp.set_status(status=status, update=True) + @frappe.whitelist() def declare_enquiry_lost(self, lost_reasons_list, detailed_reason=None): if not self.has_sales_order(): get_lost_reasons = frappe.get_list('Quotation Lost Reason', diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index e56129170c..d7146782d7 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -372,6 +372,7 @@ class SalesOrder(SellingController): self.indicator_color = "green" self.indicator_title = _("Paid") + @frappe.whitelist() def get_work_order_items(self, for_raw_material_request=0): '''Returns items with BOM that already do not have a linked work order''' items = [] diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 433851cde5..09221714d3 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -66,6 +66,7 @@ class Company(NestedSet): if frappe.db.sql("select abbr from tabCompany where name!=%s and abbr=%s", (self.name, self.abbr)): frappe.throw(_("Abbreviation already used for another company")) + @frappe.whitelist() def create_default_tax_template(self): from erpnext.setup.setup_wizard.operations.taxes_setup import create_sales_tax create_sales_tax({ diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py index cbb4c7c5de..ac55fdfdb8 100644 --- a/erpnext/setup/doctype/email_digest/email_digest.py +++ b/erpnext/setup/doctype/email_digest/email_digest.py @@ -24,6 +24,7 @@ class EmailDigest(Document): self._accounts = {} self.currency = frappe.db.get_value('Company', self.company, "default_currency") + @frappe.whitelist() def get_users(self): """get list of users""" user_list = frappe.db.sql(""" @@ -41,6 +42,7 @@ class EmailDigest(Document): frappe.response['user_list'] = user_list + @frappe.whitelist() def send(self): # send email only to enabled users valid_users = [p[0] for p in frappe.db.sql("""select name from `tabUser` diff --git a/erpnext/setup/doctype/global_defaults/global_defaults.py b/erpnext/setup/doctype/global_defaults/global_defaults.py index fa7bc504b6..76a8450829 100644 --- a/erpnext/setup/doctype/global_defaults/global_defaults.py +++ b/erpnext/setup/doctype/global_defaults/global_defaults.py @@ -50,6 +50,7 @@ class GlobalDefaults(Document): # clear cache frappe.clear_cache() + @frappe.whitelist() def get_defaults(self): return frappe.defaults.get_defaults() diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py index 2ea0bc08ca..c4f1de14e4 100644 --- a/erpnext/setup/doctype/naming_series/naming_series.py +++ b/erpnext/setup/doctype/naming_series/naming_series.py @@ -15,6 +15,7 @@ from frappe.core.doctype.doctype.doctype import validate_series class NamingSeriesNotSetError(frappe.ValidationError): pass class NamingSeries(Document): + @frappe.whitelist() def get_transactions(self, arg=None): doctypes = list(set(frappe.db.sql_list("""select parent from `tabDocField` df where fieldname='naming_series'""") @@ -53,6 +54,7 @@ class NamingSeries(Document): options = list(filter(lambda x: x, [cstr(n).strip() for n in ol])) return options + @frappe.whitelist() def update_series(self, arg=None): """update series list""" self.validate_series_set() @@ -139,10 +141,12 @@ class NamingSeries(Document): if not re.match("^[\w\- /.#{}]*$", n, re.UNICODE): throw(_('Special Characters except "-", "#", ".", "/", "{" and "}" not allowed in naming series')) + @frappe.whitelist() def get_options(self, arg=None): if frappe.get_meta(arg or self.select_doc_for_series).get_field("naming_series"): return frappe.get_meta(arg or self.select_doc_for_series).get_field("naming_series").options + @frappe.whitelist() def get_current(self, arg=None): """get series current""" if self.prefix: diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index 28e9533186..de85bc3922 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -90,6 +90,7 @@ class DeliveryTrip(Document): delivery_notes = [get_link_to_form("Delivery Note", note) for note in delivery_notes] frappe.msgprint(_("Delivery Notes {0} updated").format(", ".join(delivery_notes))) + @frappe.whitelist() def process_route(self, optimize): """ Estimate the arrival times for each stop in the Delivery Trip. diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 7b7d2da969..7cb84a69f0 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -50,6 +50,7 @@ class Item(WebsiteGenerator): self.set_onload('stock_exists', self.stock_ledger_created()) self.set_asset_naming_series() + @frappe.whitelist() def set_asset_naming_series(self): if not hasattr(self, '_asset_naming_series'): from erpnext.assets.doctype.asset.asset import get_asset_naming_series @@ -706,6 +707,7 @@ class Item(WebsiteGenerator): frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock) frappe.db.auto_commit_on_many_writes = 0 + @frappe.whitelist() def copy_specification_from_item_group(self): self.set("website_specifications", []) if self.item_group: diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py index 69a8bf19d3..83109469fc 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py @@ -12,6 +12,7 @@ from erpnext.accounts.doctype.account.account import get_account_currency from erpnext.controllers.taxes_and_totals import init_landed_taxes_and_totals class LandedCostVoucher(Document): + @frappe.whitelist() def get_items_from_purchase_receipts(self): self.set("items", []) for pr in self.get("purchase_receipts"): diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.py b/erpnext/stock/doctype/packing_slip/packing_slip.py index a7a29cca7f..2008bffcd3 100644 --- a/erpnext/stock/doctype/packing_slip/packing_slip.py +++ b/erpnext/stock/doctype/packing_slip/packing_slip.py @@ -152,6 +152,7 @@ class PackingSlip(Document): return cint(recommended_case_no[0][0]) + 1 + @frappe.whitelist() def get_items(self): self.set("items", []) diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py index d723fac11b..61b72092e7 100644 --- a/erpnext/stock/doctype/pick_list/pick_list.py +++ b/erpnext/stock/doctype/pick_list/pick_list.py @@ -33,6 +33,7 @@ class PickList(Document): frappe.throw(_('For item {0} at row {1}, count of serial numbers does not match with the picked quantity') .format(frappe.bold(item.item_code), frappe.bold(item.idx)), title=_("Quantity Mismatch")) + @frappe.whitelist() def set_item_locations(self, save=False): items = self.aggregate_item_qty() self.item_location_map = frappe._dict() diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.py b/erpnext/stock/doctype/quality_inspection/quality_inspection.py index 58b1eca2d3..05819ab854 100644 --- a/erpnext/stock/doctype/quality_inspection/quality_inspection.py +++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.py @@ -18,6 +18,7 @@ class QualityInspection(Document): if self.readings: self.inspect_and_set_status() + @frappe.whitelist() def get_item_specification_details(self): if not self.quality_inspection_template: self.quality_inspection_template = frappe.db.get_value('Item', @@ -32,6 +33,7 @@ class QualityInspection(Document): child.update(d) child.status = "Accepted" + @frappe.whitelist() def get_quality_inspection_template(self): template = '' if self.bom_no: diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index 559f9a5ed9..f8cfdf83e7 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -39,6 +39,7 @@ class RepostItemValuation(Document): frappe.enqueue(repost, timeout=1800, queue='long', job_name='repost_sle', now=frappe.flags.in_test, doc=self) + @frappe.whitelist() def restart_reposting(self): self.set_status('Queued') frappe.enqueue(repost, timeout=1800, queue='long', diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index b5f7e05f22..f8ac400a8e 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -839,6 +839,7 @@ class StockEntry(StockController): if not pro_doc.operations: pro_doc.set_actual_dates() + @frappe.whitelist() def get_item_details(self, args=None, for_update=False): item = frappe.db.sql("""select i.name, i.stock_uom, i.description, i.image, i.item_name, i.item_group, i.has_batch_no, i.sample_quantity, i.has_serial_no, i.allow_alternative_item, @@ -913,6 +914,7 @@ class StockEntry(StockController): return ret + @frappe.whitelist() def set_items_for_stock_in(self): self.items = [] @@ -937,6 +939,7 @@ class StockEntry(StockController): 'batch_no': d.batch_no }) + @frappe.whitelist() def get_items(self): self.set('items', []) self.validate_work_order() diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py index bbbbc4a527..767a8a6a29 100644 --- a/erpnext/support/doctype/issue/issue.py +++ b/erpnext/support/doctype/issue/issue.py @@ -165,6 +165,7 @@ class Issue(Document): communication.ignore_mandatory = True communication.save() + @frappe.whitelist() def split_issue(self, subject, communication_id): # Bug: Pressing enter doesn't send subject from copy import deepcopy @@ -259,6 +260,7 @@ class Issue(Document): self.set_response_and_resolution_time(priority=self.priority, service_level_agreement=self.service_level_agreement) frappe.msgprint(_("Service Level Agreement has been changed to {0}.").format(self.service_level_agreement)) + @frappe.whitelist() def reset_service_level_agreement(self, reason, user): if not frappe.db.get_single_value("Support Settings", "allow_resetting_service_level_agreement"): frappe.throw(_("Allow Resetting Service Level Agreement from Support Settings."))