Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport jphlions-staging] Bump to v13.14.1 (#320) #330

Merged
merged 2 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion erpnext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from erpnext.hooks import regional_overrides

__version__ = '13.12.1'
__version__ = '13.14.1'

def get_default_company(user=None):
'''Get default company for user'''
Expand Down
44 changes: 25 additions & 19 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ def update_payment_schedule(self, cancel=0):
invoice_paid_amount_map[invoice_key]['outstanding'] = term.outstanding
invoice_paid_amount_map[invoice_key]['discounted_amt'] = ref.total_amount * (term.discount / 100)

for key, allocated_amount in iteritems(invoice_payment_amount_map):
for idx, (key, allocated_amount) in enumerate(iteritems(invoice_payment_amount_map), 1):
if not invoice_paid_amount_map.get(key):
frappe.throw(_('Payment term {0} not used in {1}').format(key[0], key[1]))

Expand All @@ -407,7 +407,7 @@ def update_payment_schedule(self, cancel=0):
(allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]))
else:
if allocated_amount > outstanding:
frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
frappe.throw(_('Row #{0}: Cannot allocate more than {1} against payment term {2}').format(idx, outstanding, key[0]))

if allocated_amount and outstanding:
frappe.db.sql("""
Expand Down Expand Up @@ -1052,12 +1052,6 @@ def get_outstanding_reference_documents(args):
party_account_currency = get_account_currency(args.get("party_account"))
company_currency = frappe.get_cached_value('Company', args.get("company"), "default_currency")

# Get negative outstanding sales /purchase invoices
negative_outstanding_invoices = []
if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"),
args.get("party_account"), args.get("company"), party_account_currency, company_currency)

# Get positive outstanding sales /purchase invoices/ Fees
condition = ""
if args.get("voucher_type") and args.get("voucher_no"):
Expand Down Expand Up @@ -1104,6 +1098,12 @@ def get_outstanding_reference_documents(args):
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
args.get("party"), args.get("company"), party_account_currency, company_currency, filters=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"):
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"),
args.get("party_account"), party_account_currency, company_currency, condition=condition)

data = negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed

if not data:
Expand Down Expand Up @@ -1136,22 +1136,26 @@ def split_invoices_based_on_payment_terms(outstanding_invoices):
'invoice_amount': flt(d.invoice_amount),
'outstanding_amount': flt(d.outstanding_amount),
'payment_amount': payment_term.payment_amount,
'payment_term': payment_term.payment_term,
'allocated_amount': payment_term.outstanding
'payment_term': payment_term.payment_term
}))

outstanding_invoices_after_split = []
if invoice_ref_based_on_payment_terms:
for idx, ref in invoice_ref_based_on_payment_terms.items():
voucher_no = outstanding_invoices[idx]['voucher_no']
voucher_type = outstanding_invoices[idx]['voucher_type']
voucher_no = ref[0]['voucher_no']
voucher_type = ref[0]['voucher_type']

frappe.msgprint(_("Spliting {} {} into {} rows as per payment terms").format(
frappe.msgprint(_("Spliting {} {} into {} row(s) as per Payment Terms").format(
voucher_type, voucher_no, len(ref)), alert=True)

outstanding_invoices.pop(idx - 1)
outstanding_invoices += invoice_ref_based_on_payment_terms[idx]
outstanding_invoices_after_split += invoice_ref_based_on_payment_terms[idx]

existing_row = list(filter(lambda x: x.get('voucher_no') == voucher_no, outstanding_invoices))
index = outstanding_invoices.index(existing_row[0])
outstanding_invoices.pop(index)

return outstanding_invoices
outstanding_invoices_after_split += outstanding_invoices
return outstanding_invoices_after_split

def get_orders_to_be_billed(posting_date, party_type, party,
company, party_account_currency, company_currency, cost_center=None, filters=None):
Expand Down Expand Up @@ -1218,7 +1222,7 @@ def get_orders_to_be_billed(posting_date, party_type, party,
return order_list

def get_negative_outstanding_invoices(party_type, party, party_account,
company, party_account_currency, company_currency, cost_center=None):
party_account_currency, company_currency, cost_center=None, condition=None):
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
supplier_condition = ""
if voucher_type == "Purchase Invoice":
Expand All @@ -1240,19 +1244,21 @@ def get_negative_outstanding_invoices(party_type, party, party_account,
`tab{voucher_type}`
where
{party_type} = %s and {party_account} = %s and docstatus = 1 and
company = %s and outstanding_amount < 0
outstanding_amount < 0
{supplier_condition}
{condition}
order by
posting_date, name
""".format(**{
"supplier_condition": supplier_condition,
"condition": condition,
"rounded_total_field": rounded_total_field,
"grand_total_field": grand_total_field,
"voucher_type": voucher_type,
"party_type": scrub(party_type),
"party_account": "debit_to" if party_type == "Customer" else "credit_to",
"cost_center": cost_center
}), (party, party_account, company), as_dict=True)
}), (party, party_account), as_dict=True)


