mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-30 20:18:27 +00:00
fix: pos screen ui ux (#47680)
* fix: pos addl info dialog submit form on save * feat: new invoice and recent order button on page action * fix: item cart highlighted item scrolling * fix: using icon instead of text in fullscreen button * fix: search field clear button alignment * fix: hide item selector on item details display * fix: using add_action_icon * fix: action of 'New Invoice' for unsaved changes * fix: highlight numpad btns on hover * fix: pos recent orders filter and list items * chore: added icons for pos icon buttons * fix: recent order toggle after invoice submission * fix: capitalized text in select options
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
"allow_rate_change",
|
||||
"allow_discount_change",
|
||||
"set_grand_total_to_default_mop",
|
||||
"action_on_new_invoice",
|
||||
"section_break_23",
|
||||
"item_groups",
|
||||
"column_break_25",
|
||||
@@ -415,6 +416,13 @@
|
||||
"fieldname": "set_grand_total_to_default_mop",
|
||||
"fieldtype": "Check",
|
||||
"label": "Set Grand Total to Default Payment Method"
|
||||
},
|
||||
{
|
||||
"default": "Always Ask",
|
||||
"fieldname": "action_on_new_invoice",
|
||||
"fieldtype": "Select",
|
||||
"label": "Action on New Invoice",
|
||||
"options": "Always Ask\nSave Changes and Load New Invoice\nDiscard Changes and Load New Invoice"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
@@ -443,7 +451,7 @@
|
||||
"link_fieldname": "pos_profile"
|
||||
}
|
||||
],
|
||||
"modified": "2025-05-09 11:23:28.632136",
|
||||
"modified": "2025-05-23 12:12:32.247652",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
||||
@@ -28,6 +28,9 @@ class POSProfile(Document):
|
||||
from erpnext.accounts.doctype.pos_profile_user.pos_profile_user import POSProfileUser
|
||||
|
||||
account_for_change_amount: DF.Link | None
|
||||
action_on_new_invoice: DF.Literal[
|
||||
"Always Ask", "Save Changes and Load New Invoice", "Discard Changes and Load New Invoice"
|
||||
]
|
||||
allow_discount_change: DF.Check
|
||||
allow_rate_change: DF.Check
|
||||
applicable_for_users: DF.Table[POSProfileUser]
|
||||
|
||||
@@ -28,6 +28,14 @@ web_include_js = "erpnext-web.bundle.js"
|
||||
web_include_css = "erpnext-web.bundle.css"
|
||||
email_css = "email_erpnext.bundle.css"
|
||||
|
||||
app_include_icons = [
|
||||
"/assets/erpnext/icons/pos-icons.svg",
|
||||
]
|
||||
|
||||
web_include_icons = [
|
||||
"/assets/erpnext/icons/pos-icons.svg",
|
||||
]
|
||||
|
||||
doctype_js = {
|
||||
"Address": "public/js/address.js",
|
||||
"Communication": "public/js/communication.js",
|
||||
|
||||
15
erpnext/public/icons/pos-icons.svg
Normal file
15
erpnext/public/icons/pos-icons.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- Icons for POS Icon Buttons. Taken from frappe/public/icons/lucide.svg -->
|
||||
|
||||
<svg id="frappe-symbols" aria-hidden="true" style="display: none;" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-fullscreen">
|
||||
<path d="M3 7V5a2 2 0 0 1 2-2h2" /> <path d="M17 3h2a2 2 0 0 1 2 2v2" /> <path d="M21 17v2a2 2 0 0 1-2 2h-2" /> <path d="M7 21H5a2 2 0 0 1-2-2v-2" /> <rect width="10" height="8" x="7" y="8" rx="1" />
|
||||
</symbol>
|
||||
|
||||
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-maximize">
|
||||
<path d="M8 3H5a2 2 0 0 0-2 2v3" /> <path d="M21 8V5a2 2 0 0 0-2-2h-3" /> <path d="M3 16v3a2 2 0 0 0 2 2h3" /> <path d="M16 21h3a2 2 0 0 0 2-2v-3" />
|
||||
</symbol>
|
||||
|
||||
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" id="icon-minimize">
|
||||
<path d="M8 3v3a2 2 0 0 1-2 2H3" /> <path d="M21 8h-3a2 2 0 0 1-2-2V3" /> <path d="M3 16h3a2 2 0 0 1 2 2v3" /> <path d="M16 21v-3a2 2 0 0 1 2-2h3" />
|
||||
</symbol>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1011 B |
@@ -579,7 +579,11 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--padding-md);
|
||||
box-shadow: var(--shadow-sm);
|
||||
box-shadow: var(--shadow-base);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--control-bg);
|
||||
}
|
||||
}
|
||||
|
||||
> .col-span-2 {
|
||||
@@ -615,26 +619,30 @@
|
||||
background-color: var(--control-bg);
|
||||
}
|
||||
|
||||
> .invoice-name-date {
|
||||
&.invoice-selected {
|
||||
background-color: var(--control-bg);
|
||||
}
|
||||
|
||||
> .invoice-name-customer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
|
||||
> .invoice-name {
|
||||
> .invoice-customer {
|
||||
@extend .nowrap;
|
||||
font-size: var(--text-md);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
> .invoice-date {
|
||||
> .invoice-name {
|
||||
@extend .nowrap;
|
||||
font-size: var(--text-sm);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
> .invoice-total-status {
|
||||
> .invoice-total-date {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-weight: 500;
|
||||
@@ -648,17 +656,19 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
> .invoice-status {
|
||||
> .invoice-date {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--gray-500);
|
||||
justify-content: right;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .item-details-container {
|
||||
@extend .pos-card;
|
||||
grid-column: span 4 / span 4;
|
||||
grid-column: span 6 / span 6;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
padding: var(--padding-lg);
|
||||
@@ -915,6 +925,10 @@
|
||||
justify-content: center;
|
||||
padding: var(--padding-md);
|
||||
box-shadow: var(--shadow-base);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--control-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -978,18 +992,23 @@
|
||||
background-color: var(--fg-color);
|
||||
padding: var(--padding-lg);
|
||||
|
||||
> .search-field {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> .status-search-fields {
|
||||
display: grid;
|
||||
grid-template-columns: 30% auto;
|
||||
column-gap: 10px;
|
||||
margin-top: var(--margin-md);
|
||||
margin-bottom: var(--margin-xs);
|
||||
}
|
||||
|
||||
> .status-field {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> .status-field {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
> .search-field {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ erpnext.PointOfSale.Controller = class {
|
||||
this.prepare_dom();
|
||||
this.prepare_components();
|
||||
this.prepare_menu();
|
||||
this.prepare_fullscreen_btn();
|
||||
this.prepare_btns();
|
||||
this.make_new_invoice();
|
||||
}
|
||||
|
||||
@@ -234,52 +234,42 @@ erpnext.PointOfSale.Controller = class {
|
||||
|
||||
prepare_menu() {
|
||||
this.page.clear_menu();
|
||||
|
||||
this.page.add_menu_item(__("Open Form View"), this.open_form_view.bind(this), false, "Ctrl+F");
|
||||
|
||||
this.page.add_menu_item(
|
||||
__("Toggle Recent Orders"),
|
||||
this.toggle_recent_order.bind(this),
|
||||
false,
|
||||
"Ctrl+O"
|
||||
);
|
||||
|
||||
this.page.add_menu_item(__("Save as Draft"), this.save_draft_invoice.bind(this), false, "Ctrl+S");
|
||||
|
||||
this.page.add_menu_item(__("Close the POS"), this.close_pos.bind(this), false, "Shift+Ctrl+C");
|
||||
}
|
||||
|
||||
prepare_fullscreen_btn() {
|
||||
this.page.page_actions.find(".custom-actions").empty();
|
||||
|
||||
this.page.add_button(__("Full Screen"), null, { btn_class: "btn-default fullscreen-btn" });
|
||||
|
||||
this.bind_fullscreen_events();
|
||||
prepare_btns() {
|
||||
this.page.clear_custom_actions();
|
||||
this.page.clear_icons();
|
||||
this.page.set_primary_action(__("New Invoice"), this.new_invoice_event.bind(this));
|
||||
this.page.set_secondary_action(__("Recent Orders"), this.toggle_recent_order.bind(this));
|
||||
this.page.add_action_icon(
|
||||
"fullscreen",
|
||||
this.bind_fullscreen_events.bind(this),
|
||||
"btn-fullscreen",
|
||||
"Fullscreen"
|
||||
);
|
||||
this.page.add_action_icon(
|
||||
"minimize",
|
||||
this.bind_fullscreen_events.bind(this),
|
||||
"btn-minimize hide",
|
||||
"Minimize"
|
||||
);
|
||||
}
|
||||
|
||||
bind_fullscreen_events() {
|
||||
this.$fullscreen_btn = this.page.page_actions.find(".fullscreen-btn");
|
||||
|
||||
this.$fullscreen_btn.on("click", function () {
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement.requestFullscreen();
|
||||
} else if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("fullscreenchange", this.handle_fullscreen_change_event.bind(this));
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement.requestFullscreen();
|
||||
this.toggle_fullscreen_btn(".btn-minimize", ".btn-fullscreen");
|
||||
} else if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
this.toggle_fullscreen_btn(".btn-fullscreen", ".btn-minimize");
|
||||
}
|
||||
}
|
||||
|
||||
handle_fullscreen_change_event() {
|
||||
let enable_fullscreen_label = __("Full Screen");
|
||||
let exit_fullscreen_label = __("Exit Full Screen");
|
||||
|
||||
if (document.fullscreenElement) {
|
||||
this.$fullscreen_btn[0].innerText = exit_fullscreen_label;
|
||||
} else {
|
||||
this.$fullscreen_btn[0].innerText = enable_fullscreen_label;
|
||||
}
|
||||
toggle_fullscreen_btn(show, hide) {
|
||||
this.page.page_actions.find(hide).addClass("hide");
|
||||
this.page.page_actions.find(show).removeClass("hide");
|
||||
}
|
||||
|
||||
open_form_view() {
|
||||
@@ -289,36 +279,48 @@ erpnext.PointOfSale.Controller = class {
|
||||
|
||||
toggle_recent_order() {
|
||||
const show = this.recent_order_list.$component.is(":hidden");
|
||||
this.page.btn_secondary.get(0).innerText = show ? __("Hide Recent Orders") : __("Recent Orders");
|
||||
this.toggle_recent_order_list(show);
|
||||
}
|
||||
|
||||
save_draft_invoice() {
|
||||
new_invoice_event() {
|
||||
const me = this;
|
||||
if (!this.$components_wrapper.is(":visible")) return;
|
||||
|
||||
if (this.frm.doc.items.length == 0) {
|
||||
frappe.show_alert({
|
||||
message: __("You must add atleast one item to save it as draft."),
|
||||
indicator: "red",
|
||||
});
|
||||
frappe.utils.play_sound("error");
|
||||
if (this.frm.doc.items.length !== 0 && (this.frm.is_new() || this.frm.is_dirty())) {
|
||||
if (this.settings.action_on_new_invoice === "Always Ask") {
|
||||
frappe.confirm(
|
||||
__("You have unsaved changes. Do you want to save the invoice?"),
|
||||
() => {
|
||||
me.frm.save().then(me.load_new_invoice_on_pos.bind(me));
|
||||
},
|
||||
() => {
|
||||
me.load_new_invoice_on_pos();
|
||||
}
|
||||
);
|
||||
return;
|
||||
} else if (this.settings.action_on_new_invoice === "Save Changes and Load New Invoice") {
|
||||
this.frm.save().then(me.load_new_invoice_on_pos.bind(me));
|
||||
return;
|
||||
}
|
||||
|
||||
this.load_new_invoice_on_pos();
|
||||
return;
|
||||
}
|
||||
|
||||
this.frm
|
||||
.save(undefined, undefined, undefined, () => {
|
||||
frappe.show_alert({
|
||||
message: __("There was an error saving the document."),
|
||||
indicator: "red",
|
||||
});
|
||||
frappe.utils.play_sound("error");
|
||||
})
|
||||
.then(() => {
|
||||
frappe.run_serially([
|
||||
() => frappe.dom.freeze(),
|
||||
() => this.make_new_invoice(),
|
||||
() => frappe.dom.unfreeze(),
|
||||
]);
|
||||
});
|
||||
if (this.payment.$component.is(":visible")) {
|
||||
this.load_new_invoice_on_pos();
|
||||
}
|
||||
}
|
||||
|
||||
load_new_invoice_on_pos() {
|
||||
frappe.run_serially([
|
||||
() => frappe.dom.freeze(),
|
||||
() => this.make_new_invoice(),
|
||||
() => this.toggle_recent_order_list(false),
|
||||
() => this.toggle_components(true),
|
||||
() => frappe.dom.unfreeze(),
|
||||
]);
|
||||
}
|
||||
|
||||
close_pos() {
|
||||
@@ -384,7 +386,7 @@ erpnext.PointOfSale.Controller = class {
|
||||
get_frm: () => this.frm,
|
||||
|
||||
toggle_item_selector: (minimize) => {
|
||||
this.item_selector.resize_selector(minimize);
|
||||
this.item_selector.toggle_component(!minimize);
|
||||
this.cart.toggle_numpad(minimize);
|
||||
},
|
||||
|
||||
@@ -468,8 +470,7 @@ erpnext.PointOfSale.Controller = class {
|
||||
submit_invoice: () => {
|
||||
this.frm.savesubmit().then((r) => {
|
||||
this.toggle_components(false);
|
||||
this.order_summary.toggle_component(true);
|
||||
this.order_summary.load_summary_of(this.frm.doc, true);
|
||||
this.toggle_submitted_invoice_summary(true);
|
||||
frappe.show_alert({
|
||||
indicator: "green",
|
||||
message: __("POS invoice {0} created successfully", [r.doc.name]),
|
||||
@@ -518,7 +519,7 @@ erpnext.PointOfSale.Controller = class {
|
||||
});
|
||||
},
|
||||
edit_order: (doctype, name) => {
|
||||
this.recent_order_list.toggle_component(false);
|
||||
this.toggle_recent_order();
|
||||
frappe.run_serially([
|
||||
() => this.make_invoice_frm(doctype),
|
||||
() => this.sync_draft_invoice_to_frm(doctype, name),
|
||||
@@ -550,19 +551,29 @@ erpnext.PointOfSale.Controller = class {
|
||||
}
|
||||
|
||||
toggle_recent_order_list(show) {
|
||||
this.toggle_components(!show);
|
||||
this.frm.doc.docstatus === 1
|
||||
? this.toggle_submitted_invoice_summary(!show)
|
||||
: this.toggle_components(!show);
|
||||
|
||||
this.recent_order_list.toggle_component(show);
|
||||
this.order_summary.toggle_component(show);
|
||||
if (this.frm.doc.docstatus === 0) this.order_summary.toggle_component(show);
|
||||
}
|
||||
|
||||
toggle_components(show) {
|
||||
this.cart.toggle_component(show);
|
||||
this.cart.toggle_numpad(!show);
|
||||
this.cart.toggle_checkout_btn(show);
|
||||
this.item_selector.toggle_component(show);
|
||||
|
||||
// do not show item details or payment if recent order is toggled off
|
||||
!show ? this.item_details.toggle_component(false) || this.payment.toggle_component(false) : "";
|
||||
}
|
||||
|
||||
toggle_submitted_invoice_summary(show) {
|
||||
this.order_summary.toggle_component(show);
|
||||
this.order_summary.load_summary_of(this.frm.doc, true);
|
||||
}
|
||||
|
||||
make_new_invoice() {
|
||||
return frappe.run_serially([
|
||||
() => frappe.dom.freeze(),
|
||||
|
||||
@@ -171,8 +171,11 @@ erpnext.PointOfSale.ItemCart = class {
|
||||
|
||||
me.toggle_item_highlight(this);
|
||||
|
||||
const scrollTop = $cart_item.offset().top - me.$cart_items_wrapper.offset().top;
|
||||
me.$cart_items_wrapper.animate({ scrollTop });
|
||||
const numpad_section_hidden = !me.$numpad_section.is(":visible");
|
||||
if (numpad_section_hidden) {
|
||||
const scrollTop = $cart_item.offset().top - me.$cart_items_wrapper.offset().top;
|
||||
me.$cart_items_wrapper.animate({ scrollTop });
|
||||
}
|
||||
|
||||
const payment_section_hidden = !me.$totals_section.find(".edit-cart-btn").is(":visible");
|
||||
if (!payment_section_hidden) {
|
||||
|
||||
@@ -188,7 +188,7 @@ erpnext.PointOfSale.ItemSelector = class {
|
||||
|
||||
attach_clear_btn() {
|
||||
this.search_field.$wrapper.find(".control-input").append(
|
||||
`<span class="link-btn" style="top: 2px;">
|
||||
`<span class="link-btn">
|
||||
<a class="btn-open no-decoration" title="${__("Clear")}">
|
||||
${frappe.utils.icon("close", "sm")}
|
||||
</a>
|
||||
|
||||
@@ -17,8 +17,10 @@ erpnext.PointOfSale.PastOrderList = class {
|
||||
`<section class="past-order-list">
|
||||
<div class="filter-section">
|
||||
<div class="label">${__("Recent Orders")}</div>
|
||||
<div class="search-field"></div>
|
||||
<div class="status-field"></div>
|
||||
<div class="status-search-fields">
|
||||
<div class="status-field"></div>
|
||||
<div class="search-field"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoices-container"></div>
|
||||
</section>`
|
||||
@@ -38,8 +40,12 @@ erpnext.PointOfSale.PastOrderList = class {
|
||||
});
|
||||
const me = this;
|
||||
this.$invoices_container.on("click", ".invoice-wrapper", function () {
|
||||
const invoice_doctype = $(this).attr("data-invoice-doctype");
|
||||
const invoice_name = unescape($(this).attr("data-invoice-name"));
|
||||
const invoice_clicked = $(this);
|
||||
const invoice_doctype = invoice_clicked.attr("data-invoice-doctype");
|
||||
const invoice_name = unescape(invoice_clicked.attr("data-invoice-name"));
|
||||
|
||||
$(".invoice-wrapper").removeClass("invoice-selected");
|
||||
invoice_clicked.addClass("invoice-selected");
|
||||
|
||||
me.events.open_invoice_data(invoice_doctype, invoice_name);
|
||||
});
|
||||
@@ -103,16 +109,16 @@ erpnext.PointOfSale.PastOrderList = class {
|
||||
return `<div class="invoice-wrapper" data-invoice-doctype="${
|
||||
invoice.doctype
|
||||
}" data-invoice-name="${escape(invoice.name)}">
|
||||
<div class="invoice-name-date">
|
||||
<div class="invoice-name">${invoice.name}</div>
|
||||
<div class="invoice-date">
|
||||
<div class="invoice-name-customer">
|
||||
<div class="invoice-customer">
|
||||
<svg class="mr-2" width="12" height="12" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>
|
||||
</svg>
|
||||
${frappe.ellipsis(invoice.customer, 20)}
|
||||
</div>
|
||||
<div class="invoice-name">${invoice.name}</div>
|
||||
</div>
|
||||
<div class="invoice-total-status">
|
||||
<div class="invoice-total-date">
|
||||
<div class="invoice-total">${format_currency(invoice.grand_total, invoice.currency) || 0}</div>
|
||||
<div class="invoice-date">${posting_datetime}</div>
|
||||
</div>
|
||||
|
||||
@@ -459,6 +459,7 @@ erpnext.PointOfSale.PastOrderSummary = class {
|
||||
}
|
||||
|
||||
toggle_component(show) {
|
||||
this.$component.css("grid-column", "span 6 / span 6");
|
||||
show ? this.$component.css("display", "flex") : this.$component.css("display", "none");
|
||||
}
|
||||
|
||||
|
||||
@@ -61,9 +61,15 @@ erpnext.PointOfSale.Payment = class {
|
||||
primary_action_label: __("Save"),
|
||||
primary_action(values) {
|
||||
me.set_values_to_frm(values);
|
||||
if (this.complete_order) {
|
||||
me.events.submit_invoice();
|
||||
}
|
||||
this.hide();
|
||||
},
|
||||
});
|
||||
me.addl_dlg.$wrapper.on("hide.bs.modal", function () {
|
||||
me.addl_dlg.complete_order = false;
|
||||
});
|
||||
me.add_btn_field_click_listener();
|
||||
me.set_value_on_dialog_fields();
|
||||
me.make_addl_info_dialog_btn_visible();
|
||||
@@ -218,10 +224,6 @@ erpnext.PointOfSale.Payment = class {
|
||||
const paid_amount = doc.paid_amount;
|
||||
const items = doc.items;
|
||||
|
||||
if (!this.validate_reqd_invoice_fields()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!items.length || (paid_amount == 0 && doc.additional_discount_percentage != 100)) {
|
||||
const message = items.length
|
||||
? __("You cannot submit the order without payment.")
|
||||
@@ -231,6 +233,10 @@ erpnext.PointOfSale.Payment = class {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.validate_reqd_invoice_fields()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.events.submit_invoice();
|
||||
});
|
||||
|
||||
@@ -683,16 +689,12 @@ erpnext.PointOfSale.Payment = class {
|
||||
}
|
||||
|
||||
validate_reqd_invoice_fields() {
|
||||
if (this.invoice_fields.length === 0) return true;
|
||||
const doc = this.events.get_frm().doc;
|
||||
for (const df of this.addl_dlg.fields) {
|
||||
if (df.reqd && !doc[df.fieldname]) {
|
||||
frappe.show_alert({
|
||||
message: __(
|
||||
"Invoice cannot be submitted without filling the mandatory Additional Information fields."
|
||||
),
|
||||
indicator: "red",
|
||||
});
|
||||
frappe.utils.play_sound("error");
|
||||
this.addl_dlg.primary_action_label = "Submit";
|
||||
this.addl_dlg.complete_order = true;
|
||||
this.addl_dlg.show();
|
||||
this.addl_dlg.fields_dict[df.fieldname].$input.focus();
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user