mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-13 10:11:20 +00:00
Merge pull request #39978 from frappe/version-14-hotfix
chore: release v14
This commit is contained in:
@@ -41,9 +41,10 @@ class BankTransaction(StatusUpdater):
|
|||||||
else:
|
else:
|
||||||
allocated_amount = 0.0
|
allocated_amount = 0.0
|
||||||
|
|
||||||
amount = abs(flt(self.withdrawal) - flt(self.deposit))
|
unallocated_amount = abs(flt(self.withdrawal) - flt(self.deposit)) - allocated_amount
|
||||||
self.db_set("allocated_amount", flt(allocated_amount))
|
|
||||||
self.db_set("unallocated_amount", amount - flt(allocated_amount))
|
self.db_set("allocated_amount", flt(allocated_amount, self.precision("allocated_amount")))
|
||||||
|
self.db_set("unallocated_amount", flt(unallocated_amount, self.precision("unallocated_amount")))
|
||||||
self.reload()
|
self.reload()
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
||||||
|
|
||||||
|
|||||||
@@ -11,23 +11,8 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
|
|||||||
super.setup(doc);
|
super.setup(doc);
|
||||||
}
|
}
|
||||||
company() {
|
company() {
|
||||||
|
super.company();
|
||||||
erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);
|
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() {
|
onload() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|||||||
@@ -85,7 +85,10 @@ class ReceivablePayableReport(object):
|
|||||||
self.skip_total_row = 1
|
self.skip_total_row = 1
|
||||||
|
|
||||||
if self.filters.get("in_party_currency"):
|
if self.filters.get("in_party_currency"):
|
||||||
self.skip_total_row = 1
|
if self.filters.get("party") and len(self.filters.get("party")) == 1:
|
||||||
|
self.skip_total_row = 0
|
||||||
|
else:
|
||||||
|
self.skip_total_row = 1
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
self.get_ple_entries()
|
self.get_ple_entries()
|
||||||
|
|||||||
@@ -6,6 +6,19 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
|
|
||||||
erpnext.utils.add_dimensions('Balance Sheet', 10);
|
erpnext.utils.add_dimensions('Balance Sheet', 10);
|
||||||
|
|
||||||
|
frappe.query_reports["Balance Sheet"]["filters"].push(
|
||||||
|
{
|
||||||
|
"fieldname": "selected_view",
|
||||||
|
"label": __("Select View"),
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": [
|
||||||
|
{ "value": "Report", "label": __("Report View") },
|
||||||
|
{ "value": "Growth", "label": __("Growth View") }
|
||||||
|
],
|
||||||
|
"default": "Report",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
);
|
||||||
frappe.query_reports["Balance Sheet"]["filters"].push({
|
frappe.query_reports["Balance Sheet"]["filters"].push({
|
||||||
"fieldname": "accumulated_values",
|
"fieldname": "accumulated_values",
|
||||||
"label": __("Accumulated Values"),
|
"label": __("Accumulated Values"),
|
||||||
|
|||||||
@@ -319,7 +319,8 @@ def get_items(filters, additional_query_columns):
|
|||||||
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
|
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
|
||||||
`tabPurchase Invoice`.unrealized_profit_loss_account,
|
`tabPurchase Invoice`.unrealized_profit_loss_account,
|
||||||
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
|
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
|
||||||
`tabPurchase Invoice Item`.`item_name` as pi_item_name, `tabPurchase Invoice Item`.`item_group` as pi_item_group,
|
`tabPurchase Invoice Item`.`item_name` as pi_item_name, `tabPurchase Invoice Item`.`item_group`
|
||||||
|
,`tabPurchase Invoice Item`.`item_group` as pi_item_group,
|
||||||
`tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group,
|
`tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group,
|
||||||
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
|
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
|
||||||
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
|
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
|
||||||
|
|||||||
@@ -350,7 +350,13 @@ def get_conditions(filters, additional_conditions=None):
|
|||||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||||
|
|
||||||
if filters.get("warehouse"):
|
if filters.get("warehouse"):
|
||||||
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
|
if frappe.db.get_value("Warehouse", filters.get("warehouse"), "is_group"):
|
||||||
|
lft, rgt = frappe.db.get_all(
|
||||||
|
"Warehouse", filters={"name": filters.get("warehouse")}, fields=["lft", "rgt"], as_list=True
|
||||||
|
)[0]
|
||||||
|
conditions += f"and ifnull(`tabSales Invoice Item`.warehouse, '') in (select name from `tabWarehouse` where lft > {lft} and rgt < {rgt}) "
|
||||||
|
else:
|
||||||
|
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
|
||||||
|
|
||||||
if filters.get("brand"):
|
if filters.get("brand"):
|
||||||
conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""
|
conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""
|
||||||
|
|||||||
@@ -8,6 +8,21 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
|
|
||||||
erpnext.utils.add_dimensions('Profit and Loss Statement', 10);
|
erpnext.utils.add_dimensions('Profit and Loss Statement', 10);
|
||||||
|
|
||||||
|
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
|
||||||
|
{
|
||||||
|
"fieldname": "selected_view",
|
||||||
|
"label": __("Select View"),
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"options": [
|
||||||
|
{ "value": "Report", "label": __("Report View") },
|
||||||
|
{ "value": "Growth", "label": __("Growth View") },
|
||||||
|
{ "value": "Margin", "label": __("Margin View") },
|
||||||
|
],
|
||||||
|
"default": "Report",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
|
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
|
||||||
{
|
{
|
||||||
"fieldname": "include_default_book_entries",
|
"fieldname": "include_default_book_entries",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import frappe.defaults
|
|||||||
from frappe import _, qb, throw
|
from frappe import _, qb, throw
|
||||||
from frappe.model.meta import get_field_precision
|
from frappe.model.meta import get_field_precision
|
||||||
from frappe.query_builder import AliasedQuery, Criterion, Table
|
from frappe.query_builder import AliasedQuery, Criterion, Table
|
||||||
from frappe.query_builder.functions import Sum
|
from frappe.query_builder.functions import Round, Sum
|
||||||
from frappe.query_builder.utils import DocType
|
from frappe.query_builder.utils import DocType
|
||||||
from frappe.utils import (
|
from frappe.utils import (
|
||||||
cint,
|
cint,
|
||||||
@@ -549,16 +549,19 @@ def check_if_advance_entry_modified(args):
|
|||||||
args,
|
args,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
ret = frappe.db.sql(
|
pe = qb.DocType("Payment Entry")
|
||||||
"""select name from `tabPayment Entry`
|
ret = (
|
||||||
where
|
qb.from_(pe)
|
||||||
name = %(voucher_no)s and docstatus = 1
|
.select(pe.name)
|
||||||
and party_type = %(party_type)s and party = %(party)s and {0} = %(account)s
|
.where(
|
||||||
and round(unallocated_amount, {1}) = round(%(unreconciled_amount)s, {1})
|
(pe.name == args.voucher_no)
|
||||||
""".format(
|
& (pe.docstatus == 1)
|
||||||
party_account_field, precision
|
& (pe.party_type == args.party_type)
|
||||||
),
|
& (pe.party == args.party)
|
||||||
args,
|
& (pe[party_account_field] == args.account)
|
||||||
|
& (Round(pe.unallocated_amount, precision) == Round(args.unreconciled_amount, precision))
|
||||||
|
)
|
||||||
|
.run()
|
||||||
)
|
)
|
||||||
|
|
||||||
if not ret:
|
if not ret:
|
||||||
|
|||||||
@@ -513,14 +513,15 @@ class Asset(AccountsController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Adjust depreciation amount in the last period based on the expected value after useful life
|
# Adjust depreciation amount in the last period based on the expected value after useful life
|
||||||
if finance_book.expected_value_after_useful_life and (
|
if (
|
||||||
(
|
n == cint(final_number_of_depreciations) - 1
|
||||||
n == cint(final_number_of_depreciations) - 1
|
and flt(value_after_depreciation) != flt(finance_book.expected_value_after_useful_life)
|
||||||
and value_after_depreciation != finance_book.expected_value_after_useful_life
|
) or flt(value_after_depreciation) < flt(
|
||||||
)
|
finance_book.expected_value_after_useful_life
|
||||||
or value_after_depreciation < finance_book.expected_value_after_useful_life
|
|
||||||
):
|
):
|
||||||
depreciation_amount += value_after_depreciation - finance_book.expected_value_after_useful_life
|
depreciation_amount += flt(value_after_depreciation) - flt(
|
||||||
|
finance_book.expected_value_after_useful_life
|
||||||
|
)
|
||||||
skip_row = True
|
skip_row = True
|
||||||
|
|
||||||
if flt(depreciation_amount, self.precision("gross_purchase_amount")) > 0:
|
if flt(depreciation_amount, self.precision("gross_purchase_amount")) > 0:
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ def reverse_depreciation_entry_made_after_disposal(asset, date):
|
|||||||
else:
|
else:
|
||||||
row += 1
|
row += 1
|
||||||
|
|
||||||
if schedule.schedule_date == date:
|
if schedule.schedule_date == date and schedule.journal_entry:
|
||||||
if not disposal_was_made_on_original_schedule_date(
|
if not disposal_was_made_on_original_schedule_date(
|
||||||
asset, schedule, row, date
|
asset, schedule, row, date
|
||||||
) or disposal_happens_in_the_future(date):
|
) or disposal_happens_in_the_future(date):
|
||||||
|
|||||||
@@ -77,13 +77,13 @@ class AssetCapitalization(StockController):
|
|||||||
"Stock Ledger Entry",
|
"Stock Ledger Entry",
|
||||||
"Repost Item Valuation",
|
"Repost Item Valuation",
|
||||||
"Asset",
|
"Asset",
|
||||||
"Asset Movement"
|
"Asset Movement",
|
||||||
)
|
)
|
||||||
self.cancel_target_asset()
|
self.cancel_target_asset()
|
||||||
self.update_stock_ledger()
|
self.update_stock_ledger()
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
self.restore_consumed_asset_items()
|
self.restore_consumed_asset_items()
|
||||||
|
|
||||||
def cancel_target_asset(self):
|
def cancel_target_asset(self):
|
||||||
if self.entry_type == "Capitalization" and self.target_asset:
|
if self.entry_type == "Capitalization" and self.target_asset:
|
||||||
asset_doc = frappe.get_doc("Asset", self.target_asset)
|
asset_doc = frappe.get_doc("Asset", self.target_asset)
|
||||||
|
|||||||
@@ -201,6 +201,18 @@ class AccountsController(TransactionBase):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.get("is_return") and self.get("return_against"):
|
||||||
|
document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note"
|
||||||
|
frappe.msgprint(
|
||||||
|
_(
|
||||||
|
"{0} will be treated as a standalone {0}. Post creation use {1} tool to reconcile against {2}."
|
||||||
|
).format(
|
||||||
|
document_type,
|
||||||
|
get_link_to_form("Payment Reconciliation", "Payment Reconciliation"),
|
||||||
|
get_link_to_form(self.doctype, self.get("return_against")),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
|
pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
|
||||||
if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
|
if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
|
||||||
self.set_advances()
|
self.set_advances()
|
||||||
|
|||||||
@@ -16,11 +16,49 @@ class BlanketOrder(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
self.validate_duplicate_items()
|
self.validate_duplicate_items()
|
||||||
|
self.set_party_item_code()
|
||||||
|
|
||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
if getdate(self.from_date) > getdate(self.to_date):
|
if getdate(self.from_date) > getdate(self.to_date):
|
||||||
frappe.throw(_("From date cannot be greater than To date"))
|
frappe.throw(_("From date cannot be greater than To date"))
|
||||||
|
|
||||||
|
def set_party_item_code(self):
|
||||||
|
item_ref = {}
|
||||||
|
if self.blanket_order_type == "Selling":
|
||||||
|
item_ref = self.get_customer_items_ref()
|
||||||
|
else:
|
||||||
|
item_ref = self.get_supplier_items_ref()
|
||||||
|
|
||||||
|
if not item_ref:
|
||||||
|
return
|
||||||
|
|
||||||
|
for row in self.items:
|
||||||
|
row.party_item_code = item_ref.get(row.item_code)
|
||||||
|
|
||||||
|
def get_customer_items_ref(self):
|
||||||
|
items = [d.item_code for d in self.items]
|
||||||
|
|
||||||
|
return frappe._dict(
|
||||||
|
frappe.get_all(
|
||||||
|
"Item Customer Detail",
|
||||||
|
filters={"parent": ("in", items), "customer_name": self.customer},
|
||||||
|
fields=["parent", "ref_code"],
|
||||||
|
as_list=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_supplier_items_ref(self):
|
||||||
|
items = [d.item_code for d in self.items]
|
||||||
|
|
||||||
|
return frappe._dict(
|
||||||
|
frappe.get_all(
|
||||||
|
"Item Supplier",
|
||||||
|
filters={"parent": ("in", items), "supplier": self.supplier},
|
||||||
|
fields=["parent", "supplier_part_no"],
|
||||||
|
as_list=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def validate_duplicate_items(self):
|
def validate_duplicate_items(self):
|
||||||
item_list = []
|
item_list = []
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from frappe.tests.utils import FrappeTestCase
|
|||||||
from frappe.utils import add_months, today
|
from frappe.utils import add_months, today
|
||||||
|
|
||||||
from erpnext import get_company_currency
|
from erpnext import get_company_currency
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
|
||||||
from .blanket_order import make_order
|
from .blanket_order import make_order
|
||||||
|
|
||||||
@@ -90,6 +91,30 @@ class TestBlanketOrder(FrappeTestCase):
|
|||||||
frappe.db.set_single_value("Buying Settings", "blanket_order_allowance", 10)
|
frappe.db.set_single_value("Buying Settings", "blanket_order_allowance", 10)
|
||||||
po.submit()
|
po.submit()
|
||||||
|
|
||||||
|
def test_party_item_code(self):
|
||||||
|
item_doc = make_item("_Test Item 1 for Blanket Order")
|
||||||
|
item_code = item_doc.name
|
||||||
|
|
||||||
|
customer = "_Test Customer"
|
||||||
|
supplier = "_Test Supplier"
|
||||||
|
|
||||||
|
if not frappe.db.exists(
|
||||||
|
"Item Customer Detail", {"customer_name": customer, "parent": item_code}
|
||||||
|
):
|
||||||
|
item_doc.append("customer_items", {"customer_name": customer, "ref_code": "CUST-REF-1"})
|
||||||
|
item_doc.save()
|
||||||
|
|
||||||
|
if not frappe.db.exists("Item Supplier", {"supplier": supplier, "parent": item_code}):
|
||||||
|
item_doc.append("supplier_items", {"supplier": supplier, "supplier_part_no": "SUPP-PART-1"})
|
||||||
|
item_doc.save()
|
||||||
|
|
||||||
|
# Blanket Order for Selling
|
||||||
|
bo = make_blanket_order(blanket_order_type="Selling", customer=customer, item_code=item_code)
|
||||||
|
self.assertEqual(bo.items[0].party_item_code, "CUST-REF-1")
|
||||||
|
|
||||||
|
bo = make_blanket_order(blanket_order_type="Purchasing", supplier=supplier, item_code=item_code)
|
||||||
|
self.assertEqual(bo.items[0].party_item_code, "SUPP-PART-1")
|
||||||
|
|
||||||
|
|
||||||
def make_blanket_order(**args):
|
def make_blanket_order(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2018-05-24 07:20:04.255236",
|
"creation": "2018-05-24 07:20:04.255236",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -6,6 +7,7 @@
|
|||||||
"field_order": [
|
"field_order": [
|
||||||
"item_code",
|
"item_code",
|
||||||
"item_name",
|
"item_name",
|
||||||
|
"party_item_code",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"qty",
|
"qty",
|
||||||
"rate",
|
"rate",
|
||||||
@@ -62,10 +64,17 @@
|
|||||||
"fieldname": "terms_and_conditions",
|
"fieldname": "terms_and_conditions",
|
||||||
"fieldtype": "Text",
|
"fieldtype": "Text",
|
||||||
"label": "Terms and Conditions"
|
"label": "Terms and Conditions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "party_item_code",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Party Item Code",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-11-18 19:37:46.245878",
|
"links": [],
|
||||||
|
"modified": "2024-02-14 18:25:26.479672",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Blanket Order Item",
|
"name": "Blanket Order Item",
|
||||||
@@ -74,5 +83,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,57 @@ frappe.provide("erpnext.financial_statements");
|
|||||||
|
|
||||||
erpnext.financial_statements = {
|
erpnext.financial_statements = {
|
||||||
"filters": get_filters(),
|
"filters": get_filters(),
|
||||||
|
"baseData": null,
|
||||||
"formatter": function(value, row, column, data, default_formatter, filter) {
|
"formatter": function(value, row, column, data, default_formatter, filter) {
|
||||||
|
if(frappe.query_report.get_filter_value("selected_view") == "Growth" && data && column.colIndex >= 3){
|
||||||
|
//Assuming that the first three columns are s.no, account name and the very first year of the accounting values, to calculate the relative percentage values of the successive columns.
|
||||||
|
const lastAnnualValue = row[column.colIndex - 1].content;
|
||||||
|
const currentAnnualvalue = data[column.fieldname];
|
||||||
|
if(currentAnnualvalue == undefined) return 'NA'; //making this not applicable for undefined/null values
|
||||||
|
let annualGrowth = 0;
|
||||||
|
if(lastAnnualValue == 0 && currentAnnualvalue > 0){
|
||||||
|
//If the previous year value is 0 and the current value is greater than 0
|
||||||
|
annualGrowth = 1;
|
||||||
|
}
|
||||||
|
else if(lastAnnualValue > 0){
|
||||||
|
annualGrowth = (currentAnnualvalue - lastAnnualValue) / lastAnnualValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const growthPercent = (Math.round(annualGrowth*10000)/100); //calculating the rounded off percentage
|
||||||
|
|
||||||
|
value = $(`<span>${((growthPercent >=0)? '+':'' )+growthPercent+'%'}</span>`);
|
||||||
|
if(growthPercent < 0){
|
||||||
|
value = $(value).addClass("text-danger");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
value = $(value).addClass("text-success");
|
||||||
|
}
|
||||||
|
value = $(value).wrap("<p></p>").parent().html();
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else if(frappe.query_report.get_filter_value("selected_view") == "Margin" && data){
|
||||||
|
if(column.fieldname =="account" && data.account_name == __("Income")){
|
||||||
|
//Taking the total income from each column (for all the financial years) as the base (100%)
|
||||||
|
this.baseData = row;
|
||||||
|
}
|
||||||
|
if(column.colIndex >= 2){
|
||||||
|
//Assuming that the first two columns are s.no and account name, to calculate the relative percentage values of the successive columns.
|
||||||
|
const currentAnnualvalue = data[column.fieldname];
|
||||||
|
const baseValue = this.baseData[column.colIndex].content;
|
||||||
|
if(currentAnnualvalue == undefined || baseValue <= 0) return 'NA';
|
||||||
|
const marginPercent = Math.round((currentAnnualvalue/baseValue)*10000)/100;
|
||||||
|
|
||||||
|
value = $(`<span>${marginPercent+'%'}</span>`);
|
||||||
|
if(marginPercent < 0)
|
||||||
|
value = $(value).addClass("text-danger");
|
||||||
|
else
|
||||||
|
value = $(value).addClass("text-success");
|
||||||
|
value = $(value).wrap("<p></p>").parent().html();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (data && column.fieldname=="account") {
|
if (data && column.fieldname=="account") {
|
||||||
value = data.account_name || value;
|
value = data.account_name || value;
|
||||||
|
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ frappe.ui.form.on('Material Request', {
|
|||||||
fields: [
|
fields: [
|
||||||
{"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"),
|
{"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"),
|
||||||
options:"BOM", reqd: 1, get_query: function() {
|
options:"BOM", reqd: 1, get_query: function() {
|
||||||
return {filters: { docstatus:1 }};
|
return {filters: { docstatus:1, "is_active": 1 }};
|
||||||
}},
|
}},
|
||||||
{"fieldname":"warehouse", "fieldtype":"Link", "label":__("For Warehouse"),
|
{"fieldname":"warehouse", "fieldtype":"Link", "label":__("For Warehouse"),
|
||||||
options:"Warehouse", reqd: 1},
|
options:"Warehouse", reqd: 1},
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ class PickList(Document):
|
|||||||
self.update_status()
|
self.update_status()
|
||||||
self.set_item_locations()
|
self.set_item_locations()
|
||||||
|
|
||||||
|
if self.get("locations"):
|
||||||
|
self.validate_sales_order_percentage()
|
||||||
|
|
||||||
|
def validate_sales_order_percentage(self):
|
||||||
# set percentage picked in SO
|
# set percentage picked in SO
|
||||||
for location in self.get("locations"):
|
for location in self.get("locations"):
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -548,7 +548,9 @@ frappe.ui.form.on('Stock Entry', {
|
|||||||
|
|
||||||
let fields = [
|
let fields = [
|
||||||
{"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"),
|
{"fieldname":"bom", "fieldtype":"Link", "label":__("BOM"),
|
||||||
options:"BOM", reqd: 1, get_query: filters()},
|
options:"BOM", reqd: 1, get_query: () => {
|
||||||
|
return {filters: { docstatus:1, "is_active": 1 }};
|
||||||
|
}},
|
||||||
{"fieldname":"source_warehouse", "fieldtype":"Link", "label":__("Source Warehouse"),
|
{"fieldname":"source_warehouse", "fieldtype":"Link", "label":__("Source Warehouse"),
|
||||||
options:"Warehouse"},
|
options:"Warehouse"},
|
||||||
{"fieldname":"target_warehouse", "fieldtype":"Link", "label":__("Target Warehouse"),
|
{"fieldname":"target_warehouse", "fieldtype":"Link", "label":__("Target Warehouse"),
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ class Issue(Document):
|
|||||||
"reference_name": self.name,
|
"reference_name": self.name,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
communication.ignore_permissions = True
|
communication.flags.ignore_permissions = True
|
||||||
communication.ignore_mandatory = True
|
communication.flags.ignore_mandatory = True
|
||||||
communication.save()
|
communication.save()
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ def get_web_item_qty_in_stock(item_code, item_warehouse_field, warehouse=None):
|
|||||||
.where((BIN.item_code == item_code) & (BIN.warehouse == warehouse))
|
.where((BIN.item_code == item_code) & (BIN.warehouse == warehouse))
|
||||||
).run()
|
).run()
|
||||||
|
|
||||||
stock_qty = stock_qty[0][0]
|
|
||||||
if stock_qty:
|
if stock_qty:
|
||||||
|
stock_qty = flt(stock_qty[0][0])
|
||||||
total_stock += adjust_qty_for_expired_items(item_code, stock_qty, warehouse)
|
total_stock += adjust_qty_for_expired_items(item_code, stock_qty, warehouse)
|
||||||
|
|
||||||
in_stock = int(total_stock > 0)
|
in_stock = int(total_stock > 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user