Merge branch 'develop' into fix-reserve-qty

This commit is contained in:
rohitwaghchaure 2023-03-30 17:26:32 +05:30 committed by GitHub
commit edb0666b2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 229 additions and 685 deletions

View File

@ -46,7 +46,7 @@ class BankTransaction(StatusUpdater):
def add_payment_entries(self, vouchers): def add_payment_entries(self, vouchers):
"Add the vouchers with zero allocation. Save() will perform the allocations and clearance" "Add the vouchers with zero allocation. Save() will perform the allocations and clearance"
if 0.0 >= self.unallocated_amount: if 0.0 >= self.unallocated_amount:
frappe.throw(frappe._(f"Bank Transaction {self.name} is already fully reconciled")) frappe.throw(frappe._("Bank Transaction {0} is already fully reconciled").format(self.name))
added = False added = False
for voucher in vouchers: for voucher in vouchers:
@ -114,9 +114,7 @@ class BankTransaction(StatusUpdater):
elif 0.0 > unallocated_amount: elif 0.0 > unallocated_amount:
self.db_delete_payment_entry(payment_entry) self.db_delete_payment_entry(payment_entry)
frappe.throw( frappe.throw(frappe._("Voucher {0} is over-allocated by {1}").format(unallocated_amount))
frappe._(f"Voucher {payment_entry.payment_entry} is over-allocated by {unallocated_amount}")
)
self.reload() self.reload()
@ -178,7 +176,9 @@ def get_clearance_details(transaction, payment_entry):
if gle["gl_account"] == gl_bank_account: if gle["gl_account"] == gl_bank_account:
if gle["amount"] <= 0.0: if gle["amount"] <= 0.0:
frappe.throw( frappe.throw(
frappe._(f"Voucher {payment_entry.payment_entry} value is broken: {gle['amount']}") frappe._("Voucher {0} value is broken: {1}").format(
payment_entry.payment_entry, gle["amount"]
)
) )
unmatched_gles -= 1 unmatched_gles -= 1

View File

@ -490,6 +490,8 @@ def calculate_exchange_rate_using_last_gle(company, account, party_type, party):
conditions.append(gl.company == company) conditions.append(gl.company == company)
conditions.append(gl.account == account) conditions.append(gl.account == account)
conditions.append(gl.is_cancelled == 0) conditions.append(gl.is_cancelled == 0)
conditions.append((gl.debit > 0) | (gl.credit > 0))
conditions.append((gl.debit_in_account_currency > 0) | (gl.credit_in_account_currency > 0))
if party_type: if party_type:
conditions.append(gl.party_type == party_type) conditions.append(gl.party_type == party_type)
if party: if party:

View File

@ -174,6 +174,9 @@ def _get_party_details(
party_type, party.name, "tax_withholding_category" party_type, party.name, "tax_withholding_category"
) )
if not party_details.get("tax_category") and pos_profile:
party_details["tax_category"] = frappe.get_value("POS Profile", pos_profile, "tax_category")
return party_details return party_details

View File

