Merge branch 'develop' into fix_test_scrap_asset

This commit is contained in:
Anand Baburajan 2022-10-01 17:12:24 +05:30 committed by GitHub
commit 04f9e7fa73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 136 additions and 126 deletions

View File

@ -98,7 +98,6 @@
"section_break_44", "section_break_44",
"apply_discount_on", "apply_discount_on",
"base_discount_amount", "base_discount_amount",
"additional_discount_account",
"column_break_46", "column_break_46",
"additional_discount_percentage", "additional_discount_percentage",
"discount_amount", "discount_amount",
@ -1387,12 +1386,6 @@
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{
"fieldname": "additional_discount_account",
"fieldtype": "Link",
"label": "Additional Discount Account",
"options": "Account"
},
{ {
"default": "0", "default": "0",
"fieldname": "ignore_default_payment_terms_template", "fieldname": "ignore_default_payment_terms_template",
@ -1445,7 +1438,7 @@
"idx": 204, "idx": 204,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2022-09-13 23:39:54.525037", "modified": "2022-09-27 11:07:55.766844",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Purchase Invoice", "name": "Purchase Invoice",

View File

@ -669,9 +669,6 @@ class PurchaseInvoice(BuyingController):
exchange_rate_map, net_rate_map = get_purchase_document_details(self) exchange_rate_map, net_rate_map = get_purchase_document_details(self)
enable_discount_accounting = cint(
frappe.db.get_single_value("Buying Settings", "enable_discount_accounting")
)
provisional_accounting_for_non_stock_items = cint( provisional_accounting_for_non_stock_items = cint(
frappe.db.get_value( frappe.db.get_value(
"Company", self.company, "enable_provisional_accounting_for_non_stock_items" "Company", self.company, "enable_provisional_accounting_for_non_stock_items"
@ -1159,9 +1156,6 @@ class PurchaseInvoice(BuyingController):
def make_tax_gl_entries(self, gl_entries): def make_tax_gl_entries(self, gl_entries):
# tax table gl entries # tax table gl entries
valuation_tax = {} valuation_tax = {}
enable_discount_accounting = cint(
frappe.db.get_single_value("Buying Settings", "enable_discount_accounting")
)
for tax in self.get("taxes"): for tax in self.get("taxes"):
amount, base_amount = self.get_tax_amounts(tax, None) amount, base_amount = self.get_tax_amounts(tax, None)
@ -1249,15 +1243,6 @@ class PurchaseInvoice(BuyingController):
) )
) )
@property
def enable_discount_accounting(self):
if not hasattr(self, "_enable_discount_accounting"):
self._enable_discount_accounting = cint(
frappe.db.get_single_value("Buying Settings", "enable_discount_accounting")
)
return self._enable_discount_accounting
def make_internal_transfer_gl_entries(self, gl_entries): def make_internal_transfer_gl_entries(self, gl_entries):
if self.is_internal_transfer() and flt(self.base_total_taxes_and_charges): if self.is_internal_transfer() and flt(self.base_total_taxes_and_charges):
account_currency = get_account_currency(self.unrealized_profit_loss_account) account_currency = get_account_currency(self.unrealized_profit_loss_account)

View File

@ -74,7 +74,6 @@
"manufacturer_part_no", "manufacturer_part_no",
"accounting", "accounting",
"expense_account", "expense_account",
"discount_account",
"col_break5", "col_break5",
"is_fixed_asset", "is_fixed_asset",
"asset_location", "asset_location",
@ -860,12 +859,6 @@
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
}, },
{
"fieldname": "discount_account",
"fieldtype": "Link",
"label": "Discount Account",
"options": "Account"
},
{ {
"fieldname": "product_bundle", "fieldname": "product_bundle",
"fieldtype": "Link", "fieldtype": "Link",
@ -877,7 +870,7 @@
"idx": 1, "idx": 1,
"istable": 1, "istable": 1,
"links": [], "links": [],
"modified": "2022-06-17 05:31:10.520171", "modified": "2022-09-27 10:54:23.980713",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Purchase Invoice Item", "name": "Purchase Invoice Item",

View File

@ -335,6 +335,9 @@ def get_advance_vouchers(
"party": ["in", parties], "party": ["in", parties],
} }
if party_type == "Customer":
filters.update({"against_voucher": ["is", "not set"]})
if company: if company:
filters["company"] = company filters["company"] = company
if from_date and to_date: if from_date and to_date:

View File

@ -370,7 +370,7 @@ def get_conditions(filters):
where parent=`tabSales Invoice`.name where parent=`tabSales Invoice`.name
and ifnull(`tab{table}`.{field}, '') = %({field})s)""" and ifnull(`tab{table}`.{field}, '') = %({field})s)"""
conditions += get_sales_invoice_item_field_condition("mode_of_payments", "Sales Invoice Payment") conditions += get_sales_invoice_item_field_condition("mode_of_payment", "Sales Invoice Payment")
conditions += get_sales_invoice_item_field_condition("cost_center") conditions += get_sales_invoice_item_field_condition("cost_center")
conditions += get_sales_invoice_item_field_condition("warehouse") conditions += get_sales_invoice_item_field_condition("warehouse")
conditions += get_sales_invoice_item_field_condition("brand") conditions += get_sales_invoice_item_field_condition("brand")

