Merge branch 'develop' into project-link-for-all-accounts

This commit is contained in:
Saqib
2020-04-14 14:05:32 +05:30
committed by GitHub
285 changed files with 10008 additions and 18949 deletions

View File

@@ -19,6 +19,7 @@ from erpnext.accounts.doctype.pricing_rule.utils import (apply_pricing_rule_on_t
from erpnext.exceptions import InvalidCurrency
from six import text_type
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from erpnext.stock.get_item_details import get_item_warehouse
force_item_fields = ("item_group", "brand", "stock_uom", "is_fixed_asset", "item_tax_rate", "pricing_rules")
@@ -438,7 +439,7 @@ class AccountsController(TransactionBase):
if account_currency not in valid_currency:
frappe.throw(_("Account {0} is invalid. Account Currency must be {1}")
.format(account, _(" or ").join(valid_currency)))
.format(account, (' ' + _("or") + ' ').join(valid_currency)))
def clear_unallocated_advances(self, childtype, parentfield):
self.set(parentfield, self.get(parentfield, {"allocated_amount": ["not in", [0, None, ""]]}))
@@ -833,7 +834,7 @@ class AccountsController(TransactionBase):
for d in self.get("payment_schedule"):
if self.doctype == "Sales Order" and getdate(d.due_date) < getdate(self.transaction_date):
frappe.throw(_("Row {0}: Due Date cannot be before posting date").format(d.idx))
frappe.throw(_("Row {0}: Due Date in the Payment Terms table cannot be before Posting Date").format(d.idx))
elif d.due_date in dates:
li.append(_("{0} in row {1}").format(d.due_date, d.idx))
dates.append(d.due_date)
@@ -1126,16 +1127,16 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname,
"""
Returns a Sales Order Item child item containing the default values
"""
p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name)
child_item = frappe.new_doc('Sales Order Item', p_doctype, child_docname)
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname)
item = frappe.get_doc("Item", item_code)
child_item.item_code = item.item_code
child_item.item_name = item.item_name
child_item.description = item.description
child_item.reqd_by_date = p_doctype.delivery_date
child_item.reqd_by_date = p_doc.delivery_date
child_item.uom = item.stock_uom
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
child_item.warehouse = p_doctype.set_warehouse or p_doctype.items[0].warehouse
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
return child_item
@@ -1143,13 +1144,13 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna
"""
Returns a Purchase Order Item child item containing the default values
"""
p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name)
child_item = frappe.new_doc('Purchase Order Item', p_doctype, child_docname)
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname)
item = frappe.get_doc("Item", item_code)
child_item.item_code = item.item_code
child_item.item_name = item.item_name
child_item.description = item.description
child_item.schedule_date = p_doctype.schedule_date
child_item.schedule_date = p_doc.schedule_date
child_item.uom = item.stock_uom
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
child_item.base_rate = 1 # Initiallize value will update in parent validation

View File

@@ -45,6 +45,7 @@ class BuyingController(StockController):
self.validate_warehouse()
self.validate_from_warehouse()
self.set_supplier_address()
self.validate_asset_return()
if self.doctype=="Purchase Invoice":
self.validate_purchase_receipt_if_update_stock()
@@ -100,6 +101,19 @@ class BuyingController(StockController):
for d in tax_for_valuation:
d.category = 'Total'
msgprint(_('Tax Category has been changed to "Total" because all the Items are non-stock items'))
def validate_asset_return(self):
if self.doctype not in ['Purchase Receipt', 'Purchase Invoice'] or not self.is_return:
return
purchase_doc_field = 'purchase_receipt' if self.doctype == 'Purchase Receipt' else 'purchase_invoice'
not_cancelled_asset = [d.name for d in frappe.db.get_all("Asset", {
purchase_doc_field: self.return_against,
"docstatus": 1
})]
if self.is_return and len(not_cancelled_asset):
frappe.throw(_("{} has submitted assets linked to it. You need to cancel the assets to create purchase return.".format(self.return_against)),
title=_("Not Allowed"))
def get_asset_items(self):
if self.doctype not in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:

View File

@@ -179,6 +179,12 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
# scan description only if items are less than 50000
description_cond = 'or tabItem.description LIKE %(txt)s'
extra_cond = " and tabItem.has_variants=0"
if (filters and isinstance(filters, dict)
and filters.get("doctype") == "BOM"):
extra_cond = ""
del filters["doctype"]
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,
@@ -188,11 +194,11 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
{columns}
from tabItem
where tabItem.docstatus < 2
and tabItem.has_variants=0
and tabItem.disabled=0
and (tabItem.end_of_life > %(today)s or ifnull(tabItem.end_of_life, '0000-00-00')='0000-00-00')
and ({scond} or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s)
{description_cond})
{extra_cond}
{fcond} {mcond}
order by
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
@@ -203,6 +209,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
key=searchfield,
columns=columns,
scond=searchfields,
extra_cond=extra_cond,
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
mcond=get_match_cond(doctype).replace('%', '%%'),
description_cond = description_cond),

View File

@@ -69,16 +69,16 @@ status_map = {
["Cancelled", "eval:self.docstatus==2"],
["Closed", "eval:self.status=='Closed'"],
],
"Purchase Invoice": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
["Return", "eval:self.is_return==1 and self.docstatus==1"],
["Debit Note Issued",
"eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
["Cancelled", "eval:self.docstatus==2"],
"Purchase Invoice": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
["Return", "eval:self.is_return==1 and self.docstatus==1"],
["Debit Note Issued",
"eval:self.outstanding_amount <= 0 and self.docstatus==1 and self.is_return==0 and get_value('Purchase Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1})"],
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
["Cancelled", "eval:self.docstatus==2"],
],
"Material Request": [
["Draft", None],

View File

@@ -21,6 +21,7 @@ class StockController(AccountsController):
super(StockController, self).validate()
self.validate_inspection()
self.validate_serialized_batch()
self.validate_customer_provided_item()
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
if self.docstatus == 2:
@@ -379,6 +380,15 @@ class StockController(AccountsController):
for blanket_order in blanket_orders:
frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty()
def validate_customer_provided_item(self):
for d in self.get('items'):
# Customer Provided parts will have zero valuation rate
if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
d.allow_zero_valuation_rate = 1
if d.parenttype in ["Delivery Note", "Sales Invoice"] and d.rate:
frappe.throw(_("Row #{0}: {1} cannot have {2} as it is a Customer Provided Item")
.format(d.idx, frappe.bold(d.item_code), frappe.bold("Rate")))
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
warehouse_account=None, company=None):
def _delete_gl_entries(voucher_type, voucher_no):

View File

@@ -667,8 +667,7 @@ def get_itemised_tax_breakup_html(doc):
itemised_tax=itemised_tax,
itemised_taxable_amount=itemised_taxable_amount,
tax_accounts=tax_accounts,
conversion_rate=doc.conversion_rate,
currency=doc.currency
doc=doc
)
)