Merge branch 'develop' into escape-company-field
This commit is contained in:
commit
f7a7cc08d9
@ -93,6 +93,7 @@ def resolve_dunning(doc, state):
|
|||||||
|
|
||||||
def calculate_interest_and_amount(posting_date, outstanding_amount, rate_of_interest, dunning_fee, overdue_days):
|
def calculate_interest_and_amount(posting_date, outstanding_amount, rate_of_interest, dunning_fee, overdue_days):
|
||||||
interest_amount = 0
|
interest_amount = 0
|
||||||
|
grand_total = 0
|
||||||
if rate_of_interest:
|
if rate_of_interest:
|
||||||
interest_per_year = flt(outstanding_amount) * flt(rate_of_interest) / 100
|
interest_per_year = flt(outstanding_amount) * flt(rate_of_interest) / 100
|
||||||
interest_amount = (interest_per_year * cint(overdue_days)) / 365
|
interest_amount = (interest_per_year * cint(overdue_days)) / 365
|
||||||
|
@ -31,8 +31,7 @@ frappe.ui.form.on('POS Profile', {
|
|||||||
frm.set_query("print_format", function() {
|
frm.set_query("print_format", function() {
|
||||||
return {
|
return {
|
||||||
filters: [
|
filters: [
|
||||||
['Print Format', 'doc_type', '=', 'Sales Invoice'],
|
['Print Format', 'doc_type', '=', 'POS Invoice']
|
||||||
['Print Format', 'print_format_type', '=', 'Jinja'],
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -45,10 +44,6 @@ frappe.ui.form.on('POS Profile', {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
frm.set_query("print_format", function() {
|
|
||||||
return { filters: { doc_type: "Sales Invoice", print_format_type: "JS"} };
|
|
||||||
});
|
|
||||||
|
|
||||||
frm.set_query('company_address', function(doc) {
|
frm.set_query('company_address', function(doc) {
|
||||||
if(!doc.company) {
|
if(!doc.company) {
|
||||||
frappe.throw(__('Please set Company'));
|
frappe.throw(__('Please set Company'));
|
||||||
|
@ -8,7 +8,7 @@ def get_data():
|
|||||||
'fieldname': 'taxes_and_charges',
|
'fieldname': 'taxes_and_charges',
|
||||||
'non_standard_fieldnames': {
|
'non_standard_fieldnames': {
|
||||||
'Tax Rule': 'sales_tax_template',
|
'Tax Rule': 'sales_tax_template',
|
||||||
'Subscription': 'tax_template',
|
'Subscription': 'sales_tax_template',
|
||||||
'Restaurant': 'default_tax_template'
|
'Restaurant': 'default_tax_template'
|
||||||
},
|
},
|
||||||
'transactions': [
|
'transactions': [
|
||||||
|
@ -8,6 +8,7 @@ from frappe import _
|
|||||||
from frappe.utils import flt, getdate, cint, date_diff, formatdate
|
from frappe.utils import flt, getdate, cint, date_diff, formatdate
|
||||||
from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts
|
from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_checks_for_pl_and_bs_accounts
|
||||||
|
|
||||||
class AssetValueAdjustment(Document):
|
class AssetValueAdjustment(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@ -53,17 +54,33 @@ class AssetValueAdjustment(Document):
|
|||||||
je.company = self.company
|
je.company = self.company
|
||||||
je.remark = "Depreciation Entry against {0} worth {1}".format(self.asset, self.difference_amount)
|
je.remark = "Depreciation Entry against {0} worth {1}".format(self.asset, self.difference_amount)
|
||||||
|
|
||||||
je.append("accounts", {
|
credit_entry = {
|
||||||
"account": accumulated_depreciation_account,
|
"account": accumulated_depreciation_account,
|
||||||
"credit_in_account_currency": self.difference_amount,
|
"credit_in_account_currency": self.difference_amount,
|
||||||
"cost_center": depreciation_cost_center or self.cost_center
|
"cost_center": depreciation_cost_center or self.cost_center
|
||||||
})
|
}
|
||||||
|
|
||||||
je.append("accounts", {
|
debit_entry = {
|
||||||
"account": depreciation_expense_account,
|
"account": depreciation_expense_account,
|
||||||
"debit_in_account_currency": self.difference_amount,
|
"debit_in_account_currency": self.difference_amount,
|
||||||
"cost_center": depreciation_cost_center or self.cost_center
|
"cost_center": depreciation_cost_center or self.cost_center
|
||||||
})
|
}
|
||||||
|
|
||||||
|
accounting_dimensions = get_checks_for_pl_and_bs_accounts()
|
||||||
|
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
if dimension.get('mandatory_for_bs'):
|
||||||
|
credit_entry.update({
|
||||||
|
dimension['fieldname']: self.get(dimension['fieldname']) or dimension.get('default_dimension')
|
||||||
|
})
|
||||||
|
|
||||||
|
if dimension.get('mandatory_for_pl'):
|
||||||
|
debit_entry.update({
|
||||||
|
dimension['fieldname']: self.get(dimension['fieldname']) or dimension.get('default_dimension')
|
||||||
|
})
|
||||||
|
|
||||||
|
je.append("accounts", credit_entry)
|
||||||
|
je.append("accounts", debit_entry)
|
||||||
|
|
||||||
je.flags.ignore_permissions = True
|
je.flags.ignore_permissions = True
|
||||||
je.submit()
|
je.submit()
|
||||||
|
@ -613,9 +613,12 @@ def get_tax_template(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
if not taxes:
|
if not taxes:
|
||||||
return frappe.db.sql(""" SELECT name FROM `tabItem Tax Template` """)
|
return frappe.db.sql(""" SELECT name FROM `tabItem Tax Template` """)
|
||||||
else:
|
else:
|
||||||
|
valid_from = filters.get('valid_from')
|
||||||
|
valid_from = valid_from[1] if isinstance(valid_from, list) else valid_from
|
||||||
|
|
||||||
args = {
|
args = {
|
||||||
'item_code': filters.get('item_code'),
|
'item_code': filters.get('item_code'),
|
||||||
'posting_date': filters.get('valid_from'),
|
'posting_date': valid_from,
|
||||||
'tax_category': filters.get('tax_category'),
|
'tax_category': filters.get('tax_category'),
|
||||||
'company': filters.get('company')
|
'company': filters.get('company')
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ def make_opportunity_from_communication(communication, ignore_communication_link
|
|||||||
opportunity = frappe.get_doc({
|
opportunity = frappe.get_doc({
|
||||||
"doctype": "Opportunity",
|
"doctype": "Opportunity",
|
||||||
"opportunity_from": opportunity_from,
|
"opportunity_from": opportunity_from,
|
||||||
"lead": lead
|
"party_name": lead
|
||||||
}).insert(ignore_permissions=True)
|
}).insert(ignore_permissions=True)
|
||||||
|
|
||||||
link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
|
link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
|
||||||
|
@ -7,7 +7,7 @@ import frappe
|
|||||||
import unittest
|
import unittest
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
from frappe.utils.make_random import get_random
|
from frappe.utils.make_random import get_random
|
||||||
|
from erpnext.education.doctype.program.test_program import make_program_and_linked_courses
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Fees')
|
# test_records = frappe.get_test_records('Fees')
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ class TestFees(unittest.TestCase):
|
|||||||
|
|
||||||
def test_fees(self):
|
def test_fees(self):
|
||||||
student = get_random("Student")
|
student = get_random("Student")
|
||||||
|
program = make_program_and_linked_courses("_Test Program 1", ["_Test Course 1", "_Test Course 2"])
|
||||||
fee = frappe.new_doc("Fees")
|
fee = frappe.new_doc("Fees")
|
||||||
fee.posting_date = nowdate()
|
fee.posting_date = nowdate()
|
||||||
fee.due_date = nowdate()
|
fee.due_date = nowdate()
|
||||||
@ -23,6 +24,7 @@ class TestFees(unittest.TestCase):
|
|||||||
fee.income_account = "Sales - _TC"
|
fee.income_account = "Sales - _TC"
|
||||||
fee.cost_center = "_Test Cost Center - _TC"
|
fee.cost_center = "_Test Cost Center - _TC"
|
||||||
fee.company = "_Test Company"
|
fee.company = "_Test Company"
|
||||||
|
fee.program = program.name
|
||||||
|
|
||||||
fee.extend("components", [
|
fee.extend("components", [
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ let transfer_patient_dialog = function(frm) {
|
|||||||
{fieldtype: 'Link', label: 'Leave From', fieldname: 'leave_from', options: 'Healthcare Service Unit', reqd: 1, read_only:1},
|
{fieldtype: 'Link', label: 'Leave From', fieldname: 'leave_from', options: 'Healthcare Service Unit', reqd: 1, read_only:1},
|
||||||
{fieldtype: 'Link', label: 'Service Unit Type', fieldname: 'service_unit_type', options: 'Healthcare Service Unit Type'},
|
{fieldtype: 'Link', label: 'Service Unit Type', fieldname: 'service_unit_type', options: 'Healthcare Service Unit Type'},
|
||||||
{fieldtype: 'Link', label: 'Transfer To', fieldname: 'service_unit', options: 'Healthcare Service Unit', reqd: 1},
|
{fieldtype: 'Link', label: 'Transfer To', fieldname: 'service_unit', options: 'Healthcare Service Unit', reqd: 1},
|
||||||
{fieldtype: 'Datetime', label: 'Check In', fieldname: 'check_in', reqd: 1}
|
{fieldtype: 'Datetime', label: 'Check In', fieldname: 'check_in', reqd: 1, default: frappe.datetime.now_datetime()}
|
||||||
],
|
],
|
||||||
primary_action_label: __('Transfer'),
|
primary_action_label: __('Transfer'),
|
||||||
primary_action : function() {
|
primary_action : function() {
|
||||||
@ -147,7 +147,12 @@ let transfer_patient_dialog = function(frm) {
|
|||||||
if(dialog.get_value('service_unit')){
|
if(dialog.get_value('service_unit')){
|
||||||
service_unit = dialog.get_value('service_unit');
|
service_unit = dialog.get_value('service_unit');
|
||||||
}
|
}
|
||||||
if(!check_in){
|
if(check_in > frappe.datetime.now_datetime()){
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __('Not Allowed'),
|
||||||
|
message: __('Check-in time cannot be greater than the current time'),
|
||||||
|
indicator: 'red'
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Loan",
|
"label": "Loan",
|
||||||
"links": "[\n {\n \"description\": \"Loan Type for interest and penalty rates\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Applications from customers and employees.\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loans provided to customers and employees.\",\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]"
|
"links": "[\n {\n \"description\": \"Loan Type for interest and penalty rates\",\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Loan Applications from customers and employees.\",\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n { \"dependencies\": [\n \"Loan Type\"\n ],\n \"description\": \"Loans provided to customers and employees.\",\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n }\n]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
|
@ -112,16 +112,19 @@ frappe.ui.form.on('Loan Application', {
|
|||||||
frappe.ui.form.on("Proposed Pledge", {
|
frappe.ui.form.on("Proposed Pledge", {
|
||||||
loan_security: function(frm, cdt, cdn) {
|
loan_security: function(frm, cdt, cdn) {
|
||||||
let row = locals[cdt][cdn];
|
let row = locals[cdt][cdn];
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
|
if (row.loan_security) {
|
||||||
args: {
|
frappe.call({
|
||||||
loan_security: row.loan_security
|
method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
|
||||||
},
|
args: {
|
||||||
callback: function(r) {
|
loan_security: row.loan_security
|
||||||
frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
|
},
|
||||||
frm.events.calculate_amounts(frm, cdt, cdn);
|
callback: function(r) {
|
||||||
}
|
frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
|
||||||
})
|
frm.events.calculate_amounts(frm, cdt, cdn);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
amount: function(frm, cdt, cdn) {
|
amount: function(frm, cdt, cdn) {
|
||||||
|
@ -19,8 +19,8 @@ class LoanInterestAccrual(AccountsController):
|
|||||||
if not self.posting_date:
|
if not self.posting_date:
|
||||||
self.posting_date = nowdate()
|
self.posting_date = nowdate()
|
||||||
|
|
||||||
if not self.interest_amount:
|
if not self.interest_amount and not self.payable_principal_amount:
|
||||||
frappe.throw(_("Interest Amount is mandatory"))
|
frappe.throw(_("Interest Amount or Principal Amount is mandatory"))
|
||||||
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
@ -39,37 +39,38 @@ class LoanInterestAccrual(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 = []
|
||||||
|
|
||||||
gle_map.append(
|
if self.interest_amount:
|
||||||
self.get_gl_dict({
|
gle_map.append(
|
||||||
"account": self.loan_account,
|
self.get_gl_dict({
|
||||||
"party_type": self.applicant_type,
|
"account": self.loan_account,
|
||||||
"party": self.applicant,
|
"party_type": self.applicant_type,
|
||||||
"against": self.interest_income_account,
|
"party": self.applicant,
|
||||||
"debit": self.interest_amount,
|
"against": self.interest_income_account,
|
||||||
"debit_in_account_currency": self.interest_amount,
|
"debit": self.interest_amount,
|
||||||
"against_voucher_type": "Loan",
|
"debit_in_account_currency": self.interest_amount,
|
||||||
"against_voucher": self.loan,
|
"against_voucher_type": "Loan",
|
||||||
"remarks": _("Against Loan:") + self.loan,
|
"against_voucher": self.loan,
|
||||||
"cost_center": erpnext.get_default_cost_center(self.company),
|
"remarks": _("Against Loan:") + self.loan,
|
||||||
"posting_date": self.posting_date
|
"cost_center": erpnext.get_default_cost_center(self.company),
|
||||||
})
|
"posting_date": self.posting_date
|
||||||
)
|
})
|
||||||
|
)
|
||||||
|
|
||||||
gle_map.append(
|
gle_map.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": self.interest_income_account,
|
"account": self.interest_income_account,
|
||||||
"party_type": self.applicant_type,
|
"party_type": self.applicant_type,
|
||||||
"party": self.applicant,
|
"party": self.applicant,
|
||||||
"against": self.loan_account,
|
"against": self.loan_account,
|
||||||
"credit": self.interest_amount,
|
"credit": self.interest_amount,
|
||||||
"credit_in_account_currency": self.interest_amount,
|
"credit_in_account_currency": self.interest_amount,
|
||||||
"against_voucher_type": "Loan",
|
"against_voucher_type": "Loan",
|
||||||
"against_voucher": self.loan,
|
"against_voucher": self.loan,
|
||||||
"remarks": _("Against Loan:") + self.loan,
|
"remarks": _("Against Loan:") + self.loan,
|
||||||
"cost_center": erpnext.get_default_cost_center(self.company),
|
"cost_center": erpnext.get_default_cost_center(self.company),
|
||||||
"posting_date": self.posting_date
|
"posting_date": self.posting_date
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
if gle_map:
|
if gle_map:
|
||||||
make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj)
|
make_gl_entries(gle_map, cancel=cancel, adv_adj=adv_adj)
|
||||||
|
@ -173,7 +173,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "references_section",
|
"fieldname": "references_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "References"
|
"label": "Payment References"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "reference_number",
|
"fieldname": "reference_number",
|
||||||
@ -221,7 +221,7 @@
|
|||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-16 18:14:45.166754",
|
"modified": "2020-05-16 09:40:15.581165",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Repayment",
|
"name": "Loan Repayment",
|
||||||
|
@ -22,16 +22,19 @@ frappe.ui.form.on('Loan Security Pledge', {
|
|||||||
frappe.ui.form.on("Pledge", {
|
frappe.ui.form.on("Pledge", {
|
||||||
loan_security: function(frm, cdt, cdn) {
|
loan_security: function(frm, cdt, cdn) {
|
||||||
let row = locals[cdt][cdn];
|
let row = locals[cdt][cdn];
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
|
if (row.loan_security) {
|
||||||
args: {
|
frappe.call({
|
||||||
loan_security: row.loan_security
|
method: "erpnext.loan_management.doctype.loan_security_price.loan_security_price.get_loan_security_price",
|
||||||
},
|
args: {
|
||||||
callback: function(r) {
|
loan_security: row.loan_security
|
||||||
frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
|
},
|
||||||
frm.events.calculate_amounts(frm, cdt, cdn);
|
callback: function(r) {
|
||||||
}
|
frappe.model.set_value(cdt, cdn, 'loan_security_price', r.message);
|
||||||
});
|
frm.events.calculate_amounts(frm, cdt, cdn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
qty: function(frm, cdt, cdn) {
|
qty: function(frm, cdt, cdn) {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
"unique": 1
|
"unique": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "Haircut percentage is the percentage difference between market value of the Loan Security and the value ascribed to that Loan Security when used as collateral for that loan.",
|
||||||
"fieldname": "haircut",
|
"fieldname": "haircut",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"label": "Haircut %"
|
"label": "Haircut %"
|
||||||
@ -46,13 +47,14 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "Loan To Value Ratio expresses the ratio of the loan amount to the value of the security pledged. A loan security shortfall will be triggered if this falls below the specified value for any loan ",
|
||||||
"fieldname": "loan_to_value_ratio",
|
"fieldname": "loan_to_value_ratio",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"label": "Loan To Value Ratio"
|
"label": "Loan To Value Ratio"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-28 14:06:49.046177",
|
"modified": "2020-05-16 09:38:45.988080",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Loan Management",
|
"module": "Loan Management",
|
||||||
"name": "Loan Security Type",
|
"name": "Loan Security Type",
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "This account is used for booking loan repayments from the borrower and also disbursing loans to the borrower",
|
||||||
"fieldname": "payment_account",
|
"fieldname": "payment_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Payment Account",
|
"label": "Payment Account",
|
||||||
@ -83,6 +84,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "This account is capital account which is used to allocate capital for loan disbursal account ",
|
||||||
"fieldname": "loan_account",
|
"fieldname": "loan_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Loan Account",
|
"label": "Loan Account",
|
||||||
@ -94,6 +96,7 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "This account will be used for booking loan interest accruals",
|
||||||
"fieldname": "interest_income_account",
|
"fieldname": "interest_income_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Interest Income Account",
|
"label": "Interest Income Account",
|
||||||
@ -101,6 +104,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "This account will be used for booking penalties levied due to delayed repayments",
|
||||||
"fieldname": "penalty_income_account",
|
"fieldname": "penalty_income_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Penalty Income Account",
|
"label": "Penalty Income Account",
|
||||||
@ -109,6 +113,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"description": "If this is not checked the loan by default will be considered as a Demand Loan",
|
||||||
"fieldname": "is_term_loan",
|
"fieldname": "is_term_loan",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Term Loan"
|
"label": "Is Term Loan"
|
||||||
|
@ -8,7 +8,7 @@ frappe.query_reports["Downtime Analysis"] = {
|
|||||||
label: __("From Date"),
|
label: __("From Date"),
|
||||||
fieldname:"from_date",
|
fieldname:"from_date",
|
||||||
fieldtype: "Datetime",
|
fieldtype: "Datetime",
|
||||||
default: frappe.datetime.add_months(frappe.datetime.now_datetime(), -1),
|
default: frappe.datetime.convert_to_system_tz(frappe.datetime.add_months(frappe.datetime.now_datetime(), -1)),
|
||||||
reqd: 1
|
reqd: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -687,6 +687,7 @@ execute:frappe.delete_doc_if_exists("Page", "appointment-analytic")
|
|||||||
execute:frappe.rename_doc("Desk Page", "Getting Started", "Home", force=True)
|
execute:frappe.rename_doc("Desk Page", "Getting Started", "Home", force=True)
|
||||||
erpnext.patches.v12_0.unset_customer_supplier_based_on_type_of_item_price
|
erpnext.patches.v12_0.unset_customer_supplier_based_on_type_of_item_price
|
||||||
erpnext.patches.v12_0.set_valid_till_date_in_supplier_quotation
|
erpnext.patches.v12_0.set_valid_till_date_in_supplier_quotation
|
||||||
|
erpnext.patches.v13_0.update_old_loans
|
||||||
erpnext.patches.v12_0.set_serial_no_status #2020-05-21
|
erpnext.patches.v12_0.set_serial_no_status #2020-05-21
|
||||||
erpnext.patches.v12_0.update_price_list_currency_in_bom
|
erpnext.patches.v12_0.update_price_list_currency_in_bom
|
||||||
execute:frappe.delete_doc_if_exists('Dashboard', 'Accounts')
|
execute:frappe.delete_doc_if_exists('Dashboard', 'Accounts')
|
||||||
|
88
erpnext/patches/v13_0/update_old_loans.py
Normal file
88
erpnext/patches/v13_0/update_old_loans.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.accounts.doctype.account.test_account import create_account
|
||||||
|
from erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual import process_loan_interest_accrual_for_term_loans
|
||||||
|
from erpnext.loan_management.doctype.loan.loan import make_repayment_entry
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
|
||||||
|
# Create a penalty account for loan types
|
||||||
|
|
||||||
|
frappe.reload_doc('loan_management', 'doctype', 'loan_type')
|
||||||
|
frappe.reload_doc('loan_management', 'doctype', 'loan')
|
||||||
|
frappe.reload_doc('loan_management', 'doctype', 'repayment_schedule')
|
||||||
|
frappe.reload_doc('loan_management', 'doctype', 'process_loan_interest_accrual')
|
||||||
|
frappe.reload_doc('loan_management', 'doctype', 'loan_repayment')
|
||||||
|
frappe.reload_doc('loan_management', 'doctype', 'loan_repayment_detail')
|
||||||
|
frappe.reload_doc('loan_management', 'doctype', 'loan_interest_accrual')
|
||||||
|
frappe.reload_doc('accounts', 'doctype', 'gl_entry')
|
||||||
|
|
||||||
|
updated_loan_types = []
|
||||||
|
|
||||||
|
loans = frappe.get_all('Loan', fields=['name', 'loan_type', 'company', 'status', 'mode_of_payment',
|
||||||
|
'applicant_type', 'applicant', 'loan_account', 'payment_account', 'interest_income_account'])
|
||||||
|
|
||||||
|
for loan in loans:
|
||||||
|
# Update details in Loan Types and Loan
|
||||||
|
loan_type_company = frappe.db.get_value('Loan Type', loan.loan_type, 'company')
|
||||||
|
|
||||||
|
group_income_account = frappe.get_value('Account', {'company': loan.company,
|
||||||
|
'is_group': 1, 'root_type': 'Income', 'account_name': _('Indirect Income')})
|
||||||
|
|
||||||
|
if not group_income_account:
|
||||||
|
group_income_account = frappe.get_value('Account', {'company': loan.company,
|
||||||
|
'is_group': 1, 'root_type': 'Income'})
|
||||||
|
|
||||||
|
penalty_account = create_account(company=loan.company, account_type='Income Account',
|
||||||
|
account_name='Penalty Account', parent_account=group_income_account)
|
||||||
|
|
||||||
|
if not loan_type_company:
|
||||||
|
loan_type_doc = frappe.get_doc('Loan Type', loan.loan_type)
|
||||||
|
loan_type_doc.is_term_loan = 1
|
||||||
|
loan_type_doc.company = loan.company
|
||||||
|
loan_type_doc.mode_of_payment = loan.mode_of_payment
|
||||||
|
loan_type_doc.payment_account = loan.payment_account
|
||||||
|
loan_type_doc.loan_account = loan.loan_account
|
||||||
|
loan_type_doc.interest_income_account = loan.interest_income_account
|
||||||
|
loan_type_doc.penalty_income_account = penalty_account
|
||||||
|
loan_type_doc.submit()
|
||||||
|
updated_loan_types.append(loan.loan_type)
|
||||||
|
|
||||||
|
if loan.loan_type in updated_loan_types:
|
||||||
|
if loan.status == 'Fully Disbursed':
|
||||||
|
status = 'Disbursed'
|
||||||
|
elif loan.status == 'Repaid/Closed':
|
||||||
|
status = 'Closed'
|
||||||
|
else:
|
||||||
|
status = loan.status
|
||||||
|
|
||||||
|
frappe.db.set_value('Loan', loan.name, {
|
||||||
|
'is_term_loan': 1,
|
||||||
|
'penalty_income_account': penalty_account,
|
||||||
|
'status': status
|
||||||
|
})
|
||||||
|
|
||||||
|
process_loan_interest_accrual_for_term_loans(posting_date=nowdate(), loan_type=loan.loan_type,
|
||||||
|
loan=loan.name)
|
||||||
|
|
||||||
|
payments = frappe.db.sql(''' SELECT j.name, a.debit, a.debit_in_account_currency, j.posting_date
|
||||||
|
FROM `tabJournal Entry` j, `tabJournal Entry Account` a
|
||||||
|
WHERE a.parent = j.name and a.reference_type='Loan' and a.reference_name = %s
|
||||||
|
and account = %s
|
||||||
|
''', (loan.name, loan.loan_account), as_dict=1)
|
||||||
|
|
||||||
|
for payment in payments:
|
||||||
|
repayment_entry = make_repayment_entry(loan.name, loan.loan_applicant_type, loan.applicant,
|
||||||
|
loan.loan_type, loan.company)
|
||||||
|
|
||||||
|
repayment_entry.amount_paid = payment.debit_in_account_currency
|
||||||
|
repayment_entry.posting_date = payment.posting_date
|
||||||
|
repayment_entry.save()
|
||||||
|
repayment_entry.submit()
|
||||||
|
|
||||||
|
jv = frappe.get_doc('Journal Entry', payment.name)
|
||||||
|
jv.flags.ignore_links = True
|
||||||
|
jv.cancel()
|
||||||
|
|
@ -13,7 +13,7 @@ frappe.ui.form.on("Communication", {
|
|||||||
frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
|
frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
|
||||||
frm.trigger('make_issue_from_communication');
|
frm.trigger('make_issue_from_communication');
|
||||||
})
|
})
|
||||||
}, "Make");
|
}, "Create");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!in_list(["Lead", "Opportunity"], frm.doc.reference_doctype)) {
|
if(!in_list(["Lead", "Opportunity"], frm.doc.reference_doctype)) {
|
||||||
|
@ -1821,7 +1821,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
set_query_for_item_tax_template: function(doc, cdt, cdn) {
|
set_query_for_item_tax_template: function(doc, cdt, cdn) {
|
||||||
|
|
||||||
var item = frappe.get_doc(cdt, cdn);
|
var item = frappe.get_doc(cdt, cdn);
|
||||||
if(!item.item_code) {
|
if(!item.item_code) {
|
||||||
frappe.throw(__("Please enter Item Code to get item taxes"));
|
frappe.throw(__("Please enter Item Code to get item taxes"));
|
||||||
@ -1829,7 +1828,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
|
|
||||||
let filters = {
|
let filters = {
|
||||||
'item_code': item.item_code,
|
'item_code': item.item_code,
|
||||||
'valid_from': doc.transaction_date || doc.bill_date || doc.posting_date,
|
'valid_from': ["<=", doc.transaction_date || doc.bill_date || doc.posting_date],
|
||||||
'item_group': item.item_group,
|
'item_group': item.item_group,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,9 +234,6 @@ class GSTR3BReport(Document):
|
|||||||
self.report_dict[supply_type][supply_category][account_map.get(account_type)] += \
|
self.report_dict[supply_type][supply_category][account_map.get(account_type)] += \
|
||||||
flt(tax_details.get((account_name, gst_category), {}).get("amount"), 2)
|
flt(tax_details.get((account_name, gst_category), {}).get("amount"), 2)
|
||||||
|
|
||||||
for k, v in iteritems(account_map):
|
|
||||||
txval -= self.report_dict.get(supply_type, {}).get(supply_category, {}).get(v, 0)
|
|
||||||
|
|
||||||
self.report_dict[supply_type][supply_category]["txval"] += flt(txval, 2)
|
self.report_dict[supply_type][supply_category]["txval"] += flt(txval, 2)
|
||||||
|
|
||||||
def set_inter_state_supply(self, inter_state_supply):
|
def set_inter_state_supply(self, inter_state_supply):
|
||||||
@ -256,7 +253,7 @@ class GSTR3BReport(Document):
|
|||||||
def get_total_taxable_value(self, doctype, reverse_charge):
|
def get_total_taxable_value(self, doctype, reverse_charge):
|
||||||
|
|
||||||
return frappe._dict(frappe.db.sql("""
|
return frappe._dict(frappe.db.sql("""
|
||||||
select gst_category, sum(base_grand_total) as total
|
select gst_category, sum(net_total) as total
|
||||||
from `tab{doctype}`
|
from `tab{doctype}`
|
||||||
where docstatus = 1 and month(posting_date) = %s
|
where docstatus = 1 and month(posting_date) = %s
|
||||||
and year(posting_date) = %s and reverse_charge = %s
|
and year(posting_date) = %s and reverse_charge = %s
|
||||||
@ -309,26 +306,27 @@ class GSTR3BReport(Document):
|
|||||||
inter_state_supply_tax_mapping.setdefault(d.name, {
|
inter_state_supply_tax_mapping.setdefault(d.name, {
|
||||||
'place_of_supply': d.place_of_supply,
|
'place_of_supply': d.place_of_supply,
|
||||||
'taxable_value': d.net_total,
|
'taxable_value': d.net_total,
|
||||||
|
'gst_category': d.gst_category,
|
||||||
'camt': 0.0,
|
'camt': 0.0,
|
||||||
'samt': 0.0,
|
'samt': 0.0,
|
||||||
'iamt': 0.0,
|
'iamt': 0.0,
|
||||||
'csamt': 0.0
|
'csamt': 0.0
|
||||||
})
|
})
|
||||||
|
|
||||||
if d.account_head in [d.cgst_account for d in self.account_heads]:
|
if d.account_head in [a.cgst_account for a in self.account_heads]:
|
||||||
inter_state_supply_tax_mapping[d.name]['camt'] += d.tax_amount
|
inter_state_supply_tax_mapping[d.name]['camt'] += d.tax_amount
|
||||||
|
|
||||||
if d.account_head in [d.sgst_account for d in self.account_heads]:
|
if d.account_head in [a.sgst_account for a in self.account_heads]:
|
||||||
inter_state_supply_tax_mapping[d.name]['samt'] += d.tax_amount
|
inter_state_supply_tax_mapping[d.name]['samt'] += d.tax_amount
|
||||||
|
|
||||||
if d.account_head in [d.igst_account for d in self.account_heads]:
|
if d.account_head in [a.igst_account for a in self.account_heads]:
|
||||||
inter_state_supply_tax_mapping[d.name]['iamt'] += d.tax_amount
|
inter_state_supply_tax_mapping[d.name]['iamt'] += d.tax_amount
|
||||||
|
|
||||||
if d.account_head in [d.cess_account for d in self.account_heads]:
|
if d.account_head in [a.cess_account for a in self.account_heads]:
|
||||||
inter_state_supply_tax_mapping[d.name]['csamt'] += d.tax_amount
|
inter_state_supply_tax_mapping[d.name]['csamt'] += d.tax_amount
|
||||||
|
|
||||||
for key, value in iteritems(inter_state_supply_tax_mapping):
|
for key, value in iteritems(inter_state_supply_tax_mapping):
|
||||||
if d.place_of_supply:
|
if value.get('place_of_supply'):
|
||||||
osup_det = self.report_dict["sup_details"]["osup_det"]
|
osup_det = self.report_dict["sup_details"]["osup_det"]
|
||||||
osup_det["txval"] = flt(osup_det["txval"] + value['taxable_value'], 2)
|
osup_det["txval"] = flt(osup_det["txval"] + value['taxable_value'], 2)
|
||||||
osup_det["iamt"] = flt(osup_det["iamt"] + value['iamt'], 2)
|
osup_det["iamt"] = flt(osup_det["iamt"] + value['iamt'], 2)
|
||||||
@ -336,15 +334,15 @@ class GSTR3BReport(Document):
|
|||||||
osup_det["samt"] = flt(osup_det["samt"] + value['samt'], 2)
|
osup_det["samt"] = flt(osup_det["samt"] + value['samt'], 2)
|
||||||
osup_det["csamt"] = flt(osup_det["csamt"] + value['csamt'], 2)
|
osup_det["csamt"] = flt(osup_det["csamt"] + value['csamt'], 2)
|
||||||
|
|
||||||
if state_number != d.place_of_supply.split("-")[0]:
|
if state_number != value.get('place_of_supply').split("-")[0]:
|
||||||
inter_state_supply_details.setdefault((d.gst_category, d.place_of_supply), {
|
inter_state_supply_details.setdefault((value.get('gst_category'), value.get('place_of_supply')), {
|
||||||
"txval": 0.0,
|
"txval": 0.0,
|
||||||
"pos": d.place_of_supply.split("-")[0],
|
"pos": value.get('place_of_supply').split("-")[0],
|
||||||
"iamt": 0.0
|
"iamt": 0.0
|
||||||
})
|
})
|
||||||
|
|
||||||
inter_state_supply_details[(d.gst_category, d.place_of_supply)]['txval'] += value['taxable_value']
|
inter_state_supply_details[(value.get('gst_category'), value.get('place_of_supply'))]['txval'] += value['taxable_value']
|
||||||
inter_state_supply_details[(d.gst_category, d.place_of_supply)]['iamt'] += value['iamt']
|
inter_state_supply_details[(value.get('gst_category'), value.get('place_of_supply'))]['iamt'] += value['iamt']
|
||||||
|
|
||||||
return inter_state_supply_details
|
return inter_state_supply_details
|
||||||
|
|
||||||
|
@ -131,6 +131,9 @@ class Gstr1Report(object):
|
|||||||
taxable_value += abs(net_amount)
|
taxable_value += abs(net_amount)
|
||||||
elif tax_rate:
|
elif tax_rate:
|
||||||
taxable_value += abs(net_amount)
|
taxable_value += abs(net_amount)
|
||||||
|
elif not tax_rate and self.filters.get('type_of_business') == 'EXPORT' \
|
||||||
|
and invoice_details.get('export_type') == "Without Payment of Tax":
|
||||||
|
taxable_value += abs(net_amount)
|
||||||
|
|
||||||
row += [tax_rate or 0, taxable_value]
|
row += [tax_rate or 0, taxable_value]
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ def get_data():
|
|||||||
'Payment Entry': 'party',
|
'Payment Entry': 'party',
|
||||||
'Quotation': 'party_name',
|
'Quotation': 'party_name',
|
||||||
'Opportunity': 'party_name',
|
'Opportunity': 'party_name',
|
||||||
'Bank Account': 'party'
|
'Bank Account': 'party',
|
||||||
|
'Subscription': 'party'
|
||||||
},
|
},
|
||||||
'dynamic_links': {
|
'dynamic_links': {
|
||||||
'party_name': ['Customer', 'quotation_to']
|
'party_name': ['Customer', 'quotation_to']
|
||||||
|
@ -14,10 +14,9 @@ from six import string_types
|
|||||||
def get_items(start, page_length, price_list, item_group, search_value="", pos_profile=None):
|
def get_items(start, page_length, price_list, item_group, search_value="", pos_profile=None):
|
||||||
data = dict()
|
data = dict()
|
||||||
warehouse = ""
|
warehouse = ""
|
||||||
display_items_in_stock = 0
|
|
||||||
|
|
||||||
if pos_profile:
|
if pos_profile:
|
||||||
warehouse, display_items_in_stock = frappe.db.get_value('POS Profile', pos_profile, ['warehouse', 'display_items_in_stock'])
|
warehouse = frappe.db.get_value('POS Profile', pos_profile, ['warehouse'])
|
||||||
|
|
||||||
if not frappe.db.exists('Item Group', item_group):
|
if not frappe.db.exists('Item Group', item_group):
|
||||||
item_group = get_root_of('Item Group')
|
item_group = get_root_of('Item Group')
|
||||||
@ -85,7 +84,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
|
|||||||
item_price = item_prices.get(item_code) or {}
|
item_price = item_prices.get(item_code) or {}
|
||||||
item_stock_qty = get_stock_availability(item_code, warehouse)
|
item_stock_qty = get_stock_availability(item_code, warehouse)
|
||||||
|
|
||||||
if display_items_in_stock and not item_stock_qty:
|
if not item_stock_qty:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
row = {}
|
row = {}
|
||||||
|
@ -35,7 +35,8 @@ erpnext.PointOfSale.Controller = class {
|
|||||||
create_opening_voucher() {
|
create_opening_voucher() {
|
||||||
const table_fields = [
|
const table_fields = [
|
||||||
{ fieldname: "mode_of_payment", fieldtype: "Link", in_list_view: 1, label: "Mode of Payment", options: "Mode of Payment", reqd: 1 },
|
{ fieldname: "mode_of_payment", fieldtype: "Link", in_list_view: 1, label: "Mode of Payment", options: "Mode of Payment", reqd: 1 },
|
||||||
{ fieldname: "opening_amount", fieldtype: "Currency", in_list_view: 1, label: "Opening Amount", options: "company:company_currency", reqd: 1 }
|
{ fieldname: "opening_amount", fieldtype: "Currency", default: 0, in_list_view: 1, label: "Opening Amount",
|
||||||
|
options: "company:company_currency", reqd: 1 }
|
||||||
];
|
];
|
||||||
|
|
||||||
const dialog = new frappe.ui.Dialog({
|
const dialog = new frappe.ui.Dialog({
|
||||||
@ -66,7 +67,7 @@ erpnext.PointOfSale.Controller = class {
|
|||||||
frappe.db.get_doc("POS Closing Entry", pos_closing_entry.name).then(({ payment_reconciliation }) => {
|
frappe.db.get_doc("POS Closing Entry", pos_closing_entry.name).then(({ payment_reconciliation }) => {
|
||||||
dialog.fields_dict.balance_details.df.data = [];
|
dialog.fields_dict.balance_details.df.data = [];
|
||||||
payment_reconciliation.forEach(pay => {
|
payment_reconciliation.forEach(pay => {
|
||||||
const { mode_of_payment, closing_amount } = pay;
|
const { mode_of_payment } = pay;
|
||||||
dialog.fields_dict.balance_details.df.data.push({
|
dialog.fields_dict.balance_details.df.data.push({
|
||||||
mode_of_payment: mode_of_payment
|
mode_of_payment: mode_of_payment
|
||||||
});
|
});
|
||||||
@ -152,7 +153,7 @@ erpnext.PointOfSale.Controller = class {
|
|||||||
},
|
},
|
||||||
() => this.make_new_invoice(),
|
() => this.make_new_invoice(),
|
||||||
() => frappe.dom.unfreeze(),
|
() => frappe.dom.unfreeze(),
|
||||||
() => this.page.set_title(__('Point of Sale Beta')),
|
() => this.page.set_title(__('Point of Sale')),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user