View File

@ -20,7 +20,6 @@
"maintain_same_rate", "maintain_same_rate",
"allow_multiple_items", "allow_multiple_items",
"bill_for_rejected_quantity_in_purchase_invoice", "bill_for_rejected_quantity_in_purchase_invoice",
"enable_discount_accounting",
"subcontract", "subcontract",
"backflush_raw_materials_of_subcontract_based_on", "backflush_raw_materials_of_subcontract_based_on",
"column_break_11", "column_break_11",
@ -134,13 +133,6 @@
{ {
"fieldname": "column_break_12", "fieldname": "column_break_12",
"fieldtype": "Column Break" "fieldtype": "Column Break"
},
{
"default": "0",
"description": "If enabled, additional ledger entries will be made for discounts in a separate Discount Account",
"fieldname": "enable_discount_accounting",
"fieldtype": "Check",
"label": "Enable Discount Accounting for Buying"
} }
], ],
"icon": "fa fa-cog", "icon": "fa fa-cog",
@ -148,7 +140,7 @@
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"issingle": 1, "issingle": 1,
"links": [], "links": [],
"modified": "2022-09-01 18:01:34.994657", "modified": "2022-09-27 10:50:27.050252",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Buying Settings", "name": "Buying Settings",

View File

@ -5,15 +5,10 @@
import frappe import frappe
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from frappe.model.document import Document from frappe.model.document import Document
from frappe.utils import cint
class BuyingSettings(Document): class BuyingSettings(Document):
def on_update(self):
self.toggle_discount_accounting_fields()
def validate(self): def validate(self):
for key in ["supplier_group", "supp_master_name", "maintain_same_rate", "buying_price_list"]: for key in ["supplier_group", "supp_master_name", "maintain_same_rate", "buying_price_list"]:
frappe.db.set_default(key, self.get(key, "")) frappe.db.set_default(key, self.get(key, ""))
@ -26,60 +21,3 @@ class BuyingSettings(Document):
self.get("supp_master_name") == "Naming Series", self.get("supp_master_name") == "Naming Series",
hide_name_field=False, hide_name_field=False,
) )
def toggle_discount_accounting_fields(self):
enable_discount_accounting = cint(self.enable_discount_accounting)
make_property_setter(
"Purchase Invoice Item",
"discount_account",
"hidden",
not (enable_discount_accounting),
"Check",
validate_fields_for_doctype=False,
)
if enable_discount_accounting:
make_property_setter(
"Purchase Invoice Item",
"discount_account",
"mandatory_depends_on",
"eval: doc.discount_amount",
"Code",
validate_fields_for_doctype=False,
)
else:
make_property_setter(
"Purchase Invoice Item",
"discount_account",
"mandatory_depends_on",
"",
"Code",
validate_fields_for_doctype=False,
)
make_property_setter(
"Purchase Invoice",
"additional_discount_account",
"hidden",
not (enable_discount_accounting),
"Check",
validate_fields_for_doctype=False,
)
if enable_discount_accounting:
make_property_setter(
"Purchase Invoice",
"additional_discount_account",
"mandatory_depends_on",
"eval: doc.discount_amount",
"Code",
validate_fields_for_doctype=False,
)
else:
make_property_setter(
"Purchase Invoice",
"additional_discount_account",
"mandatory_depends_on",
"",
"Code",
validate_fields_for_doctype=False,
)

