Merge branch 'develop' into UX
This commit is contained in:
commit
99522252c4
@ -328,6 +328,21 @@ class TestPricingRule(unittest.TestCase):
|
||||
self.assertEquals(item.discount_amount, 110)
|
||||
self.assertEquals(item.rate, 990)
|
||||
|
||||
def test_pricing_rule_with_margin_and_discount_amount(self):
|
||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||
make_pricing_rule(selling=1, margin_type="Percentage", margin_rate_or_amount=10,
|
||||
rate_or_discount="Discount Amount", discount_amount=110)
|
||||
si = create_sales_invoice(do_not_save=True)
|
||||
si.items[0].price_list_rate = 1000
|
||||
si.payment_schedule = []
|
||||
si.insert(ignore_permissions=True)
|
||||
|
||||
item = si.items[0]
|
||||
self.assertEquals(item.margin_rate_or_amount, 10)
|
||||
self.assertEquals(item.rate_with_margin, 1100)
|
||||
self.assertEquals(item.discount_amount, 110)
|
||||
self.assertEquals(item.rate, 990)
|
||||
|
||||
def test_pricing_rule_for_product_discount_on_same_item(self):
|
||||
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
|
||||
test_record = {
|
||||
@ -560,6 +575,7 @@ def make_pricing_rule(**args):
|
||||
"margin_rate_or_amount": args.margin_rate_or_amount or 0.0,
|
||||
"condition": args.condition or '',
|
||||
"priority": 1,
|
||||
"discount_amount": args.discount_amount or 0.0,
|
||||
"apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0
|
||||
})
|
||||
|
||||
|
@ -127,7 +127,6 @@
|
||||
"write_off_cost_center",
|
||||
"advances_section",
|
||||
"allocate_advances_automatically",
|
||||
"adjust_advance_taxes",
|
||||
"get_advances",
|
||||
"advances",
|
||||
"payment_schedule_section",
|
||||
@ -1326,13 +1325,6 @@
|
||||
"label": "Project",
|
||||
"options": "Project"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Taxes paid while advance payment will be adjusted against this invoice",
|
||||
"fieldname": "adjust_advance_taxes",
|
||||
"fieldtype": "Check",
|
||||
"label": "Adjust Advance Taxes"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.is_internal_supplier",
|
||||
"description": "Unrealized Profit / Loss account for intra-company transfers",
|
||||
@ -1378,7 +1370,7 @@
|
||||
"idx": 204,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-09 21:12:30.422084",
|
||||
"modified": "2021-03-30 21:45:58.334107",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
@ -406,9 +406,10 @@ def check_if_advance_entry_modified(args):
|
||||
throw(_("""Payment Entry has been modified after you pulled it. Please pull it again."""))
|
||||
|
||||
def validate_allocated_amount(args):
|
||||
precision = args.get('precision') or frappe.db.get_single_value("System Settings", "currency_precision")
|
||||
if args.get("allocated_amount") < 0:
|
||||
throw(_("Allocated amount cannot be negative"))
|
||||
elif args.get("allocated_amount") > args.get("unadjusted_amount"):
|
||||
elif flt(args.get("allocated_amount"), precision) > flt(args.get("unadjusted_amount"), precision):
|
||||
throw(_("Allocated amount cannot be greater than unadjusted amount"))
|
||||
|
||||
def update_reference_in_journal_entry(d, jv_obj):
|
||||
|
@ -659,6 +659,7 @@ class AccountsController(TransactionBase):
|
||||
'dr_or_cr': dr_or_cr,
|
||||
'unadjusted_amount': flt(d.advance_amount),
|
||||
'allocated_amount': flt(d.allocated_amount),
|
||||
'precision': d.precision('advance_amount'),
|
||||
'exchange_rate': (self.conversion_rate
|
||||
if self.party_account_currency != self.company_currency else 1),
|
||||
'grand_total': (self.base_grand_total
|
||||
|
@ -406,8 +406,7 @@ class StockController(AccountsController):
|
||||
def set_rate_of_stock_uom(self):
|
||||
if self.doctype in ["Purchase Receipt", "Purchase Invoice", "Purchase Order", "Sales Invoice", "Sales Order", "Delivery Note", "Quotation"]:
|
||||
for d in self.get("items"):
|
||||
if d.conversion_factor:
|
||||
d.stock_uom_rate = d.rate / d.conversion_factor
|
||||
d.stock_uom_rate = d.rate / (d.conversion_factor or 1)
|
||||
|
||||
def validate_internal_transfer(self):
|
||||
if self.doctype in ('Sales Invoice', 'Delivery Note', 'Purchase Invoice', 'Purchase Receipt') \
|
||||
|
8
erpnext/crm/doctype/lead_source/lead_source.js
Normal file
8
erpnext/crm/doctype/lead_source/lead_source.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Lead Source', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
62
erpnext/crm/doctype/lead_source/lead_source.json
Normal file
62
erpnext/crm/doctype/lead_source/lead_source.json
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:source_name",
|
||||
"creation": "2016-09-16 01:47:47.382372",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"source_name",
|
||||
"details"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "source_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Source Name",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "details",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Details"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2021-02-08 12:51:48.971517",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Lead Source",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales User",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LeadSource(Document):
|
@ -1,12 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Lead Source')
|
||||
|
||||
class TestLeadSource(unittest.TestCase):
|
||||
pass
|
@ -23,6 +23,7 @@
|
||||
"rate_of_interest",
|
||||
"is_secured_loan",
|
||||
"disbursement_date",
|
||||
"closure_date",
|
||||
"disbursed_amount",
|
||||
"column_break_11",
|
||||
"maximum_loan_amount",
|
||||
@ -348,12 +349,18 @@
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "closure_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Closure Date",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-11-24 12:27:23.208240",
|
||||
"modified": "2021-04-10 09:28:21.946972",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan",
|
||||
|
@ -523,33 +523,7 @@ class TestLoan(unittest.TestCase):
|
||||
self.assertEqual(flt(repayment_entry.total_interest_paid, 0), flt(interest_amount, 0))
|
||||
|
||||
def test_penalty(self):
|
||||
pledge = [{
|
||||
"loan_security": "Test Security 1",
|
||||
"qty": 4000.00
|
||||
}]
|
||||
|
||||
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_application, posting_date='2019-10-01')
|
||||
loan.submit()
|
||||
|
||||
self.assertEquals(loan.loan_amount, 1000000)
|
||||
|
||||
first_date = '2019-10-01'
|
||||
last_date = '2019-10-30'
|
||||
|
||||
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
|
||||
process_loan_interest_accrual_for_demand_loans(posting_date = last_date)
|
||||
|
||||
amounts = calculate_amounts(loan.name, add_days(last_date, 1))
|
||||
paid_amount = amounts['interest_amount']/2
|
||||
|
||||
repayment_entry = create_repayment_entry(loan.name, self.applicant2, add_days(last_date, 5),
|
||||
paid_amount)
|
||||
|
||||
repayment_entry.submit()
|
||||
|
||||
loan, amounts = create_loan_scenario_for_penalty(self)
|
||||
# 30 days - grace period
|
||||
penalty_days = 30 - 4
|
||||
penalty_applicable_amount = flt(amounts['interest_amount']/2)
|
||||
@ -559,8 +533,28 @@ class TestLoan(unittest.TestCase):
|
||||
calculated_penalty_amount = frappe.db.get_value('Loan Interest Accrual',
|
||||
{'process_loan_interest_accrual': process, 'loan': loan.name}, 'penalty_amount')
|
||||
|
||||
self.assertEquals(loan.loan_amount, 1000000)
|
||||
self.assertEquals(calculated_penalty_amount, penalty_amount)
|
||||
|
||||
def test_penalty_repayment(self):
|
||||
loan, dummy = create_loan_scenario_for_penalty(self)
|
||||
amounts = calculate_amounts(loan.name, '2019-11-30 00:00:00')
|
||||
|
||||
first_penalty = 10000
|
||||
second_penalty = amounts['penalty_amount'] - 10000
|
||||
|
||||
repayment_entry = create_repayment_entry(loan.name, self.applicant2, '2019-11-30 00:00:00', 10000)
|
||||
repayment_entry.submit()
|
||||
|
||||
amounts = calculate_amounts(loan.name, '2019-11-30 00:00:01')
|
||||
self.assertEquals(amounts['penalty_amount'], second_penalty)
|
||||
|
||||
repayment_entry = create_repayment_entry(loan.name, self.applicant2, '2019-11-30 00:00:01', second_penalty)
|
||||
repayment_entry.submit()
|
||||
|
||||
amounts = calculate_amounts(loan.name, '2019-11-30 00:00:02')
|
||||
self.assertEquals(amounts['penalty_amount'], 0)
|
||||
|
||||
def test_loan_write_off_limit(self):
|
||||
pledge = [{
|
||||
"loan_security": "Test Security 1",
|
||||
@ -651,6 +645,32 @@ class TestLoan(unittest.TestCase):
|
||||
amounts = calculate_amounts(loan.name, add_days(last_date, 5))
|
||||
self.assertEquals(flt(amounts['pending_principal_amount'], 0), 0)
|
||||
|
||||
def create_loan_scenario_for_penalty(doc):
|
||||
pledge = [{
|
||||
"loan_security": "Test Security 1",
|
||||
"qty": 4000.00
|
||||
}]
|
||||
|
||||
loan_application = create_loan_application('_Test Company', doc.applicant2, 'Demand Loan', pledge)
|
||||
create_pledge(loan_application)
|
||||
loan = create_demand_loan(doc.applicant2, "Demand Loan", loan_application, posting_date='2019-10-01')
|
||||
loan.submit()
|
||||
|
||||
first_date = '2019-10-01'
|
||||
last_date = '2019-10-30'
|
||||
|
||||
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=first_date)
|
||||
process_loan_interest_accrual_for_demand_loans(posting_date = last_date)
|
||||
|
||||
amounts = calculate_amounts(loan.name, add_days(last_date, 1))
|
||||
paid_amount = amounts['interest_amount']/2
|
||||
|
||||
repayment_entry = create_repayment_entry(loan.name, doc.applicant2, add_days(last_date, 5),
|
||||
paid_amount)
|
||||
|
||||
repayment_entry.submit()
|
||||
|
||||
return loan, amounts
|
||||
|
||||
def create_loan_accounts():
|
||||
if not frappe.db.exists("Account", "Loans and Advances (Assets) - _TC"):
|
||||
|
@ -20,6 +20,10 @@
|
||||
"cost_center",
|
||||
"customer_details_section",
|
||||
"bank_account",
|
||||
"disbursement_references_section",
|
||||
"reference_date",
|
||||
"column_break_17",
|
||||
"reference_number",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
@ -126,12 +130,31 @@
|
||||
{
|
||||
"fieldname": "column_break_8",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "disbursement_references_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Disbursement References"
|
||||
},
|
||||
{
|
||||
"fieldname": "reference_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Reference Date"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "reference_number",
|
||||
"fieldtype": "Data",
|
||||
"label": "Reference Number"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-11-06 10:04:30.882322",
|
||||
"modified": "2021-04-10 10:03:41.502210",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan Disbursement",
|
||||
|
@ -239,14 +239,16 @@
|
||||
{
|
||||
"fieldname": "total_penalty_paid",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 1,
|
||||
"label": "Total Penalty Paid",
|
||||
"options": "Company:company:default_currency"
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-04-05 13:45:19.137896",
|
||||
"modified": "2021-04-10 10:00:31.859076",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Loan Management",
|
||||
"name": "Loan Repayment",
|
||||
|
@ -75,7 +75,7 @@ class LoanRepayment(AccountsController):
|
||||
"docstatus": 1, "against_loan": self.against_loan}, 'posting_date')
|
||||
|
||||
if future_repayment_date:
|
||||
frappe.throw("Repayment already made till date {0}".format(getdate(future_repayment_date)))
|
||||
frappe.throw("Repayment already made till date {0}".format(get_datetime(future_repayment_date)))
|
||||
|
||||
def validate_amount(self):
|
||||
precision = cint(frappe.db.get_default("currency_precision")) or 2
|
||||
@ -83,10 +83,6 @@ class LoanRepayment(AccountsController):
|
||||
if not self.amount_paid:
|
||||
frappe.throw(_("Amount paid cannot be zero"))
|
||||
|
||||
if not self.shortfall_amount and self.amount_paid < self.penalty_amount:
|
||||
msg = _("Paid amount cannot be less than {0}").format(self.penalty_amount)
|
||||
frappe.throw(msg)
|
||||
|
||||
def book_unaccrued_interest(self):
|
||||
precision = cint(frappe.db.get_default("currency_precision")) or 2
|
||||
if self.total_interest_paid > self.interest_payable:
|
||||
@ -231,6 +227,14 @@ class LoanRepayment(AccountsController):
|
||||
gle_map = []
|
||||
loan_details = frappe.get_doc("Loan", self.against_loan)
|
||||
|
||||
if self.shortfall_amount and self.amount_paid > self.shortfall_amount:
|
||||
remarks = _("Shortfall Repayment of {0}.\nRepayment against Loan: {1}").format(self.shortfall_amount,
|
||||
self.against_loan)
|
||||
elif self.shortfall_amount:
|
||||
remarks = _("Shortfall Repayment of {0}").format(self.shortfall_amount)
|
||||
else:
|
||||
remarks = _("Repayment against Loan: ") + self.against_loan
|
||||
|
||||
if self.total_penalty_paid:
|
||||
gle_map.append(
|
||||
self.get_gl_dict({
|
||||
@ -271,7 +275,7 @@ class LoanRepayment(AccountsController):
|
||||
"debit_in_account_currency": self.amount_paid,
|
||||
"against_voucher_type": "Loan",
|
||||
"against_voucher": self.against_loan,
|
||||
"remarks": _("Repayment against Loan: ") + self.against_loan,
|
||||
"remarks": remarks,
|
||||
"cost_center": self.cost_center,
|
||||
"posting_date": getdate(self.posting_date)
|
||||
})
|
||||
@ -287,7 +291,7 @@ class LoanRepayment(AccountsController):
|
||||
"credit_in_account_currency": self.amount_paid,
|
||||
"against_voucher_type": "Loan",
|
||||
"against_voucher": self.against_loan,
|
||||
"remarks": _("Repayment against Loan: ") + self.against_loan,
|
||||
"remarks": remarks,
|
||||
"cost_center": self.cost_center,
|
||||
"posting_date": getdate(self.posting_date)
|
||||
})
|
||||
@ -338,6 +342,18 @@ def get_accrued_interest_entries(against_loan, posting_date=None):
|
||||
|
||||
return unpaid_accrued_entries
|
||||
|
||||
def get_penalty_details(against_loan):
|
||||
penalty_details = frappe.db.sql("""
|
||||
SELECT posting_date, (penalty_amount - total_penalty_paid) as pending_penalty_amount
|
||||
FROM `tabLoan Repayment` where posting_date >= (SELECT MAX(posting_date) from `tabLoan Repayment`
|
||||
where against_loan = %s) and docstatus = 1 and against_loan = %s
|
||||
""", (against_loan, against_loan))
|
||||
|
||||
if penalty_details:
|
||||
return penalty_details[0][0], flt(penalty_details[0][1])
|
||||
else:
|
||||
return None, 0
|
||||
|
||||
# This function returns the amounts that are payable at the time of loan repayment based on posting date
|
||||
# So it pulls all the unpaid Loan Interest Accrual Entries and calculates the penalty if applicable
|
||||
|
||||
@ -348,6 +364,7 @@ def get_amounts(amounts, against_loan, posting_date):
|
||||
loan_type_details = frappe.get_doc("Loan Type", against_loan_doc.loan_type)
|
||||
accrued_interest_entries = get_accrued_interest_entries(against_loan_doc.name, posting_date)
|
||||
|
||||
computed_penalty_date, pending_penalty_amount = get_penalty_details(against_loan)
|
||||
pending_accrual_entries = {}
|
||||
|
||||
total_pending_interest = 0
|
||||
@ -362,8 +379,13 @@ def get_amounts(amounts, against_loan, posting_date):
|
||||
# and if no_of_late days are positive then penalty is levied
|
||||
|
||||
due_date = add_days(entry.posting_date, 1)
|
||||
no_of_late_days = date_diff(posting_date,
|
||||
add_days(due_date, loan_type_details.grace_period_in_days)) + 1
|
||||
due_date_after_grace_period = add_days(due_date, loan_type_details.grace_period_in_days)
|
||||
|
||||
# Consider one day after already calculated penalty
|
||||
if computed_penalty_date and getdate(computed_penalty_date) >= due_date_after_grace_period:
|
||||
due_date_after_grace_period = add_days(computed_penalty_date, 1)
|
||||
|
||||
no_of_late_days = date_diff(posting_date, due_date_after_grace_period) + 1
|
||||
|
||||
if no_of_late_days > 0 and (not against_loan_doc.repay_from_salary) and entry.accrual_type == 'Regular':
|
||||
penalty_amount += (entry.interest_amount * (loan_type_details.penalty_interest_rate / 100) * no_of_late_days)
|
||||
@ -401,7 +423,7 @@ def get_amounts(amounts, against_loan, posting_date):
|
||||
amounts["pending_principal_amount"] = flt(pending_principal_amount, precision)
|
||||
amounts["payable_principal_amount"] = flt(payable_principal_amount, precision)
|
||||
amounts["interest_amount"] = flt(total_pending_interest, precision)
|
||||
amounts["penalty_amount"] = flt(penalty_amount, precision)
|
||||
amounts["penalty_amount"] = flt(penalty_amount + pending_penalty_amount, precision)
|
||||
amounts["payable_amount"] = flt(payable_principal_amount + total_pending_interest + penalty_amount, precision)
|
||||
amounts["pending_accrual_entries"] = pending_accrual_entries
|
||||
amounts["unaccrued_interest"] = flt(unaccrued_interest, precision)
|
||||
|
@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_datetime, flt
|
||||
from frappe.utils import get_datetime, flt, getdate
|
||||
import json
|
||||
from six import iteritems
|
||||
from erpnext.loan_management.doctype.loan_security_price.loan_security_price import get_loan_security_price
|
||||
@ -113,7 +113,11 @@ class LoanSecurityUnpledge(Document):
|
||||
pledged_qty += qty
|
||||
|
||||
if not pledged_qty:
|
||||
frappe.db.set_value('Loan', self.loan, 'status', 'Closed')
|
||||
frappe.db.set_value('Loan', self.loan,
|
||||
{
|
||||
'status': 'Closed',
|
||||
'closure_date': getdate()
|
||||
})
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_pledged_security_qty(loan):
|
||||
|
@ -763,4 +763,5 @@ erpnext.patches.v13_0.setup_gratuity_rule_for_india_and_uae
|
||||
erpnext.patches.v13_0.setup_uae_vat_fields
|
||||
execute:frappe.db.set_value('System Settings', None, 'app_name', 'ERPNext')
|
||||
erpnext.patches.v13_0.rename_discharge_date_in_ip_record
|
||||
erpnext.patches.v12_0.add_gst_category_in_delivery_note
|
||||
erpnext.patches.v12_0.purchase_receipt_status
|
||||
|
19
erpnext/patches/v12_0/add_gst_category_in_delivery_note.py
Normal file
19
erpnext/patches/v12_0/add_gst_category_in_delivery_note.py
Normal file
@ -0,0 +1,19 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||
|
||||
def execute():
|
||||
company = frappe.get_all('Company', filters = {'country': 'India'})
|
||||
if not company:
|
||||
return
|
||||
|
||||
custom_fields = {
|
||||
'Delivery Note': [
|
||||
dict(fieldname='gst_category', label='GST Category',
|
||||
fieldtype='Select', insert_after='gst_vehicle_type', print_hide=1,
|
||||
options='\nRegistered Regular\nRegistered Composition\nUnregistered\nSEZ\nOverseas\nConsumer\nDeemed Export\nUIN Holders',
|
||||
fetch_from='customer.gst_category', fetch_if_empty=1),
|
||||
]
|
||||
}
|
||||
|
||||
create_custom_fields(custom_fields, update=True)
|
@ -18,6 +18,7 @@ def execute():
|
||||
|
||||
for old_dt, new_dt in doctypes.items():
|
||||
if not frappe.db.table_exists(new_dt) and frappe.db.table_exists(old_dt):
|
||||
frappe.reload_doc('healthcare', 'doctype', frappe.scrub(old_dt))
|
||||
frappe.rename_doc('DocType', old_dt, new_dt, force=True)
|
||||
frappe.reload_doc('healthcare', 'doctype', frappe.scrub(new_dt))
|
||||
frappe.delete_doc_if_exists('DocType', old_dt)
|
||||
@ -36,6 +37,18 @@ def execute():
|
||||
SET parentfield = %(parentfield)s
|
||||
""".format(doctype), {'parentfield': parentfield})
|
||||
|
||||
# copy renamed child table fields (fields were already renamed in old doctype json, hence sql)
|
||||
frappe.db.sql("""UPDATE `tabNormal Test Result` SET lab_test_name = test_name""")
|
||||
frappe.db.sql("""UPDATE `tabNormal Test Result` SET lab_test_event = test_event""")
|
||||
frappe.db.sql("""UPDATE `tabNormal Test Result` SET lab_test_uom = test_uom""")
|
||||
frappe.db.sql("""UPDATE `tabNormal Test Result` SET lab_test_comment = test_comment""")
|
||||
frappe.db.sql("""UPDATE `tabNormal Test Template` SET lab_test_event = test_event""")
|
||||
frappe.db.sql("""UPDATE `tabNormal Test Template` SET lab_test_uom = test_uom""")
|
||||
frappe.db.sql("""UPDATE `tabDescriptive Test Result` SET lab_test_particulars = test_particulars""")
|
||||
frappe.db.sql("""UPDATE `tabLab Test Group Template` SET lab_test_template = test_template""")
|
||||
frappe.db.sql("""UPDATE `tabLab Test Group Template` SET lab_test_description = test_description""")
|
||||
frappe.db.sql("""UPDATE `tabLab Test Group Template` SET lab_test_rate = test_rate""")
|
||||
|
||||
# rename field
|
||||
frappe.reload_doc('healthcare', 'doctype', 'lab_test')
|
||||
if frappe.db.has_column('Lab Test', 'special_toggle'):
|
||||
|
@ -20,9 +20,11 @@ def execute():
|
||||
frappe.clear_cache()
|
||||
frappe.flags.warehouse_account_map = {}
|
||||
|
||||
company_list = []
|
||||
|
||||
data = frappe.db.sql('''
|
||||
SELECT
|
||||
name, item_code, warehouse, voucher_type, voucher_no, posting_date, posting_time
|
||||
name, item_code, warehouse, voucher_type, voucher_no, posting_date, posting_time, company
|
||||
FROM
|
||||
`tabStock Ledger Entry`
|
||||
WHERE
|
||||
@ -36,6 +38,9 @@ def execute():
|
||||
total_sle = len(data)
|
||||
i = 0
|
||||
for d in data:
|
||||
if d.company not in company_list:
|
||||
company_list.append(d.company)
|
||||
|
||||
update_entries_after({
|
||||
"item_code": d.item_code,
|
||||
"warehouse": d.warehouse,
|
||||
@ -53,8 +58,10 @@ def execute():
|
||||
|
||||
print("Reposting General Ledger Entries...")
|
||||
|
||||
for row in frappe.get_all('Company', filters= {'enable_perpetual_inventory': 1}):
|
||||
update_gl_entries_after(posting_date, posting_time, company=row.name)
|
||||
if data:
|
||||
for row in frappe.get_all('Company', filters= {'enable_perpetual_inventory': 1}):
|
||||
if row.name in company_list:
|
||||
update_gl_entries_after(posting_date, posting_time, company=row.name)
|
||||
|
||||
frappe.db.auto_commit_on_many_writes = 0
|
||||
|
||||
|
@ -8,6 +8,7 @@ def execute():
|
||||
|
||||
frappe.reload_doc("healthcare", "doctype", "Therapy Session")
|
||||
frappe.reload_doc("healthcare", "doctype", "Inpatient Medication Order")
|
||||
frappe.reload_doc("healthcare", "doctype", "Clinical Procedure")
|
||||
frappe.reload_doc("healthcare", "doctype", "Patient History Settings")
|
||||
frappe.reload_doc("healthcare", "doctype", "Patient History Standard Document Type")
|
||||
frappe.reload_doc("healthcare", "doctype", "Patient History Custom Document Type")
|
||||
|
@ -5,7 +5,7 @@ from frappe import _
|
||||
def execute():
|
||||
from erpnext.setup.setup_wizard.operations.install_fixtures import default_lead_sources
|
||||
|
||||
frappe.reload_doc('selling', 'doctype', 'lead_source')
|
||||
frappe.reload_doc('crm', 'doctype', 'lead_source')
|
||||
|
||||
frappe.local.lang = frappe.db.get_default("lang") or 'en'
|
||||
|
||||
|
@ -33,12 +33,16 @@ class TestProject(unittest.TestCase):
|
||||
|
||||
def test_project_template_having_parent_child_tasks(self):
|
||||
project_name = "Test Project with Template - Tasks with Parent-Child Relation"
|
||||
|
||||
if frappe.db.get_value('Project', {'project_name': project_name}, 'name'):
|
||||
project_name = frappe.db.get_value('Project', {'project_name': project_name}, 'name')
|
||||
|
||||
frappe.db.sql(""" delete from tabTask where project = %s """, project_name)
|
||||
frappe.delete_doc('Project', project_name)
|
||||
|
||||
task1 = task_exists("Test Template Task Parent")
|
||||
if not task1:
|
||||
task1 = create_task(subject="Test Template Task Parent", is_group=1, is_template=1, begin=1, duration=4)
|
||||
task1 = create_task(subject="Test Template Task Parent", is_group=1, is_template=1, begin=1, duration=10)
|
||||
|
||||
task2 = task_exists("Test Template Task Child 1")
|
||||
if not task2:
|
||||
@ -53,7 +57,7 @@ class TestProject(unittest.TestCase):
|
||||
tasks = frappe.get_all('Task', ['subject','exp_end_date','depends_on_tasks', 'name', 'parent_task'], dict(project=project.name), order_by='creation asc')
|
||||
|
||||
self.assertEqual(tasks[0].subject, 'Test Template Task Parent')
|
||||
self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, 1, 4))
|
||||
self.assertEqual(getdate(tasks[0].exp_end_date), calculate_end_date(project, 1, 10))
|
||||
|
||||
self.assertEqual(tasks[1].subject, 'Test Template Task Child 1')
|
||||
self.assertEqual(getdate(tasks[1].exp_end_date), calculate_end_date(project, 1, 3))
|
||||
|
@ -156,6 +156,13 @@ def make_custom_fields(update=True):
|
||||
fetch_if_empty=1),
|
||||
]
|
||||
|
||||
delivery_note_gst_category = [
|
||||
dict(fieldname='gst_category', label='GST Category',
|
||||
fieldtype='Select', insert_after='gst_vehicle_type', print_hide=1,
|
||||
options='\nRegistered Regular\nRegistered Composition\nUnregistered\nSEZ\nOverseas\nConsumer\nDeemed Export\nUIN Holders',
|
||||
fetch_from='customer.gst_category', fetch_if_empty=1),
|
||||
]
|
||||
|
||||
invoice_gst_fields = [
|
||||
dict(fieldname='invoice_copy', label='Invoice Copy',
|
||||
fieldtype='Select', insert_after='export_type', print_hide=1, allow_on_submit=1,
|
||||
@ -280,7 +287,7 @@ def make_custom_fields(update=True):
|
||||
'allow_on_submit': 1,
|
||||
'insert_after': 'customer_name_in_arabic',
|
||||
'translatable': 0,
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
si_ewaybill_fields = [
|
||||
@ -438,7 +445,7 @@ def make_custom_fields(update=True):
|
||||
'Purchase Order': purchase_invoice_gst_fields,
|
||||
'Purchase Receipt': purchase_invoice_gst_fields,
|
||||
'Sales Invoice': sales_invoice_gst_category + invoice_gst_fields + sales_invoice_shipping_fields + sales_invoice_gst_fields + si_ewaybill_fields + si_einvoice_fields,
|
||||
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields,
|
||||
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields + delivery_note_gst_category,
|
||||
'Sales Order': sales_invoice_gst_fields,
|
||||
'Tax Category': inter_state_gst_field,
|
||||
'Item': [
|
||||
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Lead Source', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
@ -1,131 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:source_name",
|
||||
"beta": 0,
|
||||
"creation": "2016-09-16 01:47:47.382372",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "source_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Source Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "details",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Details",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2020-09-16 02:03:01.441622",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Lead Source",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_seen": 0
|
||||
}
|
@ -279,11 +279,6 @@ erpnext.PointOfSale.Controller = class {
|
||||
const item_row = frappe.model.get_doc(cdt, cdn);
|
||||
if (item_row && item_row[fieldname] != value) {
|
||||
|
||||
if (fieldname === 'qty' && flt(value) == 0) {
|
||||
this.remove_item_from_cart();
|
||||
return;
|
||||
}
|
||||
|
||||
const { item_code, batch_no, uom } = this.item_details.current_item;
|
||||
const event = {
|
||||
field: fieldname,
|
||||
|
@ -27,7 +27,7 @@ def delete_company_transactions(company_name):
|
||||
if doctype not in ("Account", "Cost Center", "Warehouse", "Budget",
|
||||
"Party Account", "Employee", "Sales Taxes and Charges Template",
|
||||
"Purchase Taxes and Charges Template", "POS Profile", "BOM",
|
||||
"Company", "Bank Account", "Item Tax Template", "Mode Of Payment",
|
||||
"Company", "Bank Account", "Item Tax Template", "Mode Of Payment", "Mode of Payment Account",
|
||||
"Item Default", "Customer", "Supplier", "GST Account"):
|
||||
delete_for_doctype(doctype, company_name)
|
||||
|
||||
|
@ -494,7 +494,8 @@ def make_item_variant():
|
||||
|
||||
test_records = frappe.get_test_records('Item')
|
||||
|
||||
def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None, is_customer_provided_item=None, customer=None, is_purchase_item=None, opening_stock=None):
|
||||
def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None, is_customer_provided_item=None,
|
||||
customer=None, is_purchase_item=None, opening_stock=None, company=None):
|
||||
if not frappe.db.exists("Item", item_code):
|
||||
item = frappe.new_doc("Item")
|
||||
item.item_code = item_code
|
||||
@ -509,7 +510,7 @@ def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None,
|
||||
item.customer = customer or ''
|
||||
item.append("item_defaults", {
|
||||
"default_warehouse": warehouse or '_Test Warehouse - _TC',
|
||||
"company": "_Test Company"
|
||||
"company": company or "_Test Company"
|
||||
})
|
||||
item.save()
|
||||
else:
|
||||
|
@ -379,7 +379,6 @@ def create_stock_entry(pick_list):
|
||||
else:
|
||||
stock_entry = update_stock_entry_items_with_no_reference(pick_list, stock_entry)
|
||||
|
||||
stock_entry.set_incoming_rate()
|
||||
stock_entry.set_actual_qty()
|
||||
stock_entry.calculate_rate_and_amount()
|
||||
|
||||
|
@ -124,7 +124,7 @@ def repost_entries():
|
||||
return
|
||||
|
||||
for d in frappe.get_all('Company', filters= {'enable_perpetual_inventory': 1}):
|
||||
check_if_stock_and_account_balance_synced(today(), d.company)
|
||||
check_if_stock_and_account_balance_synced(today(), d.name)
|
||||
|
||||
def get_repost_item_valuation_entries():
|
||||
date = add_to_date(today(), hours=-12)
|
||||
|
@ -179,11 +179,15 @@ class TestStockEntry(unittest.TestCase):
|
||||
def test_material_transfer_gl_entry(self):
|
||||
company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')
|
||||
|
||||
mtn = make_stock_entry(item_code="_Test Item", source="Stores - TCP1",
|
||||
item_code = 'Hand Sanitizer - 001'
|
||||
create_item(item_code =item_code, is_stock_item = 1,
|
||||
is_purchase_item=1, opening_stock=1000, valuation_rate=10, company=company, warehouse="Stores - TCP1")
|
||||
|
||||
mtn = make_stock_entry(item_code=item_code, source="Stores - TCP1",
|
||||
target="Finished Goods - TCP1", qty=45, company=company)
|
||||
|
||||
self.check_stock_ledger_entries("Stock Entry", mtn.name,
|
||||
[["_Test Item", "Stores - TCP1", -45.0], ["_Test Item", "Finished Goods - TCP1", 45.0]])
|
||||
[[item_code, "Stores - TCP1", -45.0], [item_code, "Finished Goods - TCP1", 45.0]])
|
||||
|
||||
source_warehouse_account = get_inventory_account(mtn.company, mtn.get("items")[0].s_warehouse)
|
||||
|
||||
|
@ -48,44 +48,62 @@ frappe.ui.form.on("Issue", {
|
||||
}
|
||||
},
|
||||
|
||||
refresh: function (frm) {
|
||||
if (frm.doc.status !== "Closed") {
|
||||
if (frm.doc.service_level_agreement && frm.doc.agreement_status === "Ongoing") {
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Service Level Agreement",
|
||||
name: frm.doc.service_level_agreement
|
||||
},
|
||||
callback: function(data) {
|
||||
let statuses = data.message.pause_sla_on;
|
||||
const hold_statuses = [];
|
||||
$.each(statuses, (_i, entry) => {
|
||||
hold_statuses.push(entry.status);
|
||||
});
|
||||
if (hold_statuses.includes(frm.doc.status)) {
|
||||
frm.dashboard.clear_headline();
|
||||
let message = {"indicator": "orange", "msg": __("SLA is on hold since {0}", [moment(frm.doc.on_hold_since).fromNow(true)])};
|
||||
frm.dashboard.set_headline_alert(
|
||||
'<div class="row">' +
|
||||
'<div class="col-xs-12">' +
|
||||
'<span class="indicator whitespace-nowrap '+ message.indicator +'"><span>'+ message.msg +'</span></span> ' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
} else {
|
||||
set_time_to_resolve_and_response(frm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
refresh: function(frm) {
|
||||
|
||||
frm.add_custom_button(__("Close"), function () {
|
||||
// alert messages
|
||||
if (frm.doc.status !== "Closed" && frm.doc.service_level_agreement
|
||||
&& frm.doc.agreement_status === "Ongoing") {
|
||||
frappe.call({
|
||||
"method": "frappe.client.get",
|
||||
args: {
|
||||
doctype: "Service Level Agreement",
|
||||
name: frm.doc.service_level_agreement
|
||||
},
|
||||
callback: function(data) {
|
||||
let statuses = data.message.pause_sla_on;
|
||||
const hold_statuses = [];
|
||||
$.each(statuses, (_i, entry) => {
|
||||
hold_statuses.push(entry.status);
|
||||
});
|
||||
if (hold_statuses.includes(frm.doc.status)) {
|
||||
frm.dashboard.clear_headline();
|
||||
let message = { "indicator": "orange", "msg": __("SLA is on hold since {0}", [moment(frm.doc.on_hold_since).fromNow(true)]) };
|
||||
frm.dashboard.set_headline_alert(
|
||||
'<div class="row">' +
|
||||
'<div class="col-xs-12">' +
|
||||
'<span class="indicator whitespace-nowrap ' + message.indicator + '"><span>' + message.msg + '</span></span> ' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
} else {
|
||||
set_time_to_resolve_and_response(frm);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (frm.doc.service_level_agreement) {
|
||||
frm.dashboard.clear_headline();
|
||||
|
||||
let agreement_status = (frm.doc.agreement_status == "Fulfilled") ?
|
||||
{ "indicator": "green", "msg": "Service Level Agreement has been fulfilled" } :
|
||||
{ "indicator": "red", "msg": "Service Level Agreement Failed" };
|
||||
|
||||
frm.dashboard.set_headline_alert(
|
||||
'<div class="row">' +
|
||||
'<div class="col-xs-12">' +
|
||||
'<span class="indicator whitespace-nowrap ' + agreement_status.indicator + '"><span class="hidden-xs">' + agreement_status.msg + '</span></span> ' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
// buttons
|
||||
if (frm.doc.status !== "Closed") {
|
||||
frm.add_custom_button(__("Close"), function() {
|
||||
frm.set_value("status", "Closed");
|
||||
frm.save();
|
||||
});
|
||||
|
||||
frm.add_custom_button(__("Task"), function () {
|
||||
frm.add_custom_button(__("Task"), function() {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: "erpnext.support.doctype.issue.issue.make_task",
|
||||
frm: frm
|
||||
@ -93,23 +111,7 @@ frappe.ui.form.on("Issue", {
|
||||
}, __("Create"));
|
||||
|
||||
} else {
|
||||
if (frm.doc.service_level_agreement) {
|
||||
frm.dashboard.clear_headline();
|
||||
|
||||
let agreement_status = (frm.doc.agreement_status == "Fulfilled") ?
|
||||
{"indicator": "green", "msg": "Service Level Agreement has been fulfilled"} :
|
||||
{"indicator": "red", "msg": "Service Level Agreement Failed"};
|
||||
|
||||
frm.dashboard.set_headline_alert(
|
||||
'<div class="row">' +
|
||||
'<div class="col-xs-12">' +
|
||||
'<span class="indicator whitespace-nowrap '+ agreement_status.indicator +'"><span class="hidden-xs">'+ agreement_status.msg +'</span></span> ' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
frm.add_custom_button(__("Reopen"), function () {
|
||||
frm.add_custom_button(__("Reopen"), function() {
|
||||
frm.set_value("status", "Open");
|
||||
frm.save();
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ import json
|
||||
from frappe import _
|
||||
from frappe import utils
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import now_datetime, getdate, get_weekdays, add_to_date, get_time, get_datetime, time_diff_in_seconds
|
||||
from frappe.utils import cint, now_datetime, getdate, get_weekdays, add_to_date, get_time, get_datetime, time_diff_in_seconds
|
||||
from datetime import datetime, timedelta
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe.utils.user import is_website_user
|
||||
@ -128,8 +128,8 @@ class Issue(Document):
|
||||
|
||||
def update_agreement_status(self):
|
||||
if self.service_level_agreement and self.agreement_status == "Ongoing":
|
||||
if frappe.db.get_value("Issue", self.name, "response_by_variance") < 0 or \
|
||||
frappe.db.get_value("Issue", self.name, "resolution_by_variance") < 0:
|
||||
if cint(frappe.db.get_value("Issue", self.name, "response_by_variance")) < 0 or \
|
||||
cint(frappe.db.get_value("Issue", self.name, "resolution_by_variance")) < 0:
|
||||
|
||||
self.agreement_status = "Failed"
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user