Merge branch 'version-14-hotfix' into handle_post_depr_entries_fail

This commit is contained in:
Anand Baburajan
2022-12-08 01:29:43 +05:30
committed by GitHub
18 changed files with 320 additions and 133 deletions

View File

@@ -169,5 +169,6 @@ def auto_create_fiscal_year():
def get_from_and_to_date(fiscal_year): def get_from_and_to_date(fiscal_year):
fields = ["year_start_date as from_date", "year_end_date as to_date"] fields = ["year_start_date", "year_end_date"]
return frappe.db.get_value("Fiscal Year", fiscal_year, fields, as_dict=1) cached_results = frappe.get_cached_value("Fiscal Year", fiscal_year, fields, as_dict=1)
return dict(from_date=cached_results.year_start_date, to_date=cached_results.year_end_date)

View File

@@ -231,7 +231,9 @@ class PurchaseInvoice(BuyingController):
) )
if ( if (
cint(frappe.db.get_single_value("Buying Settings", "maintain_same_rate")) and not self.is_return cint(frappe.db.get_single_value("Buying Settings", "maintain_same_rate"))
and not self.is_return
and not self.is_internal_supplier
): ):
self.validate_rate_with_reference_doc( self.validate_rate_with_reference_doc(
[ [

View File

@@ -920,6 +920,7 @@
"fieldtype": "Table", "fieldtype": "Table",
"hide_days": 1, "hide_days": 1,
"hide_seconds": 1, "hide_seconds": 1,
"label": "Sales Taxes and Charges",
"oldfieldname": "other_charges", "oldfieldname": "other_charges",
"oldfieldtype": "Table", "oldfieldtype": "Table",
"options": "Sales Taxes and Charges" "options": "Sales Taxes and Charges"
@@ -2116,7 +2117,7 @@
"link_fieldname": "consolidated_invoice" "link_fieldname": "consolidated_invoice"
} }
], ],
"modified": "2022-11-17 17:17:10.883487", "modified": "2022-12-05 16:18:14.532114",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice", "name": "Sales Invoice",

View File

@@ -28,7 +28,7 @@ def get_currency(filters):
filters["presentation_currency"] if filters.get("presentation_currency") else company_currency filters["presentation_currency"] if filters.get("presentation_currency") else company_currency
) )
report_date = filters.get("to_date") report_date = filters.get("to_date") or filters.get("period_end_date")
if not report_date: if not report_date:
fiscal_year_to_date = get_from_and_to_date(filters.get("to_fiscal_year"))["to_date"] fiscal_year_to_date = get_from_and_to_date(filters.get("to_fiscal_year"))["to_date"]

View File

@@ -322,17 +322,18 @@ class BuyingController(SubcontractingController):
) )
if self.is_internal_transfer(): if self.is_internal_transfer():
if rate != d.rate: if self.doctype == "Purchase Receipt" or self.get("update_stock"):
d.rate = rate if rate != d.rate:
frappe.msgprint( d.rate = rate
_( frappe.msgprint(
"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer" _(
).format(d.idx), "Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
alert=1, ).format(d.idx),
) alert=1,
d.discount_percentage = 0.0 )
d.discount_amount = 0.0 d.discount_percentage = 0.0
d.margin_rate_or_amount = 0.0 d.discount_amount = 0.0
d.margin_rate_or_amount = 0.0
def validate_for_subcontracting(self): def validate_for_subcontracting(self):
if self.is_subcontracted and self.get("is_old_subcontracting_flow"): if self.is_subcontracted and self.get("is_old_subcontracting_flow"):

View File

@@ -442,30 +442,31 @@ class SellingController(StockController):
# For internal transfers use incoming rate as the valuation rate # For internal transfers use incoming rate as the valuation rate
if self.is_internal_transfer(): if self.is_internal_transfer():
if d.doctype == "Packed Item": if self.doctype == "Delivery Note" or self.get("update_stock"):
incoming_rate = flt( if d.doctype == "Packed Item":
flt(d.incoming_rate, d.precision("incoming_rate")) * d.conversion_factor, incoming_rate = flt(
d.precision("incoming_rate"), flt(d.incoming_rate, d.precision("incoming_rate")) * d.conversion_factor,
) d.precision("incoming_rate"),
if d.incoming_rate != incoming_rate:
d.incoming_rate = incoming_rate
else:
rate = flt(
flt(d.incoming_rate, d.precision("incoming_rate")) * d.conversion_factor,
d.precision("rate"),
)
if d.rate != rate:
d.rate = rate
frappe.msgprint(
_(
"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
).format(d.idx),
alert=1,
) )
if d.incoming_rate != incoming_rate:
d.incoming_rate = incoming_rate
else:
rate = flt(
flt(d.incoming_rate, d.precision("incoming_rate")) * d.conversion_factor,
d.precision("rate"),
)
if d.rate != rate:
d.rate = rate
frappe.msgprint(
_(
"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
).format(d.idx),
alert=1,
)
d.discount_percentage = 0.0 d.discount_percentage = 0.0
d.discount_amount = 0.0 d.discount_amount = 0.0
d.margin_rate_or_amount = 0.0 d.margin_rate_or_amount = 0.0
elif self.get("return_against"): elif self.get("return_against"):
# Get incoming rate of return entry from reference document # Get incoming rate of return entry from reference document

