mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-15 15:45:01 +00:00
Merge branch 'develop' into erpnext_form_cleanups
This commit is contained in:
@@ -535,10 +535,12 @@ class PaymentRequest(Document):
|
||||
row_number += TO_SKIP_NEW_ROW
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@frappe.whitelist()
|
||||
def make_payment_request(**args):
|
||||
"""Make payment request"""
|
||||
|
||||
frappe.has_permission(doctype="Payment Request", ptype="write", throw=True)
|
||||
|
||||
args = frappe._dict(args)
|
||||
if args.dt not in ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST:
|
||||
frappe.throw(_("Payment Requests cannot be created against: {0}").format(frappe.bold(args.dt)))
|
||||
|
||||
@@ -12,56 +12,76 @@
|
||||
"disabled",
|
||||
"column_break_9",
|
||||
"warehouse",
|
||||
"utm_source",
|
||||
"utm_campaign",
|
||||
"utm_medium",
|
||||
"company_address",
|
||||
"section_break_15",
|
||||
"applicable_for_users",
|
||||
"accounting_tab",
|
||||
"section_break_11",
|
||||
"payments",
|
||||
"set_grand_total_to_default_mop",
|
||||
"price_list_and_currency_section",
|
||||
"currency",
|
||||
"column_break_bptt",
|
||||
"selling_price_list",
|
||||
"write_off_section",
|
||||
"write_off_account",
|
||||
"column_break_ukpz",
|
||||
"write_off_cost_center",
|
||||
"column_break_pkca",
|
||||
"write_off_limit",
|
||||
"income_and_expense_account",
|
||||
"income_account",
|
||||
"column_break_byzk",
|
||||
"expense_account",
|
||||
"taxes_section",
|
||||
"taxes_and_charges",
|
||||
"column_break_cjpp",
|
||||
"tax_category",
|
||||
"section_break_19",
|
||||
"account_for_change_amount",
|
||||
"disable_rounded_total",
|
||||
"column_break_23",
|
||||
"apply_discount_on",
|
||||
"allow_partial_payment",
|
||||
"accounting_dimensions_section",
|
||||
"cost_center",
|
||||
"dimension_col_break",
|
||||
"project",
|
||||
"pos_configurations_tab",
|
||||
"section_break_14",
|
||||
"hide_images",
|
||||
"hide_unavailable_items",
|
||||
"auto_add_item_to_cart",
|
||||
"validate_stock_on_save",
|
||||
"print_receipt_on_order_complete",
|
||||
"action_on_new_invoice",
|
||||
"validate_stock_on_save",
|
||||
"column_break_16",
|
||||
"update_stock",
|
||||
"ignore_pricing_rule",
|
||||
"print_receipt_on_order_complete",
|
||||
"pos_item_selector_section",
|
||||
"hide_images",
|
||||
"column_break_rpny",
|
||||
"hide_unavailable_items",
|
||||
"column_break_stcl",
|
||||
"auto_add_item_to_cart",
|
||||
"pos_item_details_section",
|
||||
"allow_rate_change",
|
||||
"column_break_hwfg",
|
||||
"allow_discount_change",
|
||||
"set_grand_total_to_default_mop",
|
||||
"allow_partial_payment",
|
||||
"section_break_15",
|
||||
"applicable_for_users",
|
||||
"section_break_23",
|
||||
"item_groups",
|
||||
"column_break_25",
|
||||
"customer_groups",
|
||||
"more_info_tab",
|
||||
"section_break_16",
|
||||
"print_format",
|
||||
"letter_head",
|
||||
"column_break0",
|
||||
"tc_name",
|
||||
"select_print_heading",
|
||||
"section_break_19",
|
||||
"selling_price_list",
|
||||
"currency",
|
||||
"write_off_account",
|
||||
"write_off_cost_center",
|
||||
"write_off_limit",
|
||||
"account_for_change_amount",
|
||||
"disable_rounded_total",
|
||||
"column_break_23",
|
||||
"income_account",
|
||||
"expense_account",
|
||||
"taxes_and_charges",
|
||||
"tax_category",
|
||||
"apply_discount_on",
|
||||
"accounting_dimensions_section",
|
||||
"cost_center",
|
||||
"dimension_col_break",
|
||||
"project"
|
||||
"campaign_section_break",
|
||||
"utm_source",
|
||||
"column_break_tvls",
|
||||
"utm_campaign",
|
||||
"column_break_xygw",
|
||||
"utm_medium"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -130,8 +150,7 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_14",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Configuration"
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"description": "Only show Items from these Item Groups",
|
||||
@@ -152,6 +171,7 @@
|
||||
"options": "POS Customer Group"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "section_break_16",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Print Settings"
|
||||
@@ -191,7 +211,7 @@
|
||||
{
|
||||
"fieldname": "section_break_19",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Accounting"
|
||||
"label": "Miscellaneous"
|
||||
},
|
||||
{
|
||||
"fieldname": "selling_price_list",
|
||||
@@ -427,9 +447,101 @@
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Applicable on POS Invoice",
|
||||
"fieldname": "allow_partial_payment",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Partial Payment"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_tvls",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_xygw",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "campaign_section_break",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Campaign"
|
||||
},
|
||||
{
|
||||
"fieldname": "accounting_tab",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "Accounting"
|
||||
},
|
||||
{
|
||||
"fieldname": "more_info_tab",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "More Info"
|
||||
},
|
||||
{
|
||||
"fieldname": "pos_configurations_tab",
|
||||
"fieldtype": "Tab Break",
|
||||
"label": "POS Configurations"
|
||||
},
|
||||
{
|
||||
"fieldname": "price_list_and_currency_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Price List & Currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_bptt",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "write_off_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Write Off"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_ukpz",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_pkca",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "income_and_expense_account",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Income and Expense"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_byzk",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Taxes"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_cjpp",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "pos_item_selector_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "POS Item Selector"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_rpny",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_stcl",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "pos_item_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "POS Item Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_hwfg",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
@@ -458,7 +570,7 @@
|
||||
"link_fieldname": "pos_profile"
|
||||
}
|
||||
],
|
||||
"modified": "2025-06-24 11:19:19.834905",
|
||||
"modified": "2026-02-05 03:38:13.216277",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
"email_append_to": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"company",
|
||||
"title",
|
||||
"naming_series",
|
||||
"supplier",
|
||||
"supplier_name",
|
||||
"tax_id",
|
||||
"company",
|
||||
"column_break_6",
|
||||
"posting_date",
|
||||
"posting_time",
|
||||
@@ -85,20 +85,24 @@
|
||||
"taxes_and_charges_added",
|
||||
"taxes_and_charges_deducted",
|
||||
"total_taxes_and_charges",
|
||||
"section_break_49",
|
||||
"totals_section",
|
||||
"grand_total",
|
||||
"disable_rounded_total",
|
||||
"rounding_adjustment",
|
||||
"column_break8",
|
||||
"use_company_roundoff_cost_center",
|
||||
"in_words",
|
||||
"rounded_total",
|
||||
"base_totals_section",
|
||||
"base_grand_total",
|
||||
"base_rounding_adjustment",
|
||||
"base_rounded_total",
|
||||
"column_break_hcca",
|
||||
"base_in_words",
|
||||
"column_break8",
|
||||
"grand_total",
|
||||
"rounding_adjustment",
|
||||
"use_company_roundoff_cost_center",
|
||||
"rounded_total",
|
||||
"in_words",
|
||||
"base_rounded_total",
|
||||
"section_break_ttrv",
|
||||
"total_advance",
|
||||
"column_break_peap",
|
||||
"outstanding_amount",
|
||||
"disable_rounded_total",
|
||||
"section_tax_withholding_entry",
|
||||
"tax_withholding_group",
|
||||
"ignore_tax_withholding_threshold",
|
||||
@@ -882,15 +886,10 @@
|
||||
"options": "currency",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_49",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals"
|
||||
},
|
||||
{
|
||||
"fieldname": "base_grand_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Grand Total (Company Currency)",
|
||||
"label": "Grand Total",
|
||||
"oldfieldname": "grand_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
@@ -901,7 +900,7 @@
|
||||
"depends_on": "eval:!doc.disable_rounded_total",
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"label": "Rounding Adjustment",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
@@ -911,7 +910,7 @@
|
||||
"depends_on": "eval:!doc.disable_rounded_total",
|
||||
"fieldname": "base_rounded_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounded Total (Company Currency)",
|
||||
"label": "Rounded Total",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
@@ -920,7 +919,7 @@
|
||||
{
|
||||
"fieldname": "base_in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "In Words (Company Currency)",
|
||||
"label": "In Words",
|
||||
"length": 240,
|
||||
"oldfieldname": "in_words",
|
||||
"oldfieldtype": "Data",
|
||||
@@ -1625,8 +1624,7 @@
|
||||
"hidden": 1,
|
||||
"label": "Item Wise Tax Details",
|
||||
"no_copy": 1,
|
||||
"options": "Item Wise Tax Detail",
|
||||
"print_hide": 1
|
||||
"options": "Item Wise Tax Detail"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
@@ -1661,6 +1659,28 @@
|
||||
"fieldname": "override_tax_withholding_entries",
|
||||
"fieldtype": "Check",
|
||||
"label": "Edit Tax Withholding Entries"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_hcca",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_ttrv",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_peap",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "base_totals_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals (Company Currency)"
|
||||
},
|
||||
{
|
||||
"fieldname": "totals_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
@@ -1668,7 +1688,7 @@
|
||||
"idx": 204,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2026-02-03 14:23:47.937128",
|
||||
"modified": "2026-02-04 16:32:19.664287",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
||||
@@ -461,27 +461,6 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends (
|
||||
}
|
||||
}
|
||||
|
||||
get_items_from_open_material_requests() {
|
||||
erpnext.utils.map_current_doc({
|
||||
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order_based_on_supplier",
|
||||
args: {
|
||||
supplier: this.frm.doc.supplier,
|
||||
},
|
||||
source_doctype: "Material Request",
|
||||
source_name: this.frm.doc.supplier,
|
||||
target: this.frm,
|
||||
setters: {
|
||||
company: this.frm.doc.company,
|
||||
},
|
||||
get_query_filters: {
|
||||
docstatus: ["!=", 2],
|
||||
supplier: this.frm.doc.supplier,
|
||||
},
|
||||
get_query_method:
|
||||
"erpnext.stock.doctype.material_request.material_request.get_material_requests_based_on_supplier",
|
||||
});
|
||||
}
|
||||
|
||||
validate() {
|
||||
set_schedule_date(this.frm);
|
||||
}
|
||||
|
||||
@@ -9,23 +9,20 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"supplier_section",
|
||||
"company",
|
||||
"title",
|
||||
"naming_series",
|
||||
"supplier",
|
||||
"supplier_name",
|
||||
"order_confirmation_no",
|
||||
"order_confirmation_date",
|
||||
"get_items_from_open_material_requests",
|
||||
"mps",
|
||||
"column_break_7",
|
||||
"transaction_date",
|
||||
"schedule_date",
|
||||
"column_break1",
|
||||
"supplier",
|
||||
"company",
|
||||
"is_subcontracted",
|
||||
"supplier_name",
|
||||
"has_unit_price_items",
|
||||
"supplier_warehouse",
|
||||
"amended_from",
|
||||
"accounting_dimensions_section",
|
||||
"cost_center",
|
||||
"dimension_col_break",
|
||||
@@ -79,16 +76,19 @@
|
||||
"taxes_and_charges_deducted",
|
||||
"total_taxes_and_charges",
|
||||
"totals_section",
|
||||
"grand_total",
|
||||
"disable_rounded_total",
|
||||
"rounding_adjustment",
|
||||
"column_break4",
|
||||
"in_words",
|
||||
"rounded_total",
|
||||
"base_totals_section",
|
||||
"base_grand_total",
|
||||
"base_rounding_adjustment",
|
||||
"column_break_jkoz",
|
||||
"base_in_words",
|
||||
"base_rounded_total",
|
||||
"column_break4",
|
||||
"grand_total",
|
||||
"rounding_adjustment",
|
||||
"rounded_total",
|
||||
"disable_rounded_total",
|
||||
"in_words",
|
||||
"section_break_tnkm",
|
||||
"advance_paid",
|
||||
"discount_section",
|
||||
"apply_discount_on",
|
||||
@@ -154,11 +154,13 @@
|
||||
"auto_repeat",
|
||||
"update_auto_repeat_reference",
|
||||
"additional_info_section",
|
||||
"is_internal_supplier",
|
||||
"party_account_currency",
|
||||
"represents_company",
|
||||
"ref_sq",
|
||||
"amended_from",
|
||||
"column_break_74",
|
||||
"party_account_currency",
|
||||
"mps",
|
||||
"is_internal_supplier",
|
||||
"inter_company_order_reference",
|
||||
"is_old_subcontracting_flow",
|
||||
"connections_tab"
|
||||
@@ -206,13 +208,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
|
||||
"description": "Fetch items based on Default Supplier.",
|
||||
"fieldname": "get_items_from_open_material_requests",
|
||||
"fieldtype": "Button",
|
||||
"label": "Get Items from Open Material Requests"
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"fetch_from": "supplier.supplier_name",
|
||||
@@ -773,7 +768,7 @@
|
||||
{
|
||||
"fieldname": "base_grand_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Grand Total (Company Currency)",
|
||||
"label": "Grand Total",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "grand_total",
|
||||
"oldfieldtype": "Currency",
|
||||
@@ -785,7 +780,7 @@
|
||||
"depends_on": "eval:!doc.disable_rounded_total",
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"label": "Rounding Adjustment",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
@@ -794,7 +789,7 @@
|
||||
{
|
||||
"fieldname": "base_in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "In Words (Company Currency)",
|
||||
"label": "In Words",
|
||||
"length": 240,
|
||||
"oldfieldname": "in_words",
|
||||
"oldfieldtype": "Data",
|
||||
@@ -804,7 +799,7 @@
|
||||
{
|
||||
"fieldname": "base_rounded_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounded Total (Company Currency)",
|
||||
"label": "Rounded Total",
|
||||
"oldfieldname": "rounded_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
@@ -862,7 +857,7 @@
|
||||
{
|
||||
"fieldname": "advance_paid",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Advance Paid",
|
||||
"label": "Advance Paid (Company Currency)",
|
||||
"no_copy": 1,
|
||||
"options": "party_account_currency",
|
||||
"print_hide": 1,
|
||||
@@ -1301,8 +1296,21 @@
|
||||
"hidden": 1,
|
||||
"label": "Item Wise Tax Details",
|
||||
"no_copy": 1,
|
||||
"options": "Item Wise Tax Detail",
|
||||
"print_hide": 1
|
||||
"options": "Item Wise Tax Detail"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_jkoz",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "base_totals_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals (Company Currency)",
|
||||
"options": "Company:company:default_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_tnkm",
|
||||
"fieldtype": "Section Break"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
@@ -1310,7 +1318,7 @@
|
||||
"idx": 105,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2026-02-03 14:44:55.192192",
|
||||
"modified": "2026-02-04 13:01:36.628472",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
||||
@@ -1251,10 +1251,26 @@ class JobCard(Document):
|
||||
frappe.db.set_value("Workstation", self.workstation, "status", status)
|
||||
|
||||
def add_time_logs(self, **kwargs):
|
||||
row = None
|
||||
kwargs = frappe._dict(kwargs)
|
||||
if not kwargs.employees and kwargs.to_time:
|
||||
for row in self.time_logs:
|
||||
if not row.to_time and row.from_time:
|
||||
row.to_time = kwargs.to_time
|
||||
row.time_in_mins = time_diff_in_minutes(row.to_time, row.from_time)
|
||||
|
||||
if kwargs.completed_qty:
|
||||
row.completed_qty = kwargs.completed_qty
|
||||
row.db_update()
|
||||
else:
|
||||
self.add_time_logs_for_employess(kwargs)
|
||||
|
||||
self.validate_time_logs(save=True)
|
||||
self.save()
|
||||
|
||||
def add_time_logs_for_employess(self, kwargs):
|
||||
row = None
|
||||
update_status = False
|
||||
|
||||
for employee in kwargs.employees:
|
||||
kwargs.employee = employee.get("employee")
|
||||
if kwargs.from_time and not kwargs.to_time:
|
||||
@@ -1290,9 +1306,6 @@ class JobCard(Document):
|
||||
|
||||
self.set_status(update_status=update_status)
|
||||
|
||||
self.validate_time_logs(save=True)
|
||||
self.save()
|
||||
|
||||
def update_workstation_status(self):
|
||||
status_map = {
|
||||
"Open": "Off",
|
||||
|
||||
@@ -496,7 +496,7 @@ class ProductionPlan(Document):
|
||||
|
||||
item_details = get_item_details(data.item_code, throw=False)
|
||||
if self.combine_items:
|
||||
bom_no = item_details.bom_no
|
||||
bom_no = item_details.get("bom_no")
|
||||
if data.get("bom_no"):
|
||||
bom_no = data.get("bom_no")
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ from frappe.utils import getdate, today
|
||||
|
||||
from erpnext.stock.report.stock_analytics.stock_analytics import get_period, get_period_date_ranges
|
||||
|
||||
WORK_ORDER_STATUS_LIST = ["Not Started", "Overdue", "Pending", "Completed", "Closed", "Stopped"]
|
||||
|
||||
|
||||
def execute(filters=None):
|
||||
columns = get_columns(filters)
|
||||
@@ -16,119 +18,98 @@ def execute(filters=None):
|
||||
|
||||
|
||||
def get_columns(filters):
|
||||
columns = [{"label": _("Status"), "fieldname": "Status", "fieldtype": "Data", "width": 140}]
|
||||
|
||||
columns = [{"label": _("Status"), "fieldname": "status", "fieldtype": "Data", "width": 140}]
|
||||
ranges = get_period_date_ranges(filters)
|
||||
|
||||
for _dummy, end_date in ranges:
|
||||
period = get_period(end_date, filters)
|
||||
|
||||
columns.append({"label": _(period), "fieldname": scrub(period), "fieldtype": "Float", "width": 120})
|
||||
|
||||
return columns
|
||||
|
||||
|
||||
def get_periodic_data(filters, entry):
|
||||
periodic_data = {
|
||||
"Not Started": {},
|
||||
"Overdue": {},
|
||||
"Pending": {},
|
||||
"Completed": {},
|
||||
"Closed": {},
|
||||
"Stopped": {},
|
||||
}
|
||||
def get_work_orders(filters):
|
||||
from_date = filters.get("from_date")
|
||||
to_date = filters.get("to_date")
|
||||
|
||||
ranges = get_period_date_ranges(filters)
|
||||
WorkOrder = frappe.qb.DocType("Work Order")
|
||||
|
||||
for from_date, end_date in ranges:
|
||||
period = get_period(end_date, filters)
|
||||
for d in entry:
|
||||
if getdate(from_date) <= getdate(d.creation) <= getdate(end_date) and d.status not in [
|
||||
"Draft",
|
||||
"Submitted",
|
||||
"Completed",
|
||||
"Cancelled",
|
||||
]:
|
||||
if d.status in ["Not Started", "Closed", "Stopped"]:
|
||||
periodic_data = update_periodic_data(periodic_data, d.status, period)
|
||||
elif getdate(today()) > getdate(d.planned_end_date):
|
||||
periodic_data = update_periodic_data(periodic_data, "Overdue", period)
|
||||
elif getdate(today()) < getdate(d.planned_end_date):
|
||||
periodic_data = update_periodic_data(periodic_data, "Pending", period)
|
||||
|
||||
if (
|
||||
getdate(from_date) <= getdate(d.actual_end_date) <= getdate(end_date)
|
||||
and d.status == "Completed"
|
||||
):
|
||||
periodic_data = update_periodic_data(periodic_data, "Completed", period)
|
||||
|
||||
return periodic_data
|
||||
|
||||
|
||||
def update_periodic_data(periodic_data, status, period):
|
||||
if periodic_data.get(status).get(period):
|
||||
periodic_data[status][period] += 1
|
||||
else:
|
||||
periodic_data[status][period] = 1
|
||||
|
||||
return periodic_data
|
||||
return (
|
||||
frappe.qb.from_(WorkOrder)
|
||||
.select(WorkOrder.creation, WorkOrder.actual_end_date, WorkOrder.planned_end_date, WorkOrder.status)
|
||||
.where(
|
||||
(WorkOrder.docstatus == 1)
|
||||
& (WorkOrder.company == filters.get("company"))
|
||||
& (
|
||||
(WorkOrder.creation.between(from_date, to_date))
|
||||
| (WorkOrder.actual_end_date.between(from_date, to_date))
|
||||
)
|
||||
)
|
||||
.run(as_dict=True)
|
||||
)
|
||||
|
||||
|
||||
def get_data(filters, columns):
|
||||
data = []
|
||||
entry = frappe.get_all(
|
||||
"Work Order",
|
||||
fields=[
|
||||
"creation",
|
||||
"actual_end_date",
|
||||
"planned_end_date",
|
||||
"status",
|
||||
],
|
||||
filters={"docstatus": 1, "company": filters["company"]},
|
||||
)
|
||||
ranges = build_ranges(filters)
|
||||
period_labels = [scrub(pd) for _fd, _td, pd in ranges]
|
||||
periodic_data = {status: {pd: 0 for pd in period_labels} for status in WORK_ORDER_STATUS_LIST}
|
||||
entries = get_work_orders(filters)
|
||||
|
||||
periodic_data = get_periodic_data(filters, entry)
|
||||
for d in entries:
|
||||
if d.status == "Completed":
|
||||
if not d.actual_end_date:
|
||||
continue
|
||||
|
||||
labels = ["Not Started", "Overdue", "Pending", "Completed", "Closed", "Stopped"]
|
||||
chart_data = get_chart_data(periodic_data, columns)
|
||||
ranges = get_period_date_ranges(filters)
|
||||
if period := scrub(get_period_for_date(getdate(d.actual_end_date), ranges)):
|
||||
periodic_data["Completed"][period] += 1
|
||||
continue
|
||||
|
||||
for label in labels:
|
||||
work = {}
|
||||
work["Status"] = _(label)
|
||||
for _dummy, end_date in ranges:
|
||||
period = get_period(end_date, filters)
|
||||
if periodic_data.get(label).get(period):
|
||||
work[scrub(period)] = periodic_data.get(label).get(period)
|
||||
creation_date = getdate(d.creation)
|
||||
period = scrub(get_period_for_date(creation_date, ranges))
|
||||
if not period:
|
||||
continue
|
||||
|
||||
if d.status in ("Not Started", "Closed", "Stopped"):
|
||||
periodic_data[d.status][period] += 1
|
||||
else:
|
||||
if d.planned_end_date and getdate(today()) > getdate(d.planned_end_date):
|
||||
periodic_data["Overdue"][period] += 1
|
||||
else:
|
||||
work[scrub(period)] = 0.0
|
||||
data.append(work)
|
||||
periodic_data["Pending"][period] += 1
|
||||
|
||||
return data, chart_data
|
||||
data = []
|
||||
for status in WORK_ORDER_STATUS_LIST:
|
||||
row = {"status": _(status)}
|
||||
for _fd, _td, period in ranges:
|
||||
row[scrub(period)] = periodic_data[status].get(scrub(period), 0)
|
||||
data.append(row)
|
||||
|
||||
chart = get_chart_data(periodic_data, columns)
|
||||
return data, chart
|
||||
|
||||
|
||||
def get_period_for_date(date, ranges):
|
||||
for from_date, to_date, period in ranges:
|
||||
if from_date <= date <= to_date:
|
||||
return period
|
||||
return None
|
||||
|
||||
|
||||
def build_ranges(filters):
|
||||
ranges = []
|
||||
for from_date, end_date in get_period_date_ranges(filters):
|
||||
period = get_period(end_date, filters)
|
||||
ranges.append((getdate(from_date), getdate(end_date), period))
|
||||
return ranges
|
||||
|
||||
|
||||
def get_chart_data(periodic_data, columns):
|
||||
labels = [d.get("label") for d in columns[1:]]
|
||||
period_labels = [d.get("label") for d in columns[1:]]
|
||||
period_fieldnames = [d.get("fieldname") for d in columns[1:]]
|
||||
|
||||
not_start, overdue, pending, completed, closed, stopped = [], [], [], [], [], []
|
||||
datasets = []
|
||||
for status in WORK_ORDER_STATUS_LIST:
|
||||
values = [periodic_data.get(status, {}).get(fieldname, 0) for fieldname in period_fieldnames]
|
||||
datasets.append({"name": _(status), "values": values})
|
||||
|
||||
for d in labels:
|
||||
not_start.append(periodic_data.get("Not Started").get(d))
|
||||
overdue.append(periodic_data.get("Overdue").get(d))
|
||||
pending.append(periodic_data.get("Pending").get(d))
|
||||
completed.append(periodic_data.get("Completed").get(d))
|
||||
closed.append(periodic_data.get("Closed").get(d))
|
||||
stopped.append(periodic_data.get("Stopped").get(d))
|
||||
|
||||
datasets.append({"name": _("Not Started"), "values": not_start})
|
||||
datasets.append({"name": _("Overdue"), "values": overdue})
|
||||
datasets.append({"name": _("Pending"), "values": pending})
|
||||
datasets.append({"name": _("Completed"), "values": completed})
|
||||
datasets.append({"name": _("Closed"), "values": closed})
|
||||
datasets.append({"name": _("Stopped"), "values": stopped})
|
||||
|
||||
chart = {"data": {"labels": labels, "datasets": datasets}}
|
||||
chart["type"] = "line"
|
||||
|
||||
return chart
|
||||
return {"data": {"labels": period_labels, "datasets": datasets}, "type": "line"}
|
||||
|
||||
@@ -461,4 +461,5 @@ erpnext.patches.v15_0.create_accounting_dimensions_in_advance_taxes_and_charges
|
||||
execute:frappe.delete_doc_if_exists("Workspace Sidebar", "Opening & Closing")
|
||||
erpnext.patches.v16_0.migrate_transaction_deletion_task_flags_to_status # 2
|
||||
erpnext.patches.v16_0.set_ordered_qty_in_quotation_item
|
||||
erpnext.patches.v16_0.update_company_custom_field_in_bin
|
||||
erpnext.patches.v16_0.update_company_custom_field_in_bin
|
||||
erpnext.patches.v15_0.replace_http_with_https_in_sales_partner
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import frappe
|
||||
from frappe import qb
|
||||
from pypika.functions import Replace
|
||||
|
||||
|
||||
def execute():
|
||||
sp = frappe.qb.DocType("Sales Partner")
|
||||
qb.update(sp).set(sp.partner_website, Replace(sp.partner_website, "http://", "https://")).where(
|
||||
sp.partner_website.rlike("^http://.*")
|
||||
).run()
|
||||
@@ -1733,13 +1733,11 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
|
||||
this.frm.set_currency_labels(
|
||||
[
|
||||
"advance_paid",
|
||||
"base_total",
|
||||
"base_net_total",
|
||||
"base_total_taxes_and_charges",
|
||||
"base_discount_amount",
|
||||
"base_grand_total",
|
||||
"base_rounded_total",
|
||||
"base_in_words",
|
||||
"base_taxes_and_charges_added",
|
||||
"base_taxes_and_charges_deducted",
|
||||
"total_amount_to_pay",
|
||||
@@ -1762,17 +1760,13 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
"net_total",
|
||||
"total_taxes_and_charges",
|
||||
"discount_amount",
|
||||
"grand_total",
|
||||
"taxes_and_charges_added",
|
||||
"taxes_and_charges_deducted",
|
||||
"tax_withholding_net_total",
|
||||
"rounded_total",
|
||||
"in_words",
|
||||
"paid_amount",
|
||||
"write_off_amount",
|
||||
"operating_cost",
|
||||
"scrap_material_cost",
|
||||
"rounding_adjustment",
|
||||
"raw_material_cost",
|
||||
"total_cost",
|
||||
"totals_section",
|
||||
@@ -1829,6 +1823,19 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
this.frm.doc.price_list_currency != company_currency
|
||||
);
|
||||
|
||||
let taxes_fields = [
|
||||
"total_taxes_and_charges",
|
||||
"taxes_and_charges_deducted",
|
||||
"taxes_and_charges_added",
|
||||
"base_taxes_and_charges_added",
|
||||
"base_taxes_and_charges_deducted",
|
||||
"base_total_taxes_and_charges",
|
||||
];
|
||||
|
||||
taxes_fields.forEach((field) => {
|
||||
this.frm.toggle_display(field, this.frm.doc[field] !== 0 || this.frm.doc.docstatus !== 1);
|
||||
});
|
||||
|
||||
let show =
|
||||
cint(this.frm.doc.discount_amount) ||
|
||||
(this.frm.doc.taxes || []).filter(function (d) {
|
||||
|
||||
@@ -50,8 +50,17 @@ class SalesPartner(WebsiteGenerator):
|
||||
if not self.route:
|
||||
self.route = "partners/" + self.scrub(self.partner_name)
|
||||
super().validate()
|
||||
if self.partner_website and not self.partner_website.startswith("http"):
|
||||
self.partner_website = "http://" + self.partner_website
|
||||
if self.partner_website:
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
# scrub http
|
||||
parts = urlsplit(self.partner_website)
|
||||
if not parts.netloc and parts.path:
|
||||
parts = parts._replace(netloc=parts.path, path="")
|
||||
if not parts.scheme or parts.scheme == "http":
|
||||
parts = parts._replace(scheme="https")
|
||||
|
||||
self.partner_website = urlunsplit(parts)
|
||||
|
||||
def get_context(self, context):
|
||||
address_names = frappe.db.get_all(
|
||||
|
||||
@@ -77,17 +77,19 @@
|
||||
"taxes_and_charges_added",
|
||||
"taxes_and_charges_deducted",
|
||||
"total_taxes_and_charges",
|
||||
"section_break_46",
|
||||
"totals_section",
|
||||
"grand_total",
|
||||
"disable_rounded_total",
|
||||
"rounding_adjustment",
|
||||
"column_break_50",
|
||||
"in_words",
|
||||
"rounded_total",
|
||||
"base_totals_section",
|
||||
"base_grand_total",
|
||||
"base_rounding_adjustment",
|
||||
"base_rounded_total",
|
||||
"column_break_ugyv",
|
||||
"base_in_words",
|
||||
"column_break_50",
|
||||
"grand_total",
|
||||
"rounding_adjustment",
|
||||
"rounded_total",
|
||||
"in_words",
|
||||
"disable_rounded_total",
|
||||
"base_rounded_total",
|
||||
"section_break_42",
|
||||
"apply_discount_on",
|
||||
"base_discount_amount",
|
||||
@@ -772,15 +774,10 @@
|
||||
"options": "currency",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_46",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals"
|
||||
},
|
||||
{
|
||||
"fieldname": "base_grand_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Grand Total (Company Currency)",
|
||||
"label": "Grand Total",
|
||||
"oldfieldname": "grand_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
@@ -791,7 +788,7 @@
|
||||
"depends_on": "eval:!doc.disable_rounded_total",
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"label": "Rounding Adjustment",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"print_hide": 1,
|
||||
@@ -800,7 +797,7 @@
|
||||
{
|
||||
"fieldname": "base_in_words",
|
||||
"fieldtype": "Data",
|
||||
"label": "In Words (Company Currency)",
|
||||
"label": "In Words",
|
||||
"length": 240,
|
||||
"oldfieldname": "in_words",
|
||||
"oldfieldtype": "Data",
|
||||
@@ -810,7 +807,7 @@
|
||||
{
|
||||
"fieldname": "base_rounded_total",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Rounded Total (Company Currency)",
|
||||
"label": "Rounded Total",
|
||||
"oldfieldname": "rounded_total",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
@@ -1282,8 +1279,22 @@
|
||||
"hidden": 1,
|
||||
"label": "Item Wise Tax Details",
|
||||
"no_copy": 1,
|
||||
"options": "Item Wise Tax Detail",
|
||||
"print_hide": 1
|
||||
"options": "Item Wise Tax Detail"
|
||||
},
|
||||
{
|
||||
"fieldname": "totals_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals"
|
||||
},
|
||||
{
|
||||
"fieldname": "base_totals_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals (Company Currency)",
|
||||
"options": "Company:company:default_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_ugyv",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
@@ -1291,7 +1302,7 @@
|
||||
"idx": 261,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2026-01-29 21:24:30.652933",
|
||||
"modified": "2026-02-04 14:36:41.087460",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt",
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 3,
|
||||
"columns": 2,
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
@@ -436,7 +436,6 @@
|
||||
"columns": 2,
|
||||
"fieldname": "net_amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Net Amount",
|
||||
"options": "currency",
|
||||
"print_hide": 1,
|
||||
@@ -1141,7 +1140,7 @@
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2025-10-21 10:39:32.659933",
|
||||
"modified": "2026-02-04 14:42:10.646809",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt Item",
|
||||
|
||||
@@ -522,6 +522,9 @@ class StockReconciliation(StockController):
|
||||
if abs(difference_amount) > 0:
|
||||
return True
|
||||
|
||||
float_precision = frappe.db.get_default("float_precision") or 3
|
||||
item_dict["rate"] = flt(item_dict.get("rate"), float_precision)
|
||||
item.valuation_rate = flt(item.valuation_rate, float_precision) if item.valuation_rate else None
|
||||
if (
|
||||
(item.qty is None or item.qty == item_dict.get("qty"))
|
||||
and (item.valuation_rate is None or item.valuation_rate == item_dict.get("rate"))
|
||||
|
||||
Reference in New Issue
Block a user