View File

@ -33,6 +33,7 @@ frappe.ui.form.on("Purchase Order", {
frm.set_query("fg_item", "items", function() { frm.set_query("fg_item", "items", function() {
return { return {
filters: { filters: {
'is_stock_item': 1,
'is_sub_contracted_item': 1, 'is_sub_contracted_item': 1,
'default_bom': ['!=', ''] 'default_bom': ['!=', '']
} }

View File

@ -212,21 +212,15 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
meta = frappe.get_meta(doctype, cached=True) meta = frappe.get_meta(doctype, cached=True)
searchfields = meta.get_search_fields() searchfields = meta.get_search_fields()
# 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 = "" columns = ""
extra_searchfields = [ extra_searchfields = [field for field in searchfields if not field in ["name", "description"]]
field
for field in searchfields
if not field in ["name", "item_group", "description", "item_name"]
]
if extra_searchfields: if extra_searchfields:
columns = ", " + ", ".join(extra_searchfields) columns += ", " + ", ".join(extra_searchfields)
if "description" in searchfields:
columns += """, if(length(tabItem.description) > 40, \
concat(substr(tabItem.description, 1, 40), "..."), description) as description"""
searchfields = searchfields + [ searchfields = searchfields + [
field field
@ -266,12 +260,10 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
if frappe.db.count(doctype, cache=True) < 50000: if frappe.db.count(doctype, cache=True) < 50000:
# scan description only if items are less than 50000 # scan description only if items are less than 50000
description_cond = "or tabItem.description LIKE %(txt)s" description_cond = "or tabItem.description LIKE %(txt)s"
return frappe.db.sql( return frappe.db.sql(
"""select """select
tabItem.name, tabItem.item_name, tabItem.item_group, tabItem.name {columns}
if(length(tabItem.description) > 40, \
concat(substr(tabItem.description, 1, 40), "..."), description) as description
{columns}
from tabItem from tabItem
where tabItem.docstatus < 2 where tabItem.docstatus < 2
and tabItem.disabled=0 and tabItem.disabled=0

View File

@ -69,9 +69,18 @@ class SubcontractingController(StockController):
def validate_items(self): def validate_items(self):
for item in self.items: for item in self.items:
if not frappe.get_value("Item", item.item_code, "is_sub_contracted_item"): is_stock_item, is_sub_contracted_item = frappe.get_value(
"Item", item.item_code, ["is_stock_item", "is_sub_contracted_item"]
)
if not is_stock_item:
msg = f"Item {item.item_name} must be a stock item."
frappe.throw(_(msg))
if not is_sub_contracted_item:
msg = f"Item {item.item_name} must be a subcontracted item." msg = f"Item {item.item_name} must be a subcontracted item."
frappe.throw(_(msg)) frappe.throw(_(msg))
if item.bom: if item.bom:
bom = frappe.get_doc("BOM", item.bom) bom = frappe.get_doc("BOM", item.bom)
if not bom.is_active: if not bom.is_active:

View File

@ -508,6 +508,7 @@ accounting_dimension_doctypes = [
"Landed Cost Item", "Landed Cost Item",
"Asset Value Adjustment", "Asset Value Adjustment",
"Asset Repair", "Asset Repair",
"Asset Capitalization",
"Loyalty Program", "Loyalty Program",
"Stock Reconciliation", "Stock Reconciliation",
"POS Profile", "POS Profile",

View File

@ -315,3 +315,4 @@ erpnext.patches.v14_0.fix_crm_no_of_employees
erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes erpnext.patches.v14_0.create_accounting_dimensions_in_subcontracting_doctypes
erpnext.patches.v14_0.fix_subcontracting_receipt_gl_entries erpnext.patches.v14_0.fix_subcontracting_receipt_gl_entries
erpnext.patches.v14_0.migrate_remarks_from_gl_to_payment_ledger erpnext.patches.v14_0.migrate_remarks_from_gl_to_payment_ledger
erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization

View File

@ -0,0 +1,31 @@
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
def execute():
accounting_dimensions = frappe.db.get_all(
"Accounting Dimension", fields=["fieldname", "label", "document_type", "disabled"]
)
if not accounting_dimensions:
return
doctype = "Asset Capitalization"
for d in accounting_dimensions:
field = frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": d.fieldname})
if field:
continue
df = {
"fieldname": d.fieldname,
"label": d.label,
"fieldtype": "Link",
"options": d.document_type,
"insert_after": "accounting_dimensions_section",
}
create_custom_field(doctype, df, ignore_validate=True)
frappe.clear_cache(doctype=doctype)

View File

@ -10,6 +10,31 @@ frappe.ui.form.on("Item", {
frm.add_fetch('attribute', 'to_range', 'to_range'); frm.add_fetch('attribute', 'to_range', 'to_range');
frm.add_fetch('attribute', 'increment', 'increment'); frm.add_fetch('attribute', 'increment', 'increment');
frm.add_fetch('tax_type', 'tax_rate', 'tax_rate'); frm.add_fetch('tax_type', 'tax_rate', 'tax_rate');
frm.make_methods = {
'Sales Order': () => {
open_form(frm, "Sales Order", "Sales Order Item", "items");
},
'Delivery Note': () => {
open_form(frm, "Delivery Note", "Delivery Note Item", "items");
},
'Sales Invoice': () => {
open_form(frm, "Sales Invoice", "Sales Invoice Item", "items");
},
'Purchase Order': () => {
open_form(frm, "Purchase Order", "Purchase Order Item", "items");
},
'Purchase Receipt': () => {
open_form(frm, "Purchase Receipt", "Purchase Receipt Item", "items");
},
'Purchase Invoice': () => {
open_form(frm, "Purchase Invoice", "Purchase Invoice Item", "items");
},
'Material Request': () => {
open_form(frm, "Material Request", "Material Request Item", "items");
},
};
}, },
onload: function(frm) { onload: function(frm) {
erpnext.item.setup_queries(frm); erpnext.item.setup_queries(frm);
@ -858,3 +883,17 @@ frappe.tour['Item'] = [
]; ];
function open_form(frm, doctype, child_doctype, parentfield) {
frappe.model.with_doctype(doctype, () => {
let new_doc = frappe.model.get_new_doc(doctype);
let new_child_doc = frappe.model.add_child(new_doc, child_doctype, parentfield);
new_child_doc.item_code = frm.doc.name;
new_child_doc.item_name = frm.doc.item_name;
new_child_doc.uom = frm.doc.stock_uom;
new_child_doc.description = frm.doc.description;
frappe.ui.form.make_quick_entry(doctype, null, null, new_doc);
});
}

View File

@ -937,17 +937,21 @@ class Item(Document):
"Purchase Order Item", "Purchase Order Item",
"Material Request Item", "Material Request Item",
"Product Bundle", "Product Bundle",
"BOM",
] ]
for doctype in linked_doctypes: for doctype in linked_doctypes:
filters = {"item_code": self.name, "docstatus": 1} filters = {"item_code": self.name, "docstatus": 1}
if doctype in ("Product Bundle", "BOM"):
if doctype == "Product Bundle": if doctype == "Product Bundle":
filters = {"new_item_code": self.name} filters = {"new_item_code": self.name}
fieldname = "new_item_code as docname"
else:
filters = {"item": self.name, "docstatus": 1}
fieldname = "name as docname"
if linked_doc := frappe.db.get_value( if linked_doc := frappe.db.get_value(doctype, filters, fieldname, as_dict=True):
doctype, filters, ["new_item_code as docname"], as_dict=True
):
return linked_doc.update({"doctype": doctype}) return linked_doc.update({"doctype": doctype})
elif doctype in ( elif doctype in (

View File

@ -5,6 +5,7 @@
import json import json
import frappe import frappe
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from frappe.test_runner import make_test_objects from frappe.test_runner import make_test_objects
from frappe.tests.utils import FrappeTestCase, change_settings from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, today from frappe.utils import add_days, today
@ -816,6 +817,30 @@ class TestItem(FrappeTestCase):
item.reload() item.reload()
self.assertEqual(item.is_stock_item, 1) self.assertEqual(item.is_stock_item, 1)
def test_serach_fields_for_item(self):
from erpnext.controllers.queries import item_query
make_property_setter("Item", None, "search_fields", "item_name", "Data", for_doctype="Doctype")
item = make_item(properties={"item_name": "Test Item", "description": "Test Description"})
data = item_query(
"Item", "Test Item", "", 0, 20, filters={"item_name": "Test Item"}, as_dict=True
)
self.assertEqual(data[0].name, item.name)
self.assertEqual(data[0].item_name, item.item_name)
self.assertTrue("description" not in data[0])
make_property_setter(
"Item", None, "search_fields", "item_name, description", "Data", for_doctype="Doctype"
)
data = item_query(
"Item", "Test Item", "", 0, 20, filters={"item_name": "Test Item"}, as_dict=True
)
self.assertEqual(data[0].name, item.name)
self.assertEqual(data[0].item_name, item.item_name)
self.assertEqual(data[0].description, item.description)
self.assertTrue("description" in data[0])
def set_item_variant_settings(fields): def set_item_variant_settings(fields):
doc = frappe.get_doc("Item Variant Settings") doc = frappe.get_doc("Item Variant Settings")

View File

@ -18,7 +18,7 @@
<b class="caret"></b> <b class="caret"></b>
</button> </button>
<ul class="dropdown-menu dropdown-menu-right" role="menu"> <ul class="dropdown-menu dropdown-menu-right" role="menu">
{% if doc.doctype == 'Purchase Order' %} {% if doc.doctype == 'Purchase Order' and show_make_pi_button %}
<a class="dropdown-item" href="/api/method/erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice_from_portal?purchase_order_name={{ doc.name }}" data-action="make_purchase_invoice">{{ _("Make Purchase Invoice") }}</a> <a class="dropdown-item" href="/api/method/erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice_from_portal?purchase_order_name={{ doc.name }}" data-action="make_purchase_invoice">{{ _("Make Purchase Invoice") }}</a>
{% endif %} {% endif %}
<a class="dropdown-item" href='/printview?doctype={{ doc.doctype}}&name={{ doc.name }}&format={{ print_format }}' <a class="dropdown-item" href='/printview?doctype={{ doc.doctype}}&name={{ doc.name }}&format={{ print_format }}'

View File

@ -52,6 +52,9 @@ def get_context(context):
) )
context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points")) context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points"))
# show Make Purchase Invoice button based on permission
context.show_make_pi_button = frappe.has_permission("Purchase Invoice", "create")
def get_attachments(dt, dn): def get_attachments(dt, dn):
return frappe.get_all( return frappe.get_all(