View File

@@ -635,6 +635,10 @@ class TestWorkOrder(FrappeTestCase):
bom.submit() bom.submit()
bom_name = bom.name bom_name = bom.name
ste1 = test_stock_entry.make_stock_entry(
item_code=rm1, target="_Test Warehouse - _TC", qty=32, basic_rate=5000.0
)
work_order = make_wo_order_test_record( work_order = make_wo_order_test_record(
item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1 item=fg_item, skip_transfer=True, planned_start_date=now(), qty=1
) )
@@ -659,11 +663,29 @@ class TestWorkOrder(FrappeTestCase):
work_order.insert() work_order.insert()
work_order.submit() work_order.submit()
self.assertEqual(work_order.has_batch_no, 1) self.assertEqual(work_order.has_batch_no, 1)
ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 30)) batches = frappe.get_all("Batch", filters={"reference_name": work_order.name})
self.assertEqual(len(batches), 3)
batches = [batch.name for batch in batches]
ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 10))
for row in ste1.get("items"): for row in ste1.get("items"):
if row.is_finished_item: if row.is_finished_item:
self.assertEqual(row.item_code, fg_item) self.assertEqual(row.item_code, fg_item)
self.assertEqual(row.qty, 10) self.assertEqual(row.qty, 10)
self.assertTrue(row.batch_no in batches)
batches.remove(row.batch_no)
ste1.submit()
remaining_batches = []
ste1 = frappe.get_doc(make_stock_entry(work_order.name, "Manufacture", 20))
for row in ste1.get("items"):
if row.is_finished_item:
self.assertEqual(row.item_code, fg_item)
self.assertEqual(row.qty, 10)
remaining_batches.append(row.batch_no)
self.assertEqual(sorted(remaining_batches), sorted(batches))
frappe.db.set_value("Manufacturing Settings", None, "make_serial_no_batch_from_work_order", 0) frappe.db.set_value("Manufacturing Settings", None, "make_serial_no_batch_from_work_order", 0)

View File

@@ -49,7 +49,7 @@ class ProductionPlanReport(object):
parent.bom_no, parent.bom_no,
parent.fg_warehouse.as_("warehouse"), parent.fg_warehouse.as_("warehouse"),
) )
.where(parent.status.notin(["Completed", "Stopped"])) .where(parent.status.notin(["Completed", "Stopped", "Closed"]))
) )
if order_by == "Planned Start Date": if order_by == "Planned Start Date":
@@ -79,10 +79,11 @@ class ProductionPlanReport(object):
query = query.where(child.parent.isin(self.filters.docnames)) query = query.where(child.parent.isin(self.filters.docnames))
if doctype == "Sales Order": if doctype == "Sales Order":
query = query.select( query = query.select(child.delivery_date, parent.base_grand_total,).where(
child.delivery_date, (child.stock_qty > child.produced_qty)
parent.base_grand_total, & (parent.per_delivered < 100.0)
).where((child.stock_qty > child.produced_qty) & (parent.per_delivered < 100.0)) & (parent.status.notin(["Completed", "Closed"]))
)
if order_by == "Delivery Date": if order_by == "Delivery Date":
query = query.orderby(child.delivery_date, order=Order.asc) query = query.orderby(child.delivery_date, order=Order.asc)
@@ -91,7 +92,9 @@ class ProductionPlanReport(object):
elif doctype == "Material Request": elif doctype == "Material Request":
query = query.select(child.schedule_date,).where( query = query.select(child.schedule_date,).where(
(parent.per_ordered < 100) & (parent.material_request_type == "Manufacture") (parent.per_ordered < 100)
& (parent.material_request_type == "Manufacture")
& (parent.status != "Stopped")
) )
if order_by == "Required Date": if order_by == "Required Date":

