Merge branch 'develop' into item_discounts_quotation
This commit is contained in:
commit
afb69b0b7f
@ -131,11 +131,3 @@ def allow_regional(fn):
|
||||
return frappe.get_attr(overrides[function_path][-1])(*args, **kwargs)
|
||||
|
||||
return caller
|
||||
|
||||
def get_last_membership(member):
|
||||
'''Returns last membership if exists'''
|
||||
last_membership = frappe.get_all('Membership', 'name,to_date,membership_type',
|
||||
dict(member=member, paid=1), order_by='to_date desc', limit=1)
|
||||
|
||||
if last_membership:
|
||||
return last_membership[0]
|
||||
|
@ -7,6 +7,7 @@ import json
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.query_builder.custom import ConstantColumn
|
||||
from frappe.utils import flt
|
||||
|
||||
from erpnext import get_company_currency
|
||||
@ -275,6 +276,10 @@ def check_matching(bank_account, company, transaction, document_types):
|
||||
}
|
||||
|
||||
matching_vouchers = []
|
||||
|
||||
matching_vouchers.extend(get_loan_vouchers(bank_account, transaction,
|
||||
document_types, filters))
|
||||
|
||||
for query in subquery:
|
||||
matching_vouchers.extend(
|
||||
frappe.db.sql(query, filters,)
|
||||
@ -311,6 +316,114 @@ def get_queries(bank_account, company, transaction, document_types):
|
||||
|
||||
return queries
|
||||
|
||||
def get_loan_vouchers(bank_account, transaction, document_types, filters):
|
||||
vouchers = []
|
||||
amount_condition = True if "exact_match" in document_types else False
|
||||
|
||||
if transaction.withdrawal > 0 and "loan_disbursement" in document_types:
|
||||
vouchers.extend(get_ld_matching_query(bank_account, amount_condition, filters))
|
||||
|
||||
if transaction.deposit > 0 and "loan_repayment" in document_types:
|
||||
vouchers.extend(get_lr_matching_query(bank_account, amount_condition, filters))
|
||||
|
||||
return vouchers
|
||||
|
||||
def get_ld_matching_query(bank_account, amount_condition, filters):
|
||||
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
|
||||
matching_reference = loan_disbursement.reference_number == filters.get("reference_number")
|
||||
matching_party = loan_disbursement.applicant_type == filters.get("party_type") and \
|
||||
loan_disbursement.applicant == filters.get("party")
|
||||
|
||||
rank = (
|
||||
frappe.qb.terms.Case()
|
||||
.when(matching_reference, 1)
|
||||
.else_(0)
|
||||
)
|
||||
|
||||
rank1 = (
|
||||
frappe.qb.terms.Case()
|
||||
.when(matching_party, 1)
|
||||
.else_(0)
|
||||
)
|
||||
|
||||
query = frappe.qb.from_(loan_disbursement).select(
|
||||
rank + rank1 + 1,
|
||||
ConstantColumn("Loan Disbursement").as_("doctype"),
|
||||
loan_disbursement.name,
|
||||
loan_disbursement.disbursed_amount,
|
||||
loan_disbursement.reference_number,
|
||||
loan_disbursement.reference_date,
|
||||
loan_disbursement.applicant_type,
|
||||
loan_disbursement.disbursement_date
|
||||
).where(
|
||||
loan_disbursement.docstatus == 1
|
||||
).where(
|
||||
loan_disbursement.clearance_date.isnull()
|
||||
).where(
|
||||
loan_disbursement.disbursement_account == bank_account
|
||||
)
|
||||
|
||||
if amount_condition:
|
||||
query.where(
|
||||
loan_disbursement.disbursed_amount == filters.get('amount')
|
||||
)
|
||||
else:
|
||||
query.where(
|
||||
loan_disbursement.disbursed_amount <= filters.get('amount')
|
||||
)
|
||||
|
||||
vouchers = query.run(as_list=True)
|
||||
|
||||
return vouchers
|
||||
|
||||
def get_lr_matching_query(bank_account, amount_condition, filters):
|
||||
loan_repayment = frappe.qb.DocType("Loan Repayment")
|
||||
matching_reference = loan_repayment.reference_number == filters.get("reference_number")
|
||||
matching_party = loan_repayment.applicant_type == filters.get("party_type") and \
|
||||
loan_repayment.applicant == filters.get("party")
|
||||
|
||||
rank = (
|
||||
frappe.qb.terms.Case()
|
||||
.when(matching_reference, 1)
|
||||
.else_(0)
|
||||
)
|
||||
|
||||
rank1 = (
|
||||
frappe.qb.terms.Case()
|
||||
.when(matching_party, 1)
|
||||
.else_(0)
|
||||
)
|
||||
|
||||
query = frappe.qb.from_(loan_repayment).select(
|
||||
rank + rank1 + 1,
|
||||
ConstantColumn("Loan Repayment").as_("doctype"),
|
||||
loan_repayment.name,
|
||||
loan_repayment.amount_paid,
|
||||
loan_repayment.reference_number,
|
||||
loan_repayment.reference_date,
|
||||
loan_repayment.applicant_type,
|
||||
loan_repayment.posting_date
|
||||
).where(
|
||||
loan_repayment.docstatus == 1
|
||||
).where(
|
||||
loan_repayment.clearance_date.isnull()
|
||||
).where(
|
||||
loan_repayment.payment_account == bank_account
|
||||
)
|
||||
|
||||
if amount_condition:
|
||||
query.where(
|
||||
loan_repayment.amount_paid == filters.get('amount')
|
||||
)
|
||||
else:
|
||||
query.where(
|
||||
loan_repayment.amount_paid <= filters.get('amount')
|
||||
)
|
||||
|
||||
vouchers = query.run()
|
||||
|
||||
return vouchers
|
||||
|
||||
def get_pe_matching_query(amount_condition, account_from_to, transaction):
|
||||
# get matching payment entries query
|
||||
if transaction.deposit > 0:
|
||||
@ -348,7 +461,6 @@ def get_je_matching_query(amount_condition, transaction):
|
||||
# We have mapping at the bank level
|
||||
# So one bank could have both types of bank accounts like asset and liability
|
||||
# So cr_or_dr should be judged only on basis of withdrawal and deposit and not account type
|
||||
company_account = frappe.get_value("Bank Account", transaction.bank_account, "account")
|
||||
cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit"
|
||||
|
||||
return f"""
|
||||
|
@ -49,7 +49,8 @@ class BankTransaction(StatusUpdater):
|
||||
|
||||
def clear_linked_payment_entries(self, for_cancel=False):
|
||||
for payment_entry in self.payment_entries:
|
||||
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
|
||||
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim", "Loan Repayment",
|
||||
"Loan Disbursement"]:
|
||||
self.clear_simple_entry(payment_entry, for_cancel=for_cancel)
|
||||
|
||||
elif payment_entry.payment_document == "Sales Invoice":
|
||||
@ -116,11 +117,18 @@ def get_paid_amount(payment_entry, currency, bank_account):
|
||||
payment_entry.payment_entry, paid_amount_field)
|
||||
|
||||
elif payment_entry.payment_document == "Journal Entry":
|
||||
return frappe.db.get_value('Journal Entry Account', {'parent': payment_entry.payment_entry, 'account': bank_account}, "sum(credit_in_account_currency)")
|
||||
return frappe.db.get_value('Journal Entry Account', {'parent': payment_entry.payment_entry, 'account': bank_account},
|
||||
"sum(credit_in_account_currency)")
|
||||
|
||||
elif payment_entry.payment_document == "Expense Claim":
|
||||
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed")
|
||||
|
||||
elif payment_entry.payment_document == "Loan Disbursement":
|
||||
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "disbursed_amount")
|
||||
|
||||
elif payment_entry.payment_document == "Loan Repayment":
|
||||
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "amount_paid")
|
||||
|
||||
else:
|
||||
frappe.throw("Please reconcile {0}: {1} manually".format(payment_entry.payment_document, payment_entry.payment_entry))
|
||||
|
||||
|
@ -109,7 +109,7 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
|
||||
frappe.get_doc({
|
||||
"doctype": "Bank",
|
||||
"bank_name":bank_name,
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
@ -119,7 +119,7 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
|
||||
"account_name":"Checking Account",
|
||||
"bank": bank_name,
|
||||
"account": account_name
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
@ -184,7 +184,7 @@ def add_vouchers():
|
||||
"supplier_group":"All Supplier Groups",
|
||||
"supplier_type": "Company",
|
||||
"supplier_name": "Conrad Electronic"
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
@ -203,7 +203,7 @@ def add_vouchers():
|
||||
"supplier_group":"All Supplier Groups",
|
||||
"supplier_type": "Company",
|
||||
"supplier_name": "Mr G"
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
@ -227,7 +227,7 @@ def add_vouchers():
|
||||
"supplier_group":"All Supplier Groups",
|
||||
"supplier_type": "Company",
|
||||
"supplier_name": "Poore Simon's"
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
@ -237,7 +237,7 @@ def add_vouchers():
|
||||
"customer_group":"All Customer Groups",
|
||||
"customer_type": "Company",
|
||||
"customer_name": "Poore Simon's"
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
@ -266,7 +266,7 @@ def add_vouchers():
|
||||
"customer_group":"All Customer Groups",
|
||||
"customer_type": "Company",
|
||||
"customer_name": "Fayva"
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
|
@ -166,7 +166,7 @@ class OpeningInvoiceCreationTool(Document):
|
||||
frappe.scrub(row.party_type): row.party,
|
||||
"is_pos": 0,
|
||||
"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice",
|
||||
"update_stock": 0,
|
||||
"update_stock": 0, # important: https://github.com/frappe/erpnext/pull/23559
|
||||
"invoice_number": row.invoice_number,
|
||||
"disable_rounded_total": 1
|
||||
})
|
||||
|
@ -1,11 +1,8 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.cache_manager import clear_doctype_cache
|
||||
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
|
||||
create_dimension,
|
||||
@ -17,11 +14,13 @@ from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_crea
|
||||
|
||||
test_dependencies = ["Customer", "Supplier", "Accounting Dimension"]
|
||||
|
||||
class TestOpeningInvoiceCreationTool(unittest.TestCase):
|
||||
def setUp(self):
|
||||
class TestOpeningInvoiceCreationTool(FrappeTestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
|
||||
make_company()
|
||||
create_dimension()
|
||||
return super().setUpClass()
|
||||
|
||||
def make_invoices(self, invoice_type="Sales", company=None, party_1=None, party_2=None, invoice_number=None, department=None):
|
||||
doc = frappe.get_single("Opening Invoice Creation Tool")
|
||||
@ -31,26 +30,20 @@ class TestOpeningInvoiceCreationTool(unittest.TestCase):
|
||||
return doc.make_invoices()
|
||||
|
||||
def test_opening_sales_invoice_creation(self):
|
||||
property_setter = make_property_setter("Sales Invoice", "update_stock", "default", 1, "Check")
|
||||
try:
|
||||
invoices = self.make_invoices(company="_Test Opening Invoice Company")
|
||||
invoices = self.make_invoices(company="_Test Opening Invoice Company")
|
||||
|
||||
self.assertEqual(len(invoices), 2)
|
||||
expected_value = {
|
||||
"keys": ["customer", "outstanding_amount", "status"],
|
||||
0: ["_Test Customer", 300, "Overdue"],
|
||||
1: ["_Test Customer 1", 250, "Overdue"],
|
||||
}
|
||||
self.check_expected_values(invoices, expected_value)
|
||||
self.assertEqual(len(invoices), 2)
|
||||
expected_value = {
|
||||
"keys": ["customer", "outstanding_amount", "status"],
|
||||
0: ["_Test Customer", 300, "Overdue"],
|
||||
1: ["_Test Customer 1", 250, "Overdue"],
|
||||
}
|
||||
self.check_expected_values(invoices, expected_value)
|
||||
|
||||
si = frappe.get_doc("Sales Invoice", invoices[0])
|
||||
si = frappe.get_doc("Sales Invoice", invoices[0])
|
||||
|
||||
# Check if update stock is not enabled
|
||||
self.assertEqual(si.update_stock, 0)
|
||||
|
||||
finally:
|
||||
property_setter.delete()
|
||||
clear_doctype_cache("Sales Invoice")
|
||||
# Check if update stock is not enabled
|
||||
self.assertEqual(si.update_stock, 0)
|
||||
|
||||
def check_expected_values(self, invoices, expected_value, invoice_type="Sales"):
|
||||
doctype = "Sales Invoice" if invoice_type == "Sales" else "Purchase Invoice"
|
||||
|
@ -114,8 +114,6 @@ frappe.ui.form.on('Payment Entry', {
|
||||
var doctypes = ["Expense Claim", "Journal Entry"];
|
||||
} else if (frm.doc.party_type == "Student") {
|
||||
var doctypes = ["Fees"];
|
||||
} else if (frm.doc.party_type == "Donor") {
|
||||
var doctypes = ["Donation"];
|
||||
} else {
|
||||
var doctypes = ["Journal Entry"];
|
||||
}
|
||||
@ -144,7 +142,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
const child = locals[cdt][cdn];
|
||||
const filters = {"docstatus": 1, "company": doc.company};
|
||||
const party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice',
|
||||
'Purchase Order', 'Expense Claim', 'Fees', 'Dunning', 'Donation'];
|
||||
'Purchase Order', 'Expense Claim', 'Fees', 'Dunning'];
|
||||
|
||||
if (in_list(party_type_doctypes, child.reference_doctype)) {
|
||||
filters[doc.party_type.toLowerCase()] = doc.party;
|
||||
@ -196,8 +194,14 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency));
|
||||
|
||||
frm.toggle_display("base_paid_amount", frm.doc.paid_from_account_currency != company_currency);
|
||||
frm.toggle_display("base_total_taxes_and_charges", frm.doc.total_taxes_and_charges &&
|
||||
(frm.doc.paid_from_account_currency != company_currency));
|
||||
|
||||
if (frm.doc.payment_type == "Pay") {
|
||||
frm.toggle_display("base_total_taxes_and_charges", frm.doc.total_taxes_and_charges &&
|
||||
(frm.doc.paid_to_account_currency != company_currency));
|
||||
} else {
|
||||
frm.toggle_display("base_total_taxes_and_charges", frm.doc.total_taxes_and_charges &&
|
||||
(frm.doc.paid_from_account_currency != company_currency));
|
||||
}
|
||||
|
||||
frm.toggle_display("base_received_amount", (
|
||||
frm.doc.paid_to_account_currency != company_currency
|
||||
@ -232,7 +236,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
|
||||
|
||||
frm.set_currency_labels(["base_paid_amount", "base_received_amount", "base_total_allocated_amount",
|
||||
"difference_amount", "base_paid_amount_after_tax", "base_received_amount_after_tax"], company_currency);
|
||||
"difference_amount", "base_paid_amount_after_tax", "base_received_amount_after_tax",
|
||||
"base_total_taxes_and_charges"], company_currency);
|
||||
|
||||
frm.set_currency_labels(["paid_amount"], frm.doc.paid_from_account_currency);
|
||||
frm.set_currency_labels(["received_amount"], frm.doc.paid_to_account_currency);
|
||||
@ -747,8 +752,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Donor")
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
||||
) {
|
||||
if(total_positive_outstanding > total_negative_outstanding)
|
||||
if (!frm.doc.paid_amount)
|
||||
@ -791,8 +795,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Donor")
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
||||
) {
|
||||
if(total_positive_outstanding_including_order > paid_amount) {
|
||||
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
|
||||
@ -951,12 +954,6 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Expense Claim or Journal Entry", [row.idx]));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frm.doc.party_type == "Donor" && row.reference_doctype != "Donation") {
|
||||
frappe.model.set_value(row.doctype, row.name, "reference_doctype", null);
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be Donation", [row.idx]));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (row) {
|
||||
|
@ -66,7 +66,9 @@
|
||||
"tax_withholding_category",
|
||||
"section_break_56",
|
||||
"taxes",
|
||||
"section_break_60",
|
||||
"base_total_taxes_and_charges",
|
||||
"column_break_61",
|
||||
"total_taxes_and_charges",
|
||||
"deductions_or_loss_section",
|
||||
"deductions",
|
||||
@ -715,12 +717,21 @@
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Paid To Account Type"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_61",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_60",
|
||||
"fieldtype": "Section Break",
|
||||
"hide_border": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-11-24 18:58:24.919764",
|
||||
"modified": "2022-02-23 20:08:39.559814",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
@ -763,6 +774,7 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"title_field": "title",
|
||||
"track_changes": 1
|
||||
}
|
@ -91,7 +91,6 @@ class PaymentEntry(AccountsController):
|
||||
self.update_expense_claim()
|
||||
self.update_outstanding_amounts()
|
||||
self.update_advance_paid()
|
||||
self.update_donation()
|
||||
self.update_payment_schedule()
|
||||
self.set_status()
|
||||
|
||||
@ -101,7 +100,6 @@ class PaymentEntry(AccountsController):
|
||||
self.update_expense_claim()
|
||||
self.update_outstanding_amounts()
|
||||
self.update_advance_paid()
|
||||
self.update_donation(cancel=1)
|
||||
self.delink_advance_entry_references()
|
||||
self.update_payment_schedule(cancel=1)
|
||||
self.set_payment_req_status()
|
||||
@ -284,8 +282,6 @@ class PaymentEntry(AccountsController):
|
||||
valid_reference_doctypes = ("Expense Claim", "Journal Entry", "Employee Advance", "Gratuity")
|
||||
elif self.party_type == "Shareholder":
|
||||
valid_reference_doctypes = ("Journal Entry")
|
||||
elif self.party_type == "Donor":
|
||||
valid_reference_doctypes = ("Donation")
|
||||
|
||||
for d in self.get("references"):
|
||||
if not d.allocated_amount:
|
||||
@ -843,13 +839,6 @@ class PaymentEntry(AccountsController):
|
||||
else:
|
||||
update_reimbursed_amount(doc, d.allocated_amount)
|
||||
|
||||
def update_donation(self, cancel=0):
|
||||
if self.payment_type == "Receive" and self.party_type == "Donor" and self.party:
|
||||
for d in self.get("references"):
|
||||
if d.reference_doctype=="Donation" and d.reference_name:
|
||||
is_paid = 0 if cancel else 1
|
||||
frappe.db.set_value("Donation", d.reference_name, "paid", is_paid)
|
||||
|
||||
def on_recurring(self, reference_doc, auto_repeat_doc):
|
||||
self.reference_no = reference_doc.name
|
||||
self.reference_date = nowdate()
|
||||
@ -945,8 +934,12 @@ class PaymentEntry(AccountsController):
|
||||
|
||||
tax.base_total = tax.total * self.source_exchange_rate
|
||||
|
||||
self.total_taxes_and_charges += current_tax_amount
|
||||
self.base_total_taxes_and_charges += current_tax_amount * self.source_exchange_rate
|
||||
if self.payment_type == 'Pay':
|
||||
self.base_total_taxes_and_charges += flt(current_tax_amount / self.source_exchange_rate)
|
||||
self.total_taxes_and_charges += flt(current_tax_amount / self.target_exchange_rate)
|
||||
else:
|
||||
self.base_total_taxes_and_charges += flt(current_tax_amount / self.target_exchange_rate)
|
||||
self.total_taxes_and_charges += flt(current_tax_amount / self.source_exchange_rate)
|
||||
|
||||
if self.get('taxes'):
|
||||
self.paid_amount_after_tax = self.get('taxes')[-1].base_total
|
||||
@ -1077,7 +1070,7 @@ def get_outstanding_reference_documents(args):
|
||||
if d.voucher_type in ("Purchase Invoice"):
|
||||
d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no")
|
||||
|
||||
# Get all SO / PO which are not fully billed or aginst which full advance not paid
|
||||
# Get all SO / PO which are not fully billed or against which full advance not paid
|
||||
orders_to_be_billed = []
|
||||
if (args.get("party_type") != "Student"):
|
||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
||||
@ -1337,10 +1330,6 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
total_amount = ref_doc.get("grand_total")
|
||||
exchange_rate = 1
|
||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||
elif reference_doctype == "Donation":
|
||||
total_amount = ref_doc.get("amount")
|
||||
outstanding_amount = total_amount
|
||||
exchange_rate = 1
|
||||
elif reference_doctype == "Dunning":
|
||||
total_amount = ref_doc.get("dunning_amount")
|
||||
exchange_rate = 1
|
||||
@ -1611,8 +1600,6 @@ def set_party_type(dt):
|
||||
party_type = "Employee"
|
||||
elif dt == "Fees":
|
||||
party_type = "Student"
|
||||
elif dt == "Donation":
|
||||
party_type = "Donor"
|
||||
return party_type
|
||||
|
||||
def set_party_account(dt, dn, doc, party_type):
|
||||
@ -1640,7 +1627,7 @@ def set_party_account_currency(dt, party_account, doc):
|
||||
return party_account_currency
|
||||
|
||||
def set_payment_type(dt, doc):
|
||||
if (dt in ("Sales Order", "Donation") or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)) \
|
||||
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees", "Dunning") and doc.outstanding_amount > 0)) \
|
||||
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||
payment_type = "Receive"
|
||||
else:
|
||||
@ -1673,9 +1660,6 @@ def set_grand_total_and_outstanding_amount(party_amount, dt, party_account_curre
|
||||
elif dt == "Dunning":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.grand_total
|
||||
elif dt == "Donation":
|
||||
grand_total = doc.amount
|
||||
outstanding_amount = doc.amount
|
||||
elif dt == "Gratuity":
|
||||
grand_total = doc.amount
|
||||
outstanding_amount = flt(doc.amount) - flt(doc.paid_amount)
|
||||
|
@ -633,6 +633,45 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
self.assertEqual(flt(expected_party_balance), party_balance)
|
||||
self.assertEqual(flt(expected_party_account_balance), party_account_balance)
|
||||
|
||||
def test_multi_currency_payment_entry_with_taxes(self):
|
||||
payment_entry = create_payment_entry(party='_Test Supplier USD', paid_to = '_Test Payable USD - _TC',
|
||||
save=True)
|
||||
payment_entry.append('taxes', {
|
||||
'account_head': '_Test Account Service Tax - _TC',
|
||||
'charge_type': 'Actual',
|
||||
'tax_amount': 10,
|
||||
'add_deduct_tax': 'Add',
|
||||
'description': 'Test'
|
||||
})
|
||||
|
||||
payment_entry.save()
|
||||
self.assertEqual(payment_entry.base_total_taxes_and_charges, 10)
|
||||
self.assertEqual(flt(payment_entry.total_taxes_and_charges, 2), flt(10 / payment_entry.target_exchange_rate, 2))
|
||||
|
||||
def create_payment_entry(**args):
|
||||
payment_entry = frappe.new_doc('Payment Entry')
|
||||
payment_entry.company = args.get('company') or '_Test Company'
|
||||
payment_entry.payment_type = args.get('payment_type') or 'Pay'
|
||||
payment_entry.party_type = args.get('party_type') or 'Supplier'
|
||||
payment_entry.party = args.get('party') or '_Test Supplier'
|
||||
payment_entry.paid_from = args.get('paid_from') or '_Test Bank - _TC'
|
||||
payment_entry.paid_to = args.get('paid_to') or 'Creditors - _TC'
|
||||
payment_entry.paid_amount = args.get('paid_amount') or 1000
|
||||
|
||||
payment_entry.setup_party_account_field()
|
||||
payment_entry.set_missing_values()
|
||||
payment_entry.set_exchange_rate()
|
||||
payment_entry.received_amount = payment_entry.paid_amount / payment_entry.target_exchange_rate
|
||||
payment_entry.reference_no = 'Test001'
|
||||
payment_entry.reference_date = nowdate()
|
||||
|
||||
if args.get('save'):
|
||||
payment_entry.save()
|
||||
if args.get('submit'):
|
||||
payment_entry.submit()
|
||||
|
||||
return payment_entry
|
||||
|
||||
def create_payment_terms_template():
|
||||
|
||||
create_payment_term('Basic Amount Receivable')
|
||||
|
@ -439,7 +439,6 @@ class POSInvoice(SalesInvoice):
|
||||
self.paid_amount = 0
|
||||
|
||||
def set_account_for_mode_of_payment(self):
|
||||
self.payments = [d for d in self.payments if d.amount or d.base_amount or d.default]
|
||||
for pay in self.payments:
|
||||
if not pay.account:
|
||||
pay.account = get_bank_cash_account(pay.mode_of_payment, self.company).get("account")
|
||||
|
@ -73,7 +73,7 @@ def get_report_pdf(doc, consolidated=True):
|
||||
'to_date': doc.to_date,
|
||||
'company': doc.company,
|
||||
'finance_book': doc.finance_book if doc.finance_book else None,
|
||||
'account': doc.account if doc.account else None,
|
||||
'account': [doc.account] if doc.account else None,
|
||||
'party_type': 'Customer',
|
||||
'party': [entry.customer],
|
||||
'presentation_currency': presentation_currency,
|
||||
|
@ -2429,14 +2429,22 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
|
||||
def test_sales_commission(self):
|
||||
si = frappe.copy_doc(test_records[0])
|
||||
si = frappe.copy_doc(test_records[2])
|
||||
|
||||
frappe.db.set_value('Item', si.get('items')[0].item_code, 'grant_commission', 1)
|
||||
frappe.db.set_value('Item', si.get('items')[1].item_code, 'grant_commission', 0)
|
||||
|
||||
item = copy.deepcopy(si.get('items')[0])
|
||||
item.update({
|
||||
"qty": 1,
|
||||
"rate": 500,
|
||||
"grant_commission": 1
|
||||
})
|
||||
si.append("items", item)
|
||||
|
||||
item = copy.deepcopy(si.get('items')[1])
|
||||
item.update({
|
||||
"qty": 1,
|
||||
"rate": 500,
|
||||
})
|
||||
|
||||
# Test valid values
|
||||
for commission_rate, total_commission in ((0, 0), (10, 50), (100, 500)):
|
||||
|
@ -832,6 +832,7 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fetch_from": "item_code.grant_commission",
|
||||
"fieldname": "grant_commission",
|
||||
"fieldtype": "Check",
|
||||
"label": "Grant Commission",
|
||||
@ -841,7 +842,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-10-05 12:24:54.968907",
|
||||
"modified": "2022-02-24 14:41:36.392560",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
@ -849,5 +850,6 @@
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
}
|
@ -46,7 +46,7 @@ def valdiate_taxes_and_charges_template(doc):
|
||||
|
||||
for tax in doc.get("taxes"):
|
||||
validate_taxes_and_charges(tax)
|
||||
validate_account_head(tax, doc)
|
||||
validate_account_head(tax.idx, tax.account_head, doc.company)
|
||||
validate_cost_center(tax, doc)
|
||||
validate_inclusive_tax(tax, doc)
|
||||
|
||||
|
@ -307,7 +307,7 @@ def validate_party_gle_currency(party_type, party, company, party_account_curren
|
||||
.format(frappe.bold(party_type), frappe.bold(party), frappe.bold(existing_gle_currency), frappe.bold(company)), InvalidAccountCurrency)
|
||||
|
||||
def validate_party_accounts(doc):
|
||||
|
||||
from erpnext.controllers.accounts_controller import validate_account_head
|
||||
companies = []
|
||||
|
||||
for account in doc.get("accounts"):
|
||||
@ -330,6 +330,9 @@ def validate_party_accounts(doc):
|
||||
if doc.default_currency != party_account_currency and doc.default_currency != company_default_currency:
|
||||
frappe.throw(_("Billing currency must be equal to either default company's currency or party account currency"))
|
||||
|
||||
# validate if account is mapped for same company
|
||||
validate_account_head(account.idx, account.account, account.company)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_due_date(posting_date, party_type, party, company=None, bill_date=None):
|
||||
|
@ -4,7 +4,12 @@
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, getdate, nowdate
|
||||
from frappe.query_builder.custom import ConstantColumn
|
||||
from frappe.query_builder.functions import Sum
|
||||
from frappe.utils import flt, getdate
|
||||
from pypika import CustomFunction
|
||||
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
|
||||
|
||||
def execute(filters=None):
|
||||
@ -18,7 +23,6 @@ def execute(filters=None):
|
||||
|
||||
data = get_entries(filters)
|
||||
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
||||
|
||||
total_debit, total_credit = 0,0
|
||||
@ -118,7 +122,21 @@ def get_columns():
|
||||
]
|
||||
|
||||
def get_entries(filters):
|
||||
journal_entries = frappe.db.sql("""
|
||||
journal_entries = get_journal_entries(filters)
|
||||
|
||||
payment_entries = get_payment_entries(filters)
|
||||
|
||||
loan_entries = get_loan_entries(filters)
|
||||
|
||||
pos_entries = []
|
||||
if filters.include_pos_transactions:
|
||||
pos_entries = get_pos_entries(filters)
|
||||
|
||||
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries) + list(loan_entries)),
|
||||
key=lambda k: getdate(k['posting_date']))
|
||||
|
||||
def get_journal_entries(filters):
|
||||
return frappe.db.sql("""
|
||||
select "Journal Entry" as payment_document, jv.posting_date,
|
||||
jv.name as payment_entry, jvd.debit_in_account_currency as debit,
|
||||
jvd.credit_in_account_currency as credit, jvd.against_account,
|
||||
@ -130,7 +148,8 @@ def get_entries(filters):
|
||||
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s
|
||||
and ifnull(jv.is_opening, 'No') = 'No'""", filters, as_dict=1)
|
||||
|
||||
payment_entries = frappe.db.sql("""
|
||||
def get_payment_entries(filters):
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
"Payment Entry" as payment_document, name as payment_entry,
|
||||
reference_no, reference_date as ref_date,
|
||||
@ -145,9 +164,8 @@ def get_entries(filters):
|
||||
and ifnull(clearance_date, '4000-01-01') > %(report_date)s
|
||||
""", filters, as_dict=1)
|
||||
|
||||
pos_entries = []
|
||||
if filters.include_pos_transactions:
|
||||
pos_entries = frappe.db.sql("""
|
||||
def get_pos_entries(filters):
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
|
||||
si.posting_date, si.debit_to as against_account, sip.clearance_date,
|
||||
@ -161,8 +179,42 @@ def get_entries(filters):
|
||||
si.posting_date ASC, si.name DESC
|
||||
""", filters, as_dict=1)
|
||||
|
||||
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
||||
def get_loan_entries(filters):
|
||||
loan_docs = []
|
||||
for doctype in ["Loan Disbursement", "Loan Repayment"]:
|
||||
loan_doc = frappe.qb.DocType(doctype)
|
||||
ifnull = CustomFunction('IFNULL', ['value', 'default'])
|
||||
|
||||
if doctype == "Loan Disbursement":
|
||||
amount_field = (loan_doc.disbursed_amount).as_("credit")
|
||||
posting_date = (loan_doc.disbursement_date).as_("posting_date")
|
||||
account = loan_doc.disbursement_account
|
||||
else:
|
||||
amount_field = (loan_doc.amount_paid).as_("debit")
|
||||
posting_date = (loan_doc.posting_date).as_("posting_date")
|
||||
account = loan_doc.payment_account
|
||||
|
||||
entries = frappe.qb.from_(loan_doc).select(
|
||||
ConstantColumn(doctype).as_("payment_document"),
|
||||
(loan_doc.name).as_("payment_entry"),
|
||||
(loan_doc.reference_number).as_("reference_no"),
|
||||
(loan_doc.reference_date).as_("ref_date"),
|
||||
amount_field,
|
||||
posting_date,
|
||||
).where(
|
||||
loan_doc.docstatus == 1
|
||||
).where(
|
||||
account == filters.get('account')
|
||||
).where(
|
||||
posting_date <= getdate(filters.get('report_date'))
|
||||
).where(
|
||||
ifnull(loan_doc.clearance_date, '4000-01-01') > getdate(filters.get('report_date'))
|
||||
).run(as_dict=1)
|
||||
|
||||
loan_docs.extend(entries)
|
||||
|
||||
return loan_docs
|
||||
|
||||
|
||||
def get_amounts_not_reflected_in_system(filters):
|
||||
je_amount = frappe.db.sql("""
|
||||
@ -182,7 +234,40 @@ def get_amounts_not_reflected_in_system(filters):
|
||||
|
||||
pe_amount = flt(pe_amount[0][0]) if pe_amount else 0.0
|
||||
|
||||
return je_amount + pe_amount
|
||||
loan_amount = get_loan_amount(filters)
|
||||
|
||||
return je_amount + pe_amount + loan_amount
|
||||
|
||||
def get_loan_amount(filters):
|
||||
total_amount = 0
|
||||
for doctype in ["Loan Disbursement", "Loan Repayment"]:
|
||||
loan_doc = frappe.qb.DocType(doctype)
|
||||
ifnull = CustomFunction('IFNULL', ['value', 'default'])
|
||||
|
||||
if doctype == "Loan Disbursement":
|
||||
amount_field = Sum(loan_doc.disbursed_amount)
|
||||
posting_date = (loan_doc.disbursement_date).as_("posting_date")
|
||||
account = loan_doc.disbursement_account
|
||||
else:
|
||||
amount_field = Sum(loan_doc.amount_paid)
|
||||
posting_date = (loan_doc.posting_date).as_("posting_date")
|
||||
account = loan_doc.payment_account
|
||||
|
||||
amount = frappe.qb.from_(loan_doc).select(
|
||||
amount_field
|
||||
).where(
|
||||
loan_doc.docstatus == 1
|
||||
).where(
|
||||
account == filters.get('account')
|
||||
).where(
|
||||
posting_date > getdate(filters.get('report_date'))
|
||||
).where(
|
||||
ifnull(loan_doc.clearance_date, '4000-01-01') <= getdate(filters.get('report_date'))
|
||||
).run()[0][0]
|
||||
|
||||
total_amount += flt(amount)
|
||||
|
||||
return amount
|
||||
|
||||
def get_balance_row(label, amount, account_currency):
|
||||
if amount > 0:
|
||||
|
@ -61,7 +61,7 @@ class TestTaxDetail(unittest.TestCase):
|
||||
# Create GL Entries:
|
||||
db_doc.submit()
|
||||
else:
|
||||
db_doc.insert()
|
||||
db_doc.insert(ignore_if_duplicate=True)
|
||||
except frappe.exceptions.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
|
@ -39,10 +39,11 @@ class TestReports(unittest.TestCase):
|
||||
def test_execute_all_accounts_reports(self):
|
||||
"""Test that all script report in stock modules are executable with supported filters"""
|
||||
for report, filter in REPORT_FILTER_TEST_CASES:
|
||||
execute_script_report(
|
||||
report_name=report,
|
||||
module="Accounts",
|
||||
filters=filter,
|
||||
default_filters=DEFAULT_FILTERS,
|
||||
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
|
||||
)
|
||||
with self.subTest(report=report):
|
||||
execute_script_report(
|
||||
report_name=report,
|
||||
module="Accounts",
|
||||
filters=filter,
|
||||
default_filters=DEFAULT_FILTERS,
|
||||
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
|
||||
)
|
||||
|
@ -847,7 +847,7 @@ def create_payment_gateway_account(gateway, payment_channel="Email"):
|
||||
"payment_account": bank_account.name,
|
||||
"currency": bank_account.account_currency,
|
||||
"payment_channel": payment_channel
|
||||
}).insert(ignore_permissions=True)
|
||||
}).insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||
|
||||
except frappe.DuplicateEntryError:
|
||||
# already exists, due to a reinstall?
|
||||
|
@ -417,11 +417,12 @@ class Asset(AccountsController):
|
||||
def validate_asset_finance_books(self, row):
|
||||
if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
|
||||
frappe.throw(_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount")
|
||||
.format(row.idx))
|
||||
.format(row.idx), title=_("Invalid Schedule"))
|
||||
|
||||
if not row.depreciation_start_date:
|
||||
if not self.available_for_use_date:
|
||||
frappe.throw(_("Row {0}: Depreciation Start Date is required").format(row.idx))
|
||||
frappe.throw(_("Row {0}: Depreciation Start Date is required")
|
||||
.format(row.idx), title=_("Invalid Schedule"))
|
||||
row.depreciation_start_date = get_last_day(self.available_for_use_date)
|
||||
|
||||
if not self.is_existing_asset:
|
||||
@ -439,8 +440,9 @@ class Asset(AccountsController):
|
||||
else:
|
||||
self.number_of_depreciations_booked = 0
|
||||
|
||||
if cint(self.number_of_depreciations_booked) > cint(row.total_number_of_depreciations):
|
||||
frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
|
||||
if flt(row.total_number_of_depreciations) <= cint(self.number_of_depreciations_booked):
|
||||
frappe.throw(_("Row {0}: Total Number of Depreciations cannot be less than or equal to Number of Depreciations Booked")
|
||||
.format(row.idx), title=_("Invalid Schedule"))
|
||||
|
||||
if row.depreciation_start_date and getdate(row.depreciation_start_date) < getdate(self.purchase_date):
|
||||
frappe.throw(_("Depreciation Row {0}: Next Depreciation Date cannot be before Purchase Date")
|
||||
|
@ -873,8 +873,9 @@ class TestDepreciationBasics(AssetSetup):
|
||||
self.assertRaises(frappe.ValidationError, asset.save)
|
||||
|
||||
def test_number_of_depreciations(self):
|
||||
"""Tests if an error is raised when number_of_depreciations_booked > total_number_of_depreciations."""
|
||||
"""Tests if an error is raised when number_of_depreciations_booked >= total_number_of_depreciations."""
|
||||
|
||||
# number_of_depreciations_booked > total_number_of_depreciations
|
||||
asset = create_asset(
|
||||
item_code = "Macbook Pro",
|
||||
calculate_depreciation = 1,
|
||||
@ -889,6 +890,21 @@ class TestDepreciationBasics(AssetSetup):
|
||||
|
||||
self.assertRaises(frappe.ValidationError, asset.save)
|
||||
|
||||
# number_of_depreciations_booked = total_number_of_depreciations
|
||||
asset_2 = create_asset(
|
||||
item_code = "Macbook Pro",
|
||||
calculate_depreciation = 1,
|
||||
available_for_use_date = "2019-12-31",
|
||||
total_number_of_depreciations = 5,
|
||||
expected_value_after_useful_life = 10000,
|
||||
depreciation_start_date = "2020-07-01",
|
||||
opening_accumulated_depreciation = 10000,
|
||||
number_of_depreciations_booked = 5,
|
||||
do_not_save = 1
|
||||
)
|
||||
|
||||
self.assertRaises(frappe.ValidationError, asset_2.save)
|
||||
|
||||
def test_depreciation_start_date_is_before_purchase_date(self):
|
||||
asset = create_asset(
|
||||
item_code = "Macbook Pro",
|
||||
@ -1264,7 +1280,7 @@ def create_asset(**args):
|
||||
|
||||
if not args.do_not_save:
|
||||
try:
|
||||
asset.save()
|
||||
asset.insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
@ -1305,7 +1321,7 @@ def create_fixed_asset_item(item_code=None, auto_create_assets=1, is_grouped_ass
|
||||
"is_grouped_asset": is_grouped_asset,
|
||||
"asset_naming_series": naming_series
|
||||
})
|
||||
item.insert()
|
||||
item.insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
return item
|
||||
|
@ -23,7 +23,7 @@ class TestAssetCategory(unittest.TestCase):
|
||||
})
|
||||
|
||||
try:
|
||||
asset_category.insert()
|
||||
asset_category.insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_days, flt, getdate, nowdate
|
||||
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||
@ -27,7 +27,7 @@ from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
class TestPurchaseOrder(unittest.TestCase):
|
||||
class TestPurchaseOrder(FrappeTestCase):
|
||||
def test_make_purchase_receipt(self):
|
||||
po = create_purchase_order(do_not_submit=True)
|
||||
self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name)
|
||||
|
@ -1,9 +1,9 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import nowdate
|
||||
|
||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
||||
@ -16,7 +16,7 @@ from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||
|
||||
|
||||
class TestRequestforQuotation(unittest.TestCase):
|
||||
class TestRequestforQuotation(FrappeTestCase):
|
||||
def test_quote_status(self):
|
||||
rfq = make_request_for_quotation()
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
@ -12,153 +11,154 @@ from erpnext.exceptions import PartyDisabled
|
||||
test_dependencies = ['Payment Term', 'Payment Terms Template']
|
||||
test_records = frappe.get_test_records('Supplier')
|
||||
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
class TestSupplier(unittest.TestCase):
|
||||
def test_get_supplier_group_details(self):
|
||||
doc = frappe.new_doc("Supplier Group")
|
||||
doc.supplier_group_name = "_Testing Supplier Group"
|
||||
doc.payment_terms = "_Test Payment Term Template 3"
|
||||
doc.accounts = []
|
||||
test_account_details = {
|
||||
"company": "_Test Company",
|
||||
"account": "Creditors - _TC",
|
||||
}
|
||||
doc.append("accounts", test_account_details)
|
||||
doc.save()
|
||||
s_doc = frappe.new_doc("Supplier")
|
||||
s_doc.supplier_name = "Testing Supplier"
|
||||
s_doc.supplier_group = "_Testing Supplier Group"
|
||||
s_doc.payment_terms = ""
|
||||
s_doc.accounts = []
|
||||
s_doc.insert()
|
||||
s_doc.get_supplier_group_details()
|
||||
self.assertEqual(s_doc.payment_terms, "_Test Payment Term Template 3")
|
||||
self.assertEqual(s_doc.accounts[0].company, "_Test Company")
|
||||
self.assertEqual(s_doc.accounts[0].account, "Creditors - _TC")
|
||||
s_doc.delete()
|
||||
doc.delete()
|
||||
|
||||
def test_supplier_default_payment_terms(self):
|
||||
# Payment Term based on Days after invoice date
|
||||
frappe.db.set_value(
|
||||
"Supplier", "_Test Supplier With Template 1", "payment_terms", "_Test Payment Term Template 3")
|
||||
class TestSupplier(FrappeTestCase):
|
||||
def test_get_supplier_group_details(self):
|
||||
doc = frappe.new_doc("Supplier Group")
|
||||
doc.supplier_group_name = "_Testing Supplier Group"
|
||||
doc.payment_terms = "_Test Payment Term Template 3"
|
||||
doc.accounts = []
|
||||
test_account_details = {
|
||||
"company": "_Test Company",
|
||||
"account": "Creditors - _TC",
|
||||
}
|
||||
doc.append("accounts", test_account_details)
|
||||
doc.save()
|
||||
s_doc = frappe.new_doc("Supplier")
|
||||
s_doc.supplier_name = "Testing Supplier"
|
||||
s_doc.supplier_group = "_Testing Supplier Group"
|
||||
s_doc.payment_terms = ""
|
||||
s_doc.accounts = []
|
||||
s_doc.insert()
|
||||
s_doc.get_supplier_group_details()
|
||||
self.assertEqual(s_doc.payment_terms, "_Test Payment Term Template 3")
|
||||
self.assertEqual(s_doc.accounts[0].company, "_Test Company")
|
||||
self.assertEqual(s_doc.accounts[0].account, "Creditors - _TC")
|
||||
s_doc.delete()
|
||||
doc.delete()
|
||||
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-21")
|
||||
def test_supplier_default_payment_terms(self):
|
||||
# Payment Term based on Days after invoice date
|
||||
frappe.db.set_value(
|
||||
"Supplier", "_Test Supplier With Template 1", "payment_terms", "_Test Payment Term Template 3")
|
||||
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2017-02-21")
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-21")
|
||||
|
||||
# Payment Term based on last day of month
|
||||
frappe.db.set_value(
|
||||
"Supplier", "_Test Supplier With Template 1", "payment_terms", "_Test Payment Term Template 1")
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2017-02-21")
|
||||
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-29")
|
||||
# Payment Term based on last day of month
|
||||
frappe.db.set_value(
|
||||
"Supplier", "_Test Supplier With Template 1", "payment_terms", "_Test Payment Term Template 1")
|
||||
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2017-02-28")
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-29")
|
||||
|
||||
frappe.db.set_value("Supplier", "_Test Supplier With Template 1", "payment_terms", "")
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2017-02-28")
|
||||
|
||||
# Set credit limit for the supplier group instead of supplier and evaluate the due date
|
||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "_Test Payment Term Template 3")
|
||||
frappe.db.set_value("Supplier", "_Test Supplier With Template 1", "payment_terms", "")
|
||||
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-21")
|
||||
# Set credit limit for the supplier group instead of supplier and evaluate the due date
|
||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "_Test Payment Term Template 3")
|
||||
|
||||
# Payment terms for Supplier Group instead of supplier and evaluate the due date
|
||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "_Test Payment Term Template 1")
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-21")
|
||||
|
||||
# Leap year
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-29")
|
||||
# # Non Leap year
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2017-02-28")
|
||||
# Payment terms for Supplier Group instead of supplier and evaluate the due date
|
||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "_Test Payment Term Template 1")
|
||||
|
||||
# Supplier with no default Payment Terms Template
|
||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "")
|
||||
frappe.db.set_value("Supplier", "_Test Supplier", "payment_terms", "")
|
||||
# Leap year
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2016-02-29")
|
||||
# # Non Leap year
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||
self.assertEqual(due_date, "2017-02-28")
|
||||
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier")
|
||||
self.assertEqual(due_date, "2016-01-22")
|
||||
# # Non Leap year
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier")
|
||||
self.assertEqual(due_date, "2017-01-22")
|
||||
# Supplier with no default Payment Terms Template
|
||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "")
|
||||
frappe.db.set_value("Supplier", "_Test Supplier", "payment_terms", "")
|
||||
|
||||
def test_supplier_disabled(self):
|
||||
make_test_records("Item")
|
||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier")
|
||||
self.assertEqual(due_date, "2016-01-22")
|
||||
# # Non Leap year
|
||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier")
|
||||
self.assertEqual(due_date, "2017-01-22")
|
||||
|
||||
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 1)
|
||||
def test_supplier_disabled(self):
|
||||
make_test_records("Item")
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 1)
|
||||
|
||||
po = create_purchase_order(do_not_save=True)
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
|
||||
self.assertRaises(PartyDisabled, po.save)
|
||||
po = create_purchase_order(do_not_save=True)
|
||||
|
||||
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 0)
|
||||
self.assertRaises(PartyDisabled, po.save)
|
||||
|
||||
po.save()
|
||||
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 0)
|
||||
|
||||
def test_supplier_country(self):
|
||||
# Test that country field exists in Supplier DocType
|
||||
supplier = frappe.get_doc('Supplier', '_Test Supplier with Country')
|
||||
self.assertTrue('country' in supplier.as_dict())
|
||||
po.save()
|
||||
|
||||
# Test if test supplier field record is 'Greece'
|
||||
self.assertEqual(supplier.country, "Greece")
|
||||
def test_supplier_country(self):
|
||||
# Test that country field exists in Supplier DocType
|
||||
supplier = frappe.get_doc('Supplier', '_Test Supplier with Country')
|
||||
self.assertTrue('country' in supplier.as_dict())
|
||||
|
||||
# Test update Supplier instance country value
|
||||
supplier = frappe.get_doc('Supplier', '_Test Supplier')
|
||||
supplier.country = 'Greece'
|
||||
supplier.save()
|
||||
self.assertEqual(supplier.country, "Greece")
|
||||
# Test if test supplier field record is 'Greece'
|
||||
self.assertEqual(supplier.country, "Greece")
|
||||
|
||||
def test_party_details_tax_category(self):
|
||||
from erpnext.accounts.party import get_party_details
|
||||
# Test update Supplier instance country value
|
||||
supplier = frappe.get_doc('Supplier', '_Test Supplier')
|
||||
supplier.country = 'Greece'
|
||||
supplier.save()
|
||||
self.assertEqual(supplier.country, "Greece")
|
||||
|
||||
frappe.delete_doc_if_exists("Address", "_Test Address With Tax Category-Billing")
|
||||
def test_party_details_tax_category(self):
|
||||
from erpnext.accounts.party import get_party_details
|
||||
|
||||
# Tax Category without Address
|
||||
details = get_party_details("_Test Supplier With Tax Category", party_type="Supplier")
|
||||
self.assertEqual(details.tax_category, "_Test Tax Category 1")
|
||||
frappe.delete_doc_if_exists("Address", "_Test Address With Tax Category-Billing")
|
||||
|
||||
address = frappe.get_doc(dict(
|
||||
doctype='Address',
|
||||
address_title='_Test Address With Tax Category',
|
||||
tax_category='_Test Tax Category 2',
|
||||
address_type='Billing',
|
||||
address_line1='Station Road',
|
||||
city='_Test City',
|
||||
country='India',
|
||||
links=[dict(
|
||||
link_doctype='Supplier',
|
||||
link_name='_Test Supplier With Tax Category'
|
||||
)]
|
||||
)).insert()
|
||||
# Tax Category without Address
|
||||
details = get_party_details("_Test Supplier With Tax Category", party_type="Supplier")
|
||||
self.assertEqual(details.tax_category, "_Test Tax Category 1")
|
||||
|
||||
# Tax Category with Address
|
||||
details = get_party_details("_Test Supplier With Tax Category", party_type="Supplier")
|
||||
self.assertEqual(details.tax_category, "_Test Tax Category 2")
|
||||
address = frappe.get_doc(dict(
|
||||
doctype='Address',
|
||||
address_title='_Test Address With Tax Category',
|
||||
tax_category='_Test Tax Category 2',
|
||||
address_type='Billing',
|
||||
address_line1='Station Road',
|
||||
city='_Test City',
|
||||
country='India',
|
||||
links=[dict(
|
||||
link_doctype='Supplier',
|
||||
link_name='_Test Supplier With Tax Category'
|
||||
)]
|
||||
)).insert()
|
||||
|
||||
# Rollback
|
||||
address.delete()
|
||||
# Tax Category with Address
|
||||
details = get_party_details("_Test Supplier With Tax Category", party_type="Supplier")
|
||||
self.assertEqual(details.tax_category, "_Test Tax Category 2")
|
||||
|
||||
# Rollback
|
||||
address.delete()
|
||||
|
||||
def create_supplier(**args):
|
||||
args = frappe._dict(args)
|
||||
args = frappe._dict(args)
|
||||
|
||||
try:
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Supplier",
|
||||
"supplier_name": args.supplier_name,
|
||||
"supplier_group": args.supplier_group or "Services",
|
||||
"supplier_type": args.supplier_type or "Company",
|
||||
"tax_withholding_category": args.tax_withholding_category
|
||||
}).insert()
|
||||
if frappe.db.exists("Supplier", args.supplier_name):
|
||||
return frappe.get_doc("Supplier", args.supplier_name)
|
||||
|
||||
return doc
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Supplier",
|
||||
"supplier_name": args.supplier_name,
|
||||
"supplier_group": args.supplier_group or "Services",
|
||||
"supplier_type": args.supplier_type or "Company",
|
||||
"tax_withholding_category": args.tax_withholding_category
|
||||
}).insert()
|
||||
|
||||
except frappe.DuplicateEntryError:
|
||||
return frappe.get_doc("Supplier", args.supplier_name)
|
||||
return doc
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestPurchaseOrder(unittest.TestCase):
|
||||
class TestPurchaseOrder(FrappeTestCase):
|
||||
def test_make_purchase_order(self):
|
||||
from erpnext.buying.doctype.supplier_quotation.supplier_quotation import make_purchase_order
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestSupplierScorecard(unittest.TestCase):
|
||||
class TestSupplierScorecard(FrappeTestCase):
|
||||
|
||||
def test_create_scorecard(self):
|
||||
doc = make_supplier_scorecard().insert()
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestSupplierScorecardCriteria(unittest.TestCase):
|
||||
class TestSupplierScorecardCriteria(FrappeTestCase):
|
||||
def test_variables_exist(self):
|
||||
delete_test_scorecards()
|
||||
for d in test_good_criteria:
|
||||
|
@ -1,16 +1,16 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable import (
|
||||
VariablePathNotFound,
|
||||
)
|
||||
|
||||
|
||||
class TestSupplierScorecardVariable(unittest.TestCase):
|
||||
class TestSupplierScorecardVariable(FrappeTestCase):
|
||||
def test_variable_exist(self):
|
||||
for d in test_existing_variables:
|
||||
my_doc = frappe.get_doc("Supplier Scorecard Variable", d.get("name"))
|
||||
|
@ -2,10 +2,10 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import unittest
|
||||
from datetime import datetime
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
||||
from erpnext.buying.report.procurement_tracker.procurement_tracker import execute
|
||||
@ -14,7 +14,7 @@ from erpnext.stock.doctype.material_request.test_material_request import make_ma
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
|
||||
|
||||
class TestProcurementTracker(unittest.TestCase):
|
||||
class TestProcurementTracker(FrappeTestCase):
|
||||
def test_result_for_procurement_tracker(self):
|
||||
filters = {
|
||||
'company': '_Test Procurement Company',
|
||||
|
@ -3,9 +3,9 @@
|
||||
# Compiled at: 2019-05-06 09:51:46
|
||||
# Decompiled by https://python-decompiler.com
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
@ -15,7 +15,7 @@ from erpnext.buying.report.subcontracted_item_to_be_received.subcontracted_item_
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
class TestSubcontractedItemToBeReceived(unittest.TestCase):
|
||||
class TestSubcontractedItemToBeReceived(FrappeTestCase):
|
||||
|
||||
def test_pending_and_received_qty(self):
|
||||
po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes')
|
||||
|
@ -4,9 +4,9 @@
|
||||
# Decompiled by https://python-decompiler.com
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_rm_stock_entry
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
@ -16,7 +16,7 @@ from erpnext.buying.report.subcontracted_raw_materials_to_be_transferred.subcont
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
|
||||
|
||||
class TestSubcontractedItemToBeTransferred(unittest.TestCase):
|
||||
class TestSubcontractedItemToBeTransferred(FrappeTestCase):
|
||||
|
||||
def test_pending_and_transferred_qty(self):
|
||||
po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes', supplier_warehouse="_Test Warehouse 1 - _TC")
|
||||
|
@ -1566,13 +1566,12 @@ def validate_taxes_and_charges(tax):
|
||||
tax.rate = None
|
||||
|
||||
|
||||
def validate_account_head(tax, doc):
|
||||
company = frappe.get_cached_value('Account',
|
||||
tax.account_head, 'company')
|
||||
def validate_account_head(idx, account, company):
|
||||
account_company = frappe.get_cached_value('Account', account, 'company')
|
||||
|
||||
if company != doc.company:
|
||||
if account_company != company:
|
||||
frappe.throw(_('Row {0}: Account {1} does not belong to Company {2}')
|
||||
.format(tax.idx, frappe.bold(tax.account_head), frappe.bold(doc.company)), title=_('Invalid Account'))
|
||||
.format(idx, frappe.bold(account), frappe.bold(company)), title=_('Invalid Account'))
|
||||
|
||||
|
||||
def validate_cost_center(tax, doc):
|
||||
|
@ -104,11 +104,11 @@ class EmployeeBoardingController(Document):
|
||||
def get_task_dates(self, activity, holiday_list):
|
||||
start_date = end_date = None
|
||||
|
||||
if activity.begin_on:
|
||||
if activity.begin_on is not None:
|
||||
start_date = add_days(self.boarding_begins_on, activity.begin_on)
|
||||
start_date = self.update_if_holiday(start_date, holiday_list)
|
||||
|
||||
if activity.duration:
|
||||
if activity.duration is not None:
|
||||
end_date = add_days(self.boarding_begins_on, activity.begin_on + activity.duration)
|
||||
end_date = self.update_if_holiday(end_date, holiday_list)
|
||||
|
||||
|
@ -363,8 +363,6 @@ class Subcontracting():
|
||||
return
|
||||
|
||||
for row in self.get(self.raw_material_table):
|
||||
self.__validate_consumed_qty(row)
|
||||
|
||||
key = (row.rm_item_code, row.main_item_code, row.purchase_order)
|
||||
if not self.__transferred_items or not self.__transferred_items.get(key):
|
||||
return
|
||||
@ -372,12 +370,6 @@ class Subcontracting():
|
||||
self.__validate_batch_no(row, key)
|
||||
self.__validate_serial_no(row, key)
|
||||
|
||||
def __validate_consumed_qty(self, row):
|
||||
if self.backflush_based_on != 'BOM' and flt(row.consumed_qty) == 0.0:
|
||||
msg = f'Row {row.idx}: the consumed qty cannot be zero for the item {frappe.bold(row.rm_item_code)}'
|
||||
|
||||
frappe.throw(_(msg),title=_('Consumed Items Qty Check'))
|
||||
|
||||
def __validate_batch_no(self, row, key):
|
||||
if row.get('batch_no') and row.get('batch_no') not in self.__transferred_items.get(key).get('batch_no'):
|
||||
link = get_link_to_form('Purchase Order', row.purchase_order)
|
||||
|
@ -1,22 +0,0 @@
|
||||
data = {
|
||||
'desktop_icons': [
|
||||
'Non Profit',
|
||||
'Member',
|
||||
'Donor',
|
||||
'Volunteer',
|
||||
'Grant Application',
|
||||
'Accounts',
|
||||
'Buying',
|
||||
'HR',
|
||||
'ToDo'
|
||||
],
|
||||
'restricted_roles': [
|
||||
'Non Profit Manager',
|
||||
'Non Profit Member',
|
||||
'Non Profit Portal User'
|
||||
],
|
||||
'modules': [
|
||||
'Non Profit'
|
||||
],
|
||||
'default_portal_role': 'Non Profit Manager'
|
||||
}
|
@ -264,7 +264,7 @@ class ProductQuery:
|
||||
customer = get_customer(silent=True)
|
||||
if customer:
|
||||
quotation = frappe.get_all("Quotation", fields=["name"], filters=
|
||||
{"party_name": customer, "order_type": "Shopping Cart", "docstatus": 0},
|
||||
{"party_name": customer, "contact_email": frappe.session.user, "order_type": "Shopping Cart", "docstatus": 0},
|
||||
order_by="modified desc", limit_page_length=1)
|
||||
if quotation:
|
||||
items = frappe.get_all(
|
||||
@ -298,4 +298,4 @@ class ProductQuery:
|
||||
# slice results manually
|
||||
result[:self.page_length]
|
||||
|
||||
return result
|
||||
return result
|
||||
|
@ -310,7 +310,7 @@ def _get_cart_quotation(party=None):
|
||||
party = get_party()
|
||||
|
||||
quotation = frappe.get_all("Quotation", fields=["name"], filters=
|
||||
{"party_name": party.name, "order_type": "Shopping Cart", "docstatus": 0},
|
||||
{"party_name": party.name, "contact_email": frappe.session.user, "order_type": "Shopping Cart", "docstatus": 0},
|
||||
order_by="modified desc", limit_page_length=1)
|
||||
|
||||
if quotation:
|
||||
|
@ -5,6 +5,7 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import change_settings
|
||||
from frappe.utils import add_months, nowdate
|
||||
|
||||
from erpnext.accounts.doctype.tax_rule.tax_rule import ConflictingTaxRule
|
||||
@ -15,7 +16,7 @@ from erpnext.e_commerce.shopping_cart.cart import (
|
||||
get_party,
|
||||
update_cart,
|
||||
)
|
||||
from erpnext.tests.utils import change_settings, create_test_contact_and_address
|
||||
from erpnext.tests.utils import create_test_contact_and_address
|
||||
|
||||
# test_dependencies = ['Payment Terms Template']
|
||||
|
||||
@ -57,13 +58,19 @@ class TestShoppingCart(unittest.TestCase):
|
||||
return quotation
|
||||
|
||||
def test_get_cart_customer(self):
|
||||
self.login_as_customer()
|
||||
def validate_quotation():
|
||||
# test if quotation with customer is fetched
|
||||
quotation = _get_cart_quotation()
|
||||
self.assertEqual(quotation.quotation_to, "Customer")
|
||||
self.assertEqual(quotation.party_name, "_Test Customer")
|
||||
self.assertEqual(quotation.contact_email, frappe.session.user)
|
||||
return quotation
|
||||
|
||||
# test if quotation with customer is fetched
|
||||
quotation = _get_cart_quotation()
|
||||
self.assertEqual(quotation.quotation_to, "Customer")
|
||||
self.assertEqual(quotation.party_name, "_Test Customer")
|
||||
self.assertEqual(quotation.contact_email, frappe.session.user)
|
||||
self.login_as_customer("test_contact_two_customer@example.com", "_Test Contact 2 For _Test Customer")
|
||||
validate_quotation()
|
||||
|
||||
self.login_as_customer()
|
||||
quotation = validate_quotation()
|
||||
|
||||
return quotation
|
||||
|
||||
@ -175,7 +182,7 @@ class TestShoppingCart(unittest.TestCase):
|
||||
def create_tax_rule(self):
|
||||
tax_rule = frappe.get_test_records("Tax Rule")[0]
|
||||
try:
|
||||
frappe.get_doc(tax_rule).insert()
|
||||
frappe.get_doc(tax_rule).insert(ignore_if_duplicate=True)
|
||||
except (frappe.DuplicateEntryError, ConflictingTaxRule):
|
||||
pass
|
||||
|
||||
@ -254,10 +261,9 @@ class TestShoppingCart(unittest.TestCase):
|
||||
self.create_user_if_not_exists("test_cart_user@example.com")
|
||||
frappe.set_user("test_cart_user@example.com")
|
||||
|
||||
def login_as_customer(self):
|
||||
self.create_user_if_not_exists("test_contact_customer@example.com",
|
||||
"_Test Contact For _Test Customer")
|
||||
frappe.set_user("test_contact_customer@example.com")
|
||||
def login_as_customer(self, email="test_contact_customer@example.com", name="_Test Contact For _Test Customer"):
|
||||
self.create_user_if_not_exists(email, name)
|
||||
frappe.set_user(email)
|
||||
|
||||
def clear_existing_quotations(self):
|
||||
quotations = frappe.get_all("Quotation", filters={
|
||||
|
@ -1,4 +1,5 @@
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.controllers.item_variant import create_variant
|
||||
from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import (
|
||||
@ -7,11 +8,10 @@ from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings imp
|
||||
from erpnext.e_commerce.doctype.website_item.website_item import make_website_item
|
||||
from erpnext.e_commerce.variant_selector.utils import get_next_attribute_and_values
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ["Item"]
|
||||
|
||||
class TestVariantSelector(ERPNextTestCase):
|
||||
class TestVariantSelector(FrappeTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
@ -116,4 +116,4 @@ class TestVariantSelector(ERPNextTestCase):
|
||||
self.assertEqual(next_values["exact_match"][0],"Test-Tshirt-Temp-S-R")
|
||||
self.assertEqual(next_values["exact_match"][0],"Test-Tshirt-Temp-S-R")
|
||||
self.assertEqual(price_info["price_list_rate"], 100.0)
|
||||
self.assertEqual(price_info["formatted_price_sales_uom"], "₹ 100.00")
|
||||
self.assertEqual(price_info["formatted_price_sales_uom"], "₹ 100.00")
|
||||
|
@ -3,6 +3,10 @@
|
||||
frappe.provide("education");
|
||||
|
||||
frappe.ui.form.on('Student Attendance Tool', {
|
||||
setup: (frm) => {
|
||||
frm.students_area = $('<div>')
|
||||
.appendTo(frm.fields_dict.students_html.wrapper);
|
||||
},
|
||||
onload: function(frm) {
|
||||
frm.set_query("student_group", function() {
|
||||
return {
|
||||
@ -34,6 +38,7 @@ frappe.ui.form.on('Student Attendance Tool', {
|
||||
|
||||
student_group: function(frm) {
|
||||
if ((frm.doc.student_group && frm.doc.date) || frm.doc.course_schedule) {
|
||||
frm.students_area.find('.student-attendance-checks').html(`<div style='padding: 2rem 0'>Fetching...</div>`);
|
||||
var method = "erpnext.education.doctype.student_attendance_tool.student_attendance_tool.get_student_attendance_records";
|
||||
|
||||
frappe.call({
|
||||
@ -62,10 +67,6 @@ frappe.ui.form.on('Student Attendance Tool', {
|
||||
},
|
||||
|
||||
get_students: function(frm, students) {
|
||||
if (!frm.students_area) {
|
||||
frm.students_area = $('<div>')
|
||||
.appendTo(frm.fields_dict.students_html.wrapper);
|
||||
}
|
||||
students = students || [];
|
||||
frm.students_editor = new education.StudentsEditor(frm, frm.students_area, students);
|
||||
}
|
||||
@ -163,16 +164,26 @@ education.StudentsEditor = class StudentsEditor {
|
||||
);
|
||||
});
|
||||
|
||||
var htmls = students.map(function(student) {
|
||||
return frappe.render_template("student_button", {
|
||||
student: student.student,
|
||||
student_name: student.student_name,
|
||||
group_roll_number: student.group_roll_number,
|
||||
status: student.status
|
||||
})
|
||||
});
|
||||
// make html grid of students
|
||||
let student_html = '';
|
||||
for (let student of students) {
|
||||
student_html += `<div class="col-sm-3">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
data-group_roll_number="${student.group_roll_number}"
|
||||
data-student="${student.student}"
|
||||
data-student-name="${student.student_name}"
|
||||
class="students-check"
|
||||
${student.status==='Present' ? 'checked' : ''}>
|
||||
${student.group_roll_number} - ${student.student_name}
|
||||
</label>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
$(htmls.join("")).appendTo(me.wrapper);
|
||||
$(`<div class='student-attendance-checks'>${student_html}</div>`).appendTo(me.wrapper);
|
||||
}
|
||||
|
||||
show_empty_state() {
|
||||
|
@ -24,24 +24,24 @@ def get_student_attendance_records(based_on, date=None, student_group=None, cour
|
||||
student_list = frappe.get_all("Student Group Student", fields=["student", "student_name", "group_roll_number"],
|
||||
filters={"parent": student_group, "active": 1}, order_by= "group_roll_number")
|
||||
|
||||
table = frappe.qb.DocType("Student Attendance")
|
||||
StudentAttendance = frappe.qb.DocType("Student Attendance")
|
||||
|
||||
if course_schedule:
|
||||
student_attendance_list = (
|
||||
frappe.qb.from_(table)
|
||||
.select(table.student, table.status)
|
||||
frappe.qb.from_(StudentAttendance)
|
||||
.select(StudentAttendance.student, StudentAttendance.status)
|
||||
.where(
|
||||
(table.course_schedule == course_schedule)
|
||||
(StudentAttendance.course_schedule == course_schedule)
|
||||
)
|
||||
).run(as_dict=True)
|
||||
else:
|
||||
student_attendance_list = (
|
||||
frappe.qb.from_(table)
|
||||
.select(table.student, table.status)
|
||||
frappe.qb.from_(StudentAttendance)
|
||||
.select(StudentAttendance.student, StudentAttendance.status)
|
||||
.where(
|
||||
(table.student_group == student_group)
|
||||
& (table.date == date)
|
||||
& (table.course_schedule == "") | (table.course_schedule.isnull())
|
||||
(StudentAttendance.student_group == student_group)
|
||||
& (StudentAttendance.date == date)
|
||||
& ((StudentAttendance.course_schedule == "") | (StudentAttendance.course_schedule.isnull()))
|
||||
)
|
||||
).run(as_dict=True)
|
||||
|
||||
|
@ -82,7 +82,7 @@ class TallyMigration(Document):
|
||||
"is_private": True
|
||||
})
|
||||
try:
|
||||
f.insert()
|
||||
f.insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
setattr(self, key, f.file_url)
|
||||
|
@ -8,10 +8,6 @@ from frappe.utils import cint, flt
|
||||
|
||||
from erpnext import get_default_company, get_region
|
||||
|
||||
TAX_ACCOUNT_HEAD = frappe.db.get_single_value("TaxJar Settings", "tax_account_head")
|
||||
SHIP_ACCOUNT_HEAD = frappe.db.get_single_value("TaxJar Settings", "shipping_account_head")
|
||||
TAXJAR_CREATE_TRANSACTIONS = frappe.db.get_single_value("TaxJar Settings", "taxjar_create_transactions")
|
||||
TAXJAR_CALCULATE_TAX = frappe.db.get_single_value("TaxJar Settings", "taxjar_calculate_tax")
|
||||
SUPPORTED_COUNTRY_CODES = ["AT", "AU", "BE", "BG", "CA", "CY", "CZ", "DE", "DK", "EE", "ES", "FI",
|
||||
"FR", "GB", "GR", "HR", "HU", "IE", "IT", "LT", "LU", "LV", "MT", "NL", "PL", "PT", "RO",
|
||||
"SE", "SI", "SK", "US"]
|
||||
@ -35,12 +31,14 @@ def get_client():
|
||||
if api_key and api_url:
|
||||
client = taxjar.Client(api_key=api_key, api_url=api_url)
|
||||
client.set_api_config('headers', {
|
||||
'x-api-version': '2020-08-07'
|
||||
'x-api-version': '2022-01-24'
|
||||
})
|
||||
return client
|
||||
|
||||
|
||||
def create_transaction(doc, method):
|
||||
TAXJAR_CREATE_TRANSACTIONS = frappe.db.get_single_value("TaxJar Settings", "taxjar_create_transactions")
|
||||
|
||||
"""Create an order transaction in TaxJar"""
|
||||
|
||||
if not TAXJAR_CREATE_TRANSACTIONS:
|
||||
@ -51,6 +49,7 @@ def create_transaction(doc, method):
|
||||
if not client:
|
||||
return
|
||||
|
||||
TAX_ACCOUNT_HEAD = frappe.db.get_single_value("TaxJar Settings", "tax_account_head")
|
||||
sales_tax = sum([tax.tax_amount for tax in doc.taxes if tax.account_head == TAX_ACCOUNT_HEAD])
|
||||
|
||||
if not sales_tax:
|
||||
@ -79,6 +78,7 @@ def create_transaction(doc, method):
|
||||
|
||||
def delete_transaction(doc, method):
|
||||
"""Delete an existing TaxJar order transaction"""
|
||||
TAXJAR_CREATE_TRANSACTIONS = frappe.db.get_single_value("TaxJar Settings", "taxjar_create_transactions")
|
||||
|
||||
if not TAXJAR_CREATE_TRANSACTIONS:
|
||||
return
|
||||
@ -92,6 +92,8 @@ def delete_transaction(doc, method):
|
||||
|
||||
|
||||
def get_tax_data(doc):
|
||||
SHIP_ACCOUNT_HEAD = frappe.db.get_single_value("TaxJar Settings", "shipping_account_head")
|
||||
|
||||
from_address = get_company_address_details(doc)
|
||||
from_shipping_state = from_address.get("state")
|
||||
from_country_code = frappe.db.get_value("Country", from_address.country, "code")
|
||||
@ -113,20 +115,20 @@ def get_tax_data(doc):
|
||||
to_shipping_state = get_state_code(to_address, 'Shipping')
|
||||
|
||||
tax_dict = {
|
||||
'from_country': from_country_code,
|
||||
'from_zip': from_address.pincode,
|
||||
'from_state': from_shipping_state,
|
||||
'from_city': from_address.city,
|
||||
'from_street': from_address.address_line1,
|
||||
'to_country': to_country_code,
|
||||
'to_zip': to_address.pincode,
|
||||
'to_city': to_address.city,
|
||||
'to_street': to_address.address_line1,
|
||||
'to_state': to_shipping_state,
|
||||
'shipping': shipping,
|
||||
'amount': doc.net_total,
|
||||
'plugin': 'erpnext',
|
||||
'line_items': line_items
|
||||
"from_country": from_country_code,
|
||||
"from_zip": from_address.pincode,
|
||||
"from_state": from_shipping_state,
|
||||
"from_city": from_address.city,
|
||||
"from_street": from_address.address_line1,
|
||||
"to_country": to_country_code,
|
||||
"to_zip": to_address.pincode,
|
||||
"to_city": to_address.city,
|
||||
"to_street": to_address.address_line1,
|
||||
"to_state": to_shipping_state,
|
||||
"shipping": shipping,
|
||||
"amount": doc.net_total,
|
||||
"plugin": "erpnext",
|
||||
"line_items": line_items
|
||||
}
|
||||
return tax_dict
|
||||
|
||||
@ -156,6 +158,9 @@ def get_line_item_dict(item, docstatus):
|
||||
return tax_dict
|
||||
|
||||
def set_sales_tax(doc, method):
|
||||
TAX_ACCOUNT_HEAD = frappe.db.get_single_value("TaxJar Settings", "tax_account_head")
|
||||
TAXJAR_CALCULATE_TAX = frappe.db.get_single_value("TaxJar Settings", "taxjar_calculate_tax")
|
||||
|
||||
if not TAXJAR_CALCULATE_TAX:
|
||||
return
|
||||
|
||||
@ -206,6 +211,7 @@ def set_sales_tax(doc, method):
|
||||
doc.run_method("calculate_taxes_and_totals")
|
||||
|
||||
def check_for_nexus(doc, tax_dict):
|
||||
TAX_ACCOUNT_HEAD = frappe.db.get_single_value("TaxJar Settings", "tax_account_head")
|
||||
if not frappe.db.get_value('TaxJar Nexus', {'region_code': tax_dict["to_state"]}):
|
||||
for item in doc.get("items"):
|
||||
item.tax_collectable = flt(0)
|
||||
@ -218,6 +224,8 @@ def check_for_nexus(doc, tax_dict):
|
||||
|
||||
def check_sales_tax_exemption(doc):
|
||||
# if the party is exempt from sales tax, then set all tax account heads to zero
|
||||
TAX_ACCOUNT_HEAD = frappe.db.get_single_value("TaxJar Settings", "tax_account_head")
|
||||
|
||||
sales_tax_exempted = hasattr(doc, "exempt_from_sales_tax") and doc.exempt_from_sales_tax \
|
||||
or frappe.db.has_column("Customer", "exempt_from_sales_tax") \
|
||||
and frappe.db.get_value("Customer", doc.customer, "exempt_from_sales_tax")
|
||||
|
@ -68,7 +68,6 @@ domains = {
|
||||
'Distribution': 'erpnext.domains.distribution',
|
||||
'Education': 'erpnext.domains.education',
|
||||
'Manufacturing': 'erpnext.domains.manufacturing',
|
||||
'Non Profit': 'erpnext.domains.non_profit',
|
||||
'Retail': 'erpnext.domains.retail',
|
||||
'Services': 'erpnext.domains.services',
|
||||
}
|
||||
@ -175,7 +174,6 @@ standard_portal_menu_items = [
|
||||
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"},
|
||||
{"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"},
|
||||
{"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission", "role": "Student"},
|
||||
{"title": _("Certification"), "route": "/certification", "reference_doctype": "Certification Application", "role": "Non Profit Portal User"},
|
||||
{"title": _("Material Request"), "route": "/material-requests", "reference_doctype": "Material Request", "role": "Customer"},
|
||||
{"title": _("Appointment Booking"), "route": "/book_appointment"},
|
||||
]
|
||||
@ -369,7 +367,6 @@ scheduler_events = {
|
||||
"erpnext.selling.doctype.quotation.quotation.set_expired_status",
|
||||
"erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status",
|
||||
"erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email",
|
||||
"erpnext.non_profit.doctype.membership.membership.set_expired_status",
|
||||
"erpnext.hr.doctype.interview.interview.send_daily_feedback_reminder"
|
||||
],
|
||||
"daily_long": [
|
||||
@ -563,19 +560,6 @@ global_search_doctypes = {
|
||||
{'doctype': 'Assessment Code', 'index': 39},
|
||||
{'doctype': 'Discussion', 'index': 40},
|
||||
],
|
||||
"Non Profit": [
|
||||
{'doctype': 'Certified Consultant', 'index': 1},
|
||||
{'doctype': 'Certification Application', 'index': 2},
|
||||
{'doctype': 'Volunteer', 'index': 3},
|
||||
{'doctype': 'Membership', 'index': 4},
|
||||
{'doctype': 'Member', 'index': 5},
|
||||
{'doctype': 'Donor', 'index': 6},
|
||||
{'doctype': 'Chapter', 'index': 7},
|
||||
{'doctype': 'Grant Application', 'index': 8},
|
||||
{'doctype': 'Volunteer Type', 'index': 9},
|
||||
{'doctype': 'Donor Type', 'index': 10},
|
||||
{'doctype': 'Membership Type', 'index': 11}
|
||||
],
|
||||
}
|
||||
|
||||
additional_timeline_content = {
|
||||
|
@ -32,7 +32,7 @@ class Department(NestedSet):
|
||||
return new
|
||||
|
||||
def on_update(self):
|
||||
if not frappe.local.flags.ignore_update_nsm:
|
||||
if not (frappe.local.flags.ignore_update_nsm or frappe.flags.in_setup_wizard):
|
||||
super(Department, self).on_update()
|
||||
|
||||
def on_trash(self):
|
||||
|
@ -1,4 +1,4 @@
|
||||
[
|
||||
{"doctype":"Department", "department_name":"_Test Department", "company": "_Test Company"},
|
||||
{"doctype":"Department", "department_name":"_Test Department 1", "company": "_Test Company"}
|
||||
{"doctype":"Department", "department_name":"_Test Department", "company": "_Test Company", "parent_department": "All Departments"},
|
||||
{"doctype":"Department", "department_name":"_Test Department 1", "company": "_Test Company", "parent_department": "All Departments"}
|
||||
]
|
@ -142,7 +142,7 @@ class Employee(NestedSet):
|
||||
"file_url": self.image,
|
||||
"attached_to_doctype": "User",
|
||||
"attached_to_name": self.user_id
|
||||
}).insert()
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
# already exists
|
||||
pass
|
||||
|
@ -4,7 +4,7 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.utils import getdate
|
||||
from frappe.utils import add_days, getdate
|
||||
|
||||
from erpnext.hr.doctype.employee_onboarding.employee_onboarding import (
|
||||
IncompleteTaskError,
|
||||
@ -35,6 +35,15 @@ class TestEmployeeOnboarding(unittest.TestCase):
|
||||
# boarding status
|
||||
self.assertEqual(onboarding.boarding_status, 'Pending')
|
||||
|
||||
# start and end dates
|
||||
start_date, end_date = frappe.db.get_value('Task', onboarding.activities[0].task, ['exp_start_date', 'exp_end_date'])
|
||||
self.assertEqual(getdate(start_date), getdate(onboarding.boarding_begins_on))
|
||||
self.assertEqual(getdate(end_date), add_days(start_date, onboarding.activities[0].duration))
|
||||
|
||||
start_date, end_date = frappe.db.get_value('Task', onboarding.activities[1].task, ['exp_start_date', 'exp_end_date'])
|
||||
self.assertEqual(getdate(start_date), add_days(onboarding.boarding_begins_on, onboarding.activities[0].duration))
|
||||
self.assertEqual(getdate(end_date), add_days(start_date, onboarding.activities[1].duration))
|
||||
|
||||
# complete the task
|
||||
project = frappe.get_doc('Project', onboarding.project)
|
||||
for task in frappe.get_all('Task', dict(project=project.name)):
|
||||
@ -57,10 +66,7 @@ class TestEmployeeOnboarding(unittest.TestCase):
|
||||
self.assertEqual(employee.employee_name, 'Test Researcher')
|
||||
|
||||
def tearDown(self):
|
||||
for entry in frappe.get_all('Employee Onboarding'):
|
||||
doc = frappe.get_doc('Employee Onboarding', entry.name)
|
||||
doc.cancel()
|
||||
doc.delete()
|
||||
frappe.db.rollback()
|
||||
|
||||
|
||||
def get_job_applicant():
|
||||
@ -87,23 +93,31 @@ def get_job_offer(applicant_name):
|
||||
def create_employee_onboarding():
|
||||
applicant = get_job_applicant()
|
||||
job_offer = get_job_offer(applicant.name)
|
||||
holiday_list = make_holiday_list()
|
||||
|
||||
holiday_list = make_holiday_list('_Test Employee Boarding')
|
||||
holiday_list = frappe.get_doc('Holiday List', holiday_list)
|
||||
holiday_list.holidays = []
|
||||
holiday_list.save()
|
||||
|
||||
onboarding = frappe.new_doc('Employee Onboarding')
|
||||
onboarding.job_applicant = applicant.name
|
||||
onboarding.job_offer = job_offer.name
|
||||
onboarding.date_of_joining = onboarding.boarding_begins_on = getdate()
|
||||
onboarding.company = '_Test Company'
|
||||
onboarding.holiday_list = holiday_list
|
||||
onboarding.holiday_list = holiday_list.name
|
||||
onboarding.designation = 'Researcher'
|
||||
onboarding.append('activities', {
|
||||
'activity_name': 'Assign ID Card',
|
||||
'role': 'HR User',
|
||||
'required_for_employee_creation': 1
|
||||
'required_for_employee_creation': 1,
|
||||
'begin_on': 0,
|
||||
'duration': 1
|
||||
})
|
||||
onboarding.append('activities', {
|
||||
'activity_name': 'Assign a laptop',
|
||||
'role': 'HR User'
|
||||
'role': 'HR User',
|
||||
'begin_on': 1,
|
||||
'duration': 1
|
||||
})
|
||||
onboarding.status = 'Pending'
|
||||
onboarding.insert()
|
||||
|
@ -128,4 +128,4 @@ def show_email_summary(email_success, email_failure):
|
||||
message += _('{0} due to missing email information for employee(s): {1}').format(
|
||||
frappe.bold('Sending Failed'), ', '.join(email_failure))
|
||||
|
||||
frappe.msgprint(message, title=_('Exit Questionnaire'), indicator='blue', is_minimizable=True, wide=True)
|
||||
frappe.msgprint(message, title=_('Exit Questionnaire'), indicator='blue', is_minimizable=True, wide=True)
|
||||
|
@ -82,7 +82,7 @@ def get_vehicle(employee_id):
|
||||
"vehicle_value": flt(500000)
|
||||
})
|
||||
try:
|
||||
vehicle.insert()
|
||||
vehicle.insert(ignore_if_duplicate=True)
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
return license_plate
|
||||
|
@ -14,11 +14,15 @@
|
||||
"applicant",
|
||||
"section_break_7",
|
||||
"disbursement_date",
|
||||
"clearance_date",
|
||||
"column_break_8",
|
||||
"disbursed_amount",
|
||||
"accounting_dimensions_section",
|
||||
"cost_center",
|
||||
"customer_details_section",
|
||||
"accounting_details",
|
||||
"disbursement_account",
|
||||
"column_break_16",
|
||||
"loan_account",
|
||||
"bank_account",
|
||||
"disbursement_references_section",
|
||||
"reference_date",
|
||||
@ -106,11 +110,6 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Disbursement Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "customer_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Customer Details"
|
||||
},
|
||||
{
|
||||
"fetch_from": "against_loan.applicant_type",
|
||||
"fieldname": "applicant_type",
|
||||
@ -149,15 +148,48 @@
|
||||
"fieldname": "reference_number",
|
||||
"fieldtype": "Data",
|
||||
"label": "Reference Number"
|
||||
},
|
||||
{
|
||||
"fieldname": "clearance_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Clearance Date",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "accounting_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Accounting Details"
|
||||
},
|
||||
{
|
||||
"fetch_from": "against_loan.disbursement_account",
|
||||
"fieldname": "disbursement_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Disbursement Account",
|
||||
"options": "Account",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_16",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fetch_from": "against_loan.loan_account",
|
||||
"fieldname": "loan_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Loan Account",
|
||||
"options": "Account",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-04-19 18:09:32.175355",
|
||||
"modified": "2022-02-17 18:23:44.157598",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan Disbursement",
|
||||
"naming_rule": "Expression (old style)",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
@ -194,5 +226,6 @@
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
@ -42,9 +42,6 @@ class LoanDisbursement(AccountsController):
|
||||
if not self.posting_date:
|
||||
self.posting_date = self.disbursement_date or nowdate()
|
||||
|
||||
if not self.bank_account and self.applicant_type == "Customer":
|
||||
self.bank_account = frappe.db.get_value("Customer", self.applicant, "default_bank_account")
|
||||
|
||||
def validate_disbursal_amount(self):
|
||||
possible_disbursal_amount = get_disbursal_amount(self.against_loan)
|
||||
|
||||
@ -117,12 +114,11 @@ class LoanDisbursement(AccountsController):
|
||||
|
||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||
gle_map = []
|
||||
loan_details = frappe.get_doc("Loan", self.against_loan)
|
||||
|
||||
gle_map.append(
|
||||
self.get_gl_dict({
|
||||
"account": loan_details.loan_account,
|
||||
"against": loan_details.disbursement_account,
|
||||
"account": self.loan_account,
|
||||
"against": self.disbursement_account,
|
||||
"debit": self.disbursed_amount,
|
||||
"debit_in_account_currency": self.disbursed_amount,
|
||||
"against_voucher_type": "Loan",
|
||||
@ -137,8 +133,8 @@ class LoanDisbursement(AccountsController):
|
||||
|
||||
gle_map.append(
|
||||
self.get_gl_dict({
|
||||
"account": loan_details.disbursement_account,
|
||||
"against": loan_details.loan_account,
|
||||
"account": self.disbursement_account,
|
||||
"against": self.loan_account,
|
||||
"credit": self.disbursed_amount,
|
||||
"credit_in_account_currency": self.disbursed_amount,
|
||||
"against_voucher_type": "Loan",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "LM-REP-.####",
|
||||
"creation": "2019-09-03 14:44:39.977266",
|
||||
"creation": "2022-01-25 10:30:02.767941",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
@ -13,6 +13,7 @@
|
||||
"column_break_3",
|
||||
"company",
|
||||
"posting_date",
|
||||
"clearance_date",
|
||||
"rate_of_interest",
|
||||
"payroll_payable_account",
|
||||
"is_term_loan",
|
||||
@ -37,7 +38,12 @@
|
||||
"total_penalty_paid",
|
||||
"total_interest_paid",
|
||||
"repayment_details",
|
||||
"amended_from"
|
||||
"amended_from",
|
||||
"accounting_details_section",
|
||||
"payment_account",
|
||||
"penalty_income_account",
|
||||
"column_break_36",
|
||||
"loan_account"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -260,12 +266,52 @@
|
||||
"fieldname": "repay_from_salary",
|
||||
"fieldtype": "Check",
|
||||
"label": "Repay From Salary"
|
||||
},
|
||||
{
|
||||
"fieldname": "clearance_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Clearance Date",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "accounting_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Accounting Details"
|
||||
},
|
||||
{
|
||||
"fetch_from": "against_loan.payment_account",
|
||||
"fieldname": "payment_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Repayment Account",
|
||||
"options": "Account",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_36",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fetch_from": "against_loan.loan_account",
|
||||
"fieldname": "loan_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Loan Account",
|
||||
"options": "Account",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "against_loan.penalty_income_account",
|
||||
"fieldname": "penalty_income_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Penalty Income Account",
|
||||
"options": "Account"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-01-06 01:51:06.707782",
|
||||
"modified": "2022-02-18 19:10:07.742298",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan Repayment",
|
||||
|
@ -310,7 +310,6 @@ class LoanRepayment(AccountsController):
|
||||
|
||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||
gle_map = []
|
||||
loan_details = frappe.get_doc("Loan", self.against_loan)
|
||||
|
||||
if self.shortfall_amount and self.amount_paid > self.shortfall_amount:
|
||||
remarks = _("Shortfall Repayment of {0}.\nRepayment against Loan: {1}").format(self.shortfall_amount,
|
||||
@ -323,13 +322,13 @@ class LoanRepayment(AccountsController):
|
||||
if self.repay_from_salary:
|
||||
payment_account = self.payroll_payable_account
|
||||
else:
|
||||
payment_account = loan_details.payment_account
|
||||
payment_account = self.payment_account
|
||||
|
||||
if self.total_penalty_paid:
|
||||
gle_map.append(
|
||||
self.get_gl_dict({
|
||||
"account": loan_details.loan_account,
|
||||
"against": loan_details.payment_account,
|
||||
"account": self.loan_account,
|
||||
"against": payment_account,
|
||||
"debit": self.total_penalty_paid,
|
||||
"debit_in_account_currency": self.total_penalty_paid,
|
||||
"against_voucher_type": "Loan",
|
||||
@ -344,8 +343,8 @@ class LoanRepayment(AccountsController):
|
||||
|
||||
gle_map.append(
|
||||
self.get_gl_dict({
|
||||
"account": loan_details.penalty_income_account,
|
||||
"against": loan_details.loan_account,
|
||||
"account": self.penalty_income_account,
|
||||
"against": self.loan_account,
|
||||
"credit": self.total_penalty_paid,
|
||||
"credit_in_account_currency": self.total_penalty_paid,
|
||||
"against_voucher_type": "Loan",
|
||||
@ -359,8 +358,7 @@ class LoanRepayment(AccountsController):
|
||||
gle_map.append(
|
||||
self.get_gl_dict({
|
||||
"account": payment_account,
|
||||
"against": loan_details.loan_account + ", " + loan_details.interest_income_account
|
||||
+ ", " + loan_details.penalty_income_account,
|
||||
"against": self.loan_account + ", " + self.penalty_income_account,
|
||||
"debit": self.amount_paid,
|
||||
"debit_in_account_currency": self.amount_paid,
|
||||
"against_voucher_type": "Loan",
|
||||
@ -368,16 +366,16 @@ class LoanRepayment(AccountsController):
|
||||
"remarks": remarks,
|
||||
"cost_center": self.cost_center,
|
||||
"posting_date": getdate(self.posting_date),
|
||||
"party_type": loan_details.applicant_type if self.repay_from_salary else '',
|
||||
"party": loan_details.applicant if self.repay_from_salary else ''
|
||||
"party_type": self.applicant_type if self.repay_from_salary else '',
|
||||
"party": self.applicant if self.repay_from_salary else ''
|
||||
})
|
||||
)
|
||||
|
||||
gle_map.append(
|
||||
self.get_gl_dict({
|
||||
"account": loan_details.loan_account,
|
||||
"party_type": loan_details.applicant_type,
|
||||
"party": loan_details.applicant,
|
||||
"account": self.loan_account,
|
||||
"party_type": self.applicant_type,
|
||||
"party": self.applicant,
|
||||
"against": payment_account,
|
||||
"credit": self.amount_paid,
|
||||
"credit_in_account_currency": self.amount_paid,
|
||||
|
@ -1,15 +1,15 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_months, today
|
||||
|
||||
from erpnext import get_company_currency
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
from .blanket_order import make_order
|
||||
|
||||
|
||||
class TestBlanketOrder(ERPNextTestCase):
|
||||
class TestBlanketOrder(FrappeTestCase):
|
||||
def setUp(self):
|
||||
frappe.flags.args = frappe._dict()
|
||||
|
||||
|
@ -7,6 +7,7 @@ from functools import partial
|
||||
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import cstr, flt
|
||||
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
@ -17,11 +18,10 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import
|
||||
create_stock_reconciliation,
|
||||
)
|
||||
from erpnext.tests.test_subcontracting import set_backflush_based_on
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_records = frappe.get_test_records('BOM')
|
||||
|
||||
class TestBOM(ERPNextTestCase):
|
||||
class TestBOM(FrappeTestCase):
|
||||
def setUp(self):
|
||||
if not frappe.get_value('Item', '_Test Item'):
|
||||
make_test_records('Item')
|
||||
|
@ -2,15 +2,15 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool import update_cost
|
||||
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_records = frappe.get_test_records('BOM')
|
||||
|
||||
class TestBOMUpdateTool(ERPNextTestCase):
|
||||
class TestBOMUpdateTool(FrappeTestCase):
|
||||
def test_replace_bom(self):
|
||||
current_bom = "BOM-_Test Item Home Desktop Manufactured-001"
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
# See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import random_string
|
||||
|
||||
from erpnext.manufacturing.doctype.job_card.job_card import OperationMismatchError, OverlapError
|
||||
@ -11,10 +12,9 @@ from erpnext.manufacturing.doctype.job_card.job_card import (
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestJobCard(ERPNextTestCase):
|
||||
class TestJobCard(FrappeTestCase):
|
||||
def setUp(self):
|
||||
make_bom_for_jc_tests()
|
||||
|
||||
|
@ -49,7 +49,7 @@ frappe.ui.form.on('Production Plan', {
|
||||
if (d.item_code) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.bom",
|
||||
filters:{'item': cstr(d.item_code)}
|
||||
filters:{'item': cstr(d.item_code), 'docstatus': 1}
|
||||
}
|
||||
} else frappe.msgprint(__("Please enter Item first"));
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import add_to_date, flt, now_datetime, nowdate
|
||||
|
||||
from erpnext.controllers.item_variant import create_variant
|
||||
@ -9,16 +10,16 @@ from erpnext.manufacturing.doctype.production_plan.production_plan import (
|
||||
get_sales_orders,
|
||||
get_warehouse_list,
|
||||
)
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import OverProductionError
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
|
||||
create_stock_reconciliation,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestProductionPlan(ERPNextTestCase):
|
||||
class TestProductionPlan(FrappeTestCase):
|
||||
def setUp(self):
|
||||
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
||||
'Raw Material Item 1', 'Raw Material Item 2']:
|
||||
@ -466,26 +467,29 @@ class TestProductionPlan(ERPNextTestCase):
|
||||
bom = make_bom(item=item, raw_materials=raw_materials)
|
||||
|
||||
# Create Production Plan
|
||||
pln = create_production_plan(item_code=bom.item, planned_qty=10)
|
||||
pln = create_production_plan(item_code=bom.item, planned_qty=5)
|
||||
|
||||
# All the created Work Orders
|
||||
wo_list = []
|
||||
|
||||
# Create and Submit 1st Work Order for 5 qty
|
||||
create_work_order(item, pln, 5)
|
||||
# Create and Submit 1st Work Order for 3 qty
|
||||
create_work_order(item, pln, 3)
|
||||
pln.reload()
|
||||
self.assertEqual(pln.po_items[0].ordered_qty, 3)
|
||||
|
||||
# Create and Submit 2nd Work Order for 2 qty
|
||||
create_work_order(item, pln, 2)
|
||||
pln.reload()
|
||||
self.assertEqual(pln.po_items[0].ordered_qty, 5)
|
||||
|
||||
# Create and Submit 2nd Work Order for 3 qty
|
||||
create_work_order(item, pln, 3)
|
||||
pln.reload()
|
||||
self.assertEqual(pln.po_items[0].ordered_qty, 8)
|
||||
# Overproduction
|
||||
self.assertRaises(OverProductionError, create_work_order, item=item, pln=pln, qty=2)
|
||||
|
||||
# Cancel 1st Work Order
|
||||
wo1 = frappe.get_doc("Work Order", wo_list[0])
|
||||
wo1.cancel()
|
||||
pln.reload()
|
||||
self.assertEqual(pln.po_items[0].ordered_qty, 3)
|
||||
self.assertEqual(pln.po_items[0].ordered_qty, 2)
|
||||
|
||||
# Cancel 2nd Work Order
|
||||
wo2 = frappe.get_doc("Work Order", wo_list[1])
|
||||
|
@ -2,14 +2,14 @@
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.manufacturing.doctype.job_card.job_card import OperationSequenceError
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
|
||||
class TestRouting(ERPNextTestCase):
|
||||
class TestRouting(FrappeTestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.item_code = "Test Routing Item - A"
|
||||
|
@ -2,6 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase, timeout
|
||||
from frappe.utils import add_days, add_months, cint, flt, now, today
|
||||
|
||||
from erpnext.manufacturing.doctype.job_card.job_card import JobCardCancelError
|
||||
@ -21,10 +22,9 @@ from erpnext.stock.doctype.item.test_item import create_item, make_item
|
||||
from erpnext.stock.doctype.stock_entry import test_stock_entry
|
||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||
from erpnext.stock.utils import get_bin
|
||||
from erpnext.tests.utils import ERPNextTestCase, timeout
|
||||
|
||||
|
||||
class TestWorkOrder(ERPNextTestCase):
|
||||
class TestWorkOrder(FrappeTestCase):
|
||||
def setUp(self):
|
||||
self.warehouse = '_Test Warehouse 2 - _TC'
|
||||
self.item = '_Test Item'
|
||||
|
@ -636,6 +636,21 @@ class WorkOrder(Document):
|
||||
if not self.qty > 0:
|
||||
frappe.throw(_("Quantity to Manufacture must be greater than 0."))
|
||||
|
||||
if self.production_plan and self.production_plan_item:
|
||||
qty_dict = frappe.db.get_value("Production Plan Item", self.production_plan_item, ["planned_qty", "ordered_qty"], as_dict=1)
|
||||
|
||||
allowance_qty =flt(frappe.db.get_single_value("Manufacturing Settings",
|
||||
"overproduction_percentage_for_work_order"))/100 * qty_dict.get("planned_qty", 0)
|
||||
|
||||
max_qty = qty_dict.get("planned_qty", 0) + allowance_qty - qty_dict.get("ordered_qty", 0)
|
||||
|
||||
if max_qty < 1:
|
||||
frappe.throw(_("Cannot produce more item for {0}")
|
||||
.format(self.production_item), OverProductionError)
|
||||
elif self.qty > max_qty:
|
||||
frappe.throw(_("Cannot produce more than {0} items for {1}")
|
||||
.format(max_qty, self.production_item), OverProductionError)
|
||||
|
||||
def validate_transfer_against(self):
|
||||
if not self.docstatus == 1:
|
||||
# let user configure operations until they're ready to submit
|
||||
@ -839,7 +854,7 @@ def get_item_details(item, project = None, skip_bom_info=False):
|
||||
res = res[0]
|
||||
if skip_bom_info: return res
|
||||
|
||||
filters = {"item": item, "is_default": 1}
|
||||
filters = {"item": item, "is_default": 1, "docstatus": 1}
|
||||
|
||||
if project:
|
||||
filters = {"item": item, "project": project}
|
||||
|
@ -2,6 +2,7 @@
|
||||
# See license.txt
|
||||
import frappe
|
||||
from frappe.test_runner import make_test_records
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
from erpnext.manufacturing.doctype.operation.test_operation import make_operation
|
||||
from erpnext.manufacturing.doctype.routing.test_routing import create_routing, setup_bom
|
||||
@ -10,13 +11,12 @@ from erpnext.manufacturing.doctype.workstation.workstation import (
|
||||
WorkstationHolidayError,
|
||||
check_if_within_operating_hours,
|
||||
)
|
||||
from erpnext.tests.utils import ERPNextTestCase
|
||||
|
||||
test_dependencies = ["Warehouse"]
|
||||
test_records = frappe.get_test_records('Workstation')
|
||||
make_test_records('Workstation')
|
||||
|
||||
class TestWorkstation(ERPNextTestCase):
|
||||
class TestWorkstation(FrappeTestCase):
|
||||
def test_validate_timings(self):
|
||||
check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 11:00:00", "2013-02-02 19:00:00")
|
||||
check_if_within_operating_hours("_Test Workstation 1", "Operation 1", "2013-02-02 10:00:00", "2013-02-02 20:00:00")
|
||||
|
@ -55,10 +55,11 @@ class TestManufacturingReports(unittest.TestCase):
|
||||
def test_execute_all_manufacturing_reports(self):
|
||||
"""Test that all script report in manufacturing modules are executable with supported filters"""
|
||||
for report, filter in REPORT_FILTER_TEST_CASES:
|
||||
execute_script_report(
|
||||
report_name=report,
|
||||
module="Manufacturing",
|
||||
filters=filter,
|
||||
default_filters=DEFAULT_FILTERS,
|
||||
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
|
||||
)
|
||||
with self.subTest(report=report):
|
||||
execute_script_report(
|
||||
report_name=report,
|
||||
module="Manufacturing",
|
||||
filters=filter,
|
||||
default_filters=DEFAULT_FILTERS,
|
||||
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
|
||||
)
|
||||
|
@ -15,7 +15,6 @@ Maintenance
|
||||
Education
|
||||
Regional
|
||||
ERPNext Integrations
|
||||
Non Profit
|
||||
Quality Management
|
||||
Communication
|
||||
Loan Management
|
||||
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Certification Application', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
@ -1,323 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "NPO-CAPP-.YYYY.-.#####",
|
||||
"beta": 0,
|
||||
"creation": "2018-06-08 16:12:42.091729",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "name_of_applicant",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Name of Applicant",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "email",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Email",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "certification_status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Certification Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Yet to appear\nCertified\nNot Certified",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "payment_details",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Payment Details",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "paid",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Paid",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Currency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "USD\nINR",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-11-04 03:36:35.337403",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Non Profit",
|
||||
"name": "Certification Application",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Non Profit",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class CertificationApplication(Document):
|
||||
pass
|
@ -1,8 +0,0 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestCertificationApplication(unittest.TestCase):
|
||||
pass
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Certified Consultant', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
@ -1,724 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "NPO-CONS-.YYYY.-.#####",
|
||||
"beta": 0,
|
||||
"creation": "2018-06-13 17:27:19.838334",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "name_of_consultant",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Name of Consultant",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "country",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Country",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Country",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "email",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Email",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "phone",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Phone",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "website_url",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Website",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "address",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Address",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Image",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "certification_application",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Certification Application",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Certification Application",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break1",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Certification Validity",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "From",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_beak2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "To",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break2",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "introduction",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Introduction",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "details",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Details",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break3",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "discuss_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Discuss ID",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "github_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "GitHub ID",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "show_in_website",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Show in Website",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-11-04 03:36:47.386618",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Non Profit",
|
||||
"name": "Certified Consultant",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Non Profit Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Non Profit",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class CertifiedConsultant(Document):
|
||||
pass
|
@ -1,8 +0,0 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestCertifiedConsultant(unittest.TestCase):
|
||||
pass
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Chapter', {
|
||||
refresh: function() {
|
||||
|
||||
}
|
||||
});
|
@ -1,397 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 1,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 1,
|
||||
"autoname": "prompt",
|
||||
"beta": 0,
|
||||
"creation": "2017-09-14 13:36:03.904702",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "chapter_head",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Chapter Head",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Member",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "region",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Region",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "introduction",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Introduction",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "meetup_embed_html",
|
||||
"fieldtype": "Code",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Meetup Embed HTML",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "address",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Address",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "chapters/chapter_name\nleave blank automatically set after saving chapter.",
|
||||
"fieldname": "route",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Route",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "published",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Published",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "chapter_members",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Chapter Members",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "members",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Members",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Chapter Member",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 1,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_published_field": "published",
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-14 12:59:31.424240",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Non Profit",
|
||||
"name": "Chapter",
|
||||
"name_case": "Title Case",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Non Profit Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Non Profit",
|
||||
"route": "chapters",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe.website.website_generator import WebsiteGenerator
|
||||
|
||||
|
||||
class Chapter(WebsiteGenerator):
|
||||
_website = frappe._dict(
|
||||
condition_field = "published",
|
||||
)
|
||||
|
||||
def get_context(self, context):
|
||||
context.no_cache = True
|
||||
context.show_sidebar = True
|
||||
context.parents = [dict(label='View All Chapters',
|
||||
route='chapters', title='View Chapters')]
|
||||
|
||||
def validate(self):
|
||||
if not self.route: #pylint: disable=E0203
|
||||
self.route = 'chapters/' + self.scrub(self.name)
|
||||
|
||||
def enable(self):
|
||||
chapter = frappe.get_doc('Chapter', frappe.form_dict.name)
|
||||
chapter.append('members', dict(enable=self.value))
|
||||
chapter.save(ignore_permissions=1)
|
||||
frappe.db.commit()
|
||||
|
||||
|
||||
def get_list_context(context):
|
||||
context.allow_guest = True
|
||||
context.no_cache = True
|
||||
context.show_sidebar = True
|
||||
context.title = 'All Chapters'
|
||||
context.no_breadcrumbs = True
|
||||
context.order_by = 'creation desc'
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def leave(title, user_id, leave_reason):
|
||||
chapter = frappe.get_doc("Chapter", title)
|
||||
for member in chapter.members:
|
||||
if member.user == user_id:
|
||||
member.enabled = 0
|
||||
member.leave_reason = leave_reason
|
||||
chapter.save(ignore_permissions=1)
|
||||
frappe.db.commit()
|
||||
return "Thank you for Feedback"
|
@ -1,79 +0,0 @@
|
||||
{% extends "templates/web.html" %}
|
||||
|
||||
{% block page_content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<p>{{ introduction }}</p>
|
||||
{% if meetup_embed_html %}
|
||||
{{ meetup_embed_html }}
|
||||
{% endif %}
|
||||
<h3>Member Details</h3>
|
||||
|
||||
{% if members %}
|
||||
<table class="table" style="max-width: 600px;">
|
||||
{% set index = [1] %}
|
||||
{% for user in members %}
|
||||
{% if user.enabled == 1 %}
|
||||
<tr>
|
||||
<td>
|
||||
<div style="margin-bottom: 30px; max-width: 600px" class="with-border">
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-6">
|
||||
<div class="pull-left">
|
||||
<b>{{ index|length }}. {{ frappe.db.get_value('User', user.user, 'full_name') }}</b></div>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
{% if user.website_url %}
|
||||
<a href="{{ user.website_url }}">{{ user.website_url | truncate (50) or '' }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<br><br>
|
||||
<div class="col-lg-12">
|
||||
{% if user.introduction %}
|
||||
{{ user.introduction }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% set __ = index.append(1) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p>No member yet.</p>
|
||||
{% endif %}
|
||||
|
||||
<h3>Chapter Head</h3>
|
||||
<div style="margin-bottom: 30px; max-width: 600px" class="with-border">
|
||||
|
||||
<table class="table table-bordered small" style="max-width: 600px;">
|
||||
{% set doc = frappe.get_doc('Member',chapter_head) %}
|
||||
<tr>
|
||||
<td style='width: 15%'>Name</td>
|
||||
<td><b>{{ doc.member_name }}<b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Email</td>
|
||||
<td>{{ frappe.db.get_value('User', doc.email, 'email') or '' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Phone</td>
|
||||
<td>{{ frappe.db.get_value('User', doc.email, 'phone') or '' }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if address %}
|
||||
<h3>Address</h3>
|
||||
<div style="margin-bottom: 30px; max-width: 600px" class="with-border">
|
||||
<p>{{ address or ''}}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<p style="margin: 20px 0 30px;"><a href="/non_profit/join-chapter?name={{ name }}" class='btn btn-primary'>Join this Chapter</a></p>
|
||||
<p style="margin: 20px 0 30px;"><a href="/non_profit/leave-chapter?name={{ name }}" class=''>Leave this Chapter</a></p>
|
||||
|
||||
{% endblock %}
|
@ -1,25 +0,0 @@
|
||||
{% if doc.published %}
|
||||
<div style="margin-bottom: 30px; max-width: 600px" class="with-border clickable">
|
||||
<a href={{ doc.route }}>
|
||||
<h3>{{ doc.name }}</h3>
|
||||
<p>
|
||||
<span class="label"> Chapter Head : {{ frappe.db.get_value('User', chapter_head, 'full_name') }} </span>
|
||||
<span class="label">
|
||||
{% if members %}
|
||||
{% set index = [] %}
|
||||
{% for user in members %}
|
||||
{% if user.enabled == 1 %}
|
||||
{% set __ = index.append(1) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
Members: {{ index|length }}
|
||||
{% else %}
|
||||
Members: 0
|
||||
{% endif %}
|
||||
</span>
|
||||
<!-- Assignment of value to global variable not working in jinja -->
|
||||
</p>
|
||||
<p>{{ html2text(doc.introduction) | truncate (200) }}</p>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
@ -1,8 +0,0 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestChapter(unittest.TestCase):
|
||||
pass
|
@ -1,199 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-09-14 13:38:04.296375",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "User",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "introduction",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Introduction",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "website_url",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Website URL",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"default": "1",
|
||||
"fieldname": "enabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Enabled",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "leave_reason",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Leave Reason",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-03-07 05:36:51.664816",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Non Profit",
|
||||
"name": "Chapter Member",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Non Profit",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class ChapterMember(Document):
|
||||
pass
|
@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Donation', {
|
||||
refresh: function(frm) {
|
||||
if (frm.doc.docstatus === 1 && !frm.doc.paid) {
|
||||
frm.add_custom_button(__('Create Payment Entry'), function() {
|
||||
frm.events.make_payment_entry(frm);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
make_payment_entry: function(frm) {
|
||||
return frappe.call({
|
||||
method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry',
|
||||
args: {
|
||||
'dt': frm.doc.doctype,
|
||||
'dn': frm.doc.name
|
||||
},
|
||||
callback: function(r) {
|
||||
var doc = frappe.model.sync(r.message);
|
||||
frappe.set_route('Form', doc[0].doctype, doc[0].name);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
@ -1,156 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2021-02-17 10:28:52.645731",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"naming_series",
|
||||
"donor",
|
||||
"donor_name",
|
||||
"email",
|
||||
"column_break_4",
|
||||
"company",
|
||||
"date",
|
||||
"payment_details_section",
|
||||
"paid",
|
||||
"amount",
|
||||
"mode_of_payment",
|
||||
"razorpay_payment_id",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "donor",
|
||||
"fieldtype": "Link",
|
||||
"label": "Donor",
|
||||
"options": "Donor",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "donor.donor_name",
|
||||
"fieldname": "donor_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Donor Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "donor.email",
|
||||
"fieldname": "email",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Email",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Date",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "payment_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Payment Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Amount",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"label": "Mode of Payment",
|
||||
"options": "Mode of Payment"
|
||||
},
|
||||
{
|
||||
"fieldname": "razorpay_payment_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Razorpay Payment ID",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Naming Series",
|
||||
"options": "NPO-DTN-.YYYY.-"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "paid",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Paid"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Donation",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-11 10:53:11.269005",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Non Profit",
|
||||
"name": "Donation",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"select": 1,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Non Profit Manager",
|
||||
"select": 1,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"search_fields": "donor_name, email",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "donor_name",
|
||||
"track_changes": 1
|
||||
}
|
@ -1,220 +0,0 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.email import sendmail_to_system_managers
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import flt, get_link_to_form, getdate
|
||||
|
||||
from erpnext.non_profit.doctype.membership.membership import verify_signature
|
||||
|
||||
|
||||
class Donation(Document):
|
||||
def validate(self):
|
||||
if not self.donor or not frappe.db.exists('Donor', self.donor):
|
||||
# for web forms
|
||||
user_type = frappe.db.get_value('User', frappe.session.user, 'user_type')
|
||||
if user_type == 'Website User':
|
||||
self.create_donor_for_website_user()
|
||||
else:
|
||||
frappe.throw(_('Please select a Member'))
|
||||
|
||||
def create_donor_for_website_user(self):
|
||||
donor_name = frappe.get_value('Donor', dict(email=frappe.session.user))
|
||||
|
||||
if not donor_name:
|
||||
user = frappe.get_doc('User', frappe.session.user)
|
||||
donor = frappe.get_doc(dict(
|
||||
doctype='Donor',
|
||||
donor_type=self.get('donor_type'),
|
||||
email=frappe.session.user,
|
||||
member_name=user.get_fullname()
|
||||
)).insert(ignore_permissions=True)
|
||||
donor_name = donor.name
|
||||
|
||||
if self.get('__islocal'):
|
||||
self.donor = donor_name
|
||||
|
||||
def on_payment_authorized(self, *args, **kwargs):
|
||||
self.load_from_db()
|
||||
self.create_payment_entry()
|
||||
|
||||
def create_payment_entry(self, date=None):
|
||||
settings = frappe.get_doc('Non Profit Settings')
|
||||
if not settings.automate_donation_payment_entries:
|
||||
return
|
||||
|
||||
if not settings.donation_payment_account:
|
||||
frappe.throw(_('You need to set <b>Payment Account</b> for Donation in {0}').format(
|
||||
get_link_to_form('Non Profit Settings', 'Non Profit Settings')))
|
||||
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||
|
||||
frappe.flags.ignore_account_permission = True
|
||||
pe = get_payment_entry(dt=self.doctype, dn=self.name)
|
||||
frappe.flags.ignore_account_permission = False
|
||||
pe.paid_from = settings.donation_debit_account
|
||||
pe.paid_to = settings.donation_payment_account
|
||||
pe.posting_date = date or getdate()
|
||||
pe.reference_no = self.name
|
||||
pe.reference_date = date or getdate()
|
||||
pe.flags.ignore_mandatory = True
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def capture_razorpay_donations(*args, **kwargs):
|
||||
"""
|
||||
Creates Donation from Razorpay Webhook Request Data on payment.captured event
|
||||
Creates Donor from email if not found
|
||||
"""
|
||||
data = frappe.request.get_data(as_text=True)
|
||||
|
||||
try:
|
||||
verify_signature(data, endpoint='Donation')
|
||||
except Exception as e:
|
||||
log = frappe.log_error(e, 'Donation Webhook Verification Error')
|
||||
notify_failure(log)
|
||||
return { 'status': 'Failed', 'reason': e }
|
||||
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
data = frappe._dict(data)
|
||||
|
||||
payment = data.payload.get('payment', {}).get('entity', {})
|
||||
payment = frappe._dict(payment)
|
||||
|
||||
try:
|
||||
if not data.event == 'payment.captured':
|
||||
return
|
||||
|
||||
# to avoid capturing subscription payments as donations
|
||||
if payment.description and 'subscription' in str(payment.description).lower():
|
||||
return
|
||||
|
||||
donor = get_donor(payment.email)
|
||||
if not donor:
|
||||
donor = create_donor(payment)
|
||||
|
||||
donation = create_donation(donor, payment)
|
||||
donation.run_method('create_payment_entry')
|
||||
|
||||
except Exception as e:
|
||||
message = '{0}\n\n{1}\n\n{2}: {3}'.format(e, frappe.get_traceback(), _('Payment ID'), payment.id)
|
||||
log = frappe.log_error(message, _('Error creating donation entry for {0}').format(donor.name))
|
||||
notify_failure(log)
|
||||
return { 'status': 'Failed', 'reason': e }
|
||||
|
||||
return { 'status': 'Success' }
|
||||
|
||||
|
||||
def create_donation(donor, payment):
|
||||
if not frappe.db.exists('Mode of Payment', payment.method):
|
||||
create_mode_of_payment(payment.method)
|
||||
|
||||
company = get_company_for_donations()
|
||||
donation = frappe.get_doc({
|
||||
'doctype': 'Donation',
|
||||
'company': company,
|
||||
'donor': donor.name,
|
||||
'donor_name': donor.donor_name,
|
||||
'email': donor.email,
|
||||
'date': getdate(),
|
||||
'amount': flt(payment.amount) / 100, # Convert to rupees from paise
|
||||
'mode_of_payment': payment.method,
|
||||
'razorpay_payment_id': payment.id
|
||||
}).insert(ignore_mandatory=True)
|
||||
|
||||
donation.submit()
|
||||
return donation
|
||||
|
||||
|
||||
def get_donor(email):
|
||||
donors = frappe.get_all('Donor',
|
||||
filters={'email': email},
|
||||
order_by='creation desc')
|
||||
|
||||
try:
|
||||
return frappe.get_doc('Donor', donors[0]['name'])
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_donor(payment):
|
||||
donor_details = frappe._dict(payment)
|
||||
donor_type = frappe.db.get_single_value('Non Profit Settings', 'default_donor_type')
|
||||
|
||||
donor = frappe.new_doc('Donor')
|
||||
donor.update({
|
||||
'donor_name': donor_details.email,
|
||||
'donor_type': donor_type,
|
||||
'email': donor_details.email,
|
||||
'contact': donor_details.contact
|
||||
})
|
||||
|
||||
if donor_details.get('notes'):
|
||||
donor = get_additional_notes(donor, donor_details)
|
||||
|
||||
donor.insert(ignore_mandatory=True)
|
||||
return donor
|
||||
|
||||
|
||||
def get_company_for_donations():
|
||||
company = frappe.db.get_single_value('Non Profit Settings', 'donation_company')
|
||||
if not company:
|
||||
from erpnext.non_profit.utils import get_company
|
||||
company = get_company()
|
||||
return company
|
||||
|
||||
|
||||
def get_additional_notes(donor, donor_details):
|
||||
if type(donor_details.notes) == dict:
|
||||
for k, v in donor_details.notes.items():
|
||||
notes = '\n'.join('{}: {}'.format(k, v))
|
||||
|
||||
# extract donor name from notes
|
||||
if 'name' in k.lower():
|
||||
donor.update({
|
||||
'donor_name': donor_details.notes.get(k)
|
||||
})
|
||||
|
||||
# extract pan from notes
|
||||
if 'pan' in k.lower():
|
||||
donor.update({
|
||||
'pan_number': donor_details.notes.get(k)
|
||||
})
|
||||
|
||||
donor.add_comment('Comment', notes)
|
||||
|
||||
elif type(donor_details.notes) == str:
|
||||
donor.add_comment('Comment', donor_details.notes)
|
||||
|
||||
return donor
|
||||
|
||||
|
||||
def create_mode_of_payment(method):
|
||||
frappe.get_doc({
|
||||
'doctype': 'Mode of Payment',
|
||||
'mode_of_payment': method
|
||||
}).insert(ignore_mandatory=True)
|
||||
|
||||
|
||||
def notify_failure(log):
|
||||
try:
|
||||
content = '''
|
||||
Dear System Manager,
|
||||
Razorpay webhook for creating donation failed due to some reason.
|
||||
Please check the error log linked below
|
||||
Error Log: {0}
|
||||
Regards, Administrator
|
||||
'''.format(get_link_to_form('Error Log', log.name))
|
||||
|
||||
sendmail_to_system_managers(_('[Important] [ERPNext] Razorpay donation webhook failed, please check.'), content)
|
||||
except Exception:
|
||||
pass
|
@ -1,16 +0,0 @@
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'donation',
|
||||
'non_standard_fieldnames': {
|
||||
'Payment Entry': 'reference_name'
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Payment'),
|
||||
'items': ['Payment Entry']
|
||||
}
|
||||
]
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
|
||||
from erpnext.non_profit.doctype.donation.donation import create_donation
|
||||
|
||||
|
||||
class TestDonation(unittest.TestCase):
|
||||
def setUp(self):
|
||||
create_donor_type()
|
||||
settings = frappe.get_doc('Non Profit Settings')
|
||||
settings.company = '_Test Company'
|
||||
settings.donation_company = '_Test Company'
|
||||
settings.default_donor_type = '_Test Donor'
|
||||
settings.automate_donation_payment_entries = 1
|
||||
settings.donation_debit_account = 'Debtors - _TC'
|
||||
settings.donation_payment_account = 'Cash - _TC'
|
||||
settings.creation_user = 'Administrator'
|
||||
settings.flags.ignore_permissions = True
|
||||
settings.save()
|
||||
|
||||
def test_payment_entry_for_donations(self):
|
||||
donor = create_donor()
|
||||
create_mode_of_payment()
|
||||
payment = frappe._dict({
|
||||
'amount': 100,
|
||||
'method': 'Debit Card',
|
||||
'id': 'pay_MeXAmsgeKOhq7O'
|
||||
})
|
||||
donation = create_donation(donor, payment)
|
||||
|
||||
self.assertTrue(donation.name)
|
||||
|
||||
# Naive test to check if at all payment entry is generated
|
||||
# This method is actually triggered from Payment Gateway
|
||||
# In any case if details were missing, this would throw an error
|
||||
donation.on_payment_authorized()
|
||||
donation.reload()
|
||||
|
||||
self.assertEqual(donation.paid, 1)
|
||||
self.assertTrue(frappe.db.exists('Payment Entry', {'reference_no': donation.name}))
|
||||
|
||||
|
||||
def create_donor_type():
|
||||
if not frappe.db.exists('Donor Type', '_Test Donor'):
|
||||
frappe.get_doc({
|
||||
'doctype': 'Donor Type',
|
||||
'donor_type': '_Test Donor'
|
||||
}).insert()
|
||||
|
||||
|
||||
def create_donor():
|
||||
donor = frappe.db.exists('Donor', 'donor@test.com')
|
||||
if donor:
|
||||
return frappe.get_doc('Donor', 'donor@test.com')
|
||||
else:
|
||||
return frappe.get_doc({
|
||||
'doctype': 'Donor',
|
||||
'donor_name': '_Test Donor',
|
||||
'donor_type': '_Test Donor',
|
||||
'email': 'donor@test.com'
|
||||
}).insert()
|
||||
|
||||
|
||||
def create_mode_of_payment():
|
||||
if not frappe.db.exists('Mode of Payment', 'Debit Card'):
|
||||
frappe.get_doc({
|
||||
'doctype': 'Mode of Payment',
|
||||
'mode_of_payment': 'Debit Card',
|
||||
'accounts': [{
|
||||
'company': '_Test Company',
|
||||
'default_account': 'Cash - _TC'
|
||||
}]
|
||||
}).insert()
|
@ -1,17 +0,0 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Donor', {
|
||||
refresh: function(frm) {
|
||||
frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Donor'};
|
||||
|
||||
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
|
||||
|
||||
if(!frm.doc.__islocal) {
|
||||
frappe.contacts.render_address_and_contact(frm);
|
||||
} else {
|
||||
frappe.contacts.clear_address_and_contact(frm);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
@ -1,110 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:email",
|
||||
"creation": "2017-09-19 16:20:27.510196",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"donor_name",
|
||||
"column_break_5",
|
||||
"donor_type",
|
||||
"email",
|
||||
"image",
|
||||
"address_contacts",
|
||||
"address_html",
|
||||
"column_break_9",
|
||||
"contact_html"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "donor_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Donor Name",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "donor_type",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Donor Type",
|
||||
"options": "Donor Type",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "email",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Email",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
"hidden": 1,
|
||||
"label": "Image",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal;",
|
||||
"fieldname": "address_contacts",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Address and Contact",
|
||||
"options": "fa fa-map-marker"
|
||||
},
|
||||
{
|
||||
"fieldname": "address_html",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Address HTML"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_9",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "contact_html",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Contact HTML"
|
||||
}
|
||||
],
|
||||
"image_field": "image",
|
||||
"links": [
|
||||
{
|
||||
"link_doctype": "Donation",
|
||||
"link_fieldname": "donor"
|
||||
}
|
||||
],
|
||||
"modified": "2021-02-17 16:36:33.470731",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Non Profit",
|
||||
"name": "Donor",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Non Profit Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"restrict_to_domain": "Non Profit",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "donor_name",
|
||||
"track_changes": 1
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.contacts.address_and_contact import load_address_and_contact
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class Donor(Document):
|
||||
def onload(self):
|
||||
"""Load address and contacts in `__onload`"""
|
||||
load_address_and_contact(self)
|
||||
|
||||
def validate(self):
|
||||
from frappe.utils import validate_email_address
|
||||
if self.email:
|
||||
validate_email_address(self.email.strip(), True)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user