@frappe.whitelist()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,7 @@
"fieldname": "pos_transactions",
"fieldtype": "Table",
"label": "POS Transactions",
"options": "POS Invoice Reference",
"reqd": 1
"options": "POS Invoice Reference"
},
{
"fieldname": "pos_opening_entry",
Expand Down Expand Up @@ -229,7 +228,7 @@
"link_fieldname": "pos_closing_entry"
}
],
"modified": "2021-08-10 11:12:22.540578",
"modified": "2021-08-11 11:12:22.540578",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Closing Entry",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,10 @@ def get_invoice_customer_map(pos_invoices):
return pos_invoice_customer_map

def consolidate_pos_invoices(pos_invoices=None, closing_entry=None):
invoices = pos_invoices or (closing_entry and closing_entry.get('pos_transactions')) or get_all_unconsolidated_invoices()
invoices = pos_invoices or (closing_entry and closing_entry.get('pos_transactions'))
if frappe.flags.in_test and not invoices:
invoices = get_all_unconsolidated_invoices()

invoice_by_customer = get_invoice_customer_map(invoices)

if len(invoices) >= 10 and closing_entry:
Expand Down
3 changes: 3 additions & 0 deletions erpnext/accounts/doctype/pricing_rule/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def get_pricing_rules(args, doc=None):
pricing_rules = []
values = {}

if not frappe.db.exists('Pricing Rule', {'disable': 0, args.transaction_type: 1}):
return

for apply_on in ['Item Code', 'Item Group', 'Brand']:
pricing_rules.extend(_get_pricing_rules(apply_on, args, values))
if pricing_rules and not apply_multiple_pricing_rules(pricing_rules):
Expand Down
15 changes: 15 additions & 0 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -590,5 +590,20 @@ frappe.ui.form.on("Purchase Invoice", {

company: function(frm) {
erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);

if (frm.doc.company) {
frappe.call({
method:
"erpnext.accounts.party.get_party_account",
args: {
party_type: 'Supplier',
party: frm.doc.supplier,
company: frm.doc.company
},
callback: (response) => {
if (response) frm.set_value("credit_to", response.message);
},
});
}
},
})
18 changes: 18 additions & 0 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,27 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
this.setup_posting_date_time_check();
this._super(doc);
},

company: function() {
erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);

let me = this;
if (this.frm.doc.company) {
frappe.call({
method:
"erpnext.accounts.party.get_party_account",
args: {
party_type: 'Customer',
party: this.frm.doc.customer,
company: this.frm.doc.company
},
callback: (response) => {
if (response) me.frm.set_value("debit_to", response.message);
},
});
}
},