View File

@@ -1,5 +1,8 @@
import frappe
from erpnext.setup.install import setup_currency_exchange from erpnext.setup.install import setup_currency_exchange
def execute(): def execute():
frappe.reload_doc("accounts", "doctype", "currency_exchange_settings")
setup_currency_exchange() setup_currency_exchange()

View File

@@ -48,7 +48,7 @@ def make_packing_list(doc):
update_packed_item_from_cancelled_doc(item_row, bundle_item, pi_row, doc) update_packed_item_from_cancelled_doc(item_row, bundle_item, pi_row, doc)
if set_price_from_children: # create/update bundle item wise price dict if set_price_from_children: # create/update bundle item wise price dict
update_product_bundle_rate(parent_items_price, pi_row) update_product_bundle_rate(parent_items_price, pi_row, item_row)
if parent_items_price: if parent_items_price:
set_product_bundle_rate_amount(doc, parent_items_price) # set price in bundle item set_product_bundle_rate_amount(doc, parent_items_price) # set price in bundle item
@@ -247,7 +247,7 @@ def get_cancelled_doc_packed_item_details(old_packed_items):
return prev_doc_packed_items_map return prev_doc_packed_items_map
def update_product_bundle_rate(parent_items_price, pi_row): def update_product_bundle_rate(parent_items_price, pi_row, item_row):
""" """
Update the price dict of Product Bundles based on the rates of the Items in the bundle. Update the price dict of Product Bundles based on the rates of the Items in the bundle.
@@ -259,7 +259,7 @@ def update_product_bundle_rate(parent_items_price, pi_row):
if not rate: if not rate:
parent_items_price[key] = 0.0 parent_items_price[key] = 0.0
parent_items_price[key] += flt(pi_row.rate) parent_items_price[key] += flt((pi_row.rate * pi_row.qty) / item_row.stock_qty)
def set_product_bundle_rate_amount(doc, parent_items_price): def set_product_bundle_rate_amount(doc, parent_items_price):

View File

@@ -126,8 +126,8 @@ class TestPackedItem(FrappeTestCase):
so.packed_items[1].rate = 200 so.packed_items[1].rate = 200
so.save() so.save()
self.assertEqual(so.items[0].rate, 350) self.assertEqual(so.items[0].rate, 700)
self.assertEqual(so.items[0].amount, 700) self.assertEqual(so.items[0].amount, 1400)
def test_newly_mapped_doc_packed_items(self): def test_newly_mapped_doc_packed_items(self):
"Test impact on packed items in newly mapped DN from SO." "Test impact on packed items in newly mapped DN from SO."

View File

