Merge branch 'hotfix' into hotfix-customer-item-price-report
This commit is contained in:
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '11.1.46'
|
||||
__version__ = '11.1.47'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -121,7 +121,7 @@ frappe.treeview_settings["Account"] = {
|
||||
},
|
||||
onrender: function(node) {
|
||||
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
||||
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
||||
var dr_or_cr = in_list(["Liability", "Income", "Equity"], node.data.root_type) ? "Cr" : "Dr";
|
||||
if (node.data && node.data.balance!==undefined) {
|
||||
$('<span class="balance-area pull-right text-muted small">'
|
||||
+ (node.data.balance_in_account_currency ?
|
||||
|
||||
@@ -38,7 +38,7 @@ def get_loyalty_details(customer, loyalty_program, expiry_date=None, company=Non
|
||||
@frappe.whitelist()
|
||||
def get_loyalty_program_details_with_points(customer, loyalty_program=None, expiry_date=None, company=None, silent=False, include_expired_entry=False, current_transaction_amount=0):
|
||||
lp_details = get_loyalty_program_details(customer, loyalty_program, company=company, silent=silent)
|
||||
loyalty_program = frappe.get_doc("Loyalty Program", loyalty_program)
|
||||
loyalty_program = frappe.get_doc("Loyalty Program", loyalty_program or lp_details.loyalty_program)
|
||||
lp_details.update(get_loyalty_details(customer, loyalty_program.name, expiry_date, company, include_expired_entry))
|
||||
|
||||
tier_spent_level = sorted([d.as_dict() for d in loyalty_program.collection_rules],
|
||||
|
||||
@@ -558,7 +558,7 @@ def get_outstanding_reference_documents(args):
|
||||
|
||||
# Get negative outstanding sales /purchase invoices
|
||||
negative_outstanding_invoices = []
|
||||
if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
|
||||
if args.get("party_type") in ("Supplier", "Customer") and not args.get("voucher_no"):
|
||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
||||
args.get("party"), args.get("party_account"), party_account_currency, company_currency)
|
||||
|
||||
@@ -589,7 +589,7 @@ def get_outstanding_reference_documents(args):
|
||||
|
||||
# Get all SO / PO which are not fully billed or aginst which full advance not paid
|
||||
orders_to_be_billed = []
|
||||
if (args.get("party_type") != "Student"):
|
||||
if (args.get("party_type") in ("Supplier", "Customer")):
|
||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
||||
args.get("party"), party_account_currency, company_currency)
|
||||
|
||||
@@ -601,7 +601,7 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
|
||||
voucher_type = 'Sales Order'
|
||||
elif party_type == "Supplier":
|
||||
voucher_type = 'Purchase Order'
|
||||
elif party_type == "Employee":
|
||||
else:
|
||||
voucher_type = None
|
||||
|
||||
# Add cost center condition
|
||||
|
||||
@@ -73,6 +73,12 @@ frappe.query_reports["Accounts Payable"] = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname":"payment_terms_template",
|
||||
"label": __("Payment Terms Template"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Payment Terms Template"
|
||||
},
|
||||
{
|
||||
"fieldname":"supplier_group",
|
||||
"label": __("Supplier Group"),
|
||||
|
||||
@@ -63,6 +63,12 @@ frappe.query_reports["Accounts Payable Summary"] = {
|
||||
"fieldtype": "Link",
|
||||
"options": "Supplier"
|
||||
},
|
||||
{
|
||||
"fieldname":"payment_terms_template",
|
||||
"label": __("Payment Terms Template"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Payment Terms Template"
|
||||
},
|
||||
{
|
||||
"fieldname":"supplier_group",
|
||||
"label": __("Supplier Group"),
|
||||
|
||||
@@ -540,6 +540,10 @@ class ReceivablePayableReport(object):
|
||||
where supplier_group=%s)""")
|
||||
values.append(self.filters.get("supplier_group"))
|
||||
|
||||
if self.filters.get("payment_terms_template"):
|
||||
conditions.append("party in (select name from tabSupplier where payment_terms=%s)")
|
||||
values.append(self.filters.get("payment_terms_template"))
|
||||
|
||||
accounts = [d.name for d in frappe.get_all("Account",
|
||||
filters={"account_type": account_type, "company": self.filters.company})]
|
||||
conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
|
||||
|
||||
@@ -12,11 +12,11 @@ def execute(filters=None):
|
||||
columns = get_columns()
|
||||
|
||||
if not filters.get("account"): return columns, []
|
||||
|
||||
|
||||
account_currency = frappe.db.get_value("Account", filters.account, "account_currency")
|
||||
|
||||
data = get_entries(filters)
|
||||
|
||||
|
||||
from erpnext.accounts.utils import get_balance_on
|
||||
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
||||
|
||||
@@ -24,7 +24,7 @@ def execute(filters=None):
|
||||
for d in data:
|
||||
total_debit += flt(d.debit)
|
||||
total_credit += flt(d.credit)
|
||||
|
||||
|
||||
amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters)
|
||||
|
||||
bank_bal = flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) \
|
||||
@@ -39,7 +39,7 @@ def execute(filters=None):
|
||||
"credit": total_credit,
|
||||
"account_currency": account_currency
|
||||
},
|
||||
get_balance_row(_("Cheques and Deposits incorrectly cleared"), amounts_not_reflected_in_system,
|
||||
get_balance_row(_("Cheques and Deposits incorrectly cleared"), amounts_not_reflected_in_system,
|
||||
account_currency),
|
||||
{},
|
||||
get_balance_row(_("Calculated Bank Statement balance"), bank_bal, account_currency)
|
||||
@@ -58,8 +58,8 @@ def get_columns():
|
||||
{
|
||||
"fieldname": "payment_entry",
|
||||
"label": _("Payment Entry"),
|
||||
"fieldtype": "Dynamic Link",
|
||||
"options": "payment_document",
|
||||
"fieldtype": "Link",
|
||||
"options": "Payment Entry",
|
||||
"width": 220
|
||||
},
|
||||
{
|
||||
@@ -100,7 +100,7 @@ def get_columns():
|
||||
"label": _("Clearance Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": 110
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "account_currency",
|
||||
"label": _("Currency"),
|
||||
@@ -112,9 +112,9 @@ def get_columns():
|
||||
|
||||
def get_entries(filters):
|
||||
journal_entries = frappe.db.sql("""
|
||||
select "Journal Entry" as payment_document, jv.posting_date,
|
||||
jv.name as payment_entry, jvd.debit_in_account_currency as debit,
|
||||
jvd.credit_in_account_currency as credit, jvd.against_account,
|
||||
select "Journal Entry" as payment_document, jv.posting_date,
|
||||
jv.name as payment_entry, jvd.debit_in_account_currency as debit,
|
||||
jvd.credit_in_account_currency as credit, jvd.against_account,
|
||||
jv.cheque_no as reference_no, jv.cheque_date as ref_date, jv.clearance_date, jvd.account_currency
|
||||
from
|
||||
`tabJournal Entry Account` jvd, `tabJournal Entry` jv
|
||||
@@ -122,13 +122,13 @@ def get_entries(filters):
|
||||
and jvd.account = %(account)s and jv.posting_date <= %(report_date)s
|
||||
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s
|
||||
and ifnull(jv.is_opening, 'No') = 'No'""", filters, as_dict=1)
|
||||
|
||||
|
||||
payment_entries = frappe.db.sql("""
|
||||
select
|
||||
"Payment Entry" as payment_document, name as payment_entry,
|
||||
reference_no, reference_date as ref_date,
|
||||
if(paid_to=%(account)s, received_amount, 0) as debit,
|
||||
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
||||
select
|
||||
"Payment Entry" as payment_document, name as payment_entry,
|
||||
reference_no, reference_date as ref_date,
|
||||
if(paid_to=%(account)s, received_amount, 0) as debit,
|
||||
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||
from `tabPayment Entry`
|
||||
@@ -156,25 +156,25 @@ def get_entries(filters):
|
||||
|
||||
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
||||
|
||||
|
||||
def get_amounts_not_reflected_in_system(filters):
|
||||
je_amount = frappe.db.sql("""
|
||||
select sum(jvd.debit_in_account_currency - jvd.credit_in_account_currency)
|
||||
from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
|
||||
where jvd.parent = jv.name and jv.docstatus=1 and jvd.account=%(account)s
|
||||
and jv.posting_date > %(report_date)s and jv.clearance_date <= %(report_date)s
|
||||
and jv.posting_date > %(report_date)s and jv.clearance_date <= %(report_date)s
|
||||
and ifnull(jv.is_opening, 'No') = 'No' """, filters)
|
||||
|
||||
je_amount = flt(je_amount[0][0]) if je_amount else 0.0
|
||||
|
||||
|
||||
pe_amount = frappe.db.sql("""
|
||||
select sum(if(paid_from=%(account)s, paid_amount, received_amount))
|
||||
from `tabPayment Entry`
|
||||
where (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
||||
where (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
||||
and posting_date > %(report_date)s and clearance_date <= %(report_date)s""", filters)
|
||||
|
||||
pe_amount = flt(pe_amount[0][0]) if pe_amount else 0.0
|
||||
|
||||
|
||||
return je_amount + pe_amount
|
||||
|
||||
def get_balance_row(label, amount, account_currency):
|
||||
|
||||
@@ -10,6 +10,7 @@ from frappe import _, _dict
|
||||
from erpnext.accounts.utils import get_account_currency
|
||||
from erpnext.accounts.report.financial_statements import get_cost_centers_with_children
|
||||
from six import iteritems
|
||||
from collections import OrderedDict
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters:
|
||||
@@ -269,7 +270,7 @@ def group_by_field(group_by):
|
||||
return 'voucher_no'
|
||||
|
||||
def initialize_gle_map(gl_entries, filters):
|
||||
gle_map = frappe._dict()
|
||||
gle_map = OrderedDict()
|
||||
group_by = group_by_field(filters.get('group_by'))
|
||||
|
||||
for gle in gl_entries:
|
||||
|
||||
@@ -104,6 +104,9 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
|
||||
# get balance of all entries that exist
|
||||
date = nowdate()
|
||||
|
||||
if account:
|
||||
acc = frappe.get_doc("Account", account)
|
||||
|
||||
try:
|
||||
year_start_date = get_fiscal_year(date, verbose=0)[1]
|
||||
except FiscalYearError:
|
||||
@@ -118,7 +121,7 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
|
||||
|
||||
allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account()
|
||||
|
||||
if cost_center and allow_cost_center_in_entry_of_bs_account:
|
||||
if cost_center and (allow_cost_center_in_entry_of_bs_account or acc.report_type =='Profit and Loss'):
|
||||
cc = frappe.get_doc("Cost Center", cost_center)
|
||||
if cc.is_group:
|
||||
cond.append(""" exists (
|
||||
@@ -132,20 +135,13 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
|
||||
|
||||
if account:
|
||||
|
||||
acc = frappe.get_doc("Account", account)
|
||||
|
||||
if not frappe.flags.ignore_account_permission:
|
||||
acc.check_permission("read")
|
||||
|
||||
|
||||
if not allow_cost_center_in_entry_of_bs_account and acc.report_type == 'Profit and Loss':
|
||||
if acc.report_type == 'Profit and Loss':
|
||||
# for pl accounts, get balance within a fiscal year
|
||||
cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
|
||||
% year_start_date)
|
||||
elif allow_cost_center_in_entry_of_bs_account:
|
||||
# for all accounts, get balance within a fiscal year if maintain cost center in balance account is checked
|
||||
cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
|
||||
% year_start_date)
|
||||
# different filter for group and ledger - improved performance
|
||||
if acc.is_group:
|
||||
cond.append("""exists (
|
||||
@@ -721,6 +717,7 @@ def get_children(doctype, parent, company, is_root=False):
|
||||
parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
|
||||
fields = [
|
||||
'name as value',
|
||||
'root_type',
|
||||
'is_group as expandable'
|
||||
]
|
||||
filters = [['docstatus', '<', 2]]
|
||||
@@ -728,7 +725,7 @@ def get_children(doctype, parent, company, is_root=False):
|
||||
filters.append(['ifnull(`{0}`,"")'.format(parent_fieldname), '=', '' if is_root else parent])
|
||||
|
||||
if is_root:
|
||||
fields += ['root_type', 'report_type', 'account_currency'] if doctype == 'Account' else []
|
||||
fields += ['report_type', 'account_currency'] if doctype == 'Account' else []
|
||||
filters.append(['company', '=', company])
|
||||
|
||||
else:
|
||||
|
||||
@@ -15,6 +15,9 @@ class calculate_taxes_and_totals(object):
|
||||
self.calculate()
|
||||
|
||||
def calculate(self):
|
||||
if not len(self.doc.get("items")):
|
||||
return
|
||||
|
||||
self.discount_amount_applied = False
|
||||
self._calculate()
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ frappe.ui.form.on("Opportunity", {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (frm.doc.opportunity_from && frm.doc.party_name){
|
||||
frm.trigger('set_contact_link');
|
||||
}
|
||||
},
|
||||
|
||||
onload_post_render: function(frm) {
|
||||
|
||||
@@ -7,7 +7,9 @@ import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from requests_oauthlib import OAuth2Session
|
||||
import json, requests
|
||||
import json
|
||||
import requests
|
||||
import traceback
|
||||
from erpnext import encode_company_abbr
|
||||
|
||||
# QuickBooks requires a redirect URL, User will be redirect to this URL
|
||||
@@ -32,7 +34,6 @@ def callback(*args, **kwargs):
|
||||
class QuickBooksMigrator(Document):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(QuickBooksMigrator, self).__init__(*args, **kwargs)
|
||||
from pprint import pprint
|
||||
self.oauth = OAuth2Session(
|
||||
client_id=self.client_id,
|
||||
redirect_uri=self.redirect_url,
|
||||
@@ -46,7 +47,9 @@ class QuickBooksMigrator(Document):
|
||||
if self.company:
|
||||
# We need a Cost Center corresponding to the selected erpnext Company
|
||||
self.default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
|
||||
self.default_warehouse = frappe.get_all('Warehouse', filters={"company": self.company, "is_group": 0})[0]["name"]
|
||||
company_warehouses = frappe.get_all('Warehouse', filters={"company": self.company, "is_group": 0})
|
||||
if company_warehouses:
|
||||
self.default_warehouse = company_warehouses[0].name
|
||||
if self.authorization_endpoint:
|
||||
self.authorization_url = self.oauth.authorization_url(self.authorization_endpoint)[0]
|
||||
|
||||
@@ -218,7 +221,7 @@ class QuickBooksMigrator(Document):
|
||||
|
||||
def _fetch_general_ledger(self):
|
||||
try:
|
||||
query_uri = "{}/company/{}/reports/GeneralLedger".format(self.api_endpoint ,self.quickbooks_company_id)
|
||||
query_uri = "{}/company/{}/reports/GeneralLedger".format(self.api_endpoint, self.quickbooks_company_id)
|
||||
response = self._get(query_uri,
|
||||
params={
|
||||
"columns": ",".join(["tx_date", "txn_type", "credit_amt", "debt_amt"]),
|
||||
@@ -493,17 +496,17 @@ class QuickBooksMigrator(Document):
|
||||
"account_currency": customer["CurrencyRef"]["value"],
|
||||
"company": self.company,
|
||||
})[0]["name"]
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
receivable_account = None
|
||||
erpcustomer = frappe.get_doc({
|
||||
"doctype": "Customer",
|
||||
"quickbooks_id": customer["Id"],
|
||||
"customer_name" : encode_company_abbr(customer["DisplayName"], self.company),
|
||||
"customer_type" : "Individual",
|
||||
"customer_group" : "Commercial",
|
||||
"customer_name": encode_company_abbr(customer["DisplayName"], self.company),
|
||||
"customer_type": "Individual",
|
||||
"customer_group": "Commercial",
|
||||
"default_currency": customer["CurrencyRef"]["value"],
|
||||
"accounts": [{"company": self.company, "account": receivable_account}],
|
||||
"territory" : "All Territories",
|
||||
"territory": "All Territories",
|
||||
"company": self.company,
|
||||
}).insert()
|
||||
if "BillAddr" in customer:
|
||||
@@ -521,7 +524,7 @@ class QuickBooksMigrator(Document):
|
||||
item_dict = {
|
||||
"doctype": "Item",
|
||||
"quickbooks_id": item["Id"],
|
||||
"item_code" : encode_company_abbr(item["Name"], self.company),
|
||||
"item_code": encode_company_abbr(item["Name"], self.company),
|
||||
"stock_uom": "Unit",
|
||||
"is_stock_item": 0,
|
||||
"item_group": "All Item Groups",
|
||||
@@ -549,14 +552,14 @@ class QuickBooksMigrator(Document):
|
||||
erpsupplier = frappe.get_doc({
|
||||
"doctype": "Supplier",
|
||||
"quickbooks_id": vendor["Id"],
|
||||
"supplier_name" : encode_company_abbr(vendor["DisplayName"], self.company),
|
||||
"supplier_group" : "All Supplier Groups",
|
||||
"supplier_name": encode_company_abbr(vendor["DisplayName"], self.company),
|
||||
"supplier_group": "All Supplier Groups",
|
||||
"company": self.company,
|
||||
}).insert()
|
||||
if "BillAddr" in vendor:
|
||||
self._create_address(erpsupplier, "Supplier", vendor["BillAddr"], "Billing")
|
||||
if "ShipAddr" in vendor:
|
||||
self._create_address(erpsupplier, "Supplier",vendor["ShipAddr"], "Shipping")
|
||||
self._create_address(erpsupplier, "Supplier", vendor["ShipAddr"], "Shipping")
|
||||
except Exception as e:
|
||||
self._log_error(e)
|
||||
|
||||
@@ -829,7 +832,7 @@ class QuickBooksMigrator(Document):
|
||||
"currency": invoice["CurrencyRef"]["value"],
|
||||
"conversion_rate": invoice.get("ExchangeRate", 1),
|
||||
"posting_date": invoice["TxnDate"],
|
||||
"due_date": invoice.get("DueDate", invoice["TxnDate"]),
|
||||
"due_date": invoice.get("DueDate", invoice["TxnDate"]),
|
||||
"credit_to": credit_to_account,
|
||||
"supplier": frappe.get_all("Supplier",
|
||||
filters={
|
||||
@@ -1200,7 +1203,7 @@ class QuickBooksMigrator(Document):
|
||||
|
||||
|
||||
def _create_address(self, entity, doctype, address, address_type):
|
||||
try :
|
||||
try:
|
||||
if not frappe.db.exists({"doctype": "Address", "quickbooks_id": address["Id"]}):
|
||||
frappe.get_doc({
|
||||
"doctype": "Address",
|
||||
@@ -1252,8 +1255,6 @@ class QuickBooksMigrator(Document):
|
||||
|
||||
|
||||
def _log_error(self, execption, data=""):
|
||||
import json, traceback
|
||||
traceback.print_exc()
|
||||
frappe.log_error(title="QuickBooks Migration Error",
|
||||
message="\n".join([
|
||||
"Data",
|
||||
|
||||
@@ -29,9 +29,12 @@ class LoanApplication(Document):
|
||||
if self.repayment_method == "Repay Fixed Amount per Period":
|
||||
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
|
||||
if monthly_interest_rate:
|
||||
self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
|
||||
math.log(self.repayment_amount - (self.loan_amount*monthly_interest_rate))) /
|
||||
(math.log(1 + monthly_interest_rate)))
|
||||
min_repayment_amount = self.loan_amount*monthly_interest_rate
|
||||
if self.repayment_amount - min_repayment_amount < 0:
|
||||
frappe.throw(_("Repayment Amount must be greater than " \
|
||||
+ str(flt(min_repayment_amount, 2))))
|
||||
self.repayment_periods = math.ceil(math.log(self.repayment_amount) -
|
||||
math.log(self.repayment_amount - min_repayment_amount) /(math.log(1 + monthly_interest_rate)))
|
||||
else:
|
||||
self.repayment_periods = self.loan_amount / self.repayment_amount
|
||||
|
||||
|
||||
@@ -31,21 +31,22 @@ class TestLoanApplication(unittest.TestCase):
|
||||
"rate_of_interest": 9.2,
|
||||
"loan_amount": 250000,
|
||||
"repayment_method": "Repay Over Number of Periods",
|
||||
"repayment_periods": 24
|
||||
"repayment_periods": 18
|
||||
})
|
||||
loan_application.insert()
|
||||
|
||||
|
||||
|
||||
def test_loan_totals(self):
|
||||
loan_application = frappe.get_doc("Loan Application", {"applicant":self.applicant})
|
||||
self.assertEquals(loan_application.repayment_amount, 11445)
|
||||
self.assertEquals(loan_application.total_payable_interest, 24657)
|
||||
self.assertEquals(loan_application.total_payable_amount, 274657)
|
||||
|
||||
loan_application.repayment_method = "Repay Fixed Amount per Period"
|
||||
loan_application.repayment_amount = 15000
|
||||
self.assertEqual(loan_application.total_payable_interest, 18599)
|
||||
self.assertEqual(loan_application.total_payable_amount, 268599)
|
||||
self.assertEqual(loan_application.repayment_amount, 14923)
|
||||
|
||||
loan_application.repayment_periods = 24
|
||||
loan_application.save()
|
||||
loan_application.reload()
|
||||
|
||||
self.assertEqual(loan_application.repayment_periods, 18)
|
||||
self.assertEqual(loan_application.total_payable_interest, 18506)
|
||||
self.assertEqual(loan_application.total_payable_amount, 268506)
|
||||
self.assertEqual(loan_application.total_payable_interest, 24657)
|
||||
self.assertEqual(loan_application.total_payable_amount, 274657)
|
||||
self.assertEqual(loan_application.repayment_amount, 11445)
|
||||
@@ -506,6 +506,7 @@ erpnext.patches.v10_0.update_hub_connector_domain
|
||||
erpnext.patches.v10_0.set_student_party_type
|
||||
erpnext.patches.v10_0.update_project_in_sle
|
||||
erpnext.patches.v10_0.fix_reserved_qty_for_sub_contract
|
||||
erpnext.patches.v10_0.repost_requested_qty_for_non_stock_uom_items
|
||||
erpnext.patches.v11_0.merge_land_unit_with_location
|
||||
erpnext.patches.v11_0.add_index_on_nestedset_doctypes
|
||||
erpnext.patches.v11_0.remove_modules_setup_page
|
||||
@@ -603,4 +604,4 @@ erpnext.patches.v11_1.update_bank_transaction_status
|
||||
erpnext.patches.v11_1.renamed_delayed_item_report
|
||||
erpnext.patches.v11_1.set_missing_opportunity_from
|
||||
erpnext.patches.v11_1.set_quotation_status
|
||||
erpnext.patches.v11_1.update_default_supplier_in_item_defaults
|
||||
erpnext.patches.v11_1.update_default_supplier_in_item_defaults
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2019, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty
|
||||
|
||||
count=0
|
||||
for item_code, warehouse in frappe.db.sql("""select distinct item_code, warehouse
|
||||
from `tabMaterial Request Item` where docstatus = 1 and stock_uom<>uom"""):
|
||||
try:
|
||||
count += 1
|
||||
update_bin_qty(item_code, warehouse, {
|
||||
"indented_qty": get_indented_qty(item_code, warehouse),
|
||||
})
|
||||
if count % 200 == 0:
|
||||
frappe.db.commit()
|
||||
except:
|
||||
frappe.db.rollback()
|
||||
@@ -1290,11 +1290,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
me.frm.set_value("taxes", r.message);
|
||||
if(me.frm.doc.shipping_rule && me.frm.doc.taxes) {
|
||||
for (let tax of r.message) {
|
||||
me.frm.add_child("taxes", tax);
|
||||
}
|
||||
|
||||
if(me.frm.doc.shipping_rule) {
|
||||
me.frm.script_manager.trigger("shipping_rule");
|
||||
refresh_field("taxes");
|
||||
} else {
|
||||
me.frm.set_value("taxes", r.message);
|
||||
me.calculate_taxes_and_totals();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
var me = this;
|
||||
if (this.frm.doc.customer) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.loyalty_program.loyalty_program.get_loyalty_program_details",
|
||||
method: "erpnext.accounts.doctype.loyalty_program.loyalty_program.get_loyalty_program_details_with_points",
|
||||
args: {
|
||||
"customer": me.frm.doc.customer,
|
||||
"expiry_date": me.frm.doc.posting_date,
|
||||
@@ -1694,7 +1694,13 @@ class Payment {
|
||||
fieldtype: 'Check',
|
||||
label: 'Redeem Loyalty Points',
|
||||
fieldname: 'redeem_loyalty_points',
|
||||
onchange: () => {
|
||||
onchange: async function () {
|
||||
if (!cint(me.dialog.get_value('redeem_loyalty_points'))) {
|
||||
await Promise.all([
|
||||
me.frm.set_value('loyalty_points', 0),
|
||||
me.dialog.set_value('loyalty_points', 0)
|
||||
]);
|
||||
}
|
||||
me.update_cur_frm_value("redeem_loyalty_points", () => {
|
||||
frappe.flags.redeem_loyalty_points = false;
|
||||
me.update_loyalty_points();
|
||||
@@ -1838,13 +1844,14 @@ class Payment {
|
||||
});
|
||||
}
|
||||
|
||||
update_loyalty_points() {
|
||||
if (this.dialog.get_value("redeem_loyalty_points")) {
|
||||
this.dialog.set_value("loyalty_points", this.frm.doc.loyalty_points);
|
||||
this.dialog.set_value("loyalty_amount", this.frm.doc.loyalty_amount);
|
||||
this.update_payment_amount();
|
||||
this.show_paid_amount();
|
||||
}
|
||||
async update_loyalty_points() {
|
||||
const { loyalty_points, loyalty_amount } = this.frm.doc;
|
||||
await Promise.all([
|
||||
this.dialog.set_value("loyalty_points", loyalty_points),
|
||||
this.dialog.set_value("loyalty_amount", loyalty_amount)
|
||||
]);
|
||||
this.update_payment_amount();
|
||||
this.show_paid_amount();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ def place_order():
|
||||
quotation.flags.ignore_permissions = True
|
||||
quotation.submit()
|
||||
|
||||
if quotation.lead:
|
||||
if quotation.quotation_to == 'Lead' and quotation.party_name:
|
||||
# company used to create customer accounts
|
||||
frappe.defaults.set_user_default("company", quotation.company)
|
||||
|
||||
|
||||
@@ -177,7 +177,8 @@ class StockEntry(StockController):
|
||||
item.set(f, item_details.get(f))
|
||||
|
||||
if not item.transfer_qty and item.qty:
|
||||
item.transfer_qty = item.qty * item.conversion_factor
|
||||
item.transfer_qty = ( flt(item.qty, item.precision("qty"))
|
||||
* flt(item.conversion_factor, item.precision("conversion_factor")) )
|
||||
|
||||
if (self.purpose in ("Material Transfer", "Material Transfer for Manufacture")
|
||||
and not item.serial_no
|
||||
|
||||
@@ -110,7 +110,7 @@ def get_reserved_qty(item_code, warehouse):
|
||||
return flt(reserved_qty[0][0]) if reserved_qty else 0
|
||||
|
||||
def get_indented_qty(item_code, warehouse):
|
||||
indented_qty = frappe.db.sql("""select sum(mr_item.qty - mr_item.ordered_qty)
|
||||
indented_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor)
|
||||
from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
|
||||
where mr_item.item_code=%s and mr_item.warehouse=%s
|
||||
and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name
|
||||
|
||||
Reference in New Issue
Block a user