onload: function() {
var me = this;
this._super();
Expand Down
33 changes: 26 additions & 7 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -2019,22 +2019,23 @@ def update_multi_mode_option(doc, pos_profile):
def append_payment(payment_mode):
payment = doc.append('payments', {})
payment.default = payment_mode.default
payment.mode_of_payment = payment_mode.parent
payment.mode_of_payment = payment_mode.mop
payment.account = payment_mode.default_account
payment.type = payment_mode.type

doc.set('payments', [])
invalid_modes = []
for pos_payment_method in pos_profile.get('payments'):
pos_payment_method = pos_payment_method.as_dict()
mode_of_payments = [d.mode_of_payment for d in pos_profile.get('payments')]
mode_of_payments_info = get_mode_of_payments_info(mode_of_payments, doc.company)

payment_mode = get_mode_of_payment_info(pos_payment_method.mode_of_payment, doc.company)
for row in pos_profile.get('payments'):
payment_mode = mode_of_payments_info.get(row.mode_of_payment)
if not payment_mode:
invalid_modes.append(get_link_to_form("Mode of Payment", pos_payment_method.mode_of_payment))
invalid_modes.append(get_link_to_form("Mode of Payment", row.mode_of_payment))
continue

payment_mode[0].default = pos_payment_method.default
append_payment(payment_mode[0])
payment_mode.default = row.default
append_payment(payment_mode)

if invalid_modes:
if invalid_modes == 1:
Expand All @@ -2050,6 +2051,24 @@ def get_all_mode_of_payments(doc):
where mpa.parent = mp.name and mpa.company = %(company)s and mp.enabled = 1""",
{'company': doc.company}, as_dict=1)

def get_mode_of_payments_info(mode_of_payments, company):
data = frappe.db.sql(
"""
select
mpa.default_account, mpa.parent as mop, mp.type as type
from
`tabMode of Payment Account` mpa,`tabMode of Payment` mp
where
mpa.parent = mp.name and
mpa.company = %s and
mp.enabled = 1 and
mp.name in %s
group by
mp.name
""", (company, mode_of_payments), as_dict=1)

return {row.get('mop'): row for row in data}

def get_mode_of_payment_info(mode_of_payment, company):
return frappe.db.sql("""
select mpa.default_account, mpa.parent, mp.type as type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
# then chargeable value is "prev invoices + advances" value which cross the threshold
tax_amount = get_tcs_amount(parties, inv, tax_details, vouchers, advance_vouchers)

if cint(tax_details.round_off_tax_amount):
tax_amount = round(tax_amount)

return tax_amount, tax_deducted

def get_invoice_vouchers(parties, tax_details, company, party_type='Supplier'):
Expand Down Expand Up @@ -322,9 +325,6 @@ def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
else:
tds_amount = supp_credit_amt * tax_details.rate / 100 if supp_credit_amt > 0 else 0

if cint(tax_details.round_off_tax_amount):
tds_amount = round(tds_amount)

return tds_amount

def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
Expand Down
9 changes: 6 additions & 3 deletions erpnext/accounts/party.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,19 @@ def set_account_and_due_date(party, account, party_type, company, posting_date,
return out

@frappe.whitelist()
def get_party_account(party_type, party, company=None):
def get_party_account(party_type, party=None, company=None):
"""Returns the account for the given `party`.
Will first search in party (Customer / Supplier) record, if not found,
will search in group (Customer Group / Supplier Group),
finally will return default."""
if not company:
frappe.throw(_("Please select a Company"))

if not party:
return
if not party and party_type in ['Customer', 'Supplier']:
default_account_name = "default_receivable_account" \
if party_type=="Customer" else "default_payable_account"

return frappe.get_cached_value('Company', company, default_account_name)

account = frappe.db.get_value("Party Account",
{"parenttype": party_type, "parent": party, "company": company}, "account")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ frappe.query_reports["Fixed Asset Register"] = {
fieldname:"status",
label: __("Status"),
fieldtype: "Select",
options: "In Location\nDisposed",
default: 'In Location',
reqd: 1
options: "\nIn Location\nDisposed",
default: 'In Location'
},
{
"fieldname":"filter_based_on",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ def get_conditions(filters):
if filters.get('cost_center'):
conditions["cost_center"] = filters.get('cost_center')

# In Store assets are those that are not sold or scrapped
operand = 'not in'
if status not in 'In Location':
operand = 'in'
if status:
# In Store assets are those that are not sold or scrapped
operand = 'not in'
if status not in 'In Location':
operand = 'in'

conditions['status'] = (operand, ['Sold', 'Scrapped'])
conditions['status'] = (operand, ['Sold', 'Scrapped'])

return conditions

Expand Down
15 changes: 8 additions & 7 deletions erpnext/controllers/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,15 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
meta = frappe.get_meta("Item", cached=True)
searchfields = meta.get_search_fields()

if "description" in searchfields:
searchfields.remove("description")
# these are handled separately
ignored_search_fields = ("item_name", "description")
for ignored_field in ignored_search_fields:
if ignored_field in searchfields:
searchfields.remove(ignored_field)

columns = ''
extra_searchfields = [field for field in searchfields
if not field in ["name", "item_group", "description"]]
if not field in ["name", "item_group", "description", "item_name"]]

if extra_searchfields:
columns = ", " + ", ".join(extra_searchfields)
Expand Down Expand Up @@ -252,10 +255,8 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
if frappe.db.count('Item', cache=True) < 50000:
# scan description only if items are less than 50000
description_cond = 'or tabItem.description LIKE %(txt)s'
return frappe.db.sql("""select tabItem.name,
if(length(tabItem.item_name) > 40,
concat(substr(tabItem.item_name, 1, 40), "..."), item_name) as item_name,
tabItem.item_group,
return frappe.db.sql("""select
tabItem.name, tabItem.item_name, tabItem.item_group,
if(length(tabItem.description) > 40, \
concat(substr(tabItem.description, 1, 40), "..."), description) as description
{columns}
Expand Down
2 changes: 1 addition & 1 deletion erpnext/e_commerce/doctype/website_item/website_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def validate_website_image(self):

def make_thumbnail(self):
"""Make a thumbnail of `website_image`"""
if frappe.flags.in_import:
if frappe.flags.in_import or frappe.flags.in_migrate:
return

import requests.exceptions
Expand Down
Loading