@@ -173,7 +173,9 @@ class PurchaseReceipt(BuyingController):
) )
if ( if (
cint(frappe.db.get_single_value("Buying Settings", "maintain_same_rate")) and not self.is_return cint(frappe.db.get_single_value("Buying Settings", "maintain_same_rate"))
and not self.is_return
and not self.is_internal_supplier
): ):
self.validate_rate_with_reference_doc( self.validate_rate_with_reference_doc(
[["Purchase Order", "purchase_order", "purchase_order_item"]] [["Purchase Order", "purchase_order", "purchase_order_item"]]

View File

@@ -1545,6 +1545,7 @@ class StockEntry(StockController):
"reference_name": self.pro_doc.name, "reference_name": self.pro_doc.name,
"reference_doctype": self.pro_doc.doctype, "reference_doctype": self.pro_doc.doctype,
"qty_to_produce": (">", 0), "qty_to_produce": (">", 0),
"batch_qty": ("=", 0),
} }
fields = ["qty_to_produce as qty", "produced_qty", "name"] fields = ["qty_to_produce as qty", "produced_qty", "name"]
@@ -2238,14 +2239,14 @@ class StockEntry(StockController):
d.qty -= process_loss_dict[d.item_code][1] d.qty -= process_loss_dict[d.item_code][1]
def set_serial_no_batch_for_finished_good(self): def set_serial_no_batch_for_finished_good(self):
args = {} serial_nos = ""
if self.pro_doc.serial_no: if self.pro_doc.serial_no:
self.get_serial_nos_for_fg(args) serial_nos = self.get_serial_nos_for_fg()
for row in self.items: for row in self.items:
if row.is_finished_item and row.item_code == self.pro_doc.production_item: if row.is_finished_item and row.item_code == self.pro_doc.production_item:
if args.get("serial_no"): if serial_nos:
row.serial_no = "\n".join(args["serial_no"][0 : cint(row.qty)]) row.serial_no = "\n".join(serial_nos[0 : cint(row.qty)])
def get_serial_nos_for_fg(self, args): def get_serial_nos_for_fg(self, args):
fields = [ fields = [
@@ -2258,14 +2259,14 @@ class StockEntry(StockController):
filters = [ filters = [
["Stock Entry", "work_order", "=", self.work_order], ["Stock Entry", "work_order", "=", self.work_order],
["Stock Entry", "purpose", "=", "Manufacture"], ["Stock Entry", "purpose", "=", "Manufacture"],
["Stock Entry", "docstatus", "=", 1], ["Stock Entry", "docstatus", "<", 2],
["Stock Entry Detail", "item_code", "=", self.pro_doc.production_item], ["Stock Entry Detail", "item_code", "=", self.pro_doc.production_item],
] ]
stock_entries = frappe.get_all("Stock Entry", fields=fields, filters=filters) stock_entries = frappe.get_all("Stock Entry", fields=fields, filters=filters)
if self.pro_doc.serial_no: if self.pro_doc.serial_no:
args["serial_no"] = self.get_available_serial_nos(stock_entries) return self.get_available_serial_nos(stock_entries)
def get_available_serial_nos(self, stock_entries): def get_available_serial_nos(self, stock_entries):
used_serial_nos = [] used_serial_nos = []

View File

@@ -0,0 +1,20 @@
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
/* eslint-disable */
frappe.query_reports["Warehouse Wise Stock Balance"] = {
"filters": [
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"reqd": 1,
"default": frappe.defaults.get_user_default("Company")
}
],
"initial_depth": 3,
"tree": true,
"parent_field": "parent_warehouse",
"name_field": "warehouse"
};

View File

@@ -0,0 +1,30 @@
{
"add_total_row": 0,
"columns": [],
"creation": "2022-12-06 14:15:31.924345",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
"json": "{}",
"modified": "2022-12-06 14:16:55.969214",
"modified_by": "Administrator",
"module": "Stock",
"name": "Warehouse Wise Stock Balance",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "Stock Ledger Entry",
"report_name": "Warehouse Wise Stock Balance",
"report_type": "Script Report",
"roles": [
{
"role": "Stock User"
},
{
"role": "Accounts Manager"
}
]
}

View File

@@ -0,0 +1,89 @@
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from typing import Any, Dict, List, Optional, TypedDict
import frappe
from frappe import _
from frappe.query_builder.functions import Sum
class StockBalanceFilter(TypedDict):
company: Optional[str]
warehouse: Optional[str]
SLEntry = Dict[str, Any]
def execute(filters=None):
columns, data = [], []
columns = get_columns()
data = get_data(filters)
return columns, data
def get_warehouse_wise_balance(filters: StockBalanceFilter) -> List[SLEntry]:
sle = frappe.qb.DocType("Stock Ledger Entry")
query = (
frappe.qb.from_(sle)
.select(sle.warehouse, Sum(sle.stock_value_difference).as_("stock_balance"))
.where((sle.docstatus < 2) & (sle.is_cancelled == 0))
.groupby(sle.warehouse)
)
if filters.get("company"):
query = query.where(sle.company == filters.get("company"))
data = query.run(as_list=True)
return frappe._dict(data) if data else frappe._dict()
def get_warehouses(report_filters: StockBalanceFilter):
return frappe.get_all(
"Warehouse",
fields=["name", "parent_warehouse", "is_group"],
filters={"company": report_filters.company, "disabled": 0},
order_by="lft",
)
def get_data(filters: StockBalanceFilter):
warehouse_balance = get_warehouse_wise_balance(filters)
warehouses = get_warehouses(filters)
for warehouse in warehouses:
warehouse["stock_balance"] = warehouse_balance.get(warehouse.name, 0)
update_indent(warehouses)
return warehouses
def update_indent(warehouses):
for warehouse in warehouses:
def add_indent(warehouse, indent):
warehouse.indent = indent
for child in warehouses:
if child.parent_warehouse == warehouse.name:
warehouse.stock_balance += child.stock_balance
add_indent(child, indent + 1)
if warehouse.is_group:
add_indent(warehouse, warehouse.indent or 0)
def get_columns():
return [
{
"label": _("Warehouse"),
"fieldname": "name",
"fieldtype": "Link",
"options": "Warehouse",
"width": 200,
},
{"label": _("Stock Balance"), "fieldname": "stock_balance", "fieldtype": "Float", "width": 150},
]

View File

@@ -5,7 +5,7 @@
"label": "Warehouse wise Stock Value" "label": "Warehouse wise Stock Value"
} }
], ],
"content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Stock\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Warehouse wise Stock Value\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Quick Access</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Material Request\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Receipt\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Delivery Note\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Ledger\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Balance\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Masters & Reports</b></span>\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Items and Pricing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Transactions\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Serial No and Batch\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Tools\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]", "content": "[{\"type\":\"onboarding\",\"data\":{\"onboarding_name\":\"Stock\",\"col\":12}},{\"type\":\"chart\",\"data\":{\"chart_name\":\"Warehouse wise Stock Value\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Quick Access</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Item\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Material Request\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Entry\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Purchase Receipt\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Delivery Note\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Ledger\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Balance\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Masters &amp; Reports</b></span>\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Items and Pricing\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Transactions\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Stock Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Serial No and Batch\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Tools\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Key Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Other Reports\",\"col\":4}}]",
"creation": "2020-03-02 15:43:10.096528", "creation": "2020-03-02 15:43:10.096528",
"docstatus": 0, "docstatus": 0,
"doctype": "Workspace", "doctype": "Workspace",
@@ -207,80 +207,6 @@
"onboard": 0, "onboard": 0,
"type": "Link" "type": "Link"
}, },
{
"hidden": 0,
"is_query_report": 0,
"label": "Stock Reports",
"link_count": 0,
"onboard": 0,
"type": "Card Break"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Ledger",
"link_count": 0,
"link_to": "Stock Ledger",
"link_type": "Report",
"onboard": 1,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Balance",
"link_count": 0,
"link_to": "Stock Balance",
"link_type": "Report",
"onboard": 1,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Projected Qty",
"link_count": 0,
"link_to": "Stock Projected Qty",
"link_type": "Report",
"onboard": 1,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 0,
"label": "Stock Summary",
"link_count": 0,
"link_to": "stock-balance",
"link_type": "Page",
"onboard": 0,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Ageing",
"link_count": 0,
"link_to": "Stock Ageing",
"link_type": "Report",
"onboard": 0,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Item Price Stock",
"link_count": 0,
"link_to": "Item Price Stock",
"link_type": "Report",
"onboard": 0,
"type": "Link"
},
{ {
"hidden": 0, "hidden": 0,
"is_query_report": 0, "is_query_report": 0,
@@ -705,15 +631,100 @@
"link_type": "Report", "link_type": "Report",
"onboard": 0, "onboard": 0,
"type": "Link" "type": "Link"
},
{
"hidden": 0,
"is_query_report": 0,
"label": "Stock Reports",
"link_count": 7,
"onboard": 0,
"type": "Card Break"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Ledger",
"link_count": 0,
"link_to": "Stock Ledger",
"link_type": "Report",
"onboard": 1,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Balance",
"link_count": 0,
"link_to": "Stock Balance",
"link_type": "Report",
"onboard": 1,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Projected Qty",
"link_count": 0,
"link_to": "Stock Projected Qty",
"link_type": "Report",
"onboard": 1,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 0,
"label": "Stock Summary",
"link_count": 0,
"link_to": "stock-balance",
"link_type": "Page",
"onboard": 0,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Stock Ageing",
"link_count": 0,
"link_to": "Stock Ageing",
"link_type": "Report",
"onboard": 0,
"type": "Link"
},
{
"dependencies": "Item",
"hidden": 0,
"is_query_report": 1,
"label": "Item Price Stock",
"link_count": 0,
"link_to": "Item Price Stock",
"link_type": "Report",
"onboard": 0,
"type": "Link"
},
{
"hidden": 0,
"is_query_report": 0,
"label": "Warehouse Wise Stock Balance",
"link_count": 0,
"link_to": "Warehouse Wise Stock Balance",
"link_type": "Report",
"onboard": 0,
"type": "Link"
} }
], ],
"modified": "2022-01-13 17:47:38.339931", "modified": "2022-12-06 17:03:56.397272",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Stock", "name": "Stock",
"owner": "Administrator", "owner": "Administrator",
"parent_page": "", "parent_page": "",
"public": 1, "public": 1,
"quick_lists": [],
"restrict_to_domain": "", "restrict_to_domain": "",
"roles": [], "roles": [],
"sequence_id": 24.0, "sequence_id": 24.0,