Merge branch 'develop' into whitelist-query
This commit is contained in:
commit
7860d9e699
File diff suppressed because it is too large
Load Diff
@ -388,7 +388,7 @@ def set_taxes(party, party_type, posting_date, company, customer_group=None, sup
|
|||||||
from erpnext.accounts.doctype.tax_rule.tax_rule import get_tax_template, get_party_details
|
from erpnext.accounts.doctype.tax_rule.tax_rule import get_tax_template, get_party_details
|
||||||
args = {
|
args = {
|
||||||
party_type.lower(): party,
|
party_type.lower(): party,
|
||||||
"company": company
|
"company": company
|
||||||
}
|
}
|
||||||
|
|
||||||
if tax_category:
|
if tax_category:
|
||||||
|
@ -133,7 +133,7 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
|
|||||||
acc = frappe.get_doc("Account", account)
|
acc = frappe.get_doc("Account", account)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
year_start_date = get_fiscal_year(date, verbose=0)[1]
|
year_start_date = get_fiscal_year(date, company=company, verbose=0)[1]
|
||||||
except FiscalYearError:
|
except FiscalYearError:
|
||||||
if getdate(date) > getdate(nowdate()):
|
if getdate(date) > getdate(nowdate()):
|
||||||
# if fiscal year not found and the date is greater than today
|
# if fiscal year not found and the date is greater than today
|
||||||
@ -787,10 +787,10 @@ def get_children(doctype, parent, company, is_root=False):
|
|||||||
company_currency = frappe.get_cached_value('Company', company, "default_currency")
|
company_currency = frappe.get_cached_value('Company', company, "default_currency")
|
||||||
for each in acc:
|
for each in acc:
|
||||||
each["company_currency"] = company_currency
|
each["company_currency"] = company_currency
|
||||||
each["balance"] = flt(get_balance_on(each.get("value"), in_account_currency=False))
|
each["balance"] = flt(get_balance_on(each.get("value"), in_account_currency=False, company=company))
|
||||||
|
|
||||||
if each.account_currency != company_currency:
|
if each.account_currency != company_currency:
|
||||||
each["balance_in_account_currency"] = flt(get_balance_on(each.get("value")))
|
each["balance_in_account_currency"] = flt(get_balance_on(each.get("value"), company=company))
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
|
|
||||||
|
@ -35,11 +35,9 @@ class Asset(AccountsController):
|
|||||||
if not self.booked_fixed_asset and self.validate_make_gl_entry():
|
if not self.booked_fixed_asset and self.validate_make_gl_entry():
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
|
||||||
def before_cancel(self):
|
|
||||||
self.cancel_auto_gen_movement()
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.validate_cancellation()
|
self.validate_cancellation()
|
||||||
|
self.cancel_movement_entries()
|
||||||
self.delete_depreciation_entries()
|
self.delete_depreciation_entries()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry')
|
self.ignore_linked_doctypes = ('GL Entry', 'Stock Ledger Entry')
|
||||||
@ -134,19 +132,6 @@ class Asset(AccountsController):
|
|||||||
Please do not book expense of multiple assets against one single Asset.")
|
Please do not book expense of multiple assets against one single Asset.")
|
||||||
.format(frappe.bold("equal"), "<br>"), title=_("Invalid Gross Purchase Amount"))
|
.format(frappe.bold("equal"), "<br>"), title=_("Invalid Gross Purchase Amount"))
|
||||||
|
|
||||||
def cancel_auto_gen_movement(self):
|
|
||||||
movements = frappe.db.sql(
|
|
||||||
"""SELECT asm.name, asm.docstatus
|
|
||||||
FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
|
|
||||||
WHERE asm_item.parent=asm.name and asm_item.asset=%s and asm.docstatus=1""", self.name, as_dict=1)
|
|
||||||
if len(movements) > 1:
|
|
||||||
frappe.throw(_('Asset has multiple Asset Movement Entries which has to be \
|
|
||||||
cancelled manually to cancel this asset.'))
|
|
||||||
if movements:
|
|
||||||
movement = frappe.get_doc('Asset Movement', movements[0].get('name'))
|
|
||||||
movement.flags.ignore_validate = True
|
|
||||||
movement.cancel()
|
|
||||||
|
|
||||||
def make_asset_movement(self):
|
def make_asset_movement(self):
|
||||||
reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
|
reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
|
||||||
reference_docname = self.purchase_receipt or self.purchase_invoice
|
reference_docname = self.purchase_receipt or self.purchase_invoice
|
||||||
@ -413,6 +398,16 @@ class Asset(AccountsController):
|
|||||||
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
|
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
|
||||||
frappe.throw(_("Asset cannot be cancelled, as it is already {0}").format(self.status))
|
frappe.throw(_("Asset cannot be cancelled, as it is already {0}").format(self.status))
|
||||||
|
|
||||||
|
def cancel_movement_entries(self):
|
||||||
|
movements = frappe.db.sql(
|
||||||
|
"""SELECT asm.name, asm.docstatus
|
||||||
|
FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
|
||||||
|
WHERE asm_item.parent=asm.name and asm_item.asset=%s and asm.docstatus=1""", self.name, as_dict=1)
|
||||||
|
|
||||||
|
for movement in movements:
|
||||||
|
movement = frappe.get_doc('Asset Movement', movement.get('name'))
|
||||||
|
movement.cancel()
|
||||||
|
|
||||||
def delete_depreciation_entries(self):
|
def delete_depreciation_entries(self):
|
||||||
for d in self.get("schedules"):
|
for d in self.get("schedules"):
|
||||||
if d.journal_entry:
|
if d.journal_entry:
|
||||||
|
@ -87,33 +87,9 @@ class AssetMovement(Document):
|
|||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.set_latest_location_in_asset()
|
self.set_latest_location_in_asset()
|
||||||
|
|
||||||
def before_cancel(self):
|
|
||||||
self.validate_last_movement()
|
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.set_latest_location_in_asset()
|
self.set_latest_location_in_asset()
|
||||||
|
|
||||||
def validate_last_movement(self):
|
|
||||||
for d in self.assets:
|
|
||||||
auto_gen_movement_entry = frappe.db.sql(
|
|
||||||
"""
|
|
||||||
SELECT asm.name
|
|
||||||
FROM `tabAsset Movement Item` asm_item, `tabAsset Movement` asm
|
|
||||||
WHERE
|
|
||||||
asm.docstatus=1 and
|
|
||||||
asm_item.parent=asm.name and
|
|
||||||
asm_item.asset=%s and
|
|
||||||
asm.company=%s and
|
|
||||||
asm_item.source_location is NULL and
|
|
||||||
asm.purpose=%s
|
|
||||||
ORDER BY
|
|
||||||
asm.transaction_date asc
|
|
||||||
""", (d.asset, self.company, 'Receipt'), as_dict=1)
|
|
||||||
|
|
||||||
if auto_gen_movement_entry and auto_gen_movement_entry[0].get('name') == self.name:
|
|
||||||
frappe.throw(_('{0} will be cancelled automatically on asset cancellation as it was \
|
|
||||||
auto generated for Asset {1}').format(self.name, d.asset))
|
|
||||||
|
|
||||||
def set_latest_location_in_asset(self):
|
def set_latest_location_in_asset(self):
|
||||||
current_location, current_employee = '', ''
|
current_location, current_employee = '', ''
|
||||||
|
@ -13,7 +13,7 @@ source_link = "https://github.com/frappe/erpnext"
|
|||||||
app_logo_url = '/assets/erpnext/images/erp-icon.svg'
|
app_logo_url = '/assets/erpnext/images/erp-icon.svg'
|
||||||
|
|
||||||
|
|
||||||
develop_version = '12.x.x-develop'
|
develop_version = '13.x.x-develop'
|
||||||
|
|
||||||
app_include_js = "assets/js/erpnext.min.js"
|
app_include_js = "assets/js/erpnext.min.js"
|
||||||
app_include_css = "assets/css/erpnext.css"
|
app_include_css = "assets/css/erpnext.css"
|
||||||
|
@ -45,15 +45,6 @@ frappe.ui.form.on('Loan', {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
frm.set_query('loan_security_pledge', function(doc, cdt, cdn) {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
applicant: frm.doc.applicant,
|
|
||||||
docstatus: 1,
|
|
||||||
loan_application: frm.doc.loan_application || ''
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
@ -86,9 +77,6 @@ frappe.ui.form.on('Loan', {
|
|||||||
frm.toggle_display("repayment_periods", s1 - frm.doc.is_term_loan);
|
frm.toggle_display("repayment_periods", s1 - frm.doc.is_term_loan);
|
||||||
},
|
},
|
||||||
|
|
||||||
is_secured_loan: function(frm) {
|
|
||||||
frm.toggle_reqd("loan_security_pledge", frm.doc.is_secured_loan);
|
|
||||||
},
|
|
||||||
|
|
||||||
make_loan_disbursement: function (frm) {
|
make_loan_disbursement: function (frm) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
@ -25,15 +25,12 @@
|
|||||||
"disbursement_date",
|
"disbursement_date",
|
||||||
"disbursed_amount",
|
"disbursed_amount",
|
||||||
"column_break_11",
|
"column_break_11",
|
||||||
|
"maximum_loan_amount",
|
||||||
"is_term_loan",
|
"is_term_loan",
|
||||||
"repayment_method",
|
"repayment_method",
|
||||||
"repayment_periods",
|
"repayment_periods",
|
||||||
"monthly_repayment_amount",
|
"monthly_repayment_amount",
|
||||||
"repayment_start_date",
|
"repayment_start_date",
|
||||||
"loan_security_details_section",
|
|
||||||
"loan_security_pledge",
|
|
||||||
"column_break_25",
|
|
||||||
"maximum_loan_value",
|
|
||||||
"account_info",
|
"account_info",
|
||||||
"mode_of_payment",
|
"mode_of_payment",
|
||||||
"payment_account",
|
"payment_account",
|
||||||
@ -292,13 +289,8 @@
|
|||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "is_secured_loan",
|
"fieldname": "is_secured_loan",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Secured Loan"
|
"label": "Is Secured Loan",
|
||||||
},
|
"read_only": 1
|
||||||
{
|
|
||||||
"depends_on": "is_secured_loan",
|
|
||||||
"fieldname": "loan_security_details_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Loan Security Details"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@ -324,12 +316,6 @@
|
|||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "loan_security_pledge",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Loan Security Pledge",
|
|
||||||
"options": "Loan Security Pledge"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "disbursed_amount",
|
"fieldname": "disbursed_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@ -338,21 +324,17 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "loan_security_pledge.maximum_loan_value",
|
"fetch_from": "loan_application.maximum_loan_amount",
|
||||||
"fieldname": "maximum_loan_value",
|
"fieldname": "maximum_loan_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Maximum Loan Value",
|
"label": "Maximum Loan Amount",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_25",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-13 13:16:10.192624",
|
"modified": "2020-07-02 20:46:40.128142",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan",
|
"name": "Loan",
|
||||||
|
@ -13,11 +13,9 @@ from erpnext.controllers.accounts_controller import AccountsController
|
|||||||
class Loan(AccountsController):
|
class Loan(AccountsController):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.set_loan_amount()
|
self.set_loan_amount()
|
||||||
|
self.validate_loan_amount()
|
||||||
self.set_missing_fields()
|
self.set_missing_fields()
|
||||||
self.validate_accounts()
|
self.validate_accounts()
|
||||||
self.validate_loan_security_pledge()
|
|
||||||
self.validate_loan_amount()
|
|
||||||
self.check_sanctioned_amount_limit()
|
self.check_sanctioned_amount_limit()
|
||||||
self.validate_repay_from_salary()
|
self.validate_repay_from_salary()
|
||||||
|
|
||||||
@ -56,21 +54,6 @@ class Loan(AccountsController):
|
|||||||
if self.repayment_method == "Repay Over Number of Periods":
|
if self.repayment_method == "Repay Over Number of Periods":
|
||||||
self.monthly_repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
|
self.monthly_repayment_amount = get_monthly_repayment_amount(self.repayment_method, self.loan_amount, self.rate_of_interest, self.repayment_periods)
|
||||||
|
|
||||||
def validate_loan_security_pledge(self):
|
|
||||||
|
|
||||||
if self.is_secured_loan and not self.loan_security_pledge:
|
|
||||||
frappe.throw(_("Loan Security Pledge is mandatory for secured loan"))
|
|
||||||
|
|
||||||
if self.loan_security_pledge:
|
|
||||||
loan_security_details = frappe.db.get_value("Loan Security Pledge", self.loan_security_pledge,
|
|
||||||
['loan', 'company'], as_dict=1)
|
|
||||||
|
|
||||||
if loan_security_details.loan:
|
|
||||||
frappe.throw(_("Loan Security Pledge already pledged against loan {0}").format(loan_security_details.loan))
|
|
||||||
|
|
||||||
if loan_security_details.company != self.company:
|
|
||||||
frappe.throw(_("Loan Security Pledge Company and Loan Company must be same"))
|
|
||||||
|
|
||||||
def check_sanctioned_amount_limit(self):
|
def check_sanctioned_amount_limit(self):
|
||||||
total_loan_amount = get_total_loan_amount(self.applicant_type, self.applicant, self.company)
|
total_loan_amount = get_total_loan_amount(self.applicant_type, self.applicant, self.company)
|
||||||
sanctioned_amount_limit = get_sanctioned_amount_limit(self.applicant_type, self.applicant, self.company)
|
sanctioned_amount_limit = get_sanctioned_amount_limit(self.applicant_type, self.applicant, self.company)
|
||||||
@ -129,22 +112,29 @@ class Loan(AccountsController):
|
|||||||
self.total_payment = self.loan_amount
|
self.total_payment = self.loan_amount
|
||||||
|
|
||||||
def set_loan_amount(self):
|
def set_loan_amount(self):
|
||||||
|
if self.loan_application and not self.loan_amount:
|
||||||
|
self.loan_amount = frappe.db.get_value('Loan Application', self.loan_application, 'loan_amount')
|
||||||
|
|
||||||
if not self.loan_amount and self.is_secured_loan and self.loan_security_pledge:
|
|
||||||
self.loan_amount = self.maximum_loan_value
|
|
||||||
|
|
||||||
def validate_loan_amount(self):
|
def validate_loan_amount(self):
|
||||||
if self.is_secured_loan and self.loan_amount > self.maximum_loan_value:
|
if self.maximum_loan_amount and self.loan_amount > self.maximum_loan_amount:
|
||||||
msg = _("Loan amount cannot be greater than {0}").format(self.maximum_loan_value)
|
msg = _("Loan amount cannot be greater than {0}").format(self.maximum_loan_amount)
|
||||||
frappe.throw(msg)
|
frappe.throw(msg)
|
||||||
|
|
||||||
if not self.loan_amount:
|
if not self.loan_amount:
|
||||||
frappe.throw(_("Loan amount is mandatory"))
|
frappe.throw(_("Loan amount is mandatory"))
|
||||||
|
|
||||||
def link_loan_security_pledge(self):
|
def link_loan_security_pledge(self):
|
||||||
frappe.db.sql("""UPDATE `tabLoan Security Pledge` SET
|
if self.is_secured_loan:
|
||||||
loan = %s, status = 'Pledged', pledge_time = %s
|
loan_security_pledge = frappe.db.get_value('Loan Security Pledge', {'loan_application': self.loan_application},
|
||||||
where name = %s """, (self.name, now_datetime(), self.loan_security_pledge))
|
'name')
|
||||||
|
|
||||||
|
if loan_security_pledge:
|
||||||
|
frappe.db.set_value('Loan Security Pledge', loan_security_pledge, {
|
||||||
|
'loan': self.name,
|
||||||
|
'status': 'Pledged',
|
||||||
|
'pledge_time': now_datetime()
|
||||||
|
})
|
||||||
|
|
||||||
def unlink_loan_security_pledge(self):
|
def unlink_loan_security_pledge(self):
|
||||||
frappe.db.sql("""UPDATE `tabLoan Security Pledge` SET
|
frappe.db.sql("""UPDATE `tabLoan Security Pledge` SET
|
||||||
|
@ -16,6 +16,7 @@ from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual
|
|||||||
from erpnext.loan_management.doctype.process_loan_security_shortfall.process_loan_security_shortfall import create_process_loan_security_shortfall
|
from erpnext.loan_management.doctype.process_loan_security_shortfall.process_loan_security_shortfall import create_process_loan_security_shortfall
|
||||||
from erpnext.loan_management.doctype.loan.loan import create_loan_security_unpledge
|
from erpnext.loan_management.doctype.loan.loan import create_loan_security_unpledge
|
||||||
from erpnext.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import get_pledged_security_qty
|
from erpnext.loan_management.doctype.loan_security_unpledge.loan_security_unpledge import get_pledged_security_qty
|
||||||
|
from erpnext.loan_management.doctype.loan_application.loan_application import create_pledge
|
||||||
|
|
||||||
class TestLoan(unittest.TestCase):
|
class TestLoan(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -72,31 +73,31 @@ class TestLoan(unittest.TestCase):
|
|||||||
self.assertEquals(loan.total_payment, 302712)
|
self.assertEquals(loan.total_payment, 302712)
|
||||||
|
|
||||||
def test_loan_with_security(self):
|
def test_loan_with_security(self):
|
||||||
pledges = []
|
|
||||||
pledges.append({
|
pledge = [{
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00,
|
||||||
"haircut": 50,
|
}]
|
||||||
"loan_security_price": 500.00
|
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant2,
|
||||||
|
'Stock Loan', pledge, "Repay Over Number of Periods", 12)
|
||||||
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_security_pledge.name)
|
create_pledge(loan_application)
|
||||||
|
|
||||||
|
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods",
|
||||||
|
12, loan_application)
|
||||||
self.assertEquals(loan.loan_amount, 1000000)
|
self.assertEquals(loan.loan_amount, 1000000)
|
||||||
|
|
||||||
def test_loan_disbursement(self):
|
def test_loan_disbursement(self):
|
||||||
pledges = []
|
pledge = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00
|
||||||
"haircut": 50
|
}]
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant2, 'Stock Loan', pledge, "Repay Over Number of Periods", 12)
|
||||||
|
|
||||||
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_security_pledge.name)
|
create_pledge(loan_application)
|
||||||
|
|
||||||
|
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application)
|
||||||
self.assertEquals(loan.loan_amount, 1000000)
|
self.assertEquals(loan.loan_amount, 1000000)
|
||||||
|
|
||||||
loan.submit()
|
loan.submit()
|
||||||
@ -121,18 +122,15 @@ class TestLoan(unittest.TestCase):
|
|||||||
self.assertTrue(gl_entries2)
|
self.assertTrue(gl_entries2)
|
||||||
|
|
||||||
def test_regular_loan_repayment(self):
|
def test_regular_loan_repayment(self):
|
||||||
pledges = []
|
pledge = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00
|
||||||
"haircut": 50
|
}]
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant2, 'Demand Loan', pledge)
|
||||||
|
create_pledge(loan_application)
|
||||||
loan = create_demand_loan(self.applicant2, "Demand Loan", loan_security_pledge.name,
|
|
||||||
posting_date=get_first_day(nowdate()))
|
|
||||||
|
|
||||||
|
loan = create_demand_loan(self.applicant2, "Demand Loan", loan_application, posting_date=get_first_day(nowdate()))
|
||||||
loan.submit()
|
loan.submit()
|
||||||
|
|
||||||
self.assertEquals(loan.loan_amount, 1000000)
|
self.assertEquals(loan.loan_amount, 1000000)
|
||||||
@ -166,16 +164,15 @@ class TestLoan(unittest.TestCase):
|
|||||||
penalty_amount - amounts[0], 2))
|
penalty_amount - amounts[0], 2))
|
||||||
|
|
||||||
def test_loan_closure_repayment(self):
|
def test_loan_closure_repayment(self):
|
||||||
pledges = []
|
pledge = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00
|
||||||
"haircut": 50
|
}]
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant2, 'Demand Loan', pledge)
|
||||||
loan = create_demand_loan(self.applicant2, "Demand Loan", loan_security_pledge.name,
|
create_pledge(loan_application)
|
||||||
posting_date=get_first_day(nowdate()))
|
|
||||||
|
loan = create_demand_loan(self.applicant2, "Demand Loan", loan_application, posting_date=get_first_day(nowdate()))
|
||||||
loan.submit()
|
loan.submit()
|
||||||
|
|
||||||
self.assertEquals(loan.loan_amount, 1000000)
|
self.assertEquals(loan.loan_amount, 1000000)
|
||||||
@ -214,23 +211,21 @@ class TestLoan(unittest.TestCase):
|
|||||||
self.assertEquals(loan.status, "Loan Closure Requested")
|
self.assertEquals(loan.status, "Loan Closure Requested")
|
||||||
|
|
||||||
def test_loan_repayment_for_term_loan(self):
|
def test_loan_repayment_for_term_loan(self):
|
||||||
pledges = []
|
pledges = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 2",
|
"loan_security": "Test Security 2",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00
|
||||||
"haircut": 50
|
},
|
||||||
})
|
{
|
||||||
|
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 2000.00,
|
"qty": 2000.00
|
||||||
"haircut": 50
|
}]
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant2, 'Stock Loan', pledges,
|
||||||
|
"Repay Over Number of Periods", 12)
|
||||||
|
create_pledge(loan_application)
|
||||||
|
|
||||||
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12,
|
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application,
|
||||||
loan_security_pledge.name, posting_date=add_months(nowdate(), -1))
|
posting_date=add_months(nowdate(), -1))
|
||||||
|
|
||||||
loan.submit()
|
loan.submit()
|
||||||
|
|
||||||
@ -250,16 +245,18 @@ class TestLoan(unittest.TestCase):
|
|||||||
self.assertEquals(amounts[1], 78303.00)
|
self.assertEquals(amounts[1], 78303.00)
|
||||||
|
|
||||||
def test_security_shortfall(self):
|
def test_security_shortfall(self):
|
||||||
pledges = []
|
pledges = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 2",
|
"loan_security": "Test Security 2",
|
||||||
"qty": 8000.00,
|
"qty": 8000.00,
|
||||||
"haircut": 50,
|
"haircut": 50,
|
||||||
})
|
}]
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant2,
|
||||||
|
'Stock Loan', pledges, "Repay Over Number of Periods", 12)
|
||||||
|
|
||||||
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_security_pledge.name)
|
create_pledge(loan_application)
|
||||||
|
|
||||||
|
loan = create_loan_with_security(self.applicant2, "Stock Loan", "Repay Over Number of Periods", 12, loan_application)
|
||||||
loan.submit()
|
loan.submit()
|
||||||
|
|
||||||
make_loan_disbursement_entry(loan.name, loan.loan_amount)
|
make_loan_disbursement_entry(loan.name, loan.loan_amount)
|
||||||
@ -279,16 +276,15 @@ class TestLoan(unittest.TestCase):
|
|||||||
where loan_security='Test Security 2'""")
|
where loan_security='Test Security 2'""")
|
||||||
|
|
||||||
def test_loan_security_unpledge(self):
|
def test_loan_security_unpledge(self):
|
||||||
pledges = []
|
pledge = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00
|
||||||
"haircut": 50
|
}]
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant2, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant2, 'Demand Loan', pledge)
|
||||||
loan = create_demand_loan(self.applicant2, "Demand Loan", loan_security_pledge.name,
|
create_pledge(loan_application)
|
||||||
posting_date=get_first_day(nowdate()))
|
|
||||||
|
loan = create_demand_loan(self.applicant2, "Demand Loan", loan_application, posting_date=get_first_day(nowdate()))
|
||||||
loan.submit()
|
loan.submit()
|
||||||
|
|
||||||
self.assertEquals(loan.loan_amount, 1000000)
|
self.assertEquals(loan.loan_amount, 1000000)
|
||||||
@ -446,12 +442,13 @@ def create_loan_security():
|
|||||||
"haircut": 50.00,
|
"haircut": 50.00,
|
||||||
}).insert(ignore_permissions=True)
|
}).insert(ignore_permissions=True)
|
||||||
|
|
||||||
def create_loan_security_pledge(applicant, pledges):
|
def create_loan_security_pledge(applicant, pledges, loan_application):
|
||||||
|
|
||||||
lsp = frappe.new_doc("Loan Security Pledge")
|
lsp = frappe.new_doc("Loan Security Pledge")
|
||||||
lsp.applicant_type = 'Customer'
|
lsp.applicant_type = 'Customer'
|
||||||
lsp.applicant = applicant
|
lsp.applicant = applicant
|
||||||
lsp.company = "_Test Company"
|
lsp.company = "_Test Company"
|
||||||
|
lsp.loan_application = loan_application
|
||||||
|
|
||||||
for pledge in pledges:
|
for pledge in pledges:
|
||||||
lsp.append('securities', {
|
lsp.append('securities', {
|
||||||
@ -510,6 +507,31 @@ def create_repayment_entry(loan, applicant, posting_date, payment_type, paid_amo
|
|||||||
|
|
||||||
return lr
|
return lr
|
||||||
|
|
||||||
|
def create_loan_application(company, applicant, loan_type, proposed_pledges, repayment_method=None,
|
||||||
|
repayment_periods=None, posting_date=None):
|
||||||
|
loan_application = frappe.new_doc('Loan Application')
|
||||||
|
loan_application.applicant_type = 'Customer'
|
||||||
|
loan_application.company = company
|
||||||
|
loan_application.applicant = applicant
|
||||||
|
loan_application.loan_type = loan_type
|
||||||
|
loan_application.posting_date = posting_date or nowdate()
|
||||||
|
loan_application.is_secured_loan = 1
|
||||||
|
|
||||||
|
if repayment_method:
|
||||||
|
loan_application.repayment_method = repayment_method
|
||||||
|
loan_application.repayment_periods = repayment_periods
|
||||||
|
|
||||||
|
for pledge in proposed_pledges:
|
||||||
|
loan_application.append('proposed_pledges', pledge)
|
||||||
|
|
||||||
|
loan_application.save()
|
||||||
|
loan_application.submit()
|
||||||
|
|
||||||
|
loan_application.status = 'Approved'
|
||||||
|
loan_application.save()
|
||||||
|
|
||||||
|
return loan_application.name
|
||||||
|
|
||||||
|
|
||||||
def create_loan(applicant, loan_type, loan_amount, repayment_method, repayment_periods,
|
def create_loan(applicant, loan_type, loan_amount, repayment_method, repayment_periods,
|
||||||
repayment_start_date=None, posting_date=None):
|
repayment_start_date=None, posting_date=None):
|
||||||
@ -531,14 +553,13 @@ def create_loan(applicant, loan_type, loan_amount, repayment_method, repayment_p
|
|||||||
loan.save()
|
loan.save()
|
||||||
return loan
|
return loan
|
||||||
|
|
||||||
def create_loan_with_security(applicant, loan_type, repayment_method, repayment_periods, loan_security_pledge,
|
def create_loan_with_security(applicant, loan_type, repayment_method, repayment_periods, loan_application, posting_date=None, repayment_start_date=None):
|
||||||
posting_date=None, repayment_start_date=None):
|
|
||||||
|
|
||||||
loan = frappe.get_doc({
|
loan = frappe.get_doc({
|
||||||
"doctype": "Loan",
|
"doctype": "Loan",
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"applicant_type": "Customer",
|
"applicant_type": "Customer",
|
||||||
"posting_date": posting_date or nowdate(),
|
"posting_date": posting_date or nowdate(),
|
||||||
|
"loan_application": loan_application,
|
||||||
"applicant": applicant,
|
"applicant": applicant,
|
||||||
"loan_type": loan_type,
|
"loan_type": loan_type,
|
||||||
"is_term_loan": 1,
|
"is_term_loan": 1,
|
||||||
@ -547,7 +568,6 @@ def create_loan_with_security(applicant, loan_type, repayment_method, repayment_
|
|||||||
"repayment_periods": repayment_periods,
|
"repayment_periods": repayment_periods,
|
||||||
"repayment_start_date": repayment_start_date or nowdate(),
|
"repayment_start_date": repayment_start_date or nowdate(),
|
||||||
"mode_of_payment": frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name'),
|
"mode_of_payment": frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name'),
|
||||||
"loan_security_pledge": loan_security_pledge,
|
|
||||||
"payment_account": 'Payment Account - _TC',
|
"payment_account": 'Payment Account - _TC',
|
||||||
"loan_account": 'Loan Account - _TC',
|
"loan_account": 'Loan Account - _TC',
|
||||||
"interest_income_account": 'Interest Income Account - _TC',
|
"interest_income_account": 'Interest Income Account - _TC',
|
||||||
@ -558,19 +578,19 @@ def create_loan_with_security(applicant, loan_type, repayment_method, repayment_
|
|||||||
|
|
||||||
return loan
|
return loan
|
||||||
|
|
||||||
def create_demand_loan(applicant, loan_type, loan_security_pledge, posting_date=None):
|
def create_demand_loan(applicant, loan_type, loan_application, posting_date=None):
|
||||||
|
|
||||||
loan = frappe.get_doc({
|
loan = frappe.get_doc({
|
||||||
"doctype": "Loan",
|
"doctype": "Loan",
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"applicant_type": "Customer",
|
"applicant_type": "Customer",
|
||||||
"posting_date": posting_date or nowdate(),
|
"posting_date": posting_date or nowdate(),
|
||||||
|
'loan_application': loan_application,
|
||||||
"applicant": applicant,
|
"applicant": applicant,
|
||||||
"loan_type": loan_type,
|
"loan_type": loan_type,
|
||||||
"is_term_loan": 0,
|
"is_term_loan": 0,
|
||||||
"is_secured_loan": 1,
|
"is_secured_loan": 1,
|
||||||
"mode_of_payment": frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name'),
|
"mode_of_payment": frappe.db.get_value('Mode of Payment', {'type': 'Cash'}, 'name'),
|
||||||
"loan_security_pledge": loan_security_pledge,
|
|
||||||
"payment_account": 'Payment Account - _TC',
|
"payment_account": 'Payment Account - _TC',
|
||||||
"loan_account": 'Loan Account - _TC',
|
"loan_account": 'Loan Account - _TC',
|
||||||
"interest_income_account": 'Interest Income Account - _TC',
|
"interest_income_account": 'Interest Income Account - _TC',
|
||||||
|
@ -103,10 +103,13 @@ class LoanApplication(Document):
|
|||||||
if self.is_secured_loan and not self.proposed_pledges:
|
if self.is_secured_loan and not self.proposed_pledges:
|
||||||
frappe.throw(_("Proposed Pledges are mandatory for secured Loans"))
|
frappe.throw(_("Proposed Pledges are mandatory for secured Loans"))
|
||||||
|
|
||||||
if not self.loan_amount and self.is_secured_loan and self.proposed_pledges:
|
if self.is_secured_loan and self.proposed_pledges:
|
||||||
self.loan_amount = 0
|
self.maximum_loan_amount = 0
|
||||||
for security in self.proposed_pledges:
|
for security in self.proposed_pledges:
|
||||||
self.loan_amount += security.post_haircut_amount
|
self.maximum_loan_amount += security.post_haircut_amount
|
||||||
|
|
||||||
|
if not self.loan_amount and self.is_secured_loan and self.proposed_pledges:
|
||||||
|
self.loan_amount = self.maximum_loan_amount
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_loan(source_name, target_doc=None, submit=0):
|
def create_loan(source_name, target_doc=None, submit=0):
|
||||||
@ -116,7 +119,6 @@ def create_loan(source_name, target_doc=None, submit=0):
|
|||||||
filters = {'name': source_doc.loan_type}
|
filters = {'name': source_doc.loan_type}
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
loan_security_pledge = frappe.db.get_value("Loan Security Pledge", {"loan_application": source_name}, 'name')
|
|
||||||
|
|
||||||
target_doc.mode_of_payment = account_details.mode_of_payment
|
target_doc.mode_of_payment = account_details.mode_of_payment
|
||||||
target_doc.payment_account = account_details.payment_account
|
target_doc.payment_account = account_details.payment_account
|
||||||
@ -124,9 +126,6 @@ def create_loan(source_name, target_doc=None, submit=0):
|
|||||||
target_doc.interest_income_account = account_details.interest_income_account
|
target_doc.interest_income_account = account_details.interest_income_account
|
||||||
target_doc.penalty_income_account = account_details.penalty_income_account
|
target_doc.penalty_income_account = account_details.penalty_income_account
|
||||||
|
|
||||||
if loan_security_pledge:
|
|
||||||
target_doc.is_secured_loan = 1
|
|
||||||
target_doc.loan_security_pledge = loan_security_pledge
|
|
||||||
|
|
||||||
doclist = get_mapped_doc("Loan Application", source_name, {
|
doclist = get_mapped_doc("Loan Application", source_name, {
|
||||||
"Loan Application": {
|
"Loan Application": {
|
||||||
|
@ -5,11 +5,12 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_last_day, date_diff, flt, add_to_date)
|
from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_last_day, date_diff, flt, add_to_date)
|
||||||
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_repayment_entry,
|
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_repayment_entry, create_loan_application,
|
||||||
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan, create_loan_security_price)
|
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan, create_loan_security_price)
|
||||||
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
||||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
|
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
|
||||||
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
||||||
|
from erpnext.loan_management.doctype.loan_application.loan_application import create_pledge
|
||||||
|
|
||||||
class TestLoanDisbursement(unittest.TestCase):
|
class TestLoanDisbursement(unittest.TestCase):
|
||||||
|
|
||||||
@ -31,18 +32,15 @@ class TestLoanDisbursement(unittest.TestCase):
|
|||||||
self.applicant = frappe.db.get_value("Customer", {'name': '_Test Loan Customer'}, 'name')
|
self.applicant = frappe.db.get_value("Customer", {'name': '_Test Loan Customer'}, 'name')
|
||||||
|
|
||||||
def test_loan_topup(self):
|
def test_loan_topup(self):
|
||||||
pledges = []
|
pledge = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00
|
||||||
"haircut": 50,
|
}]
|
||||||
"loan_security_price": 500.00
|
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant, 'Demand Loan', pledge)
|
||||||
|
create_pledge(loan_application)
|
||||||
|
|
||||||
loan = create_demand_loan(self.applicant, "Demand Loan", loan_security_pledge.name,
|
loan = create_demand_loan(self.applicant, "Demand Loan", loan_application, posting_date=get_first_day(nowdate()))
|
||||||
posting_date=get_first_day(nowdate()))
|
|
||||||
|
|
||||||
loan.submit()
|
loan.submit()
|
||||||
|
|
||||||
|
@ -6,10 +6,11 @@ import frappe
|
|||||||
import unittest
|
import unittest
|
||||||
from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_last_day, date_diff, flt, add_to_date)
|
from frappe.utils import (nowdate, add_days, get_datetime, get_first_day, get_last_day, date_diff, flt, add_to_date)
|
||||||
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_loan_security_price,
|
from erpnext.loan_management.doctype.loan.test_loan import (create_loan_type, create_loan_security_pledge, create_loan_security_price,
|
||||||
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan)
|
make_loan_disbursement_entry, create_loan_accounts, create_loan_security_type, create_loan_security, create_demand_loan, create_loan_application)
|
||||||
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_demand_loans
|
||||||
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
|
from erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual import days_in_year
|
||||||
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
|
||||||
|
from erpnext.loan_management.doctype.loan_application.loan_application import create_pledge
|
||||||
|
|
||||||
class TestLoanInterestAccrual(unittest.TestCase):
|
class TestLoanInterestAccrual(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -29,17 +30,15 @@ class TestLoanInterestAccrual(unittest.TestCase):
|
|||||||
self.applicant = frappe.db.get_value("Customer", {'name': '_Test Loan Customer'}, 'name')
|
self.applicant = frappe.db.get_value("Customer", {'name': '_Test Loan Customer'}, 'name')
|
||||||
|
|
||||||
def test_loan_interest_accural(self):
|
def test_loan_interest_accural(self):
|
||||||
pledges = []
|
pledge = [{
|
||||||
pledges.append({
|
|
||||||
"loan_security": "Test Security 1",
|
"loan_security": "Test Security 1",
|
||||||
"qty": 4000.00,
|
"qty": 4000.00
|
||||||
"haircut": 50,
|
}]
|
||||||
"loan_security_price": 500.00
|
|
||||||
})
|
|
||||||
|
|
||||||
loan_security_pledge = create_loan_security_pledge(self.applicant, pledges)
|
loan_application = create_loan_application('_Test Company', self.applicant, 'Demand Loan', pledge)
|
||||||
|
create_pledge(loan_application)
|
||||||
|
|
||||||
loan = create_demand_loan(self.applicant, "Demand Loan", loan_security_pledge.name,
|
loan = create_demand_loan(self.applicant, "Demand Loan", loan_application,
|
||||||
posting_date=get_first_day(nowdate()))
|
posting_date=get_first_day(nowdate()))
|
||||||
|
|
||||||
loan.submit()
|
loan.submit()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "LS-.{applicant}.-.#####",
|
"autoname": "LS-.{applicant}.-.#####",
|
||||||
"creation": "2019-08-29 18:48:51.371674",
|
"creation": "2019-08-29 18:48:51.371674",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -6,10 +7,10 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"loan_details_section",
|
"loan_details_section",
|
||||||
"loan_application",
|
|
||||||
"loan",
|
|
||||||
"applicant_type",
|
"applicant_type",
|
||||||
"applicant",
|
"applicant",
|
||||||
|
"loan",
|
||||||
|
"loan_application",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"company",
|
"company",
|
||||||
"pledge_time",
|
"pledge_time",
|
||||||
@ -55,15 +56,13 @@
|
|||||||
"fieldname": "loan",
|
"fieldname": "loan",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Loan",
|
"label": "Loan",
|
||||||
"options": "Loan",
|
"options": "Loan"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "loan_application",
|
"fieldname": "loan_application",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Loan Application",
|
"label": "Loan Application",
|
||||||
"options": "Loan Application",
|
"options": "Loan Application"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "total_security_value",
|
"fieldname": "total_security_value",
|
||||||
@ -133,7 +132,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-10-10 13:22:53.297519",
|
"links": [],
|
||||||
|
"modified": "2020-07-02 23:38:24.002382",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Security Pledge",
|
"name": "Loan Security Pledge",
|
||||||
|
@ -105,7 +105,7 @@ class TestSalarySlip(unittest.TestCase):
|
|||||||
#Gross pay calculation based on attendances
|
#Gross pay calculation based on attendances
|
||||||
gross_pay = 78000 - ((78000 / (days_in_month - no_of_holidays)) * flt(ss.leave_without_pay))
|
gross_pay = 78000 - ((78000 / (days_in_month - no_of_holidays)) * flt(ss.leave_without_pay))
|
||||||
|
|
||||||
self.assertEqual(ss.gross_pay, gross_pay)
|
self.assertEqual(flt(ss.gross_pay, 2), flt(gross_pay, 2))
|
||||||
|
|
||||||
frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave")
|
frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave")
|
||||||
|
|
||||||
|
@ -183,7 +183,8 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "progress",
|
"fieldname": "progress",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"label": "% Progress"
|
"label": "% Progress",
|
||||||
|
"no_copy": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@ -356,6 +357,7 @@
|
|||||||
"fieldname": "completed_by",
|
"fieldname": "completed_by",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Completed By",
|
"label": "Completed By",
|
||||||
|
"no_copy": 1,
|
||||||
"options": "User"
|
"options": "User"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -364,7 +366,7 @@
|
|||||||
"is_tree": 1,
|
"is_tree": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 5,
|
"max_attachments": 5,
|
||||||
"modified": "2020-03-18 18:08:44.153211",
|
"modified": "2020-07-03 12:36:04.960457",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Projects",
|
"module": "Projects",
|
||||||
"name": "Task",
|
"name": "Task",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
frappe.provide("erpnext.utils");
|
frappe.provide("erpnext.utils");
|
||||||
|
|
||||||
erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||||
if(!method) {
|
if (!method) {
|
||||||
method = "erpnext.accounts.party.get_party_details";
|
method = "erpnext.accounts.party.get_party_details";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,12 +22,12 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!args) {
|
if (!args) {
|
||||||
if((frm.doctype != "Purchase Order" && frm.doc.customer)
|
if ((frm.doctype != "Purchase Order" && frm.doc.customer)
|
||||||
|| (frm.doc.party_name && in_list(['Quotation', 'Opportunity'], frm.doc.doctype))) {
|
|| (frm.doc.party_name && in_list(['Quotation', 'Opportunity'], frm.doc.doctype))) {
|
||||||
|
|
||||||
let party_type = "Customer";
|
let party_type = "Customer";
|
||||||
if(frm.doc.quotation_to && frm.doc.quotation_to === "Lead") {
|
if (frm.doc.quotation_to && frm.doc.quotation_to === "Lead") {
|
||||||
party_type = "Lead";
|
party_type = "Lead";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
party_type: party_type,
|
party_type: party_type,
|
||||||
price_list: frm.doc.selling_price_list
|
price_list: frm.doc.selling_price_list
|
||||||
};
|
};
|
||||||
} else if(frm.doc.supplier) {
|
} else if (frm.doc.supplier) {
|
||||||
args = {
|
args = {
|
||||||
party: frm.doc.supplier,
|
party: frm.doc.supplier,
|
||||||
party_type: "Supplier",
|
party_type: "Supplier",
|
||||||
@ -78,13 +78,17 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
args.posting_date = frm.doc.posting_date || frm.doc.transaction_date;
|
args.posting_date = frm.doc.posting_date || frm.doc.transaction_date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!args || !args.party) return;
|
if (!args || !args.party) return;
|
||||||
|
|
||||||
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||||
if(!erpnext.utils.validate_mandatory(frm, "Posting/Transaction Date",
|
if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
|
||||||
args.posting_date, args.party_type=="Customer" ? "customer": "supplier")) return;
|
args.posting_date, args.party_type=="Customer" ? "customer": "supplier")) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!erpnext.utils.validate_mandatory(frm, "Company", frm.doc.company, args.party_type=="Customer" ? "customer": "supplier")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
args.currency = frm.doc.currency;
|
args.currency = frm.doc.currency;
|
||||||
args.company = frm.doc.company;
|
args.company = frm.doc.company;
|
||||||
args.doctype = frm.doc.doctype;
|
args.doctype = frm.doc.doctype;
|
||||||
@ -92,14 +96,14 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
method: method,
|
method: method,
|
||||||
args: args,
|
args: args,
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message) {
|
if (r.message) {
|
||||||
frm.supplier_tds = r.message.supplier_tds;
|
frm.supplier_tds = r.message.supplier_tds;
|
||||||
frm.updating_party_details = true;
|
frm.updating_party_details = true;
|
||||||
frappe.run_serially([
|
frappe.run_serially([
|
||||||
() => frm.set_value(r.message),
|
() => frm.set_value(r.message),
|
||||||
() => {
|
() => {
|
||||||
frm.updating_party_details = false;
|
frm.updating_party_details = false;
|
||||||
if(callback) callback();
|
if (callback) callback();
|
||||||
frm.refresh();
|
frm.refresh();
|
||||||
erpnext.utils.add_item(frm);
|
erpnext.utils.add_item(frm);
|
||||||
}
|
}
|
||||||
@ -110,9 +114,9 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
erpnext.utils.add_item = function(frm) {
|
erpnext.utils.add_item = function(frm) {
|
||||||
if(frm.is_new()) {
|
if (frm.is_new()) {
|
||||||
var prev_route = frappe.get_prev_route();
|
var prev_route = frappe.get_prev_route();
|
||||||
if(prev_route[1]==='Item' && !(frm.doc.items && frm.doc.items.length)) {
|
if (prev_route[1]==='Item' && !(frm.doc.items && frm.doc.items.length)) {
|
||||||
// add row
|
// add row
|
||||||
var item = frm.add_child('items');
|
var item = frm.add_child('items');
|
||||||
frm.refresh_field('items');
|
frm.refresh_field('items');
|
||||||
@ -124,23 +128,23 @@ erpnext.utils.add_item = function(frm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
erpnext.utils.get_address_display = function(frm, address_field, display_field, is_your_company_address) {
|
erpnext.utils.get_address_display = function(frm, address_field, display_field, is_your_company_address) {
|
||||||
if(frm.updating_party_details) return;
|
if (frm.updating_party_details) return;
|
||||||
|
|
||||||
if(!address_field) {
|
if (!address_field) {
|
||||||
if(frm.doctype != "Purchase Order" && frm.doc.customer) {
|
if (frm.doctype != "Purchase Order" && frm.doc.customer) {
|
||||||
address_field = "customer_address";
|
address_field = "customer_address";
|
||||||
} else if(frm.doc.supplier) {
|
} else if (frm.doc.supplier) {
|
||||||
address_field = "supplier_address";
|
address_field = "supplier_address";
|
||||||
} else return;
|
} else return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!display_field) display_field = "address_display";
|
if (!display_field) display_field = "address_display";
|
||||||
if(frm.doc[address_field]) {
|
if (frm.doc[address_field]) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "frappe.contacts.doctype.address.address.get_address_display",
|
method: "frappe.contacts.doctype.address.address.get_address_display",
|
||||||
args: {"address_dict": frm.doc[address_field] },
|
args: {"address_dict": frm.doc[address_field] },
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message) {
|
if (r.message) {
|
||||||
frm.set_value(display_field, r.message)
|
frm.set_value(display_field, r.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,15 +155,15 @@ erpnext.utils.get_address_display = function(frm, address_field, display_field,
|
|||||||
};
|
};
|
||||||
|
|
||||||
erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billing_address_field, shipping_address_field) {
|
erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billing_address_field, shipping_address_field) {
|
||||||
if(frm.updating_party_details) return;
|
if (frm.updating_party_details) return;
|
||||||
|
|
||||||
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||||
if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
|
if (!erpnext.utils.validate_mandatory(frm, "Lead / Customer / Supplier",
|
||||||
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
|
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!erpnext.utils.validate_mandatory(frm, "Posting/Transaction Date",
|
if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
|
||||||
frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
|
frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -175,8 +179,8 @@ erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billi
|
|||||||
"shipping_address": frm.doc[shipping_address_field]
|
"shipping_address": frm.doc[shipping_address_field]
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(!r.exc){
|
if (!r.exc){
|
||||||
if(frm.doc.tax_category != r.message) {
|
if (frm.doc.tax_category != r.message) {
|
||||||
frm.set_value("tax_category", r.message);
|
frm.set_value("tax_category", r.message);
|
||||||
} else {
|
} else {
|
||||||
erpnext.utils.set_taxes(frm, triggered_from_field);
|
erpnext.utils.set_taxes(frm, triggered_from_field);
|
||||||
@ -187,13 +191,17 @@ erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billi
|
|||||||
};
|
};
|
||||||
|
|
||||||
erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
||||||
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||||
if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
|
if (!erpnext.utils.validate_mandatory(frm, "Company", frm.doc.company, triggered_from_field)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!erpnext.utils.validate_mandatory(frm, "Lead / Customer / Supplier",
|
||||||
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
|
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!erpnext.utils.validate_mandatory(frm, "Posting/Transaction Date",
|
if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
|
||||||
frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
|
frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -230,7 +238,7 @@ erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
|||||||
"shipping_address": frm.doc.shipping_address_name
|
"shipping_address": frm.doc.shipping_address_name
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message){
|
if (r.message){
|
||||||
frm.set_value("taxes_and_charges", r.message)
|
frm.set_value("taxes_and_charges", r.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,14 +246,14 @@ erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
erpnext.utils.get_contact_details = function(frm) {
|
erpnext.utils.get_contact_details = function(frm) {
|
||||||
if(frm.updating_party_details) return;
|
if (frm.updating_party_details) return;
|
||||||
|
|
||||||
if(frm.doc["contact_person"]) {
|
if (frm.doc["contact_person"]) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "frappe.contacts.doctype.contact.contact.get_contact_details",
|
method: "frappe.contacts.doctype.contact.contact.get_contact_details",
|
||||||
args: {contact: frm.doc.contact_person },
|
args: {contact: frm.doc.contact_person },
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message)
|
if (r.message)
|
||||||
frm.set_value(r.message);
|
frm.set_value(r.message);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -253,10 +261,10 @@ erpnext.utils.get_contact_details = function(frm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) {
|
erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) {
|
||||||
if(!value) {
|
if (!value) {
|
||||||
frm.doc[trigger_on] = "";
|
frm.doc[trigger_on] = "";
|
||||||
refresh_field(trigger_on);
|
refresh_field(trigger_on);
|
||||||
frappe.msgprint(__("Please enter {0} first", [label]));
|
frappe.throw({message:__("Please enter {0} first", [label]), title:__("Mandatory")});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -271,12 +279,12 @@ erpnext.utils.get_shipping_address = function(frm, callback){
|
|||||||
address: frm.doc.shipping_address
|
address: frm.doc.shipping_address
|
||||||
},
|
},
|
||||||
callback: function(r){
|
callback: function(r){
|
||||||
if(r.message){
|
if (r.message){
|
||||||
frm.set_value("shipping_address", r.message[0]) //Address title or name
|
frm.set_value("shipping_address", r.message[0]) //Address title or name
|
||||||
frm.set_value("shipping_address_display", r.message[1]) //Address to be displayed on the page
|
frm.set_value("shipping_address_display", r.message[1]) //Address to be displayed on the page
|
||||||
}
|
}
|
||||||
|
|
||||||
if(callback){
|
if (callback){
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,28 @@ frappe.ui.form.on('Quality Feedback', {
|
|||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frm.set_value("date", frappe.datetime.get_today());
|
frm.set_value("date", frappe.datetime.get_today());
|
||||||
},
|
},
|
||||||
template: function(frm){
|
|
||||||
frappe.call({
|
template: function(frm) {
|
||||||
"method": "frappe.client.get",
|
if (frm.doc.template) {
|
||||||
args: {
|
frappe.call({
|
||||||
doctype: "Quality Feedback Template",
|
"method": "frappe.client.get",
|
||||||
name: frm.doc.template
|
args: {
|
||||||
},
|
doctype: "Quality Feedback Template",
|
||||||
callback: function(data){
|
name: frm.doc.template
|
||||||
frm.fields_dict.parameters.grid.remove_all();
|
},
|
||||||
for (var i in data.message.parameters){
|
callback: function(data) {
|
||||||
frm.add_child("parameters");
|
if (data && data.message) {
|
||||||
frm.fields_dict.parameters.get_value()[i].parameter = data.message.parameters[i].parameter;
|
frm.fields_dict.parameters.grid.remove_all();
|
||||||
|
|
||||||
|
// fetch parameters from template and autofill
|
||||||
|
for (let template_parameter of data.message.parameters) {
|
||||||
|
let row = frm.add_child("parameters");
|
||||||
|
row.parameter = template_parameter.parameter;
|
||||||
|
}
|
||||||
|
frm.refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
frm.refresh();
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "format:FDBK-{#####}",
|
"autoname": "format:FDBK-{#####}",
|
||||||
"creation": "2019-05-26 21:23:05.308379",
|
"creation": "2019-05-26 21:23:05.308379",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -53,12 +54,13 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "document_name",
|
"fieldname": "document_name",
|
||||||
"fieldtype": "Dynamic Link",
|
"fieldtype": "Dynamic Link",
|
||||||
"label": "Name",
|
"label": "Feedback By",
|
||||||
"options": "document_type",
|
"options": "document_type",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2019-05-28 15:16:01.161662",
|
"links": [],
|
||||||
|
"modified": "2020-07-03 15:50:58.589302",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Quality Management",
|
"module": "Quality Management",
|
||||||
"name": "Quality Feedback",
|
"name": "Quality Feedback",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "format:TMPL-{template}",
|
"autoname": "format:TMPL-{template}",
|
||||||
"creation": "2019-05-26 21:17:24.283061",
|
"creation": "2019-05-26 21:17:24.283061",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -30,10 +31,12 @@
|
|||||||
"fieldname": "parameters",
|
"fieldname": "parameters",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Parameters",
|
"label": "Parameters",
|
||||||
"options": "Quality Feedback Template Parameter"
|
"options": "Quality Feedback Template Parameter",
|
||||||
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2019-05-26 21:48:47.770610",
|
"links": [],
|
||||||
|
"modified": "2020-07-03 16:06:03.749415",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Quality Management",
|
"module": "Quality Management",
|
||||||
"name": "Quality Feedback Template",
|
"name": "Quality Feedback Template",
|
||||||
|
@ -11,14 +11,17 @@ def update_itemised_tax_data(doc):
|
|||||||
|
|
||||||
for row in doc.items:
|
for row in doc.items:
|
||||||
tax_rate = 0.0
|
tax_rate = 0.0
|
||||||
item_tax_rate = frappe.parse_json(row.item_tax_rate)
|
item_tax_rate = 0.0
|
||||||
|
|
||||||
|
if row.item_tax_rate:
|
||||||
|
item_tax_rate = frappe.parse_json(row.item_tax_rate)
|
||||||
|
|
||||||
# First check if tax rate is present
|
# First check if tax rate is present
|
||||||
# If not then look up in item_wise_tax_detail
|
# If not then look up in item_wise_tax_detail
|
||||||
if item_tax_rate:
|
if item_tax_rate:
|
||||||
for account, rate in iteritems(item_tax_rate):
|
for account, rate in iteritems(item_tax_rate):
|
||||||
tax_rate += rate
|
tax_rate += rate
|
||||||
elif itemised_tax.get(row.item_code):
|
elif row.item_code and itemised_tax.get(row.item_code):
|
||||||
tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
|
tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
|
||||||
|
|
||||||
row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
|
row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
|
||||||
|
@ -342,11 +342,10 @@ def get_loyalty_programs(doc):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_customer_list(doctype, txt, searchfield, start, page_len, filters=None):
|
def get_customer_list(doctype, txt, searchfield, start, page_len, filters=None):
|
||||||
from erpnext.controllers.queries import get_fields
|
from erpnext.controllers.queries import get_fields
|
||||||
|
fields = ["name", "customer_name", "customer_group", "territory"]
|
||||||
|
|
||||||
if frappe.db.get_default("cust_master_name") == "Customer Name":
|
if frappe.db.get_default("cust_master_name") == "Customer Name":
|
||||||
fields = ["name", "customer_group", "territory"]
|
fields = ["name", "customer_group", "territory"]
|
||||||
else:
|
|
||||||
fields = ["name", "customer_name", "customer_group", "territory"]
|
|
||||||
|
|
||||||
fields = get_fields("Customer", fields)
|
fields = get_fields("Customer", fields)
|
||||||
|
|
||||||
@ -553,4 +552,4 @@ def get_customer_primary_contact(doctype, txt, searchfield, start, page_len, fil
|
|||||||
""", {
|
""", {
|
||||||
'customer': customer,
|
'customer': customer,
|
||||||
'txt': '%%%s%%' % txt
|
'txt': '%%%s%%' % txt
|
||||||
})
|
})
|
File diff suppressed because it is too large
Load Diff
@ -987,6 +987,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"collapsible": 1,
|
||||||
"depends_on": "eval:(!doc.is_item_from_hub)",
|
"depends_on": "eval:(!doc.is_item_from_hub)",
|
||||||
"fieldname": "hub_publishing_sb",
|
"fieldname": "hub_publishing_sb",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
@ -1060,7 +1061,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 1,
|
"max_attachments": 1,
|
||||||
"modified": "2020-04-08 15:56:06.195722",
|
"modified": "2020-06-30 12:01:07.534447",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
@ -1122,4 +1123,4 @@
|
|||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "item_name",
|
"title_field": "item_name",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
@ -636,6 +636,10 @@ def get_item_price(args, item_code, ignore_party=False):
|
|||||||
if args.get('transaction_date'):
|
if args.get('transaction_date'):
|
||||||
conditions += """ and %(transaction_date)s between
|
conditions += """ and %(transaction_date)s between
|
||||||
ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
|
ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
|
||||||
|
|
||||||
|
if args.get('posting_date'):
|
||||||
|
conditions += """ and %(posting_date)s between
|
||||||
|
ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31')"""
|
||||||
|
|
||||||
return frappe.db.sql(""" select name, price_list_rate, uom
|
return frappe.db.sql(""" select name, price_list_rate, uom
|
||||||
from `tabItem Price` {conditions}
|
from `tabItem Price` {conditions}
|
||||||
@ -657,6 +661,7 @@ def get_price_list_rate_for(args, item_code):
|
|||||||
"supplier": args.get('supplier'),
|
"supplier": args.get('supplier'),
|
||||||
"uom": args.get('uom'),
|
"uom": args.get('uom'),
|
||||||
"transaction_date": args.get('transaction_date'),
|
"transaction_date": args.get('transaction_date'),
|
||||||
|
"posting_date": args.get('posting_date'),
|
||||||
}
|
}
|
||||||
|
|
||||||
item_price_data = 0
|
item_price_data = 0
|
||||||
|
@ -120,6 +120,16 @@ class TransactionBase(StatusUpdater):
|
|||||||
|
|
||||||
|
|
||||||
def validate_rate_with_reference_doc(self, ref_details):
|
def validate_rate_with_reference_doc(self, ref_details):
|
||||||
|
buying_doctypes = ["Purchase Order", "Purchase Invoice", "Purchase Receipt"]
|
||||||
|
selling_doctypes = ["Sales Invoice", "Delivery Note"]
|
||||||
|
|
||||||
|
if self.doctype in buying_doctypes:
|
||||||
|
to_disable = "Maintain same rate throughout Purchase cycle"
|
||||||
|
settings_page = "Buying Settings"
|
||||||
|
else:
|
||||||
|
to_disable = "Maintain same rate throughout Sales cycle"
|
||||||
|
settings_page = "Selling Settings"
|
||||||
|
|
||||||
for ref_dt, ref_dn_field, ref_link_field in ref_details:
|
for ref_dt, ref_dn_field, ref_link_field in ref_details:
|
||||||
for d in self.get("items"):
|
for d in self.get("items"):
|
||||||
if d.get(ref_link_field):
|
if d.get(ref_link_field):
|
||||||
@ -129,8 +139,8 @@ class TransactionBase(StatusUpdater):
|
|||||||
frappe.msgprint(_("Row #{0}: Rate must be same as {1}: {2} ({3} / {4}) ")
|
frappe.msgprint(_("Row #{0}: Rate must be same as {1}: {2} ({3} / {4}) ")
|
||||||
.format(d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate))
|
.format(d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate))
|
||||||
frappe.throw(_("To allow different rates, disable the {0} checkbox in {1}.")
|
frappe.throw(_("To allow different rates, disable the {0} checkbox in {1}.")
|
||||||
.format(frappe.bold(_("Maintain Same Rate Throughout Sales Cycle")),
|
.format(frappe.bold(_(to_disable)),
|
||||||
get_link_to_form("Selling Settings", "Selling Settings", frappe.bold("Selling Settings"))))
|
get_link_to_form(settings_page, settings_page, frappe.bold(settings_page))))
|
||||||
|
|
||||||
def get_link_filters(self, for_doctype):
|
def get_link_filters(self, for_doctype):
|
||||||
if hasattr(self, "prev_link_mapper") and self.prev_link_mapper.get(for_doctype):
|
if hasattr(self, "prev_link_mapper") and self.prev_link_mapper.get(for_doctype):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user