@ -58,9 +58,8 @@ frappe.query_reports["General Ledger"] = {
{ {
"fieldname":"party_type", "fieldname":"party_type",
"label": __("Party Type"), "label": __("Party Type"),
"fieldtype": "Link", "fieldtype": "Autocomplete",
"options": "Party Type", options: Object.keys(frappe.boot.party_account_types),
"default": "",
on_change: function() { on_change: function() {
frappe.query_report.set_filter_value('party', ""); frappe.query_report.set_filter_value('party', "");
} }

View File

@ -467,14 +467,6 @@ def reconcile_against_document(args): # nosemgrep
else: else:
update_reference_in_payment_entry(entry, doc, do_not_save=True) update_reference_in_payment_entry(entry, doc, do_not_save=True)
if doc.doctype == "Journal Entry":
try:
doc.validate_total_debit_and_credit()
except Exception as validation_exception:
raise frappe.ValidationError(
_("Validation Error for {0}").format(doc.name)
) from validation_exception
doc.save(ignore_permissions=True) doc.save(ignore_permissions=True)
# re-submit advance entry # re-submit advance entry
doc = frappe.get_doc(entry.voucher_type, entry.voucher_no) doc = frappe.get_doc(entry.voucher_type, entry.voucher_no)

View File

@ -466,6 +466,9 @@ frappe.ui.form.on('Asset', {
} else { } else {
frm.set_value('purchase_date', purchase_doc.posting_date); frm.set_value('purchase_date', purchase_doc.posting_date);
} }
if (!frm.doc.is_existing_asset && !frm.doc.available_for_use_date) {
frm.set_value('available_for_use_date', frm.doc.purchase_date);
}
const item = purchase_doc.items.find(item => item.item_code === frm.doc.item_code); const item = purchase_doc.items.find(item => item.item_code === frm.doc.item_code);
if (!item) { if (!item) {
doctype_field = frappe.scrub(doctype) doctype_field = frappe.scrub(doctype)

View File

@ -79,6 +79,9 @@
"options": "ACC-ASS-.YYYY.-" "options": "ACC-ASS-.YYYY.-"
}, },
{ {
"depends_on": "item_code",
"fetch_from": "item_code.item_name",
"fetch_if_empty": 1,
"fieldname": "asset_name", "fieldname": "asset_name",
"fieldtype": "Data", "fieldtype": "Data",
"in_list_view": 1, "in_list_view": 1,
@ -517,7 +520,7 @@
"table_fieldname": "accounts" "table_fieldname": "accounts"
} }
], ],
"modified": "2023-02-02 00:03:11.706427", "modified": "2023-03-30 15:07:41.542374",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Assets", "module": "Assets",
"name": "Asset", "name": "Asset",

View File

@ -249,10 +249,16 @@ def notify_depr_entry_posting_error(failed_asset_names):
asset_links = get_comma_separated_asset_links(failed_asset_names) asset_links = get_comma_separated_asset_links(failed_asset_names)
message = ( message = (
_("Hi,") _("Hello,")
+ "<br>" + "<br><br>"
+ _("The following assets have failed to post depreciation entries: {0}").format(asset_links) + _("The following assets have failed to automatically post depreciation entries: {0}").format(
asset_links
)
+ "." + "."
+ "<br><br>"
+ _(
"Please raise a support ticket and share this email, or forward this email to your development team so that they can find the issue in the developer console by manually creating the depreciation entry via the asset's depreciation schedule table."
)
) )
frappe.sendmail(recipients=recipients, subject=subject, message=message) frappe.sendmail(recipients=recipients, subject=subject, message=message)

View File

@ -84,6 +84,8 @@ def calculate_next_due_date(
next_due_date = add_years(start_date, 1) next_due_date = add_years(start_date, 1)
if periodicity == "2 Yearly": if periodicity == "2 Yearly":
next_due_date = add_years(start_date, 2) next_due_date = add_years(start_date, 2)
if periodicity == "3 Yearly":
next_due_date = add_years(start_date, 3)
if periodicity == "Quarterly": if periodicity == "Quarterly":
next_due_date = add_months(start_date, 3) next_due_date = add_months(start_date, 3)
if end_date and ( if end_date and (

View File

@ -1,664 +1,156 @@
{ {
"allow_copy": 0, "actions": [],
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "",
"beta": 0,
"creation": "2017-10-20 07:10:55.903571", "creation": "2017-10-20 07:10:55.903571",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "Document", "document_type": "Document",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"maintenance_task",
"maintenance_type",
"column_break_2",
"maintenance_status",
"section_break_2",
"start_date",
"periodicity",
"column_break_4",
"end_date",
"certificate_required",
"section_break_9",
"assign_to",
"column_break_10",
"assign_to_name",
"section_break_10",
"next_due_date",
"column_break_14",
"last_completion_date",
"section_break_7",
"description"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maintenance_task", "fieldname": "maintenance_task",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1, "in_filter": 1,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Maintenance Task", "label": "Maintenance Task",
"length": 0, "reqd": 1
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maintenance_type", "fieldname": "maintenance_type",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Maintenance Type", "label": "Maintenance Type",
"length": 0, "options": "Preventive Maintenance\nCalibration"
"no_copy": 0,
"options": "Preventive Maintenance\nCalibration",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2", "fieldname": "column_break_2",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "maintenance_status", "fieldname": "maintenance_status",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Maintenance Status", "label": "Maintenance Status",
"length": 0,
"no_copy": 0,
"options": "Planned\nOverdue\nCancelled", "options": "Planned\nOverdue\nCancelled",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_2", "fieldname": "section_break_2",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today", "default": "Today",
"fieldname": "start_date", "fieldname": "start_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Start Date", "label": "Start Date",
"length": 0, "reqd": 1
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "periodicity", "fieldname": "periodicity",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Periodicity", "label": "Periodicity",
"length": 0, "options": "\nDaily\nWeekly\nMonthly\nQuarterly\nYearly\n2 Yearly\n3 Yearly",
"no_copy": 0, "reqd": 1
"options": "\nDaily\nWeekly\nMonthly\nQuarterly\nYearly\n2 Yearly",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_4", "fieldname": "column_break_4",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "end_date", "fieldname": "end_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "label": "End Date"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "End Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0, "default": "0",
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "certificate_required", "fieldname": "certificate_required",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Certificate Required", "label": "Certificate Required",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1, "search_index": 1,
"set_only_once": 1, "set_only_once": 1
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_9", "fieldname": "section_break_9",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "assign_to", "fieldname": "assign_to",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Assign To", "label": "Assign To",
"length": 0, "options": "User"
"no_copy": 0,
"options": "User",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_10", "fieldname": "column_break_10",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "assign_to.full_name", "fetch_from": "assign_to.full_name",
"fieldname": "assign_to_name", "fieldname": "assign_to_name",
"fieldtype": "Read Only", "fieldtype": "Read Only",
"hidden": 0, "label": "Assign to Name"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Assign to Name",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_10", "fieldname": "section_break_10",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "next_due_date", "fieldname": "next_due_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Next Due Date"
"label": "Next Due Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_14", "fieldname": "column_break_14",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "last_completion_date", "fieldname": "last_completion_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0, "label": "Last Completion Date"
"label": "Last Completion Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_7", "fieldname": "section_break_7",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "description", "fieldname": "description",
"fieldtype": "Text Editor", "fieldtype": "Text Editor",
"hidden": 0, "label": "Description"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "links": [],
"modified": "2018-06-18 16:12:04.330021", "modified": "2023-03-23 07:03:07.113452",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Assets", "module": "Assets",
"name": "Asset Maintenance Task", "name": "Asset Maintenance Task",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC"
"track_changes": 0,
"track_seen": 0
} }

View File

@ -49,7 +49,7 @@ frappe.ui.form.on('Asset Value Adjustment', {
frm.call({ frm.call({
method: "erpnext.assets.doctype.asset.asset.get_asset_value_after_depreciation", method: "erpnext.assets.doctype.asset.asset.get_asset_value_after_depreciation",
args: { args: {
asset: frm.doc.asset, asset_name: frm.doc.asset,
finance_book: frm.doc.finance_book finance_book: frm.doc.finance_book
}, },
callback: function(r) { callback: function(r) {

View File

@ -64,7 +64,7 @@ frappe.ui.form.on("Supplier", {
// custom buttons // custom buttons
frm.add_custom_button(__('Accounting Ledger'), function () { frm.add_custom_button(__('Accounting Ledger'), function () {
frappe.set_route('query-report', 'General Ledger', frappe.set_route('query-report', 'General Ledger',
{ party_type: 'Supplier', party: frm.doc.name }); { party_type: 'Supplier', party: frm.doc.name, party_name: frm.doc.supplier_name });
}, __("View")); }, __("View"));
frm.add_custom_button(__('Accounts Payable'), function () { frm.add_custom_button(__('Accounts Payable'), function () {

View File

@ -464,7 +464,7 @@ class StatusUpdater(Document):
ifnull((select ifnull((select
ifnull(sum(case when abs(%(target_ref_field)s) > abs(%(target_field)s) then abs(%(target_field)s) else abs(%(target_ref_field)s) end), 0) ifnull(sum(case when abs(%(target_ref_field)s) > abs(%(target_field)s) then abs(%(target_field)s) else abs(%(target_ref_field)s) end), 0)
/ sum(abs(%(target_ref_field)s)) * 100 / sum(abs(%(target_ref_field)s)) * 100
from `tab%(target_dt)s` where parent='%(name)s' having sum(abs(%(target_ref_field)s)) > 0), 0), 6) from `tab%(target_dt)s` where parent='%(name)s' and parenttype='%(target_parent_dt)s' having sum(abs(%(target_ref_field)s)) > 0), 0), 6)
%(update_modified)s %(update_modified)s
where name='%(name)s'""" where name='%(name)s'"""
% args % args

View File

@ -455,7 +455,7 @@ class SubcontractingController(StockController):
"allow_zero_valuation": 1, "allow_zero_valuation": 1,
} }
) )
rm_obj.rate = get_incoming_rate(args) rm_obj.rate = bom_item.rate if self.backflush_based_on == "BOM" else get_incoming_rate(args)
if self.doctype == self.subcontract_data.order_doctype: if self.doctype == self.subcontract_data.order_doctype:
rm_obj.required_qty = qty rm_obj.required_qty = qty

View File

@ -33,7 +33,6 @@ class Opportunity(TransactionBase, CRMNote):
def after_insert(self): def after_insert(self):
if self.opportunity_from == "Lead": if self.opportunity_from == "Lead":
frappe.get_doc("Lead", self.party_name).set_status(update=True) frappe.get_doc("Lead", self.party_name).set_status(update=True)
self.disable_lead()
link_open_tasks(self.opportunity_from, self.party_name, self) link_open_tasks(self.opportunity_from, self.party_name, self)
link_open_events(self.opportunity_from, self.party_name, self) link_open_events(self.opportunity_from, self.party_name, self)
@ -119,10 +118,6 @@ class Opportunity(TransactionBase, CRMNote):
prospect.flags.ignore_mandatory = True prospect.flags.ignore_mandatory = True
prospect.save() prospect.save()
def disable_lead(self):
if self.opportunity_from == "Lead":
frappe.db.set_value("Lead", self.party_name, {"disabled": 1, "docstatus": 1})
def make_new_lead_if_required(self): def make_new_lead_if_required(self):
"""Set lead against new opportunity""" """Set lead against new opportunity"""
if (not self.get("party_name")) and self.contact_email: if (not self.get("party_name")) and self.contact_email:

View File

@ -98,7 +98,7 @@ def get_data(filters):
`tabAddress`.name=`tabDynamic Link`.parent) `tabAddress`.name=`tabDynamic Link`.parent)
WHERE WHERE
company = %(company)s company = %(company)s
AND `tabLead`.creation BETWEEN %(from_date)s AND %(to_date)s AND DATE(`tabLead`.creation) BETWEEN %(from_date)s AND %(to_date)s
{conditions} {conditions}
ORDER BY ORDER BY
`tabLead`.creation asc """.format( `tabLead`.creation asc """.format(

View File

@ -82,7 +82,7 @@ def get_data(filters):
{join} {join}
WHERE WHERE
`tabOpportunity`.status = 'Lost' and `tabOpportunity`.company = %(company)s `tabOpportunity`.status = 'Lost' and `tabOpportunity`.company = %(company)s
AND `tabOpportunity`.modified BETWEEN %(from_date)s AND %(to_date)s AND DATE(`tabOpportunity`.modified) BETWEEN %(from_date)s AND %(to_date)s
{conditions} {conditions}
GROUP BY GROUP BY
`tabOpportunity`.name `tabOpportunity`.name

View File

@ -220,7 +220,7 @@ def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
if e.code == "ITEM_LOGIN_REQUIRED": if e.code == "ITEM_LOGIN_REQUIRED":
msg = _("There was an error syncing transactions.") + " " msg = _("There was an error syncing transactions.") + " "
msg += _("Please refresh or reset the Plaid linking of the Bank {}.").format(bank) + " " msg += _("Please refresh or reset the Plaid linking of the Bank {}.").format(bank) + " "
frappe.log_error(msg, title=_("Plaid Link Refresh Required")) frappe.log_error(message=msg, title=_("Plaid Link Refresh Required"))
return transactions return transactions

View File

@ -330,3 +330,4 @@ erpnext.patches.v14_0.update_closing_balances
# below migration patches should always run last # below migration patches should always run last
erpnext.patches.v14_0.migrate_gl_to_payment_ledger erpnext.patches.v14_0.migrate_gl_to_payment_ledger
execute:frappe.delete_doc_if_exists("Report", "Tax Detail") execute:frappe.delete_doc_if_exists("Report", "Tax Detail")
erpnext.patches.v15_0.enable_all_leads

View File

@ -0,0 +1,8 @@
import frappe
def execute():
lead = frappe.qb.DocType("Lead")
frappe.qb.update(lead).set(lead.disabled, 0).set(lead.docstatus, 0).where(
lead.disabled == 1 and lead.docstatus == 1
).run()

View File

@ -123,7 +123,7 @@ frappe.ui.form.on("Customer", {
frm.add_custom_button(__('Accounting Ledger'), function () { frm.add_custom_button(__('Accounting Ledger'), function () {
frappe.set_route('query-report', 'General Ledger', frappe.set_route('query-report', 'General Ledger',
{party_type: 'Customer', party: frm.doc.name}); {party_type: 'Customer', party: frm.doc.name, party_name: frm.doc.customer_name});
}, __('View')); }, __('View'));
frm.add_custom_button(__('Pricing Rule'), function () { frm.add_custom_button(__('Pricing Rule'), function () {

View File

@ -14,7 +14,7 @@ from frappe.contacts.address_and_contact import (
from frappe.desk.reportview import build_match_conditions, get_filters_cond from frappe.desk.reportview import build_match_conditions, get_filters_cond
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_options from frappe.model.naming import set_name_by_naming_series, set_name_from_naming_options
from frappe.model.rename_doc import update_linked_doctypes from frappe.model.utils.rename_doc import update_linked_doctypes
from frappe.utils import cint, cstr, flt, get_formatted_email, today from frappe.utils import cint, cstr, flt, get_formatted_email, today
from frappe.utils.user import get_users_with_role from frappe.utils.user import get_users_with_role

View File

@ -6,7 +6,7 @@ import frappe
from frappe import _ from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
from frappe.model.naming import make_autoname, revert_series_if_last from frappe.model.naming import make_autoname, revert_series_if_last
from frappe.utils import cint, flt, get_link_to_form from frappe.utils import cint, flt, get_link_to_form, nowtime
from frappe.utils.data import add_days from frappe.utils.data import add_days
from frappe.utils.jinja import render_template from frappe.utils.jinja import render_template
@ -179,7 +179,11 @@ def get_batch_qty(
out = 0 out = 0
if batch_no and warehouse: if batch_no and warehouse:
cond = "" cond = ""
if posting_date and posting_time:
if posting_date:
if posting_time is None:
posting_time = nowtime()
cond = " and timestamp(posting_date, posting_time) <= timestamp('{0}', '{1}')".format( cond = " and timestamp(posting_date, posting_time) <= timestamp('{0}', '{1}')".format(
posting_date, posting_time posting_date, posting_time
) )

View File

@ -4,7 +4,7 @@
from typing import Optional from typing import Optional
import frappe import frappe
from frappe import _, msgprint from frappe import _, bold, msgprint
from frappe.utils import cint, cstr, flt from frappe.utils import cint, cstr, flt
import erpnext import erpnext
@ -89,7 +89,7 @@ class StockReconciliation(StockController):
if item_dict.get("serial_nos"): if item_dict.get("serial_nos"):
item.current_serial_no = item_dict.get("serial_nos") item.current_serial_no = item_dict.get("serial_nos")
if self.purpose == "Stock Reconciliation" and not item.serial_no: if self.purpose == "Stock Reconciliation" and not item.serial_no and item.qty:
item.serial_no = item.current_serial_no item.serial_no = item.current_serial_no
item.current_qty = item_dict.get("qty") item.current_qty = item_dict.get("qty")
@ -140,6 +140,14 @@ class StockReconciliation(StockController):
self.validate_item(row.item_code, row) self.validate_item(row.item_code, row)
if row.serial_no and not row.qty:
self.validation_messages.append(
_get_msg(
row_num,
f"Quantity should not be zero for the {bold(row.item_code)} since serial nos are specified",
)
)
# validate warehouse # validate warehouse
if not frappe.db.get_value("Warehouse", row.warehouse): if not frappe.db.get_value("Warehouse", row.warehouse):
self.validation_messages.append(_get_msg(row_num, _("Warehouse not found in the system"))) self.validation_messages.append(_get_msg(row_num, _("Warehouse not found in the system")))

View File

@ -7,7 +7,7 @@ from typing import Any, Dict, List, Optional, TypedDict
import frappe import frappe
from frappe import _ from frappe import _
from frappe.query_builder.functions import CombineDatetime from frappe.query_builder.functions import Coalesce, CombineDatetime
from frappe.utils import cint, date_diff, flt, getdate from frappe.utils import cint, date_diff, flt, getdate
from frappe.utils.nestedset import get_descendants_of from frappe.utils.nestedset import get_descendants_of
@ -322,6 +322,34 @@ def get_stock_ledger_entries(filters: StockBalanceFilter, items: List[str]) -> L
return query.run(as_dict=True) return query.run(as_dict=True)
def get_opening_vouchers(to_date):
opening_vouchers = {"Stock Entry": [], "Stock Reconciliation": []}
se = frappe.qb.DocType("Stock Entry")
sr = frappe.qb.DocType("Stock Reconciliation")
vouchers_data = (
frappe.qb.from_(
(
frappe.qb.from_(se)
.select(se.name, Coalesce("Stock Entry").as_("voucher_type"))
.where((se.docstatus == 1) & (se.posting_date <= to_date) & (se.is_opening == "Yes"))
)
+ (
frappe.qb.from_(sr)
.select(sr.name, Coalesce("Stock Reconciliation").as_("voucher_type"))
.where((sr.docstatus == 1) & (sr.posting_date <= to_date) & (sr.purpose == "Opening Stock"))
)
).select("voucher_type", "name")
).run(as_dict=True)
if vouchers_data:
for d in vouchers_data:
opening_vouchers[d.voucher_type].append(d.name)
return opening_vouchers
def get_inventory_dimension_fields(): def get_inventory_dimension_fields():
return [dimension.fieldname for dimension in get_inventory_dimensions()] return [dimension.fieldname for dimension in get_inventory_dimensions()]
@ -330,9 +358,8 @@ def get_item_warehouse_map(filters: StockBalanceFilter, sle: List[SLEntry]):
iwb_map = {} iwb_map = {}
from_date = getdate(filters.get("from_date")) from_date = getdate(filters.get("from_date"))
to_date = getdate(filters.get("to_date")) to_date = getdate(filters.get("to_date"))
opening_vouchers = get_opening_vouchers(to_date)
float_precision = cint(frappe.db.get_default("float_precision")) or 3 float_precision = cint(frappe.db.get_default("float_precision")) or 3
inventory_dimensions = get_inventory_dimension_fields() inventory_dimensions = get_inventory_dimension_fields()
for d in sle: for d in sle:
@ -363,11 +390,7 @@ def get_item_warehouse_map(filters: StockBalanceFilter, sle: List[SLEntry]):
value_diff = flt(d.stock_value_difference) value_diff = flt(d.stock_value_difference)
if d.posting_date < from_date or ( if d.posting_date < from_date or d.voucher_no in opening_vouchers.get(d.voucher_type, []):
d.posting_date == from_date
and d.voucher_type == "Stock Reconciliation"
and frappe.db.get_value("Stock Reconciliation", d.voucher_no, "purpose") == "Opening Stock"
):
qty_dict.opening_qty += qty_diff qty_dict.opening_qty += qty_diff
qty_dict.opening_val += value_diff qty_dict.opening_val += value_diff

View File

@ -34,6 +34,9 @@ def execute(filters=None):
conversion_factors.append(0) conversion_factors.append(0)
actual_qty = stock_value = 0 actual_qty = stock_value = 0
if opening_row:
actual_qty = opening_row.get("qty_after_transaction")
stock_value = opening_row.get("stock_value")
available_serial_nos = {} available_serial_nos = {}
inventory_dimension_filters_applied = check_inventory_dimension_filters_applied(filters) inventory_dimension_filters_applied = check_inventory_dimension_filters_applied(filters)