Merge branch 'develop' of https://github.com/frappe/erpnext into payment_entry_total_taxes
This commit is contained in:
commit
785fcca957
@ -131,11 +131,3 @@ def allow_regional(fn):
|
|||||||
return frappe.get_attr(overrides[function_path][-1])(*args, **kwargs)
|
return frappe.get_attr(overrides[function_path][-1])(*args, **kwargs)
|
||||||
|
|
||||||
return caller
|
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
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.query_builder.custom import ConstantColumn
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
|
||||||
from erpnext import get_company_currency
|
from erpnext import get_company_currency
|
||||||
@ -275,6 +276,10 @@ def check_matching(bank_account, company, transaction, document_types):
|
|||||||
}
|
}
|
||||||
|
|
||||||
matching_vouchers = []
|
matching_vouchers = []
|
||||||
|
|
||||||
|
matching_vouchers.extend(get_loan_vouchers(bank_account, transaction,
|
||||||
|
document_types, filters))
|
||||||
|
|
||||||
for query in subquery:
|
for query in subquery:
|
||||||
matching_vouchers.extend(
|
matching_vouchers.extend(
|
||||||
frappe.db.sql(query, filters,)
|
frappe.db.sql(query, filters,)
|
||||||
@ -311,6 +316,114 @@ def get_queries(bank_account, company, transaction, document_types):
|
|||||||
|
|
||||||
return queries
|
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):
|
def get_pe_matching_query(amount_condition, account_from_to, transaction):
|
||||||
# get matching payment entries query
|
# get matching payment entries query
|
||||||
if transaction.deposit > 0:
|
if transaction.deposit > 0:
|
||||||
@ -348,7 +461,6 @@ def get_je_matching_query(amount_condition, transaction):
|
|||||||
# We have mapping at the bank level
|
# We have mapping at the bank level
|
||||||
# So one bank could have both types of bank accounts like asset and liability
|
# 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
|
# 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"
|
cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit"
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
|
|||||||
@ -49,7 +49,8 @@ class BankTransaction(StatusUpdater):
|
|||||||
|
|
||||||
def clear_linked_payment_entries(self, for_cancel=False):
|
def clear_linked_payment_entries(self, for_cancel=False):
|
||||||
for payment_entry in self.payment_entries:
|
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)
|
self.clear_simple_entry(payment_entry, for_cancel=for_cancel)
|
||||||
|
|
||||||
elif payment_entry.payment_document == "Sales Invoice":
|
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)
|
payment_entry.payment_entry, paid_amount_field)
|
||||||
|
|
||||||
elif payment_entry.payment_document == "Journal Entry":
|
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":
|
elif payment_entry.payment_document == "Expense Claim":
|
||||||
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed")
|
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:
|
else:
|
||||||
frappe.throw("Please reconcile {0}: {1} manually".format(payment_entry.payment_document, payment_entry.payment_entry))
|
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({
|
frappe.get_doc({
|
||||||
"doctype": "Bank",
|
"doctype": "Bank",
|
||||||
"bank_name":bank_name,
|
"bank_name":bank_name,
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
|
|||||||
"account_name":"Checking Account",
|
"account_name":"Checking Account",
|
||||||
"bank": bank_name,
|
"bank": bank_name,
|
||||||
"account": account_name
|
"account": account_name
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ def add_vouchers():
|
|||||||
"supplier_group":"All Supplier Groups",
|
"supplier_group":"All Supplier Groups",
|
||||||
"supplier_type": "Company",
|
"supplier_type": "Company",
|
||||||
"supplier_name": "Conrad Electronic"
|
"supplier_name": "Conrad Electronic"
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
|
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
@ -203,7 +203,7 @@ def add_vouchers():
|
|||||||
"supplier_group":"All Supplier Groups",
|
"supplier_group":"All Supplier Groups",
|
||||||
"supplier_type": "Company",
|
"supplier_type": "Company",
|
||||||
"supplier_name": "Mr G"
|
"supplier_name": "Mr G"
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ def add_vouchers():
|
|||||||
"supplier_group":"All Supplier Groups",
|
"supplier_group":"All Supplier Groups",
|
||||||
"supplier_type": "Company",
|
"supplier_type": "Company",
|
||||||
"supplier_name": "Poore Simon's"
|
"supplier_name": "Poore Simon's"
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ def add_vouchers():
|
|||||||
"customer_group":"All Customer Groups",
|
"customer_group":"All Customer Groups",
|
||||||
"customer_type": "Company",
|
"customer_type": "Company",
|
||||||
"customer_name": "Poore Simon's"
|
"customer_name": "Poore Simon's"
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ def add_vouchers():
|
|||||||
"customer_group":"All Customer Groups",
|
"customer_group":"All Customer Groups",
|
||||||
"customer_type": "Company",
|
"customer_type": "Company",
|
||||||
"customer_name": "Fayva"
|
"customer_name": "Fayva"
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -166,7 +166,7 @@ class OpeningInvoiceCreationTool(Document):
|
|||||||
frappe.scrub(row.party_type): row.party,
|
frappe.scrub(row.party_type): row.party,
|
||||||
"is_pos": 0,
|
"is_pos": 0,
|
||||||
"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice",
|
"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,
|
"invoice_number": row.invoice_number,
|
||||||
"disable_rounded_total": 1
|
"disable_rounded_total": 1
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.cache_manager import clear_doctype_cache
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
|
|
||||||
|
|
||||||
from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
|
from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
|
||||||
create_dimension,
|
create_dimension,
|
||||||
@ -17,11 +14,13 @@ from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_crea
|
|||||||
|
|
||||||
test_dependencies = ["Customer", "Supplier", "Accounting Dimension"]
|
test_dependencies = ["Customer", "Supplier", "Accounting Dimension"]
|
||||||
|
|
||||||
class TestOpeningInvoiceCreationTool(unittest.TestCase):
|
class TestOpeningInvoiceCreationTool(FrappeTestCase):
|
||||||
def setUp(self):
|
@classmethod
|
||||||
|
def setUpClass(self):
|
||||||
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
|
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
|
||||||
make_company()
|
make_company()
|
||||||
create_dimension()
|
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):
|
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")
|
doc = frappe.get_single("Opening Invoice Creation Tool")
|
||||||
@ -31,26 +30,20 @@ class TestOpeningInvoiceCreationTool(unittest.TestCase):
|
|||||||
return doc.make_invoices()
|
return doc.make_invoices()
|
||||||
|
|
||||||
def test_opening_sales_invoice_creation(self):
|
def test_opening_sales_invoice_creation(self):
|
||||||
property_setter = make_property_setter("Sales Invoice", "update_stock", "default", 1, "Check")
|
invoices = self.make_invoices(company="_Test Opening Invoice Company")
|
||||||
try:
|
|
||||||
invoices = self.make_invoices(company="_Test Opening Invoice Company")
|
|
||||||
|
|
||||||
self.assertEqual(len(invoices), 2)
|
self.assertEqual(len(invoices), 2)
|
||||||
expected_value = {
|
expected_value = {
|
||||||
"keys": ["customer", "outstanding_amount", "status"],
|
"keys": ["customer", "outstanding_amount", "status"],
|
||||||
0: ["_Test Customer", 300, "Overdue"],
|
0: ["_Test Customer", 300, "Overdue"],
|
||||||
1: ["_Test Customer 1", 250, "Overdue"],
|
1: ["_Test Customer 1", 250, "Overdue"],
|
||||||
}
|
}
|
||||||
self.check_expected_values(invoices, expected_value)
|
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
|
# Check if update stock is not enabled
|
||||||
self.assertEqual(si.update_stock, 0)
|
self.assertEqual(si.update_stock, 0)
|
||||||
|
|
||||||
finally:
|
|
||||||
property_setter.delete()
|
|
||||||
clear_doctype_cache("Sales Invoice")
|
|
||||||
|
|
||||||
def check_expected_values(self, invoices, expected_value, invoice_type="Sales"):
|
def check_expected_values(self, invoices, expected_value, invoice_type="Sales"):
|
||||||
doctype = "Sales Invoice" if invoice_type == "Sales" else "Purchase Invoice"
|
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"];
|
var doctypes = ["Expense Claim", "Journal Entry"];
|
||||||
} else if (frm.doc.party_type == "Student") {
|
} else if (frm.doc.party_type == "Student") {
|
||||||
var doctypes = ["Fees"];
|
var doctypes = ["Fees"];
|
||||||
} else if (frm.doc.party_type == "Donor") {
|
|
||||||
var doctypes = ["Donation"];
|
|
||||||
} else {
|
} else {
|
||||||
var doctypes = ["Journal Entry"];
|
var doctypes = ["Journal Entry"];
|
||||||
}
|
}
|
||||||
@ -144,7 +142,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
const child = locals[cdt][cdn];
|
const child = locals[cdt][cdn];
|
||||||
const filters = {"docstatus": 1, "company": doc.company};
|
const filters = {"docstatus": 1, "company": doc.company};
|
||||||
const party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice',
|
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)) {
|
if (in_list(party_type_doctypes, child.reference_doctype)) {
|
||||||
filters[doc.party_type.toLowerCase()] = doc.party;
|
filters[doc.party_type.toLowerCase()] = doc.party;
|
||||||
@ -754,8 +752,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
(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=="Supplier") ||
|
||||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
(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=="Student")
|
||||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Donor")
|
|
||||||
) {
|
) {
|
||||||
if(total_positive_outstanding > total_negative_outstanding)
|
if(total_positive_outstanding > total_negative_outstanding)
|
||||||
if (!frm.doc.paid_amount)
|
if (!frm.doc.paid_amount)
|
||||||
@ -798,8 +795,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
(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=="Supplier") ||
|
||||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
(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=="Student")
|
||||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Donor")
|
|
||||||
) {
|
) {
|
||||||
if(total_positive_outstanding_including_order > paid_amount) {
|
if(total_positive_outstanding_including_order > paid_amount) {
|
||||||
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
|
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
|
||||||
@ -958,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]));
|
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Expense Claim or Journal Entry", [row.idx]));
|
||||||
return false;
|
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) {
|
if (row) {
|
||||||
|
|||||||
@ -91,7 +91,6 @@ class PaymentEntry(AccountsController):
|
|||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
self.update_outstanding_amounts()
|
self.update_outstanding_amounts()
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_donation()
|
|
||||||
self.update_payment_schedule()
|
self.update_payment_schedule()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
@ -101,7 +100,6 @@ class PaymentEntry(AccountsController):
|
|||||||
self.update_expense_claim()
|
self.update_expense_claim()
|
||||||
self.update_outstanding_amounts()
|
self.update_outstanding_amounts()
|
||||||
self.update_advance_paid()
|
self.update_advance_paid()
|
||||||
self.update_donation(cancel=1)
|
|
||||||
self.delink_advance_entry_references()
|
self.delink_advance_entry_references()
|
||||||
self.update_payment_schedule(cancel=1)
|
self.update_payment_schedule(cancel=1)
|
||||||
self.set_payment_req_status()
|
self.set_payment_req_status()
|
||||||
@ -284,8 +282,6 @@ class PaymentEntry(AccountsController):
|
|||||||
valid_reference_doctypes = ("Expense Claim", "Journal Entry", "Employee Advance", "Gratuity")
|
valid_reference_doctypes = ("Expense Claim", "Journal Entry", "Employee Advance", "Gratuity")
|
||||||
elif self.party_type == "Shareholder":
|
elif self.party_type == "Shareholder":
|
||||||
valid_reference_doctypes = ("Journal Entry")
|
valid_reference_doctypes = ("Journal Entry")
|
||||||
elif self.party_type == "Donor":
|
|
||||||
valid_reference_doctypes = ("Donation")
|
|
||||||
|
|
||||||
for d in self.get("references"):
|
for d in self.get("references"):
|
||||||
if not d.allocated_amount:
|
if not d.allocated_amount:
|
||||||
@ -843,13 +839,6 @@ class PaymentEntry(AccountsController):
|
|||||||
else:
|
else:
|
||||||
update_reimbursed_amount(doc, d.allocated_amount)
|
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):
|
def on_recurring(self, reference_doc, auto_repeat_doc):
|
||||||
self.reference_no = reference_doc.name
|
self.reference_no = reference_doc.name
|
||||||
self.reference_date = nowdate()
|
self.reference_date = nowdate()
|
||||||
@ -1081,7 +1070,7 @@ def get_outstanding_reference_documents(args):
|
|||||||
if d.voucher_type in ("Purchase Invoice"):
|
if d.voucher_type in ("Purchase Invoice"):
|
||||||
d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no")
|
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 = []
|
orders_to_be_billed = []
|
||||||
if (args.get("party_type") != "Student"):
|
if (args.get("party_type") != "Student"):
|
||||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
||||||
@ -1341,10 +1330,6 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
|||||||
total_amount = ref_doc.get("grand_total")
|
total_amount = ref_doc.get("grand_total")
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
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":
|
elif reference_doctype == "Dunning":
|
||||||
total_amount = ref_doc.get("dunning_amount")
|
total_amount = ref_doc.get("dunning_amount")
|
||||||
exchange_rate = 1
|
exchange_rate = 1
|
||||||
@ -1615,8 +1600,6 @@ def set_party_type(dt):
|
|||||||
party_type = "Employee"
|
party_type = "Employee"
|
||||||
elif dt == "Fees":
|
elif dt == "Fees":
|
||||||
party_type = "Student"
|
party_type = "Student"
|
||||||
elif dt == "Donation":
|
|
||||||
party_type = "Donor"
|
|
||||||
return party_type
|
return party_type
|
||||||
|
|
||||||
def set_party_account(dt, dn, doc, party_type):
|
def set_party_account(dt, dn, doc, party_type):
|
||||||
@ -1644,7 +1627,7 @@ def set_party_account_currency(dt, party_account, doc):
|
|||||||
return party_account_currency
|
return party_account_currency
|
||||||
|
|
||||||
def set_payment_type(dt, doc):
|
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):
|
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||||
payment_type = "Receive"
|
payment_type = "Receive"
|
||||||
else:
|
else:
|
||||||
@ -1677,9 +1660,6 @@ def set_grand_total_and_outstanding_amount(party_amount, dt, party_account_curre
|
|||||||
elif dt == "Dunning":
|
elif dt == "Dunning":
|
||||||
grand_total = doc.grand_total
|
grand_total = doc.grand_total
|
||||||
outstanding_amount = doc.grand_total
|
outstanding_amount = doc.grand_total
|
||||||
elif dt == "Donation":
|
|
||||||
grand_total = doc.amount
|
|
||||||
outstanding_amount = doc.amount
|
|
||||||
elif dt == "Gratuity":
|
elif dt == "Gratuity":
|
||||||
grand_total = doc.amount
|
grand_total = doc.amount
|
||||||
outstanding_amount = flt(doc.amount) - flt(doc.paid_amount)
|
outstanding_amount = flt(doc.amount) - flt(doc.paid_amount)
|
||||||
|
|||||||
@ -439,7 +439,6 @@ class POSInvoice(SalesInvoice):
|
|||||||
self.paid_amount = 0
|
self.paid_amount = 0
|
||||||
|
|
||||||
def set_account_for_mode_of_payment(self):
|
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:
|
for pay in self.payments:
|
||||||
if not pay.account:
|
if not pay.account:
|
||||||
pay.account = get_bank_cash_account(pay.mode_of_payment, self.company).get("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,
|
'to_date': doc.to_date,
|
||||||
'company': doc.company,
|
'company': doc.company,
|
||||||
'finance_book': doc.finance_book if doc.finance_book else None,
|
'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_type': 'Customer',
|
||||||
'party': [entry.customer],
|
'party': [entry.customer],
|
||||||
'presentation_currency': presentation_currency,
|
'presentation_currency': presentation_currency,
|
||||||
|
|||||||
@ -2429,14 +2429,22 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
def test_sales_commission(self):
|
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 = copy.deepcopy(si.get('items')[0])
|
||||||
item.update({
|
item.update({
|
||||||
"qty": 1,
|
"qty": 1,
|
||||||
"rate": 500,
|
"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
|
# Test valid values
|
||||||
for commission_rate, total_commission in ((0, 0), (10, 50), (100, 500)):
|
for commission_rate, total_commission in ((0, 0), (10, 50), (100, 500)):
|
||||||
|
|||||||
@ -832,6 +832,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"fetch_from": "item_code.grant_commission",
|
||||||
"fieldname": "grant_commission",
|
"fieldname": "grant_commission",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Grant Commission",
|
"label": "Grant Commission",
|
||||||
@ -841,7 +842,7 @@
|
|||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-10-05 12:24:54.968907",
|
"modified": "2022-02-24 14:41:36.392560",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Item",
|
"name": "Sales Invoice Item",
|
||||||
@ -849,5 +850,6 @@
|
|||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"sort_field": "modified",
|
"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"):
|
for tax in doc.get("taxes"):
|
||||||
validate_taxes_and_charges(tax)
|
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_cost_center(tax, doc)
|
||||||
validate_inclusive_tax(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)
|
.format(frappe.bold(party_type), frappe.bold(party), frappe.bold(existing_gle_currency), frappe.bold(company)), InvalidAccountCurrency)
|
||||||
|
|
||||||
def validate_party_accounts(doc):
|
def validate_party_accounts(doc):
|
||||||
|
from erpnext.controllers.accounts_controller import validate_account_head
|
||||||
companies = []
|
companies = []
|
||||||
|
|
||||||
for account in doc.get("accounts"):
|
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:
|
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"))
|
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()
|
@frappe.whitelist()
|
||||||
def get_due_date(posting_date, party_type, party, company=None, bill_date=None):
|
def get_due_date(posting_date, party_type, party, company=None, bill_date=None):
|
||||||
|
|||||||
@ -4,7 +4,12 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
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):
|
def execute(filters=None):
|
||||||
@ -18,7 +23,6 @@ def execute(filters=None):
|
|||||||
|
|
||||||
data = get_entries(filters)
|
data = get_entries(filters)
|
||||||
|
|
||||||
from erpnext.accounts.utils import get_balance_on
|
|
||||||
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
||||||
|
|
||||||
total_debit, total_credit = 0,0
|
total_debit, total_credit = 0,0
|
||||||
@ -118,7 +122,21 @@ def get_columns():
|
|||||||
]
|
]
|
||||||
|
|
||||||
def get_entries(filters):
|
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,
|
select "Journal Entry" as payment_document, jv.posting_date,
|
||||||
jv.name as payment_entry, jvd.debit_in_account_currency as debit,
|
jv.name as payment_entry, jvd.debit_in_account_currency as debit,
|
||||||
jvd.credit_in_account_currency as credit, jvd.against_account,
|
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.clearance_date, '4000-01-01') > %(report_date)s
|
||||||
and ifnull(jv.is_opening, 'No') = 'No'""", filters, as_dict=1)
|
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
|
select
|
||||||
"Payment Entry" as payment_document, name as payment_entry,
|
"Payment Entry" as payment_document, name as payment_entry,
|
||||||
reference_no, reference_date as ref_date,
|
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
|
and ifnull(clearance_date, '4000-01-01') > %(report_date)s
|
||||||
""", filters, as_dict=1)
|
""", filters, as_dict=1)
|
||||||
|
|
||||||
pos_entries = []
|
def get_pos_entries(filters):
|
||||||
if filters.include_pos_transactions:
|
return frappe.db.sql("""
|
||||||
pos_entries = frappe.db.sql("""
|
|
||||||
select
|
select
|
||||||
"Sales Invoice Payment" as payment_document, sip.name as payment_entry, sip.amount as debit,
|
"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,
|
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
|
si.posting_date ASC, si.name DESC
|
||||||
""", filters, as_dict=1)
|
""", filters, as_dict=1)
|
||||||
|
|
||||||
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
def get_loan_entries(filters):
|
||||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
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):
|
def get_amounts_not_reflected_in_system(filters):
|
||||||
je_amount = frappe.db.sql("""
|
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
|
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):
|
def get_balance_row(label, amount, account_currency):
|
||||||
if amount > 0:
|
if amount > 0:
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class TestTaxDetail(unittest.TestCase):
|
|||||||
# Create GL Entries:
|
# Create GL Entries:
|
||||||
db_doc.submit()
|
db_doc.submit()
|
||||||
else:
|
else:
|
||||||
db_doc.insert()
|
db_doc.insert(ignore_if_duplicate=True)
|
||||||
except frappe.exceptions.DuplicateEntryError:
|
except frappe.exceptions.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -39,10 +39,11 @@ class TestReports(unittest.TestCase):
|
|||||||
def test_execute_all_accounts_reports(self):
|
def test_execute_all_accounts_reports(self):
|
||||||
"""Test that all script report in stock modules are executable with supported filters"""
|
"""Test that all script report in stock modules are executable with supported filters"""
|
||||||
for report, filter in REPORT_FILTER_TEST_CASES:
|
for report, filter in REPORT_FILTER_TEST_CASES:
|
||||||
execute_script_report(
|
with self.subTest(report=report):
|
||||||
report_name=report,
|
execute_script_report(
|
||||||
module="Accounts",
|
report_name=report,
|
||||||
filters=filter,
|
module="Accounts",
|
||||||
default_filters=DEFAULT_FILTERS,
|
filters=filter,
|
||||||
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
|
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,
|
"payment_account": bank_account.name,
|
||||||
"currency": bank_account.account_currency,
|
"currency": bank_account.account_currency,
|
||||||
"payment_channel": payment_channel
|
"payment_channel": payment_channel
|
||||||
}).insert(ignore_permissions=True)
|
}).insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||||
|
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
# already exists, due to a reinstall?
|
# already exists, due to a reinstall?
|
||||||
|
|||||||
@ -417,11 +417,12 @@ class Asset(AccountsController):
|
|||||||
def validate_asset_finance_books(self, row):
|
def validate_asset_finance_books(self, row):
|
||||||
if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
|
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")
|
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 row.depreciation_start_date:
|
||||||
if not self.available_for_use_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)
|
row.depreciation_start_date = get_last_day(self.available_for_use_date)
|
||||||
|
|
||||||
if not self.is_existing_asset:
|
if not self.is_existing_asset:
|
||||||
@ -439,8 +440,9 @@ class Asset(AccountsController):
|
|||||||
else:
|
else:
|
||||||
self.number_of_depreciations_booked = 0
|
self.number_of_depreciations_booked = 0
|
||||||
|
|
||||||
if cint(self.number_of_depreciations_booked) > cint(row.total_number_of_depreciations):
|
if flt(row.total_number_of_depreciations) <= cint(self.number_of_depreciations_booked):
|
||||||
frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
|
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):
|
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")
|
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)
|
self.assertRaises(frappe.ValidationError, asset.save)
|
||||||
|
|
||||||
def test_number_of_depreciations(self):
|
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(
|
asset = create_asset(
|
||||||
item_code = "Macbook Pro",
|
item_code = "Macbook Pro",
|
||||||
calculate_depreciation = 1,
|
calculate_depreciation = 1,
|
||||||
@ -889,6 +890,21 @@ class TestDepreciationBasics(AssetSetup):
|
|||||||
|
|
||||||
self.assertRaises(frappe.ValidationError, asset.save)
|
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):
|
def test_depreciation_start_date_is_before_purchase_date(self):
|
||||||
asset = create_asset(
|
asset = create_asset(
|
||||||
item_code = "Macbook Pro",
|
item_code = "Macbook Pro",
|
||||||
@ -1264,7 +1280,7 @@ def create_asset(**args):
|
|||||||
|
|
||||||
if not args.do_not_save:
|
if not args.do_not_save:
|
||||||
try:
|
try:
|
||||||
asset.save()
|
asset.insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
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,
|
"is_grouped_asset": is_grouped_asset,
|
||||||
"asset_naming_series": naming_series
|
"asset_naming_series": naming_series
|
||||||
})
|
})
|
||||||
item.insert()
|
item.insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
return item
|
return item
|
||||||
|
|||||||
@ -23,7 +23,7 @@ class TestAssetCategory(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
asset_category.insert()
|
asset_category.insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import add_days, flt, getdate, nowdate
|
from frappe.utils import add_days, flt, getdate, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
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
|
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):
|
def test_make_purchase_receipt(self):
|
||||||
po = create_purchase_order(do_not_submit=True)
|
po = create_purchase_order(do_not_submit=True)
|
||||||
self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name)
|
self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name)
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
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
|
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||||
|
|
||||||
|
|
||||||
class TestRequestforQuotation(unittest.TestCase):
|
class TestRequestforQuotation(FrappeTestCase):
|
||||||
def test_quote_status(self):
|
def test_quote_status(self):
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.test_runner import make_test_records
|
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_dependencies = ['Payment Term', 'Payment Terms Template']
|
||||||
test_records = frappe.get_test_records('Supplier')
|
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):
|
class TestSupplier(FrappeTestCase):
|
||||||
# Payment Term based on Days after invoice date
|
def test_get_supplier_group_details(self):
|
||||||
frappe.db.set_value(
|
doc = frappe.new_doc("Supplier Group")
|
||||||
"Supplier", "_Test Supplier With Template 1", "payment_terms", "_Test Payment Term Template 3")
|
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")
|
def test_supplier_default_payment_terms(self):
|
||||||
self.assertEqual(due_date, "2016-02-21")
|
# 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")
|
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||||
self.assertEqual(due_date, "2017-02-21")
|
self.assertEqual(due_date, "2016-02-21")
|
||||||
|
|
||||||
# Payment Term based on last day of month
|
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||||
frappe.db.set_value(
|
self.assertEqual(due_date, "2017-02-21")
|
||||||
"Supplier", "_Test Supplier With Template 1", "payment_terms", "_Test Payment Term Template 1")
|
|
||||||
|
|
||||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
# Payment Term based on last day of month
|
||||||
self.assertEqual(due_date, "2016-02-29")
|
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")
|
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||||
self.assertEqual(due_date, "2017-02-28")
|
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", "_Test Supplier With Template 1", "payment_terms", "")
|
||||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "_Test Payment Term Template 3")
|
|
||||||
|
|
||||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
# Set credit limit for the supplier group instead of supplier and evaluate the due date
|
||||||
self.assertEqual(due_date, "2016-02-21")
|
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
|
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "_Test Payment Term Template 1")
|
self.assertEqual(due_date, "2016-02-21")
|
||||||
|
|
||||||
# Leap year
|
# Payment terms for Supplier Group instead of supplier and evaluate the due date
|
||||||
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "_Test Payment Term 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")
|
|
||||||
|
|
||||||
# Supplier with no default Payment Terms Template
|
# Leap year
|
||||||
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "")
|
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier With Template 1")
|
||||||
frappe.db.set_value("Supplier", "_Test Supplier", "payment_terms", "")
|
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")
|
# Supplier with no default Payment Terms Template
|
||||||
self.assertEqual(due_date, "2016-01-22")
|
frappe.db.set_value("Supplier Group", "_Test Supplier Group", "payment_terms", "")
|
||||||
# # Non Leap year
|
frappe.db.set_value("Supplier", "_Test Supplier", "payment_terms", "")
|
||||||
due_date = get_due_date("2017-01-22", "Supplier", "_Test Supplier")
|
|
||||||
self.assertEqual(due_date, "2017-01-22")
|
|
||||||
|
|
||||||
def test_supplier_disabled(self):
|
due_date = get_due_date("2016-01-22", "Supplier", "_Test Supplier")
|
||||||
make_test_records("Item")
|
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):
|
po.save()
|
||||||
# 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 if test supplier field record is 'Greece'
|
def test_supplier_country(self):
|
||||||
self.assertEqual(supplier.country, "Greece")
|
# 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
|
# Test if test supplier field record is 'Greece'
|
||||||
supplier = frappe.get_doc('Supplier', '_Test Supplier')
|
self.assertEqual(supplier.country, "Greece")
|
||||||
supplier.country = 'Greece'
|
|
||||||
supplier.save()
|
|
||||||
self.assertEqual(supplier.country, "Greece")
|
|
||||||
|
|
||||||
def test_party_details_tax_category(self):
|
# Test update Supplier instance country value
|
||||||
from erpnext.accounts.party import get_party_details
|
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
|
frappe.delete_doc_if_exists("Address", "_Test Address With Tax Category-Billing")
|
||||||
details = get_party_details("_Test Supplier With Tax Category", party_type="Supplier")
|
|
||||||
self.assertEqual(details.tax_category, "_Test Tax Category 1")
|
|
||||||
|
|
||||||
address = frappe.get_doc(dict(
|
# Tax Category without Address
|
||||||
doctype='Address',
|
details = get_party_details("_Test Supplier With Tax Category", party_type="Supplier")
|
||||||
address_title='_Test Address With Tax Category',
|
self.assertEqual(details.tax_category, "_Test Tax Category 1")
|
||||||
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 with Address
|
address = frappe.get_doc(dict(
|
||||||
details = get_party_details("_Test Supplier With Tax Category", party_type="Supplier")
|
doctype='Address',
|
||||||
self.assertEqual(details.tax_category, "_Test Tax Category 2")
|
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
|
# Tax Category with Address
|
||||||
address.delete()
|
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):
|
def create_supplier(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|
||||||
try:
|
if frappe.db.exists("Supplier", args.supplier_name):
|
||||||
doc = frappe.get_doc({
|
return frappe.get_doc("Supplier", args.supplier_name)
|
||||||
"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()
|
|
||||||
|
|
||||||
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 doc
|
||||||
return frappe.get_doc("Supplier", args.supplier_name)
|
|
||||||
|
|||||||
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
|
||||||
class TestPurchaseOrder(unittest.TestCase):
|
class TestPurchaseOrder(FrappeTestCase):
|
||||||
def test_make_purchase_order(self):
|
def test_make_purchase_order(self):
|
||||||
from erpnext.buying.doctype.supplier_quotation.supplier_quotation import make_purchase_order
|
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
|
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
|
||||||
class TestSupplierScorecard(unittest.TestCase):
|
class TestSupplierScorecard(FrappeTestCase):
|
||||||
|
|
||||||
def test_create_scorecard(self):
|
def test_create_scorecard(self):
|
||||||
doc = make_supplier_scorecard().insert()
|
doc = make_supplier_scorecard().insert()
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
|
|
||||||
class TestSupplierScorecardCriteria(unittest.TestCase):
|
class TestSupplierScorecardCriteria(FrappeTestCase):
|
||||||
def test_variables_exist(self):
|
def test_variables_exist(self):
|
||||||
delete_test_scorecards()
|
delete_test_scorecards()
|
||||||
for d in test_good_criteria:
|
for d in test_good_criteria:
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
from erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable import (
|
from erpnext.buying.doctype.supplier_scorecard_variable.supplier_scorecard_variable import (
|
||||||
VariablePathNotFound,
|
VariablePathNotFound,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestSupplierScorecardVariable(unittest.TestCase):
|
class TestSupplierScorecardVariable(FrappeTestCase):
|
||||||
def test_variable_exist(self):
|
def test_variable_exist(self):
|
||||||
for d in test_existing_variables:
|
for d in test_existing_variables:
|
||||||
my_doc = frappe.get_doc("Supplier Scorecard Variable", d.get("name"))
|
my_doc = frappe.get_doc("Supplier Scorecard Variable", d.get("name"))
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import frappe
|
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.purchase_order import make_purchase_receipt
|
||||||
from erpnext.buying.report.procurement_tracker.procurement_tracker import execute
|
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
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
|
|
||||||
|
|
||||||
class TestProcurementTracker(unittest.TestCase):
|
class TestProcurementTracker(FrappeTestCase):
|
||||||
def test_result_for_procurement_tracker(self):
|
def test_result_for_procurement_tracker(self):
|
||||||
filters = {
|
filters = {
|
||||||
'company': '_Test Procurement Company',
|
'company': '_Test Procurement Company',
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
# Compiled at: 2019-05-06 09:51:46
|
# Compiled at: 2019-05-06 09:51:46
|
||||||
# Decompiled by https://python-decompiler.com
|
# Decompiled by https://python-decompiler.com
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
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.purchase_order import make_purchase_receipt
|
||||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
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
|
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):
|
def test_pending_and_received_qty(self):
|
||||||
po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes')
|
po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes')
|
||||||
|
|||||||
@ -4,9 +4,9 @@
|
|||||||
# Decompiled by https://python-decompiler.com
|
# Decompiled by https://python-decompiler.com
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import unittest
|
|
||||||
|
|
||||||
import frappe
|
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.purchase_order import make_rm_stock_entry
|
||||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
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
|
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):
|
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")
|
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
|
tax.rate = None
|
||||||
|
|
||||||
|
|
||||||
def validate_account_head(tax, doc):
|
def validate_account_head(idx, account, company):
|
||||||
company = frappe.get_cached_value('Account',
|
account_company = frappe.get_cached_value('Account', account, 'company')
|
||||||
tax.account_head, 'company')
|
|
||||||
|
|
||||||
if company != doc.company:
|
if account_company != company:
|
||||||
frappe.throw(_('Row {0}: Account {1} does not belong to Company {2}')
|
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):
|
def validate_cost_center(tax, doc):
|
||||||
|
|||||||
@ -104,11 +104,11 @@ class EmployeeBoardingController(Document):
|
|||||||
def get_task_dates(self, activity, holiday_list):
|
def get_task_dates(self, activity, holiday_list):
|
||||||
start_date = end_date = None
|
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 = add_days(self.boarding_begins_on, activity.begin_on)
|
||||||
start_date = self.update_if_holiday(start_date, holiday_list)
|
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 = add_days(self.boarding_begins_on, activity.begin_on + activity.duration)
|
||||||
end_date = self.update_if_holiday(end_date, holiday_list)
|
end_date = self.update_if_holiday(end_date, holiday_list)
|
||||||
|
|
||||||
|
|||||||
@ -363,8 +363,6 @@ class Subcontracting():
|
|||||||
return
|
return
|
||||||
|
|
||||||
for row in self.get(self.raw_material_table):
|
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)
|
key = (row.rm_item_code, row.main_item_code, row.purchase_order)
|
||||||
if not self.__transferred_items or not self.__transferred_items.get(key):
|
if not self.__transferred_items or not self.__transferred_items.get(key):
|
||||||
return
|
return
|
||||||
@ -372,12 +370,6 @@ class Subcontracting():
|
|||||||
self.__validate_batch_no(row, key)
|
self.__validate_batch_no(row, key)
|
||||||
self.__validate_serial_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):
|
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'):
|
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)
|
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)
|
customer = get_customer(silent=True)
|
||||||
if customer:
|
if customer:
|
||||||
quotation = frappe.get_all("Quotation", fields=["name"], filters=
|
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)
|
order_by="modified desc", limit_page_length=1)
|
||||||
if quotation:
|
if quotation:
|
||||||
items = frappe.get_all(
|
items = frappe.get_all(
|
||||||
|
|||||||
@ -310,7 +310,7 @@ def _get_cart_quotation(party=None):
|
|||||||
party = get_party()
|
party = get_party()
|
||||||
|
|
||||||
quotation = frappe.get_all("Quotation", fields=["name"], filters=
|
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)
|
order_by="modified desc", limit_page_length=1)
|
||||||
|
|
||||||
if quotation:
|
if quotation:
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import change_settings
|
||||||
from frappe.utils import add_months, nowdate
|
from frappe.utils import add_months, nowdate
|
||||||
|
|
||||||
from erpnext.accounts.doctype.tax_rule.tax_rule import ConflictingTaxRule
|
from erpnext.accounts.doctype.tax_rule.tax_rule import ConflictingTaxRule
|
||||||
@ -15,7 +16,7 @@ from erpnext.e_commerce.shopping_cart.cart import (
|
|||||||
get_party,
|
get_party,
|
||||||
update_cart,
|
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']
|
# test_dependencies = ['Payment Terms Template']
|
||||||
|
|
||||||
@ -57,13 +58,19 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
return quotation
|
return quotation
|
||||||
|
|
||||||
def test_get_cart_customer(self):
|
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
|
self.login_as_customer("test_contact_two_customer@example.com", "_Test Contact 2 For _Test Customer")
|
||||||
quotation = _get_cart_quotation()
|
validate_quotation()
|
||||||
self.assertEqual(quotation.quotation_to, "Customer")
|
|
||||||
self.assertEqual(quotation.party_name, "_Test Customer")
|
self.login_as_customer()
|
||||||
self.assertEqual(quotation.contact_email, frappe.session.user)
|
quotation = validate_quotation()
|
||||||
|
|
||||||
return quotation
|
return quotation
|
||||||
|
|
||||||
@ -175,7 +182,7 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
def create_tax_rule(self):
|
def create_tax_rule(self):
|
||||||
tax_rule = frappe.get_test_records("Tax Rule")[0]
|
tax_rule = frappe.get_test_records("Tax Rule")[0]
|
||||||
try:
|
try:
|
||||||
frappe.get_doc(tax_rule).insert()
|
frappe.get_doc(tax_rule).insert(ignore_if_duplicate=True)
|
||||||
except (frappe.DuplicateEntryError, ConflictingTaxRule):
|
except (frappe.DuplicateEntryError, ConflictingTaxRule):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -254,10 +261,9 @@ class TestShoppingCart(unittest.TestCase):
|
|||||||
self.create_user_if_not_exists("test_cart_user@example.com")
|
self.create_user_if_not_exists("test_cart_user@example.com")
|
||||||
frappe.set_user("test_cart_user@example.com")
|
frappe.set_user("test_cart_user@example.com")
|
||||||
|
|
||||||
def login_as_customer(self):
|
def login_as_customer(self, email="test_contact_customer@example.com", name="_Test Contact For _Test Customer"):
|
||||||
self.create_user_if_not_exists("test_contact_customer@example.com",
|
self.create_user_if_not_exists(email, name)
|
||||||
"_Test Contact For _Test Customer")
|
frappe.set_user(email)
|
||||||
frappe.set_user("test_contact_customer@example.com")
|
|
||||||
|
|
||||||
def clear_existing_quotations(self):
|
def clear_existing_quotations(self):
|
||||||
quotations = frappe.get_all("Quotation", filters={
|
quotations = frappe.get_all("Quotation", filters={
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
|
|
||||||
from erpnext.controllers.item_variant import create_variant
|
from erpnext.controllers.item_variant import create_variant
|
||||||
from erpnext.e_commerce.doctype.e_commerce_settings.test_e_commerce_settings import (
|
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.doctype.website_item.website_item import make_website_item
|
||||||
from erpnext.e_commerce.variant_selector.utils import get_next_attribute_and_values
|
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.stock.doctype.item.test_item import make_item
|
||||||
from erpnext.tests.utils import ERPNextTestCase
|
|
||||||
|
|
||||||
test_dependencies = ["Item"]
|
test_dependencies = ["Item"]
|
||||||
|
|
||||||
class TestVariantSelector(ERPNextTestCase):
|
class TestVariantSelector(FrappeTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
|||||||
@ -3,6 +3,10 @@
|
|||||||
frappe.provide("education");
|
frappe.provide("education");
|
||||||
|
|
||||||
frappe.ui.form.on('Student Attendance Tool', {
|
frappe.ui.form.on('Student Attendance Tool', {
|
||||||
|
setup: (frm) => {
|
||||||
|
frm.students_area = $('<div>')
|
||||||
|
.appendTo(frm.fields_dict.students_html.wrapper);
|
||||||
|
},
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
frm.set_query("student_group", function() {
|
frm.set_query("student_group", function() {
|
||||||
return {
|
return {
|
||||||
@ -34,6 +38,7 @@ frappe.ui.form.on('Student Attendance Tool', {
|
|||||||
|
|
||||||
student_group: function(frm) {
|
student_group: function(frm) {
|
||||||
if ((frm.doc.student_group && frm.doc.date) || frm.doc.course_schedule) {
|
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";
|
var method = "erpnext.education.doctype.student_attendance_tool.student_attendance_tool.get_student_attendance_records";
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
@ -62,10 +67,6 @@ frappe.ui.form.on('Student Attendance Tool', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
get_students: function(frm, students) {
|
get_students: function(frm, students) {
|
||||||
if (!frm.students_area) {
|
|
||||||
frm.students_area = $('<div>')
|
|
||||||
.appendTo(frm.fields_dict.students_html.wrapper);
|
|
||||||
}
|
|
||||||
students = students || [];
|
students = students || [];
|
||||||
frm.students_editor = new education.StudentsEditor(frm, frm.students_area, 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) {
|
// make html grid of students
|
||||||
return frappe.render_template("student_button", {
|
let student_html = '';
|
||||||
student: student.student,
|
for (let student of students) {
|
||||||
student_name: student.student_name,
|
student_html += `<div class="col-sm-3">
|
||||||
group_roll_number: student.group_roll_number,
|
<div class="checkbox">
|
||||||
status: student.status
|
<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() {
|
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"],
|
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")
|
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:
|
if course_schedule:
|
||||||
student_attendance_list = (
|
student_attendance_list = (
|
||||||
frappe.qb.from_(table)
|
frappe.qb.from_(StudentAttendance)
|
||||||
.select(table.student, table.status)
|
.select(StudentAttendance.student, StudentAttendance.status)
|
||||||
.where(
|
.where(
|
||||||
(table.course_schedule == course_schedule)
|
(StudentAttendance.course_schedule == course_schedule)
|
||||||
)
|
)
|
||||||
).run(as_dict=True)
|
).run(as_dict=True)
|
||||||
else:
|
else:
|
||||||
student_attendance_list = (
|
student_attendance_list = (
|
||||||
frappe.qb.from_(table)
|
frappe.qb.from_(StudentAttendance)
|
||||||
.select(table.student, table.status)
|
.select(StudentAttendance.student, StudentAttendance.status)
|
||||||
.where(
|
.where(
|
||||||
(table.student_group == student_group)
|
(StudentAttendance.student_group == student_group)
|
||||||
& (table.date == date)
|
& (StudentAttendance.date == date)
|
||||||
& (table.course_schedule == "") | (table.course_schedule.isnull())
|
& ((StudentAttendance.course_schedule == "") | (StudentAttendance.course_schedule.isnull()))
|
||||||
)
|
)
|
||||||
).run(as_dict=True)
|
).run(as_dict=True)
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,7 @@ class TallyMigration(Document):
|
|||||||
"is_private": True
|
"is_private": True
|
||||||
})
|
})
|
||||||
try:
|
try:
|
||||||
f.insert()
|
f.insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
setattr(self, key, f.file_url)
|
setattr(self, key, f.file_url)
|
||||||
|
|||||||
@ -8,10 +8,6 @@ from frappe.utils import cint, flt
|
|||||||
|
|
||||||
from erpnext import get_default_company, get_region
|
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",
|
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",
|
"FR", "GB", "GR", "HR", "HU", "IE", "IT", "LT", "LU", "LV", "MT", "NL", "PL", "PT", "RO",
|
||||||
"SE", "SI", "SK", "US"]
|
"SE", "SI", "SK", "US"]
|
||||||
@ -35,12 +31,14 @@ def get_client():
|
|||||||
if api_key and api_url:
|
if api_key and api_url:
|
||||||
client = taxjar.Client(api_key=api_key, api_url=api_url)
|
client = taxjar.Client(api_key=api_key, api_url=api_url)
|
||||||
client.set_api_config('headers', {
|
client.set_api_config('headers', {
|
||||||
'x-api-version': '2020-08-07'
|
'x-api-version': '2022-01-24'
|
||||||
})
|
})
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
|
||||||
def create_transaction(doc, method):
|
def create_transaction(doc, method):
|
||||||
|
TAXJAR_CREATE_TRANSACTIONS = frappe.db.get_single_value("TaxJar Settings", "taxjar_create_transactions")
|
||||||
|
|
||||||
"""Create an order transaction in TaxJar"""
|
"""Create an order transaction in TaxJar"""
|
||||||
|
|
||||||
if not TAXJAR_CREATE_TRANSACTIONS:
|
if not TAXJAR_CREATE_TRANSACTIONS:
|
||||||
@ -51,6 +49,7 @@ def create_transaction(doc, method):
|
|||||||
if not client:
|
if not client:
|
||||||
return
|
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])
|
sales_tax = sum([tax.tax_amount for tax in doc.taxes if tax.account_head == TAX_ACCOUNT_HEAD])
|
||||||
|
|
||||||
if not sales_tax:
|
if not sales_tax:
|
||||||
@ -79,6 +78,7 @@ def create_transaction(doc, method):
|
|||||||
|
|
||||||
def delete_transaction(doc, method):
|
def delete_transaction(doc, method):
|
||||||
"""Delete an existing TaxJar order transaction"""
|
"""Delete an existing TaxJar order transaction"""
|
||||||
|
TAXJAR_CREATE_TRANSACTIONS = frappe.db.get_single_value("TaxJar Settings", "taxjar_create_transactions")
|
||||||
|
|
||||||
if not TAXJAR_CREATE_TRANSACTIONS:
|
if not TAXJAR_CREATE_TRANSACTIONS:
|
||||||
return
|
return
|
||||||
@ -92,6 +92,8 @@ def delete_transaction(doc, method):
|
|||||||
|
|
||||||
|
|
||||||
def get_tax_data(doc):
|
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_address = get_company_address_details(doc)
|
||||||
from_shipping_state = from_address.get("state")
|
from_shipping_state = from_address.get("state")
|
||||||
from_country_code = frappe.db.get_value("Country", from_address.country, "code")
|
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')
|
to_shipping_state = get_state_code(to_address, 'Shipping')
|
||||||
|
|
||||||
tax_dict = {
|
tax_dict = {
|
||||||
'from_country': from_country_code,
|
"from_country": from_country_code,
|
||||||
'from_zip': from_address.pincode,
|
"from_zip": from_address.pincode,
|
||||||
'from_state': from_shipping_state,
|
"from_state": from_shipping_state,
|
||||||
'from_city': from_address.city,
|
"from_city": from_address.city,
|
||||||
'from_street': from_address.address_line1,
|
"from_street": from_address.address_line1,
|
||||||
'to_country': to_country_code,
|
"to_country": to_country_code,
|
||||||
'to_zip': to_address.pincode,
|
"to_zip": to_address.pincode,
|
||||||
'to_city': to_address.city,
|
"to_city": to_address.city,
|
||||||
'to_street': to_address.address_line1,
|
"to_street": to_address.address_line1,
|
||||||
'to_state': to_shipping_state,
|
"to_state": to_shipping_state,
|
||||||
'shipping': shipping,
|
"shipping": shipping,
|
||||||
'amount': doc.net_total,
|
"amount": doc.net_total,
|
||||||
'plugin': 'erpnext',
|
"plugin": "erpnext",
|
||||||
'line_items': line_items
|
"line_items": line_items
|
||||||
}
|
}
|
||||||
return tax_dict
|
return tax_dict
|
||||||
|
|
||||||
@ -156,6 +158,9 @@ def get_line_item_dict(item, docstatus):
|
|||||||
return tax_dict
|
return tax_dict
|
||||||
|
|
||||||
def set_sales_tax(doc, method):
|
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:
|
if not TAXJAR_CALCULATE_TAX:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -206,6 +211,7 @@ def set_sales_tax(doc, method):
|
|||||||
doc.run_method("calculate_taxes_and_totals")
|
doc.run_method("calculate_taxes_and_totals")
|
||||||
|
|
||||||
def check_for_nexus(doc, tax_dict):
|
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"]}):
|
if not frappe.db.get_value('TaxJar Nexus', {'region_code': tax_dict["to_state"]}):
|
||||||
for item in doc.get("items"):
|
for item in doc.get("items"):
|
||||||
item.tax_collectable = flt(0)
|
item.tax_collectable = flt(0)
|
||||||
@ -218,6 +224,8 @@ def check_for_nexus(doc, tax_dict):
|
|||||||
|
|
||||||
def check_sales_tax_exemption(doc):
|
def check_sales_tax_exemption(doc):
|
||||||
# if the party is exempt from sales tax, then set all tax account heads to zero
|
# 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 \
|
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") \
|
or frappe.db.has_column("Customer", "exempt_from_sales_tax") \
|
||||||
and frappe.db.get_value("Customer", doc.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',
|
'Distribution': 'erpnext.domains.distribution',
|
||||||
'Education': 'erpnext.domains.education',
|
'Education': 'erpnext.domains.education',
|
||||||
'Manufacturing': 'erpnext.domains.manufacturing',
|
'Manufacturing': 'erpnext.domains.manufacturing',
|
||||||
'Non Profit': 'erpnext.domains.non_profit',
|
|
||||||
'Retail': 'erpnext.domains.retail',
|
'Retail': 'erpnext.domains.retail',
|
||||||
'Services': 'erpnext.domains.services',
|
'Services': 'erpnext.domains.services',
|
||||||
}
|
}
|
||||||
@ -175,7 +174,6 @@ standard_portal_menu_items = [
|
|||||||
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"},
|
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"},
|
||||||
{"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"},
|
{"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"},
|
||||||
{"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission", "role": "Student"},
|
{"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": _("Material Request"), "route": "/material-requests", "reference_doctype": "Material Request", "role": "Customer"},
|
||||||
{"title": _("Appointment Booking"), "route": "/book_appointment"},
|
{"title": _("Appointment Booking"), "route": "/book_appointment"},
|
||||||
]
|
]
|
||||||
@ -369,7 +367,6 @@ scheduler_events = {
|
|||||||
"erpnext.selling.doctype.quotation.quotation.set_expired_status",
|
"erpnext.selling.doctype.quotation.quotation.set_expired_status",
|
||||||
"erpnext.buying.doctype.supplier_quotation.supplier_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.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"
|
"erpnext.hr.doctype.interview.interview.send_daily_feedback_reminder"
|
||||||
],
|
],
|
||||||
"daily_long": [
|
"daily_long": [
|
||||||
@ -563,19 +560,6 @@ global_search_doctypes = {
|
|||||||
{'doctype': 'Assessment Code', 'index': 39},
|
{'doctype': 'Assessment Code', 'index': 39},
|
||||||
{'doctype': 'Discussion', 'index': 40},
|
{'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 = {
|
additional_timeline_content = {
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class Department(NestedSet):
|
|||||||
return new
|
return new
|
||||||
|
|
||||||
def on_update(self):
|
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()
|
super(Department, self).on_update()
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
[
|
[
|
||||||
{"doctype":"Department", "department_name":"_Test Department", "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"}
|
{"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,
|
"file_url": self.image,
|
||||||
"attached_to_doctype": "User",
|
"attached_to_doctype": "User",
|
||||||
"attached_to_name": self.user_id
|
"attached_to_name": self.user_id
|
||||||
}).insert()
|
}).insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
# already exists
|
# already exists
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import getdate
|
from frappe.utils import add_days, getdate
|
||||||
|
|
||||||
from erpnext.hr.doctype.employee_onboarding.employee_onboarding import (
|
from erpnext.hr.doctype.employee_onboarding.employee_onboarding import (
|
||||||
IncompleteTaskError,
|
IncompleteTaskError,
|
||||||
@ -35,6 +35,15 @@ class TestEmployeeOnboarding(unittest.TestCase):
|
|||||||
# boarding status
|
# boarding status
|
||||||
self.assertEqual(onboarding.boarding_status, 'Pending')
|
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
|
# complete the task
|
||||||
project = frappe.get_doc('Project', onboarding.project)
|
project = frappe.get_doc('Project', onboarding.project)
|
||||||
for task in frappe.get_all('Task', dict(project=project.name)):
|
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')
|
self.assertEqual(employee.employee_name, 'Test Researcher')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
for entry in frappe.get_all('Employee Onboarding'):
|
frappe.db.rollback()
|
||||||
doc = frappe.get_doc('Employee Onboarding', entry.name)
|
|
||||||
doc.cancel()
|
|
||||||
doc.delete()
|
|
||||||
|
|
||||||
|
|
||||||
def get_job_applicant():
|
def get_job_applicant():
|
||||||
@ -87,23 +93,31 @@ def get_job_offer(applicant_name):
|
|||||||
def create_employee_onboarding():
|
def create_employee_onboarding():
|
||||||
applicant = get_job_applicant()
|
applicant = get_job_applicant()
|
||||||
job_offer = get_job_offer(applicant.name)
|
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 = frappe.new_doc('Employee Onboarding')
|
||||||
onboarding.job_applicant = applicant.name
|
onboarding.job_applicant = applicant.name
|
||||||
onboarding.job_offer = job_offer.name
|
onboarding.job_offer = job_offer.name
|
||||||
onboarding.date_of_joining = onboarding.boarding_begins_on = getdate()
|
onboarding.date_of_joining = onboarding.boarding_begins_on = getdate()
|
||||||
onboarding.company = '_Test Company'
|
onboarding.company = '_Test Company'
|
||||||
onboarding.holiday_list = holiday_list
|
onboarding.holiday_list = holiday_list.name
|
||||||
onboarding.designation = 'Researcher'
|
onboarding.designation = 'Researcher'
|
||||||
onboarding.append('activities', {
|
onboarding.append('activities', {
|
||||||
'activity_name': 'Assign ID Card',
|
'activity_name': 'Assign ID Card',
|
||||||
'role': 'HR User',
|
'role': 'HR User',
|
||||||
'required_for_employee_creation': 1
|
'required_for_employee_creation': 1,
|
||||||
|
'begin_on': 0,
|
||||||
|
'duration': 1
|
||||||
})
|
})
|
||||||
onboarding.append('activities', {
|
onboarding.append('activities', {
|
||||||
'activity_name': 'Assign a laptop',
|
'activity_name': 'Assign a laptop',
|
||||||
'role': 'HR User'
|
'role': 'HR User',
|
||||||
|
'begin_on': 1,
|
||||||
|
'duration': 1
|
||||||
})
|
})
|
||||||
onboarding.status = 'Pending'
|
onboarding.status = 'Pending'
|
||||||
onboarding.insert()
|
onboarding.insert()
|
||||||
|
|||||||
@ -82,7 +82,7 @@ def get_vehicle(employee_id):
|
|||||||
"vehicle_value": flt(500000)
|
"vehicle_value": flt(500000)
|
||||||
})
|
})
|
||||||
try:
|
try:
|
||||||
vehicle.insert()
|
vehicle.insert(ignore_if_duplicate=True)
|
||||||
except frappe.DuplicateEntryError:
|
except frappe.DuplicateEntryError:
|
||||||
pass
|
pass
|
||||||
return license_plate
|
return license_plate
|
||||||
|
|||||||
@ -14,11 +14,15 @@
|
|||||||
"applicant",
|
"applicant",
|
||||||
"section_break_7",
|
"section_break_7",
|
||||||
"disbursement_date",
|
"disbursement_date",
|
||||||
|
"clearance_date",
|
||||||
"column_break_8",
|
"column_break_8",
|
||||||
"disbursed_amount",
|
"disbursed_amount",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"customer_details_section",
|
"accounting_details",
|
||||||
|
"disbursement_account",
|
||||||
|
"column_break_16",
|
||||||
|
"loan_account",
|
||||||
"bank_account",
|
"bank_account",
|
||||||
"disbursement_references_section",
|
"disbursement_references_section",
|
||||||
"reference_date",
|
"reference_date",
|
||||||
@ -106,11 +110,6 @@
|
|||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Disbursement Details"
|
"label": "Disbursement Details"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "customer_details_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Customer Details"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fetch_from": "against_loan.applicant_type",
|
"fetch_from": "against_loan.applicant_type",
|
||||||
"fieldname": "applicant_type",
|
"fieldname": "applicant_type",
|
||||||
@ -149,15 +148,48 @@
|
|||||||
"fieldname": "reference_number",
|
"fieldname": "reference_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Reference Number"
|
"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,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-04-19 18:09:32.175355",
|
"modified": "2022-02-17 18:23:44.157598",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Disbursement",
|
"name": "Loan Disbursement",
|
||||||
|
"naming_rule": "Expression (old style)",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
@ -194,5 +226,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@ -42,9 +42,6 @@ class LoanDisbursement(AccountsController):
|
|||||||
if not self.posting_date:
|
if not self.posting_date:
|
||||||
self.posting_date = self.disbursement_date or nowdate()
|
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):
|
def validate_disbursal_amount(self):
|
||||||
possible_disbursal_amount = get_disbursal_amount(self.against_loan)
|
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):
|
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||||
gle_map = []
|
gle_map = []
|
||||||
loan_details = frappe.get_doc("Loan", self.against_loan)
|
|
||||||
|
|
||||||
gle_map.append(
|
gle_map.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": loan_details.loan_account,
|
"account": self.loan_account,
|
||||||
"against": loan_details.disbursement_account,
|
"against": self.disbursement_account,
|
||||||
"debit": self.disbursed_amount,
|
"debit": self.disbursed_amount,
|
||||||
"debit_in_account_currency": self.disbursed_amount,
|
"debit_in_account_currency": self.disbursed_amount,
|
||||||
"against_voucher_type": "Loan",
|
"against_voucher_type": "Loan",
|
||||||
@ -137,8 +133,8 @@ class LoanDisbursement(AccountsController):
|
|||||||
|
|
||||||
gle_map.append(
|
gle_map.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": loan_details.disbursement_account,
|
"account": self.disbursement_account,
|
||||||
"against": loan_details.loan_account,
|
"against": self.loan_account,
|
||||||
"credit": self.disbursed_amount,
|
"credit": self.disbursed_amount,
|
||||||
"credit_in_account_currency": self.disbursed_amount,
|
"credit_in_account_currency": self.disbursed_amount,
|
||||||
"against_voucher_type": "Loan",
|
"against_voucher_type": "Loan",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"actions": [],
|
"actions": [],
|
||||||
"autoname": "LM-REP-.####",
|
"autoname": "LM-REP-.####",
|
||||||
"creation": "2019-09-03 14:44:39.977266",
|
"creation": "2022-01-25 10:30:02.767941",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
@ -13,6 +13,7 @@
|
|||||||
"column_break_3",
|
"column_break_3",
|
||||||
"company",
|
"company",
|
||||||
"posting_date",
|
"posting_date",
|
||||||
|
"clearance_date",
|
||||||
"rate_of_interest",
|
"rate_of_interest",
|
||||||
"payroll_payable_account",
|
"payroll_payable_account",
|
||||||
"is_term_loan",
|
"is_term_loan",
|
||||||
@ -37,7 +38,12 @@
|
|||||||
"total_penalty_paid",
|
"total_penalty_paid",
|
||||||
"total_interest_paid",
|
"total_interest_paid",
|
||||||
"repayment_details",
|
"repayment_details",
|
||||||
"amended_from"
|
"amended_from",
|
||||||
|
"accounting_details_section",
|
||||||
|
"payment_account",
|
||||||
|
"penalty_income_account",
|
||||||
|
"column_break_36",
|
||||||
|
"loan_account"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -260,12 +266,52 @@
|
|||||||
"fieldname": "repay_from_salary",
|
"fieldname": "repay_from_salary",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Repay From Salary"
|
"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,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2022-01-06 01:51:06.707782",
|
"modified": "2022-02-18 19:10:07.742298",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Repayment",
|
"name": "Loan Repayment",
|
||||||
|
|||||||
@ -310,7 +310,6 @@ class LoanRepayment(AccountsController):
|
|||||||
|
|
||||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||||
gle_map = []
|
gle_map = []
|
||||||
loan_details = frappe.get_doc("Loan", self.against_loan)
|
|
||||||
|
|
||||||
if self.shortfall_amount and self.amount_paid > self.shortfall_amount:
|
if self.shortfall_amount and self.amount_paid > self.shortfall_amount:
|
||||||
remarks = _("Shortfall Repayment of {0}.\nRepayment against Loan: {1}").format(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:
|
if self.repay_from_salary:
|
||||||
payment_account = self.payroll_payable_account
|
payment_account = self.payroll_payable_account
|
||||||
else:
|
else:
|
||||||
payment_account = loan_details.payment_account
|
payment_account = self.payment_account
|
||||||
|
|
||||||
if self.total_penalty_paid:
|
if self.total_penalty_paid:
|
||||||
gle_map.append(
|
gle_map.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": loan_details.loan_account,
|
"account": self.loan_account,
|
||||||
"against": loan_details.payment_account,
|
"against": payment_account,
|
||||||
"debit": self.total_penalty_paid,
|
"debit": self.total_penalty_paid,
|
||||||
"debit_in_account_currency": self.total_penalty_paid,
|
"debit_in_account_currency": self.total_penalty_paid,
|
||||||
"against_voucher_type": "Loan",
|
"against_voucher_type": "Loan",
|
||||||
@ -344,8 +343,8 @@ class LoanRepayment(AccountsController):
|
|||||||
|
|
||||||
gle_map.append(
|
gle_map.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": loan_details.penalty_income_account,
|
"account": self.penalty_income_account,
|
||||||
"against": loan_details.loan_account,
|
"against": self.loan_account,
|
||||||
"credit": self.total_penalty_paid,
|
"credit": self.total_penalty_paid,
|
||||||
"credit_in_account_currency": self.total_penalty_paid,
|
"credit_in_account_currency": self.total_penalty_paid,
|
||||||
"against_voucher_type": "Loan",
|
"against_voucher_type": "Loan",
|
||||||
@ -359,8 +358,7 @@ class LoanRepayment(AccountsController):
|
|||||||
gle_map.append(
|
gle_map.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": payment_account,
|
"account": payment_account,
|
||||||
"against": loan_details.loan_account + ", " + loan_details.interest_income_account
|
"against": self.loan_account + ", " + self.penalty_income_account,
|
||||||
+ ", " + loan_details.penalty_income_account,
|
|
||||||
"debit": self.amount_paid,
|
"debit": self.amount_paid,
|
||||||
"debit_in_account_currency": self.amount_paid,
|
"debit_in_account_currency": self.amount_paid,
|
||||||
"against_voucher_type": "Loan",
|
"against_voucher_type": "Loan",
|
||||||
@ -368,16 +366,16 @@ class LoanRepayment(AccountsController):
|
|||||||
"remarks": remarks,
|
"remarks": remarks,
|
||||||
"cost_center": self.cost_center,
|
"cost_center": self.cost_center,
|
||||||
"posting_date": getdate(self.posting_date),
|
"posting_date": getdate(self.posting_date),
|
||||||
"party_type": loan_details.applicant_type if self.repay_from_salary else '',
|
"party_type": self.applicant_type if self.repay_from_salary else '',
|
||||||
"party": loan_details.applicant if self.repay_from_salary else ''
|
"party": self.applicant if self.repay_from_salary else ''
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
gle_map.append(
|
gle_map.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": loan_details.loan_account,
|
"account": self.loan_account,
|
||||||
"party_type": loan_details.applicant_type,
|
"party_type": self.applicant_type,
|
||||||
"party": loan_details.applicant,
|
"party": self.applicant,
|
||||||
"against": payment_account,
|
"against": payment_account,
|
||||||
"credit": self.amount_paid,
|
"credit": self.amount_paid,
|
||||||
"credit_in_account_currency": self.amount_paid,
|
"credit_in_account_currency": self.amount_paid,
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import add_months, today
|
from frappe.utils import add_months, today
|
||||||
|
|
||||||
from erpnext import get_company_currency
|
from erpnext import get_company_currency
|
||||||
from erpnext.tests.utils import ERPNextTestCase
|
|
||||||
|
|
||||||
from .blanket_order import make_order
|
from .blanket_order import make_order
|
||||||
|
|
||||||
|
|
||||||
class TestBlanketOrder(ERPNextTestCase):
|
class TestBlanketOrder(FrappeTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
frappe.flags.args = frappe._dict()
|
frappe.flags.args = frappe._dict()
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ from functools import partial
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.test_runner import make_test_records
|
from frappe.test_runner import make_test_records
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import cstr, flt
|
from frappe.utils import cstr, flt
|
||||||
|
|
||||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
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,
|
create_stock_reconciliation,
|
||||||
)
|
)
|
||||||
from erpnext.tests.test_subcontracting import set_backflush_based_on
|
from erpnext.tests.test_subcontracting import set_backflush_based_on
|
||||||
from erpnext.tests.utils import ERPNextTestCase
|
|
||||||
|
|
||||||
test_records = frappe.get_test_records('BOM')
|
test_records = frappe.get_test_records('BOM')
|
||||||
|
|
||||||
class TestBOM(ERPNextTestCase):
|
class TestBOM(FrappeTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
if not frappe.get_value('Item', '_Test Item'):
|
if not frappe.get_value('Item', '_Test Item'):
|
||||||
make_test_records('Item')
|
make_test_records('Item')
|
||||||
|
|||||||
@ -2,15 +2,15 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
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.bom_update_tool.bom_update_tool import update_cost
|
||||||
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
|
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
from erpnext.tests.utils import ERPNextTestCase
|
|
||||||
|
|
||||||
test_records = frappe.get_test_records('BOM')
|
test_records = frappe.get_test_records('BOM')
|
||||||
|
|
||||||
class TestBOMUpdateTool(ERPNextTestCase):
|
class TestBOMUpdateTool(FrappeTestCase):
|
||||||
def test_replace_bom(self):
|
def test_replace_bom(self):
|
||||||
current_bom = "BOM-_Test Item Home Desktop Manufactured-001"
|
current_bom = "BOM-_Test Item Home Desktop Manufactured-001"
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import random_string
|
from frappe.utils import random_string
|
||||||
|
|
||||||
from erpnext.manufacturing.doctype.job_card.job_card import OperationMismatchError, OverlapError
|
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.work_order.test_work_order import make_wo_order_test_record
|
||||||
from erpnext.manufacturing.doctype.workstation.test_workstation import make_workstation
|
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.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):
|
def setUp(self):
|
||||||
make_bom_for_jc_tests()
|
make_bom_for_jc_tests()
|
||||||
|
|
||||||
|
|||||||
@ -49,7 +49,7 @@ frappe.ui.form.on('Production Plan', {
|
|||||||
if (d.item_code) {
|
if (d.item_code) {
|
||||||
return {
|
return {
|
||||||
query: "erpnext.controllers.queries.bom",
|
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"));
|
} else frappe.msgprint(__("Please enter Item first"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import add_to_date, flt, now_datetime, nowdate
|
from frappe.utils import add_to_date, flt, now_datetime, nowdate
|
||||||
|
|
||||||
from erpnext.controllers.item_variant import create_variant
|
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_sales_orders,
|
||||||
get_warehouse_list,
|
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.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.item.test_item import create_item
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
|
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
|
||||||
create_stock_reconciliation,
|
create_stock_reconciliation,
|
||||||
)
|
)
|
||||||
from erpnext.tests.utils import ERPNextTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class TestProductionPlan(ERPNextTestCase):
|
class TestProductionPlan(FrappeTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
for item in ['Test Production Item 1', 'Subassembly Item 1',
|
||||||
'Raw Material Item 1', 'Raw Material Item 2']:
|
'Raw Material Item 1', 'Raw Material Item 2']:
|
||||||
@ -466,26 +467,29 @@ class TestProductionPlan(ERPNextTestCase):
|
|||||||
bom = make_bom(item=item, raw_materials=raw_materials)
|
bom = make_bom(item=item, raw_materials=raw_materials)
|
||||||
|
|
||||||
# Create Production Plan
|
# 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
|
# All the created Work Orders
|
||||||
wo_list = []
|
wo_list = []
|
||||||
|
|
||||||
# Create and Submit 1st Work Order for 5 qty
|
# Create and Submit 1st Work Order for 3 qty
|
||||||
create_work_order(item, pln, 5)
|
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()
|
pln.reload()
|
||||||
self.assertEqual(pln.po_items[0].ordered_qty, 5)
|
self.assertEqual(pln.po_items[0].ordered_qty, 5)
|
||||||
|
|
||||||
# Create and Submit 2nd Work Order for 3 qty
|
# Overproduction
|
||||||
create_work_order(item, pln, 3)
|
self.assertRaises(OverProductionError, create_work_order, item=item, pln=pln, qty=2)
|
||||||
pln.reload()
|
|
||||||
self.assertEqual(pln.po_items[0].ordered_qty, 8)
|
|
||||||
|
|
||||||
# Cancel 1st Work Order
|
# Cancel 1st Work Order
|
||||||
wo1 = frappe.get_doc("Work Order", wo_list[0])
|
wo1 = frappe.get_doc("Work Order", wo_list[0])
|
||||||
wo1.cancel()
|
wo1.cancel()
|
||||||
pln.reload()
|
pln.reload()
|
||||||
self.assertEqual(pln.po_items[0].ordered_qty, 3)
|
self.assertEqual(pln.po_items[0].ordered_qty, 2)
|
||||||
|
|
||||||
# Cancel 2nd Work Order
|
# Cancel 2nd Work Order
|
||||||
wo2 = frappe.get_doc("Work Order", wo_list[1])
|
wo2 = frappe.get_doc("Work Order", wo_list[1])
|
||||||
|
|||||||
@ -2,14 +2,14 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.test_runner import make_test_records
|
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.job_card.job_card import OperationSequenceError
|
||||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
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.stock.doctype.item.test_item import make_item
|
||||||
from erpnext.tests.utils import ERPNextTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class TestRouting(ERPNextTestCase):
|
class TestRouting(FrappeTestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
cls.item_code = "Test Routing Item - A"
|
cls.item_code = "Test Routing Item - A"
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe.tests.utils import FrappeTestCase, timeout
|
||||||
from frappe.utils import add_days, add_months, cint, flt, now, today
|
from frappe.utils import add_days, add_months, cint, flt, now, today
|
||||||
|
|
||||||
from erpnext.manufacturing.doctype.job_card.job_card import JobCardCancelError
|
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.stock_entry import test_stock_entry
|
||||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
from erpnext.stock.utils import get_bin
|
from erpnext.stock.utils import get_bin
|
||||||
from erpnext.tests.utils import ERPNextTestCase, timeout
|
|
||||||
|
|
||||||
|
|
||||||
class TestWorkOrder(ERPNextTestCase):
|
class TestWorkOrder(FrappeTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.warehouse = '_Test Warehouse 2 - _TC'
|
self.warehouse = '_Test Warehouse 2 - _TC'
|
||||||
self.item = '_Test Item'
|
self.item = '_Test Item'
|
||||||
|
|||||||
@ -636,6 +636,21 @@ class WorkOrder(Document):
|
|||||||
if not self.qty > 0:
|
if not self.qty > 0:
|
||||||
frappe.throw(_("Quantity to Manufacture must be greater than 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):
|
def validate_transfer_against(self):
|
||||||
if not self.docstatus == 1:
|
if not self.docstatus == 1:
|
||||||
# let user configure operations until they're ready to submit
|
# 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]
|
res = res[0]
|
||||||
if skip_bom_info: return res
|
if skip_bom_info: return res
|
||||||
|
|
||||||
filters = {"item": item, "is_default": 1}
|
filters = {"item": item, "is_default": 1, "docstatus": 1}
|
||||||
|
|
||||||
if project:
|
if project:
|
||||||
filters = {"item": item, "project": project}
|
filters = {"item": item, "project": project}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.test_runner import make_test_records
|
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.operation.test_operation import make_operation
|
||||||
from erpnext.manufacturing.doctype.routing.test_routing import create_routing, setup_bom
|
from erpnext.manufacturing.doctype.routing.test_routing import create_routing, setup_bom
|
||||||
@ -10,13 +11,12 @@ from erpnext.manufacturing.doctype.workstation.workstation import (
|
|||||||
WorkstationHolidayError,
|
WorkstationHolidayError,
|
||||||
check_if_within_operating_hours,
|
check_if_within_operating_hours,
|
||||||
)
|
)
|
||||||
from erpnext.tests.utils import ERPNextTestCase
|
|
||||||
|
|
||||||
test_dependencies = ["Warehouse"]
|
test_dependencies = ["Warehouse"]
|
||||||
test_records = frappe.get_test_records('Workstation')
|
test_records = frappe.get_test_records('Workstation')
|
||||||
make_test_records('Workstation')
|
make_test_records('Workstation')
|
||||||
|
|
||||||
class TestWorkstation(ERPNextTestCase):
|
class TestWorkstation(FrappeTestCase):
|
||||||
def test_validate_timings(self):
|
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 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")
|
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):
|
def test_execute_all_manufacturing_reports(self):
|
||||||
"""Test that all script report in manufacturing modules are executable with supported filters"""
|
"""Test that all script report in manufacturing modules are executable with supported filters"""
|
||||||
for report, filter in REPORT_FILTER_TEST_CASES:
|
for report, filter in REPORT_FILTER_TEST_CASES:
|
||||||
execute_script_report(
|
with self.subTest(report=report):
|
||||||
report_name=report,
|
execute_script_report(
|
||||||
module="Manufacturing",
|
report_name=report,
|
||||||
filters=filter,
|
module="Manufacturing",
|
||||||
default_filters=DEFAULT_FILTERS,
|
filters=filter,
|
||||||
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
|
default_filters=DEFAULT_FILTERS,
|
||||||
)
|
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
|
||||||
|
)
|
||||||
|
|||||||
@ -15,7 +15,6 @@ Maintenance
|
|||||||
Education
|
Education
|
||||||
Regional
|
Regional
|
||||||
ERPNext Integrations
|
ERPNext Integrations
|
||||||
Non Profit
|
|
||||||
Quality Management
|
Quality Management
|
||||||
Communication
|
Communication
|
||||||
Loan Management
|
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)
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
frappe.listview_settings['Donor'] = {
|
|
||||||
add_fields: ["donor_name", "donor_type", "image"],
|
|
||||||
};
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# See license.txt
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
|
|
||||||
class TestDonor(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user