Merge branch 'develop' into prevent-negative-operation-time-and-batch-size

This commit is contained in:
KerollesFathy
2025-08-05 10:41:29 +00:00
32 changed files with 213 additions and 106 deletions

View File

@@ -8,7 +8,6 @@ erpnext/assets/ @khushi8112
erpnext/regional @ruthra-kumar
erpnext/selling @ruthra-kumar
erpnext/support/ @ruthra-kumar
pos* @diptanilsaha
erpnext/buying/ @rohitwaghchaure @mihir-kandoi
erpnext/maintenance/ @rohitwaghchaure

View File

@@ -18,6 +18,7 @@ def create_charts(
accounts = []
def _import_accounts(children, parent, root_type, root_account=False):
nonlocal custom_chart
for account_name, child in children.items():
if root_account:
root_type = child.get("root_type")
@@ -55,7 +56,8 @@ def create_charts(
"account_number": account_number,
"account_type": child.get("account_type"),
"account_currency": child.get("account_currency")
or frappe.get_cached_value("Company", company, "default_currency"),
if custom_chart
else frappe.get_cached_value("Company", company, "default_currency"),
"tax_rate": child.get("tax_rate"),
}
)

View File

@@ -9,7 +9,7 @@ from frappe import _
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.query_builder.functions import Sum
from frappe.utils import cint, flt
from frappe.utils import cint, create_batch, flt
from erpnext import get_default_cost_center
from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount
@@ -377,16 +377,17 @@ def auto_reconcile_vouchers(
bank_transactions = get_bank_transactions(bank_account)
if len(bank_transactions) > 10:
frappe.enqueue(
method="erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.start_auto_reconcile",
queue="long",
bank_transactions=bank_transactions,
from_date=from_date,
to_date=to_date,
filter_by_reference_date=filter_by_reference_date,
from_reference_date=from_reference_date,
to_reference_date=to_reference_date,
)
for bank_transaction_batch in create_batch(bank_transactions, 1000):
frappe.enqueue(
method="erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.start_auto_reconcile",
queue="long",
bank_transactions=bank_transaction_batch,
from_date=from_date,
to_date=to_date,
filter_by_reference_date=filter_by_reference_date,
from_reference_date=from_reference_date,
to_reference_date=to_reference_date,
)
frappe.msgprint(_("Auto Reconciliation has started in the background"))
else:
start_auto_reconcile(

View File

@@ -252,7 +252,7 @@ frappe.ui.form.on("Bank Statement Import", {
open_url_post(method, {
doctype: "Bank Transaction",
export_records: "5_records",
export_records: "blank_template",
export_fields: {
"Bank Transaction": [
"date",

View File

@@ -302,7 +302,7 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_
def get_expense_breakup(args, currency, budget_against):
msg = "<hr>Total Expenses booked through - <ul>"
msg = "<hr> {{ _('Total Expenses booked through') }} - <ul>"
common_filters = frappe._dict(
{
@@ -316,7 +316,7 @@ def get_expense_breakup(args, currency, budget_against):
"<li>"
+ frappe.utils.get_link_to_report(
"General Ledger",
label="Actual Expenses",
label=_("Actual Expenses"),
filters=common_filters.copy().update(
{
"from_date": frappe.get_cached_value("Fiscal Year", args.fiscal_year, "year_start_date"),
@@ -334,7 +334,7 @@ def get_expense_breakup(args, currency, budget_against):
"<li>"
+ frappe.utils.get_link_to_report(
"Material Request",
label="Material Requests",
label=_("Material Requests"),
report_type="Report Builder",
doctype="Material Request",
filters=common_filters.copy().update(
@@ -357,7 +357,7 @@ def get_expense_breakup(args, currency, budget_against):
"<li>"
+ frappe.utils.get_link_to_report(
"Purchase Order",
label="Unbilled Orders",
label=_("Unbilled Orders"),
report_type="Report Builder",
doctype="Purchase Order",
filters=common_filters.copy().update(

View File

@@ -296,6 +296,7 @@
"search_index": 1
},
{
"default": "Now",
"fieldname": "posting_time",
"fieldtype": "Time",
"label": "Posting Time",
@@ -1598,7 +1599,7 @@
"icon": "fa fa-file-text",
"is_submittable": 1,
"links": [],
"modified": "2025-07-18 16:50:30.516162",
"modified": "2025-08-04 22:22:31.471752",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",

View File

@@ -41,56 +41,68 @@ frappe.ui.form.on("Pricing Rule", {
<tr><td>
<h4>
<i class="fa fa-hand-right"></i>
{{__('Notes')}}
${__("Notes")}
</h4>
<ul>
<li>
{{__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria.")}}
${__("Pricing Rule is made to overwrite Price List / define discount percentage, based on some criteria.")}
</li>
<li>
{{__("If selected Pricing Rule is made for 'Rate', it will overwrite Price List. Pricing Rule rate is the final rate, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field.")}}
${__(
"If selected Pricing Rule is made for 'Rate', it will overwrite Price List. Pricing Rule rate is the final rate, so no further discount should be applied. Hence, in transactions like Sales Order, Purchase Order etc, it will be fetched in 'Rate' field, rather than 'Price List Rate' field."
)}
</li>
<li>
{{__('Discount Percentage can be applied either against a Price List or for all Price List.')}}
${__("Discount Percentage can be applied either against a Price List or for all Price List.")}
</li>
<li>
{{__('To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled.')}}
${__(
"To not apply Pricing Rule in a particular transaction, all applicable Pricing Rules should be disabled."
)}
</li>
</ul>
</td></tr>
<tr><td>
<h4><i class="fa fa-question-sign"></i>
{{__('How Pricing Rule is applied?')}}
${__("How Pricing Rule is applied?")}
</h4>
<ol>
<li>
{{__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand.")}}
${__("Pricing Rule is first selected based on 'Apply On' field, which can be Item, Item Group or Brand.")}
</li>
<li>
{{__("Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc.")}}
${__(
"Then Pricing Rules are filtered out based on Customer, Customer Group, Territory, Supplier, Supplier Type, Campaign, Sales Partner etc."
)}
</li>
<li>
{{__('Pricing Rules are further filtered based on quantity.')}}
${__("Pricing Rules are further filtered based on quantity.")}
</li>
<li>
{{__('If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions.')}}
${__(
"If two or more Pricing Rules are found based on the above conditions, Priority is applied. Priority is a number between 0 to 20 while default value is zero (blank). Higher number means it will take precedence if there are multiple Pricing Rules with same conditions."
)}
</li>
<li>
{{__('Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:')}}
${__(
"Even if there are multiple Pricing Rules with highest priority, then following internal priorities are applied:"
)}
<ul>
<li>
{{__('Item Code > Item Group > Brand')}}
${__("Item Code > Item Group > Brand")}
</li>
<li>
{{__('Customer > Customer Group > Territory')}}
${__("Customer > Customer Group > Territory")}
</li>
<li>
{{__('Supplier > Supplier Type')}}
${__("Supplier > Supplier Type")}
</li>
</ul>
</li>
<li>
{{__('If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict.')}}
${__(
"If multiple Pricing Rules continue to prevail, users are asked to set Priority manually to resolve conflict."
)}
</li>
</ol>
</td></tr>

View File

@@ -3,7 +3,7 @@
import frappe
from frappe.model.document import Document
from frappe.utils import getdate
from frappe.utils import create_batch, getdate
from erpnext.accounts.doctype.subscription.subscription import DateTimeLikeObject, process_all
@@ -23,7 +23,23 @@ class ProcessSubscription(Document):
# end: auto-generated types
def on_submit(self):
process_all(subscription=self.subscription, posting_date=self.posting_date)
self.process_all_subscription()
def process_all_subscription(self):
filters = {"status": ("!=", "Cancelled")}
if self.subscription:
filters["name"] = self.subscription
subscriptions = frappe.get_all("Subscription", filters, pluck="name")
for subscription in create_batch(subscriptions, 500):
frappe.enqueue(
method="erpnext.accounts.doctype.subscription.subscription.process_all",
queue="long",
subscription=subscription,
posting_date=self.posting_date,
)
def create_subscription_process(

View File

@@ -322,6 +322,7 @@
"search_index": 1
},
{
"default": "Now",
"fieldname": "posting_time",
"fieldtype": "Time",
"label": "Posting Time",
@@ -1668,7 +1669,7 @@
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2025-07-30 23:16:05.722875",
"modified": "2025-08-04 19:19:11.380664",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -373,6 +373,7 @@
"search_index": 1
},
{
"default": "Now",
"fieldname": "posting_time",
"fieldtype": "Time",
"hide_days": 1,
@@ -2232,7 +2233,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2025-06-26 14:06:56.773552",
"modified": "2025-08-04 19:20:28.732039",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -756,18 +756,14 @@ def get_prorata_factor(
return diff / plan_days
def process_all(subscription: str | None = None, posting_date: DateTimeLikeObject | None = None) -> None:
def process_all(subscription: list, posting_date: DateTimeLikeObject | None = None) -> None:
"""
Task to updates the status of all `Subscription` apart from those that are cancelled
"""
filters = {"status": ("!=", "Cancelled")}
if subscription:
filters["name"] = subscription
for subscription in frappe.get_all("Subscription", filters, pluck="name"):
for subscription_name in subscription:
try:
subscription = frappe.get_doc("Subscription", subscription)
subscription = frappe.get_doc("Subscription", subscription_name)
subscription.process(posting_date)
frappe.db.commit()
except frappe.ValidationError:

View File

@@ -61,7 +61,7 @@
},
{
"default": "0",
"description": "Even invoices with apply tax withholding unchecked will be considered for checking cumulative threshold breach",
"description": "Only payment entries with apply tax withholding unchecked will be considered for checking cumulative threshold breach",
"fieldname": "consider_party_ledger_amount",
"fieldtype": "Check",
"label": "Consider Entire Party Ledger Amount"
@@ -83,10 +83,11 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-03-27 13:10:52.531436",
"modified": "2025-07-30 07:13:51.785735",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Tax Withholding Category",
"naming_rule": "Set by user",
"owner": "Administrator",
"permissions": [
{
@@ -126,8 +127,9 @@
"write": 1
}
],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -197,6 +197,11 @@ frappe.query_reports["General Ledger"] = {
label: __("Show Net Values in Party Account"),
fieldtype: "Check",
},
{
fieldname: "show_amount_in_company_currency",
label: __("Show Credit / Debit in Company Currency"),
fieldtype: "Check",
},
{
fieldname: "add_values_in_transaction_currency",
label: __("Add Columns in Transaction Currency"),

View File

@@ -627,6 +627,18 @@ def get_columns(filters):
company = filters.get("company") or get_default_company()
filters["presentation_currency"] = currency = get_company_currency(company)
company_currency = get_company_currency(filters.get("company") or get_default_company())
if (
filters.get("show_amount_in_company_currency")
and filters["presentation_currency"] != company_currency
):
frappe.throw(
_(
f'Presentation Currency cannot be {frappe.bold(filters["presentation_currency"])} , When {frappe.bold("Show Credit / Debit in Company Currency")} is enabled.'
)
)
columns = [
{
"label": _("GL Entry"),

View File

@@ -45,6 +45,7 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
gle_map = get_gle_map(tds_docs)
out = []
entries = {}
for name, details in gle_map.items():
for entry in details:
tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
@@ -119,8 +120,13 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
"supplier_invoice_date": bill_date,
}
)
out.append(row)
key = entry.voucher_no
if key in entries:
entries[key]["tax_amount"] += tax_amount
else:
entries[key] = row
out = list(entries.values())
out.sort(key=lambda x: (x["section_code"], x["transaction_date"]))
return out

View File

@@ -118,7 +118,7 @@ def convert_to_presentation_currency(gl_entries, currency_info, filters=None):
len(account_currencies) == 1
and account_currency == presentation_currency
and not exchange_gain_or_loss
):
) and not filters.get("show_amount_in_company_currency"):
entry["debit"] = debit_in_account_currency
entry["credit"] = credit_in_account_currency
else:

View File

@@ -2,6 +2,7 @@
# License: GNU General Public License v3. See license.txt
from collections import defaultdict
from json import loads
from typing import TYPE_CHECKING, Optional
@@ -2451,25 +2452,37 @@ def sync_auto_reconcile_config(auto_reconciliation_job_trigger: int = 15):
).save()
def get_link_fields_grouped_by_option(doctype):
meta = frappe.get_meta(doctype)
link_fields_map = defaultdict(list)
for df in meta.fields:
if df.fieldtype == "Link" and df.options and not df.ignore_user_permissions:
link_fields_map[df.options].append(df.fieldname)
return link_fields_map
def build_qb_match_conditions(doctype, user=None) -> list:
match_filters = build_match_conditions(doctype, user, False)
link_fields_map = get_link_fields_grouped_by_option(doctype)
criterion = []
apply_strict_user_permissions = frappe.get_system_settings("apply_strict_user_permissions")
if match_filters:
from frappe import qb
_dt = qb.DocType(doctype)
for filter in match_filters:
for d, names in filter.items():
fieldname = d.lower().replace(" ", "_")
field = _dt[fieldname]
for link_option, allowed_values in filter.items():
fieldnames = link_fields_map.get(link_option, [])
cond = field.isin(names)
if not apply_strict_user_permissions:
cond = (Coalesce(field, "") == "") | field.isin(names)
for fieldname in fieldnames:
field = _dt[fieldname]
cond = field.isin(allowed_values)
criterion.append(cond)
if not apply_strict_user_permissions:
cond = (Coalesce(field, "") == "") | cond
criterion.append(cond)
return criterion

View File

@@ -1106,7 +1106,7 @@ def make_journal_entry(asset_name):
je.voucher_type = "Depreciation Entry"
je.naming_series = depreciation_series
je.company = asset.company
je.remark = f"Depreciation Entry against asset {asset_name}"
je.remark = _("Depreciation Entry against asset {0}").format(asset_name)
je.append(
"accounts",

View File

@@ -249,7 +249,9 @@ def setup_journal_entry_metadata(je, depr_schedule_doc, depr_series, depr_schedu
je.posting_date = depr_schedule.schedule_date
je.company = asset.company
je.finance_book = depr_schedule_doc.finance_book
je.remark = f"Depreciation Entry against {asset.name} worth {depr_schedule.depreciation_amount}"
je.remark = _("Depreciation Entry against {0} worth {1}").format(
asset.name, depr_schedule.depreciation_amount
)
def get_credit_and_debit_entry(

View File

@@ -86,8 +86,24 @@ class AssetDepreciationSchedule(DepreciationScheduleController):
)
def on_submit(self):
self.validate_asset()
self.db_set("status", "Active")
def validate_asset(self):
asset = frappe.get_doc("Asset", self.asset)
if not asset.calculate_depreciation:
frappe.throw(
_("Asset {0} is not set to calculate depreciation.").format(
get_link_to_form("Asset", self.asset)
)
)
if asset.docstatus != 1:
frappe.throw(
_("Asset {0} is not submitted. Please submit the asset before proceeding.").format(
get_link_to_form("Asset", self.asset)
)
)
def on_cancel(self):
self.db_set("status", "Cancelled")
if not self.flags.should_not_cancel_depreciation_entries:
@@ -96,6 +112,13 @@ class AssetDepreciationSchedule(DepreciationScheduleController):
def cancel_depreciation_entries(self):
for d in self.get("depreciation_schedule"):
if d.journal_entry:
je_status = frappe.db.get_value("Journal Entry", d.journal_entry, "docstatus")
if je_status == 0:
frappe.throw(
_(
"Cannot cancel Asset Depreciation Schedule {0} as it has a draft journal entry {1}."
).format(self.name, d.journal_entry)
)
frappe.get_doc("Journal Entry", d.journal_entry).cancel()
def update_shift_depr_schedule(self):

View File

@@ -3,13 +3,13 @@ frappe.listview_settings["Asset Maintenance Log"] = {
has_indicator_for_draft: 1,
get_indicator: function (doc) {
if (doc.maintenance_status == "Planned") {
return [__(doc.maintenance_status), "orange", "status,=," + doc.maintenance_status];
return [__(doc.maintenance_status), "orange", "maintenance_status,=," + doc.maintenance_status];
} else if (doc.maintenance_status == "Completed") {
return [__(doc.maintenance_status), "green", "status,=," + doc.maintenance_status];
return [__(doc.maintenance_status), "green", "maintenance_status,=," + doc.maintenance_status];
} else if (doc.maintenance_status == "Cancelled") {
return [__(doc.maintenance_status), "red", "status,=," + doc.maintenance_status];
return [__(doc.maintenance_status), "red", "maintenance_status,=," + doc.maintenance_status];
} else if (doc.maintenance_status == "Overdue") {
return [__(doc.maintenance_status), "red", "status,=," + doc.maintenance_status];
return [__(doc.maintenance_status), "red", "maintenance_status,=," + doc.maintenance_status];
}
},
};

View File

@@ -51,7 +51,7 @@ def get_columns(filters):
},
{
"label": _("Requestor"),
"options": "Employee",
"options": "User",
"fieldname": "requestor",
"fieldtype": "Link",
"width": 140,

View File

@@ -60,7 +60,7 @@ def import_genericode():
"doctype": "File",
"attached_to_doctype": "Code List",
"attached_to_name": code_list.name,
"folder": "Home/Attachments",
"folder": frappe.db.get_value("File", {"is_attachments_folder": 1}),
"file_name": frappe.local.uploaded_filename,
"file_url": frappe.local.uploaded_file_url,
"is_private": 1,

View File

@@ -427,7 +427,7 @@ erpnext.patches.v15_0.set_status_cancelled_on_cancelled_pos_opening_entry_and_po
erpnext.patches.v15_0.set_company_on_pos_inv_merge_log
erpnext.patches.v15_0.update_payment_ledger_entries_against_advance_doctypes
erpnext.patches.v15_0.rename_price_list_to_buying_price_list
erpnext.patches.v15_0.repost_gl_entries_with_no_account_subcontracting #2025-07-31
erpnext.patches.v15_0.repost_gl_entries_with_no_account_subcontracting #2025-08-04
erpnext.patches.v15_0.patch_missing_buying_price_list_in_material_request
erpnext.patches.v15_0.remove_sales_partner_from_consolidated_sales_invoice
erpnext.patches.v15_0.add_company_payment_gateway_account

View File

@@ -2,24 +2,31 @@ import frappe
def execute():
def cancel_incorrect_gl_entries(gl_entries):
table = frappe.qb.DocType("GL Entry")
frappe.qb.update(table).set(table.is_cancelled, 1).where(table.name.isin(gl_entries)).run()
def recreate_gl_entries(voucher_nos):
for doc in voucher_nos:
doc = frappe.get_doc("Subcontracting Receipt", doc)
for item in doc.supplied_items:
account, cost_center = frappe.db.get_values(
"Subcontracting Receipt Item", item.reference_name, ["expense_account", "cost_center"]
)[0]
if not item.expense_account:
item.db_set("expense_account", account)
if not item.cost_center:
item.db_set("cost_center", cost_center)
doc.make_gl_entries()
docs = frappe.get_all(
"GL Entry",
fields=["name", "voucher_no"],
filters={"voucher_type": "Subcontracting Receipt", "account": ["is", "not set"], "is_cancelled": 0},
pluck="voucher_no",
)
for doc in docs:
doc = frappe.get_doc("Subcontracting Receipt", doc)
for item in doc.supplied_items:
account, cost_center = frappe.db.get_values(
"Subcontracting Receipt Item", item.reference_name, ["expense_account", "cost_center"]
)[0]
if not item.expense_account:
item.db_set("expense_account", account)
if not item.cost_center:
item.db_set("cost_center", cost_center)
doc.docstatus = 2
doc.make_gl_entries_on_cancel()
doc.docstatus = 1
doc.make_gl_entries()
if docs:
cancel_incorrect_gl_entries([d.name for d in docs])
recreate_gl_entries([d.voucher_no for d in docs])

View File

@@ -943,15 +943,10 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
this.frm.refresh_fields();
}
async set_default_payment(total_amount_to_pay, update_paid_amount) {
set_default_payment(total_amount_to_pay, update_paid_amount) {
var me = this;
var payment_status = true;
if(this.frm.doc.is_pos && (update_paid_amount===undefined || update_paid_amount)) {
let r = await frappe.db.get_value("POS Profile", this.frm.doc.pos_profile, "set_grand_total_to_default_mop");
if (!r.message.set_grand_total_to_default_mop) {
return;
}
$.each(this.frm.doc['payments'] || [], function(index, data) {
if(data.default && payment_status && total_amount_to_pay > 0) {

View File

@@ -450,10 +450,11 @@ erpnext.PointOfSale.Payment = class {
}
render_payment_section() {
this.grand_total_to_default_mop();
this.render_payment_mode_dom();
this.make_invoice_field_dialog();
this.update_totals_section();
this.set_grand_total_to_default_mop();
this.focus_on_default_mop();
}
after_render() {
@@ -497,6 +498,17 @@ erpnext.PointOfSale.Payment = class {
}
}
grand_total_to_default_mop() {
if (this.set_gt_to_default_mop) return;
const doc = this.events.get_frm().doc;
const payments = doc.payments;
payments.forEach((p) => {
if (p.default) {
frappe.model.set_value(p.doctype, p.name, "amount", 0);
}
});
}
render_payment_mode_dom() {
const doc = this.events.get_frm().doc;
const payments = doc.payments;
@@ -557,6 +569,7 @@ erpnext.PointOfSale.Payment = class {
}
focus_on_default_mop() {
if (!this.set_gt_to_default_mop) return;
const doc = this.events.get_frm().doc;
const payments = doc.payments;
payments.forEach((p) => {
@@ -711,12 +724,6 @@ erpnext.PointOfSale.Payment = class {
.toLowerCase();
}
set_grand_total_to_default_mop() {
if (this.set_gt_to_default_mop) {
this.focus_on_default_mop();
}
}
validate_reqd_invoice_fields() {
if (this.invoice_fields.length === 0) return true;
const doc = this.events.get_frm().doc;

View File

@@ -251,6 +251,7 @@
"width": "100px"
},
{
"default": "Now",
"fieldname": "posting_time",
"fieldtype": "Time",
"label": "Posting Time",
@@ -1415,7 +1416,7 @@
"idx": 146,
"is_submittable": 1,
"links": [],
"modified": "2025-01-06 15:02:30.558756",
"modified": "2025-08-04 19:20:47.724218",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",
@@ -1506,6 +1507,7 @@
"write": 1
}
],
"row_format": "Dynamic",
"search_fields": "status,customer,customer_name, territory,base_grand_total",
"show_name_in_global_search": 1,
"sort_field": "creation",
@@ -1515,4 +1517,4 @@
"title_field": "customer_name",
"track_changes": 1,
"track_seen": 1
}
}

View File

@@ -96,7 +96,6 @@ class DeliveryNote(SellingController):
per_billed: DF.Percent
per_installed: DF.Percent
per_returned: DF.Percent
pick_list: DF.Link | None
plc_conversion_rate: DF.Float
po_date: DF.Date | None
po_no: DF.SmallText | None

View File

@@ -243,6 +243,7 @@
"width": "100px"
},
{
"default": "Now",
"fieldname": "posting_time",
"fieldtype": "Time",
"label": "Posting Time",
@@ -1290,7 +1291,7 @@
"idx": 261,
"is_submittable": 1,
"links": [],
"modified": "2025-04-09 16:52:19.323878",
"modified": "2025-08-04 19:18:47.754957",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",
@@ -1360,4 +1361,4 @@
"timeline_field": "supplier",
"title_field": "title",
"track_changes": 1
}
}

View File

@@ -218,6 +218,7 @@
"search_index": 1
},
{
"default": "Now",
"fieldname": "posting_time",
"fieldtype": "Time",
"label": "Posting Time",
@@ -697,7 +698,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-08-13 19:05:42.386955",
"modified": "2025-08-04 19:21:03.338958",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Entry",
@@ -763,6 +764,7 @@
"write": 1
}
],
"row_format": "Dynamic",
"search_fields": "posting_date, from_warehouse, to_warehouse, purpose, remarks",
"show_name_in_global_search": 1,
"sort_field": "creation",
@@ -770,4 +772,4 @@
"states": [],
"title_field": "stock_entry_type",
"track_changes": 1
}
}

View File

@@ -72,6 +72,7 @@
"reqd": 1
},
{
"default": "Now",
"fieldname": "posting_time",
"fieldtype": "Time",
"in_list_view": 1,
@@ -183,7 +184,7 @@
"idx": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-03-27 13:10:44.699413",
"modified": "2025-08-04 19:21:20.179658",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reconciliation",
@@ -203,9 +204,10 @@
"write": 1
}
],
"row_format": "Dynamic",
"search_fields": "posting_date",
"show_name_in_global_search": 1,
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}
}