Merge branch 'develop' of https://github.com/frappe/erpnext into rebrand-ui
diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json
index a18dbff..e1d75a8 100644
--- a/erpnext/accounts/desk_page/accounting/accounting.json
+++ b/erpnext/accounts/desk_page/accounting/accounting.json
@@ -100,6 +100,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "accounting",
"idx": 0,
"is_standard": 1,
"label": "Accounting",
diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js
index 7bbc1c9..7dc0533 100644
--- a/erpnext/accounts/doctype/account/account_tree.js
+++ b/erpnext/accounts/doctype/account/account_tree.js
@@ -120,7 +120,7 @@
} else {
treeview.new_node();
}
- }, "octicon octicon-plus");
+ }, "add");
},
onrender: function(node) {
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
@@ -130,7 +130,7 @@
let dr_or_cr = balance > 0 ? "Dr": "Cr";
if (node.data && node.data.balance!==undefined) {
- $('<span class="balance-area pull-right text-muted small">'
+ $('<span class="balance-area pull-right">'
+ (node.data.balance_in_account_currency ?
(format_currency(Math.abs(node.data.balance_in_account_currency),
node.data.account_currency) + " / ") : "")
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js
index 0627675..541901c 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js
@@ -6,3 +6,46 @@
}
});
+
+frappe.tour['Accounts Settings'] = [
+ {
+ fieldname: "acc_frozen_upto",
+ title: "Accounts Frozen Upto",
+ description: __("Freeze accounting transactions up to specified date, nobody can make/modify entry except the specified Role."),
+ },
+ {
+ fieldname: "frozen_accounts_modifier",
+ title: "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
+ description: __("Users with this Role are allowed to set frozen accounts and create/modify accounting entries against frozen accounts.")
+ },
+ {
+ fieldname: "determine_address_tax_category_from",
+ title: "Determine Address Tax Category From",
+ description: __("Tax category can be set on Addresses. An address can be Shipping or Billing address. Set which addres to select when applying Tax Category.")
+ },
+ {
+ fieldname: "over_billing_allowance",
+ title: "Over Billing Allowance Percentage",
+ description: __("The percentage by which you can overbill transactions. For example, if the order value is $100 for an Item and percentage here is set as 10% then you are allowed to bill for $110.")
+ },
+ {
+ fieldname: "credit_controller",
+ title: "Credit Controller",
+ description: __("Select the role that is allowed to submit transactions that exceed credit limits set. The credit limit can be set in the Customer form.")
+ },
+ {
+ fieldname: "make_payment_via_journal_entry",
+ title: "Make Payment via Journal Entry",
+ description: __("When checked, if user proceeds to make payment from an invoice, the system will open a Journal Entry instead of a Payment Entry.")
+ },
+ {
+ fieldname: "unlink_payment_on_cancellation_of_invoice",
+ title: "Unlink Payment on Cancellation of Invoice",
+ description: __("If checked, system will unlink the payment against the respective invoice.")
+ },
+ {
+ fieldname: "unlink_advance_payment_on_cancelation_of_order",
+ title: "Unlink Advance Payment on Cancellation of Order",
+ description: __("Similar to the previous option, this unlinks any advance payments made against Purchase/Sales Orders.")
+ }
+];
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js
index 3ce5701..22b8e0a 100644
--- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js
+++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.js
@@ -118,7 +118,8 @@
frappe.render_template('opening_invoice_creation_tool_dashboard', {
data: opening_invoices_summary,
max_count: max_count
- })
+ }),
+ __("Opening Invoices Summary")
);
section.on('click', '.invoice-link', function() {
diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py
index ee2092a..76027a3 100644
--- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py
+++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py
@@ -64,11 +64,11 @@
prepare_invoice_summary(doctype, invoices)
return invoices_summary, max_count
-
+
def validate_company(self):
if not self.company:
frappe.throw(_("Please select the Company"))
-
+
def set_missing_values(self, row):
row.qty = row.qty or 1.0
row.temporary_opening_account = row.temporary_opening_account or get_temporary_opening_account(self.company)
@@ -210,7 +210,7 @@
frappe.db.commit()
if errors:
frappe.msgprint(_("You had {} errors while creating opening invoices. Check {} for more details")
- .format(errors, "<a href='#List/Error Log' class='variant-click'>Error Log</a>"), indicator="red", title=_("Error Occured"))
+ .format(errors, "<a href='/app/List/Error Log' class='variant-click'>Error Log</a>"), indicator="red", title=_("Error Occured"))
return names
def publish(index, total, doctype):
diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html
index 5b136d4..afbcfa5 100644
--- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html
+++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool_dashboard.html
@@ -1,4 +1,3 @@
-<h5 style="margin-top: 0px;">{{ __("Opening Invoices Summary") }}</h5>
{% $.each(data, (company, summary) => { %}
<h6 style="margin: 15px 0px -10px 0px;"><a class="company-link"> {{ company }}</a></h6>
diff --git a/erpnext/accounts/doctype/payment_request/payment_request_list.js b/erpnext/accounts/doctype/payment_request/payment_request_list.js
index 72833d2..85d729c 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request_list.js
+++ b/erpnext/accounts/doctype/payment_request/payment_request_list.js
@@ -2,7 +2,7 @@
add_fields: ["status"],
get_indicator: function(doc) {
if(doc.status == "Draft") {
- return [__("Draft"), "darkgrey", "status,=,Draft"];
+ return [__("Draft"), "gray", "status,=,Draft"];
}
if(doc.status == "Requested") {
return [__("Requested"), "green", "status,=,Requested"];
@@ -19,5 +19,5 @@
else if(doc.status == "Cancelled") {
return [__("Cancelled"), "red", "status,=,Cancelled"];
}
- }
+ }
}
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js
index 8da7d6f..699a49d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice_list.js
@@ -7,21 +7,21 @@
"currency", "is_return", "release_date", "on_hold", "represents_company", "is_internal_supplier"],
get_indicator: function(doc) {
if ((flt(doc.outstanding_amount) <= 0) && doc.docstatus == 1 && doc.status == 'Debit Note Issued') {
- return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<=,0"];
+ return [__("Debit Note Issued"), "gray", "outstanding_amount,<=,0"];
} else if (flt(doc.outstanding_amount) > 0 && doc.docstatus==1) {
if(cint(doc.on_hold) && !doc.release_date) {
- return [__("On Hold"), "darkgrey"];
+ return [__("On Hold"), "gray"];
} else if (cint(doc.on_hold) && doc.release_date && frappe.datetime.get_diff(doc.release_date, frappe.datetime.nowdate()) > 0) {
- return [__("Temporarily on Hold"), "darkgrey"];
+ return [__("Temporarily on Hold"), "gray"];
} else if (frappe.datetime.get_diff(doc.due_date) < 0) {
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<,Today"];
} else {
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>=,Today"];
}
} else if (cint(doc.is_return)) {
- return [__("Return"), "darkgrey", "is_return,=,Yes"];
+ return [__("Return"), "gray", "is_return,=,Yes"];
} else if (doc.company == doc.represents_company && doc.is_internal_supplier) {
- return [__("Internal Transfer"), "darkgrey", "outstanding_amount,=,0"];
+ return [__("Internal Transfer"), "gray", "outstanding_amount,=,0"];
} else if (flt(doc.outstanding_amount)==0 && doc.docstatus==1) {
return [__("Paid"), "green", "outstanding_amount,=,0"];
}
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
index 56576df..50ec7d8 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.py
@@ -6,8 +6,5 @@
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
-
class PurchaseInvoiceItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 5efc32e..9cbfb0f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -674,12 +674,12 @@
};
},
// When multiple companies are set up. in case company name is changed set default company address
- company:function(frm){
- if (frm.doc.company)
- {
+ company: function(frm){
+ if (frm.doc.company) {
frappe.call({
- method:"erpnext.setup.doctype.company.company.get_default_company_address",
- args:{name:frm.doc.company, existing_address: frm.doc.company_address},
+ method: "erpnext.setup.doctype.company.company.get_default_company_address",
+ args: {name:frm.doc.company, existing_address: frm.doc.company_address || ""},
+ debounce: 2000,
callback: function(r){
if (r.message){
frm.set_value("company_address",r.message)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index ca6f22c..8b09130 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -53,7 +53,7 @@
"""Set indicator for portal"""
if self.outstanding_amount < 0:
self.indicator_title = _("Credit Note Issued")
- self.indicator_color = "darkgrey"
+ self.indicator_color = "gray"
elif self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()):
self.indicator_color = "orange"
self.indicator_title = _("Unpaid")
@@ -62,7 +62,7 @@
self.indicator_title = _("Overdue")
elif cint(self.is_return) == 1:
self.indicator_title = _("Return")
- self.indicator_color = "darkgrey"
+ self.indicator_color = "gray"
else:
self.indicator_color = "green"
self.indicator_title = _("Paid")
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js
index 41140d1..1a01cb5 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice_list.js
@@ -10,8 +10,8 @@
"Draft": "grey",
"Unpaid": "orange",
"Paid": "green",
- "Return": "darkgrey",
- "Credit Note Issued": "darkgrey",
+ "Return": "gray",
+ "Credit Note Issued": "gray",
"Unpaid and Discounted": "orange",
"Overdue and Discounted": "red",
"Overdue": "red",
diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
index 7a62f8e..a73b03a 100644
--- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
+++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.py
@@ -5,8 +5,6 @@
import frappe
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
class SalesInvoiceItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
index 97a6fdd..0e01188 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.js
@@ -5,3 +5,25 @@
{% include "erpnext/public/js/controllers/accounts.js" %}
+frappe.tour['Sales Taxes and Charges Template'] = [
+ {
+ fieldname: "title",
+ title: __("Title"),
+ description: __("A name by which you will identify this template. You can change this later."),
+ },
+ {
+ fieldname: "company",
+ title: __("Company"),
+ description: __("Company for which this tax template will be applicable"),
+ },
+ {
+ fieldname: "is_default",
+ title: __("Is this Default?"),
+ description: __("Set this template as the default for all sales transactions"),
+ },
+ {
+ fieldname: "taxes",
+ title: __("Taxes Table"),
+ description: __("You can add a row for a tax rule here. These rules can be applied on the net total, or can be a flat amount."),
+ }
+];
diff --git a/erpnext/accounts/doctype/subscription/subscription_list.js b/erpnext/accounts/doctype/subscription/subscription_list.js
index a4edb77..c7325fb 100644
--- a/erpnext/accounts/doctype/subscription/subscription_list.js
+++ b/erpnext/accounts/doctype/subscription/subscription_list.js
@@ -11,7 +11,7 @@
} else if(doc.status === 'Unpaid') {
return [__("Unpaid"), "red"];
} else if(doc.status === 'Cancelled') {
- return [__("Cancelled"), "darkgrey"];
+ return [__("Cancelled"), "gray"];
}
}
};
\ No newline at end of file
diff --git a/erpnext/accounts/module_onboarding/accounts/accounts.json b/erpnext/accounts/module_onboarding/accounts/accounts.json
index 570d2bd..6b5c5a1 100644
--- a/erpnext/accounts/module_onboarding/accounts/accounts.json
+++ b/erpnext/accounts/module_onboarding/accounts/accounts.json
@@ -13,7 +13,7 @@
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/accounts",
"idx": 0,
"is_complete": 0,
- "modified": "2020-07-08 14:06:09.033880",
+ "modified": "2020-10-30 15:41:15.547225",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts",
diff --git a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json
index 48637bf..fc49bd6 100644
--- a/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json
+++ b/erpnext/accounts/onboarding_step/chart_of_accounts/chart_of_accounts.json
@@ -1,19 +1,24 @@
{
"action": "Go to Page",
+ "action_label": "View Chart of Accounts",
+ "callback_message": "You can continue with the onboarding after exploring this page",
+ "callback_title": "Awesome Work",
"creation": "2020-05-13 19:58:20.928127",
+ "description": "# Chart Of Accounts\n\nThe Chart of Accounts is the blueprint of the accounts in your organization.\nIt is a tree view of the names of the Accounts (Ledgers and Groups) that a Company requires to manage its books of accounts. ERPNext sets up a simple chart of accounts for each Company you create, but you can modify it according to your needs and legal requirements.\n\nFor each company, Chart of Accounts signifies the way to classify the accounting entries, mostly\nbased on statutory (tax, compliance to government regulations) requirements.\n\nThere's a brief video tutorial about chart of accounts in the next step.",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
+ "intro_video_url": "https://www.youtube.com/embed/AcfMCT7wLLo",
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-14 17:40:28.410447",
+ "modified": "2020-10-30 14:35:59.474920",
"modified_by": "Administrator",
"name": "Chart of Accounts",
"owner": "Administrator",
"path": "Tree/Account",
"reference_document": "Account",
+ "show_form_tour": 0,
"show_full_form": 0,
"title": "Review Chart of Accounts",
"validate_action": 0
diff --git a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json
index c8be357..c84430a 100644
--- a/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json
+++ b/erpnext/accounts/onboarding_step/configure_account_settings/configure_account_settings.json
@@ -1,18 +1,19 @@
{
- "action": "Create Entry",
+ "action": "Show Form Tour",
"creation": "2020-05-14 17:53:00.876946",
+ "description": "# Account Settings\n\nThis is a crucial piece of configuration. There are various account settings in ERPNext to restrict and configure actions in the Accounting module.\n\nThe following settings are avaialble for you to configure\n\n1. Account Freezing \n2. Credit and Overbilling\n3. Invoicing and Tax Automations\n4. Balance Sheet configurations\n\nThere's much more, you can check it all out in this step",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 1,
"is_skipped": 0,
- "modified": "2020-05-14 18:06:25.212923",
+ "modified": "2020-10-19 14:40:55.584484",
"modified_by": "Administrator",
"name": "Configure Account Settings",
"owner": "Administrator",
"reference_document": "Accounts Settings",
+ "show_form_tour": 0,
"show_full_form": 1,
"title": "Configure Account Settings",
"validate_action": 1
diff --git a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json
index 5a403b0..0b6750c 100644
--- a/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json
+++ b/erpnext/accounts/onboarding_step/create_a_customer/create_a_customer.json
@@ -1,18 +1,19 @@
{
"action": "Create Entry",
"creation": "2020-05-14 17:46:41.831517",
+ "description": "## Who is a Customer?\n\nA customer, who is sometimes known as a client, buyer, or purchaser is the one who receives goods, services, products, or ideas, from a seller for a monetary consideration.\n\nEvery customer needs to be assigned a unique id. Customer name itself can be the id or you can set a naming series for ids to be generated in Selling Settings.\n\nJust like the supplier, let's quickly create a customer.",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-06-01 13:16:19.731719",
+ "modified": "2020-10-30 15:28:46.659660",
"modified_by": "Administrator",
"name": "Create a Customer",
"owner": "Administrator",
"reference_document": "Customer",
+ "show_form_tour": 0,
"show_full_form": 0,
"title": "Create a Customer",
"validate_action": 1
diff --git a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json
index d2068e1..d76f645 100644
--- a/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json
+++ b/erpnext/accounts/onboarding_step/create_a_product/create_a_product.json
@@ -1,19 +1,21 @@
{
"action": "Create Entry",
"creation": "2020-05-12 18:16:06.624554",
+ "description": "## Products and Services\n\nDepending on the nature of your business, you might be selling products or services to your clients or even both. \nERPNext is optimized for itemized management of your sales and purchase.\n\nThe **Item Master** is where you can add all your sales items. If you are in services, you can create an Item for each service that you offer. If you run a manufacturing business, the same master is used for keeping a record of raw materials, sub-assemblies etc.\n\nCompleting the Item Master is very essential for the successful implementation of ERPNext. We have a brief video introducing the item master for you, you can watch it in the next step.",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
+ "intro_video_url": "https://www.youtube.com/watch?v=Sl5UFA5H5EQ",
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-12 18:30:02.489949",
+ "modified": "2020-10-30 15:20:30.133495",
"modified_by": "Administrator",
"name": "Create a Product",
"owner": "Administrator",
"reference_document": "Item",
+ "show_form_tour": 0,
"show_full_form": 0,
- "title": "Create a Product",
+ "title": "Create a Sales Item",
"validate_action": 1
}
\ No newline at end of file
diff --git a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json
index 7a64224..64bc7bb 100644
--- a/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json
+++ b/erpnext/accounts/onboarding_step/create_a_supplier/create_a_supplier.json
@@ -1,18 +1,19 @@
{
"action": "Create Entry",
"creation": "2020-05-14 22:09:10.043554",
+ "description": "## Who is a Supplier?\n\nSuppliers are companies or individuals who provide you with products or services. ERPNext has comprehensive features for purchase cycles. \n\nLet's quickly create a supplier with the minimal details required. You need the name of the supplier, assign the supplier to a group, and select the type of the supplier, viz. Company or Individual.",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-14 22:09:10.043554",
+ "modified": "2020-10-30 15:26:48.315772",
"modified_by": "Administrator",
"name": "Create a Supplier",
"owner": "Administrator",
"reference_document": "Supplier",
+ "show_form_tour": 0,
"show_full_form": 0,
"title": "Create a Supplier",
"validate_action": 1
diff --git a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json
index 3a2b8d3..ddbc89e 100644
--- a/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json
+++ b/erpnext/accounts/onboarding_step/create_your_first_purchase_invoice/create_your_first_purchase_invoice.json
@@ -1,18 +1,19 @@
{
"action": "Create Entry",
"creation": "2020-05-14 22:10:07.049704",
+ "description": "# What's a Purchase Invoice?\n\nA Purchase Invoice is a bill you receive from your Suppliers against which you need to make the payment.\nPurchase Invoice is the exact opposite of your Sales Invoice. Here you accrue expenses to your Supplier. \n\nThe following is what a typical purchase cycle looks like, however you can create a purchase invoice directly as well.\n\n\n\n",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-14 22:10:07.049704",
+ "modified": "2020-10-30 15:30:26.337773",
"modified_by": "Administrator",
"name": "Create Your First Purchase Invoice",
"owner": "Administrator",
"reference_document": "Purchase Invoice",
+ "show_form_tour": 0,
"show_full_form": 1,
"title": "Create Your First Purchase Invoice ",
"validate_action": 1
diff --git a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json
index 473de50..9e7dd67 100644
--- a/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json
+++ b/erpnext/accounts/onboarding_step/create_your_first_sales_invoice/create_your_first_sales_invoice.json
@@ -1,18 +1,19 @@
{
"action": "Create Entry",
"creation": "2020-05-14 17:48:21.019019",
+ "description": "# All about sales invoice\n\nA Sales Invoice is a bill that you send to your Customers against which the Customer makes the payment. Sales Invoice is an accounting transaction. On submission of Sales Invoice, the system updates the receivable and books income against a Customer Account.\n\nHere's the flow of how a sales invoice is generally created\n\n\n",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-14 17:48:21.019019",
+ "modified": "2020-10-16 12:59:16.987507",
"modified_by": "Administrator",
"name": "Create Your First Sales Invoice",
"owner": "Administrator",
"reference_document": "Sales Invoice",
+ "show_form_tour": 0,
"show_full_form": 1,
"title": "Create Your First Sales Invoice ",
"validate_action": 1
diff --git a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json
index 8e00067..a492201 100644
--- a/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json
+++ b/erpnext/accounts/onboarding_step/setup_taxes/setup_taxes.json
@@ -1,18 +1,20 @@
{
"action": "Create Entry",
+ "action_label": "Make a Sales Tax Template",
"creation": "2020-05-13 19:29:43.844463",
+ "description": "# Setting up Taxes\n\nAny sophisticated accounting system, including ERPNext will have automatic tax calculations for your transactions. These calculations are based on user defined rules in compliance to local rules and regulations.\n\nERPNext allows this via *Tax Templates*. These templates can be used in Sales Orders and Sales Invoices. Other types of charges that may apply to your invoices (like shipping, insurance etc.) can also be configured as taxes.\n\nFor Tax Accounts that you want to use in the tax templates, go to:\n\n`> Accounting > Taxes > Sales Taxes and Charges Template`\n\nYou can read more about these templates in our documentation [here](https://docs.erpnext.com/docs/user/manual/en/selling/sales-taxes-and-charges-template)\n",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
- "is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-14 17:40:16.014413",
+ "modified": "2020-10-30 14:54:18.087383",
"modified_by": "Administrator",
"name": "Setup Taxes",
"owner": "Administrator",
"reference_document": "Sales Taxes and Charges Template",
+ "show_form_tour": 1,
"show_full_form": 1,
"title": "Lets create a Tax Template for Sales ",
"validate_action": 0
diff --git a/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html b/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html
index 1d758e8..3d5a9b1 100644
--- a/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html
+++ b/erpnext/accounts/print_format/sales_invoice_return/sales_invoice_return.html
@@ -1,5 +1,5 @@
{%- from "templates/print_formats/standard_macros.html" import add_header, render_field, print_value, fieldmeta,
- get_width, get_align_class -%}
+ get_width, get_align_class with context -%}
{%- macro render_currency(df, doc) -%}
<div class="row {% if df.bold %}important{% endif %} data-field">
@@ -63,14 +63,19 @@
<tr>
<td class="table-sr">{{ d.idx }}</td>
{% for tdf in visible_columns %}
- {% if not d.flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %}
+ {% if not print_settings.compact_item_print or tdf.fieldname in doc.flags.compact_item_fields %}
<td class="{{ get_align_class(tdf) }}" {{ fieldmeta(df) }}>
{% if tdf.fieldname == 'qty' %}
<div class="value">{{ (d[tdf.fieldname])|abs }}</div></td>
{% elif tdf.fieldtype == 'Currency' %}
<div class="value">{{ frappe.utils.fmt_money((d[tdf.fieldname])|abs, currency=doc.currency) }}</div></td>
{% else %}
- <div class="value">{{ print_value(tdf, d, doc, visible_columns) }}</div></td>
+ {% if doc.child_print_templates %}
+ {%- set child_templates = doc.child_print_templates.get(df.fieldname) -%}
+ <div class="value">{{ print_value(tdf, d, doc, visible_columns, child_templates) }}</div></td>
+ {% else %}
+ <div class="value">{{ print_value(tdf, d, doc, visible_columns) }}</div></td>
+ {% endif %}
{% endif %}
{% endif %}
{% endfor %}
diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py
index a858c19..1729abc 100644
--- a/erpnext/accounts/report/balance_sheet/balance_sheet.py
+++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py
@@ -147,7 +147,6 @@
{
"value": net_asset,
"label": "Total Asset",
- "indicator": "Green",
"datatype": "Currency",
"currency": currency
},
@@ -155,14 +154,12 @@
"value": net_liability,
"label": "Total Liability",
"datatype": "Currency",
- "indicator": "Red",
"currency": currency
},
{
"value": net_equity,
"label": "Total Equity",
"datatype": "Currency",
- "indicator": "Blue",
"currency": currency
},
{
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
index b34d037..fe261b3 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py
@@ -60,23 +60,25 @@
return [
{
- "value": net_profit,
- "indicator": "Green" if net_profit > 0 else "Red",
- "label": profit_label,
- "datatype": "Currency",
- "currency": currency
- },
- {
"value": net_income,
"label": income_label,
"datatype": "Currency",
"currency": currency
},
+ { "type": "separator", "value": "-"},
{
"value": net_expense,
"label": expense_label,
"datatype": "Currency",
"currency": currency
+ },
+ { "type": "separator", "value": "=", "color": "blue"},
+ {
+ "value": net_profit,
+ "indicator": "Green" if net_profit > 0 else "Red",
+ "label": profit_label,
+ "datatype": "Currency",
+ "currency": currency
}
]
diff --git a/erpnext/agriculture/desk_page/agriculture/agriculture.json b/erpnext/agriculture/desk_page/agriculture/agriculture.json
index e0d2c9c..094e165 100644
--- a/erpnext/agriculture/desk_page/agriculture/agriculture.json
+++ b/erpnext/agriculture/desk_page/agriculture/agriculture.json
@@ -24,10 +24,12 @@
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
+ "hide_custom": 0,
+ "icon": "agriculture",
"idx": 0,
"is_standard": 1,
"label": "Agriculture",
- "modified": "2020-04-01 11:28:51.032822",
+ "modified": "2020-06-30 18:35:25.350213",
"modified_by": "Administrator",
"module": "Agriculture",
"name": "Agriculture",
diff --git a/erpnext/assets/desk_page/assets/assets.json b/erpnext/assets/desk_page/assets/assets.json
index 449a5fa..515fc22 100644
--- a/erpnext/assets/desk_page/assets/assets.json
+++ b/erpnext/assets/desk_page/assets/assets.json
@@ -30,10 +30,11 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "assets",
"idx": 0,
"is_standard": 1,
"label": "Assets",
- "modified": "2020-05-20 18:05:23.994795",
+ "modified": "2020-06-30 18:36:11.169586",
"modified_by": "Administrator",
"module": "Assets",
"name": "Assets",
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 30abc66..1793dad 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -471,7 +471,7 @@
asset_bought_with_invoice = (purchase_document == self.purchase_invoice)
fixed_asset_account = self.get_fixed_asset_account()
-
+
cwip_enabled = is_cwip_accounting_enabled(self.asset_category)
cwip_account = self.get_cwip_account(cwip_enabled=cwip_enabled)
@@ -503,10 +503,10 @@
purchase_document = self.purchase_invoice if asset_bought_with_invoice else self.purchase_receipt
return purchase_document
-
+
def get_fixed_asset_account(self):
return get_asset_category_account('fixed_asset_account', None, self.name, None, self.asset_category, self.company)
-
+
def get_cwip_account(self, cwip_enabled=False):
cwip_account = None
try:
@@ -659,7 +659,7 @@
frappe.db.commit()
- frappe.msgprint(_("Asset Movement record {0} created").format("<a href='#Form/Asset Movement/{0}'>{0}</a>").format(movement_entry.name))
+ frappe.msgprint(_("Asset Movement record {0} created").format("<a href='/app/Form/Asset Movement/{0}'>{0}</a>").format(movement_entry.name))
@frappe.whitelist()
def get_item_details(item_code, asset_category):
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
index 001fc26..70b8654 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
@@ -40,14 +40,13 @@
if(!r.message) {
return;
}
- var section = frm.dashboard.add_section(`<h5 style="margin-top: 0px;">
- ${ __("Maintenance Log") }</a></h5>`);
+ const section = frm.dashboard.add_section('', __("Maintenance Log"));
var rows = $('<div></div>').appendTo(section);
// show
(r.message || []).forEach(function(d) {
$(`<div class='row' style='margin-bottom: 10px;'>
<div class='col-sm-3 small'>
- <a onclick="frappe.set_route('List', 'Asset Maintenance Log',
+ <a onclick="frappe.set_route('List', 'Asset Maintenance Log',
{'asset_name': '${d.asset_name}','maintenance_status': '${d.maintenance_status}' });">
${d.maintenance_status} <span class="badge">${d.count}</span>
</a>
diff --git a/erpnext/buying/desk_page/buying/buying.json b/erpnext/buying/desk_page/buying/buying.json
index 2e870fe..16df8df 100644
--- a/erpnext/buying/desk_page/buying/buying.json
+++ b/erpnext/buying/desk_page/buying/buying.json
@@ -57,10 +57,11 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "buying",
"idx": 0,
"is_standard": 1,
"label": "Buying",
- "modified": "2020-09-30 14:40:55.638458",
+ "modified": "2020-10-21 12:29:02.772723",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying",
@@ -70,7 +71,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#cef6d1",
+ "color": "Green",
"format": "{} Available",
"label": "Item",
"link_to": "Item",
@@ -78,7 +79,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} Pending",
"label": "Material Request",
"link_to": "Material Request",
@@ -86,7 +87,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} To Receive",
"label": "Purchase Order",
"link_to": "Purchase Order",
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py
index b711e36..8bdcd47 100644
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.py
@@ -6,11 +6,8 @@
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
-
class PurchaseOrderItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
def on_doctype_update():
frappe.db.add_index("Purchase Order Item", ["item_code", "warehouse"])
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
index ae5611f..6a4c02c 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
@@ -71,7 +71,7 @@
doc_sup = doc_sup[0] if doc_sup else None
if not doc_sup:
frappe.throw(_("Supplier {0} not found in {1}").format(self.supplier,
- "<a href='desk#Form/Request for Quotation/{0}'> Request for Quotation {0} </a>".format(doc.name)))
+ "<a href='desk/app/Form/Request for Quotation/{0}'> Request for Quotation {0} </a>".format(doc.name)))
quote_status = _('Received')
for item in doc.items:
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js
index 9f4fece..5ab6c98 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation_list.js
@@ -4,9 +4,9 @@
if(doc.status==="Ordered") {
return [__("Ordered"), "green", "status,=,Ordered"];
} else if(doc.status==="Rejected") {
- return [__("Lost"), "darkgrey", "status,=,Lost"];
+ return [__("Lost"), "gray", "status,=,Lost"];
} else if(doc.status==="Expired") {
- return [__("Expired"), "darkgrey", "status,=,Expired"];
+ return [__("Expired"), "gray", "status,=,Expired"];
}
}
};
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py
index f24e5be..64dda87 100644
--- a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.py
@@ -6,8 +6,5 @@
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
-
class SupplierQuotationItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
diff --git a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js
index c50916e..dc5474e 100644
--- a/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js
+++ b/erpnext/buying/doctype/supplier_scorecard/supplier_scorecard_list.js
@@ -10,7 +10,7 @@
if (doc.indicator_color) {
return [__(doc.status), doc.indicator_color.toLowerCase(), "status,=," + doc.status];
} else {
- return [__("Unknown"), "darkgrey", "status,=,''"];
+ return [__("Unknown"), "gray", "status,=,''"];
}
},
diff --git a/erpnext/config/education.py b/erpnext/config/education.py
index 4efaaa6..1c8ab10 100644
--- a/erpnext/config/education.py
+++ b/erpnext/config/education.py
@@ -173,7 +173,7 @@
{
"type": "doctype",
"name": "Course Schedule",
- "route": "#List/Course Schedule/Calendar"
+ "route": "/app/List/Course Schedule/Calendar"
},
{
"type": "doctype",
diff --git a/erpnext/config/projects.py b/erpnext/config/projects.py
index 47700d1..ab4db96 100644
--- a/erpnext/config/projects.py
+++ b/erpnext/config/projects.py
@@ -16,13 +16,13 @@
{
"type": "doctype",
"name": "Task",
- "route": "#List/Task",
+ "route": "/app/List/Task",
"description": _("Project activity / task."),
"onboard": 1,
},
{
"type": "report",
- "route": "#List/Task/Gantt",
+ "route": "/app/List/Task/Gantt",
"doctype": "Task",
"name": "Gantt Chart",
"description": _("Gantt chart of all tasks."),
@@ -97,5 +97,5 @@
},
]
},
-
+
]
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 32c5d3a..6237aef 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -22,6 +22,7 @@
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from erpnext.stock.get_item_details import get_item_warehouse, _get_item_tax_template, get_item_tax_map
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
+from erpnext.controllers.print_settings import set_print_templates_for_item_table, set_print_templates_for_taxes
class AccountMissingError(frappe.ValidationError): pass
@@ -31,6 +32,19 @@
def __init__(self, *args, **kwargs):
super(AccountsController, self).__init__(*args, **kwargs)
+ def get_print_settings(self):
+ print_setting_fields = []
+ items_field = self.meta.get_field('items')
+
+ if items_field and items_field.fieldtype == 'Table':
+ print_setting_fields += ['compact_item_print', 'print_uom_after_quantity']
+
+ taxes_field = self.meta.get_field('taxes')
+ if taxes_field and taxes_field.fieldtype == 'Table':
+ print_setting_fields += ['print_taxes_with_zero_amount']
+
+ return print_setting_fields
+
@property
def company_currency(self):
if not hasattr(self, "__company_currency"):
@@ -142,7 +156,7 @@
elif self.doctype in ("Quotation", "Purchase Order", "Sales Order"):
self.validate_non_invoice_documents_schedule()
- def before_print(self):
+ def before_print(self, settings=None):
if self.doctype in ['Purchase Order', 'Sales Order', 'Sales Invoice', 'Purchase Invoice',
'Supplier Quotation', 'Purchase Receipt', 'Delivery Note', 'Quotation']:
if self.get("group_same_items"):
@@ -155,6 +169,9 @@
else:
df.set("print_hide", 1)
+ set_print_templates_for_item_table(self, settings)
+ set_print_templates_for_taxes(self, settings)
+
def calculate_paid_amount(self):
if hasattr(self, "is_pos") or hasattr(self, "is_paid"):
is_paid = self.get("is_pos") or self.get("is_paid")
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 286c4f4..53f8edb 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -18,16 +18,6 @@
from erpnext.controllers.stock_controller import StockController
class BuyingController(StockController):
- def __setup__(self):
- if hasattr(self, "taxes"):
- self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
- "print_taxes_with_zero_amount"))
- self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax()
-
- self.print_templates = {
- "total": "templates/print_formats/includes/total.html",
- "taxes": "templates/print_formats/includes/taxes.html"
- }
def get_feed(self):
if self.get("supplier_name"):
diff --git a/erpnext/controllers/print_settings.py b/erpnext/controllers/print_settings.py
index c41db25..e08c400 100644
--- a/erpnext/controllers/print_settings.py
+++ b/erpnext/controllers/print_settings.py
@@ -5,20 +5,34 @@
import frappe
from frappe.utils import cint
-def print_settings_for_item_table(doc):
-
+def set_print_templates_for_item_table(doc, settings):
doc.print_templates = {
- "qty": "templates/print_formats/includes/item_table_qty.html"
+ "items": "templates/print_formats/includes/items.html",
}
- doc.hide_in_print_layout = ["uom", "stock_uom"]
- doc.flags.compact_item_print = cint(frappe.db.get_single_value("Print Settings", "compact_item_print"))
+ doc.child_print_templates = {
+ "items": {
+ "qty": "templates/print_formats/includes/item_table_qty.html",
+ }
+ }
- if doc.flags.compact_item_print:
- doc.print_templates["description"] = "templates/print_formats/includes/item_table_description.html"
- doc.flags.compact_item_fields = ["description", "qty", "rate", "amount"]
+ if doc.meta.get_field("items"):
+ doc.meta.get_field("items").hide_in_print_layout = ["uom", "stock_uom"]
+
+ doc.flags.compact_item_fields = ["description", "qty", "rate", "amount"]
+
+ if settings.compact_item_print:
+ doc.child_print_templates["items"]["description"] =\
+ "templates/print_formats/includes/item_table_description.html"
doc.flags.format_columns = format_columns
+def set_print_templates_for_taxes(doc, settings):
+ doc.flags.show_inclusive_tax_in_print = doc.is_inclusive_tax()
+ doc.print_templates.update({
+ "total": "templates/print_formats/includes/total.html",
+ "taxes": "templates/print_formats/includes/taxes.html"
+ })
+
def format_columns(display_columns, compact_fields):
compact_fields = compact_fields + ["image", "item_code", "item_name"]
final_columns = []
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 4dbd7bf..1ee1097 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -15,16 +15,6 @@
from erpnext.controllers.stock_controller import StockController
class SellingController(StockController):
- def __setup__(self):
- if hasattr(self, "taxes"):
- self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
- "print_taxes_with_zero_amount"))
- self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax()
-
- self.print_templates = {
- "total": "templates/print_formats/includes/total.html",
- "taxes": "templates/print_formats/includes/taxes.html"
- }
def get_feed(self):
return _("To {0} | {1} {2}").format(self.customer_name, self.currency,
@@ -189,7 +179,7 @@
for it in self.get("items"):
if not it.item_code:
continue
-
+
last_purchase_rate, is_stock_item = frappe.get_cached_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"])
last_purchase_rate_in_sales_uom = last_purchase_rate * (it.conversion_factor or 1)
if flt(it.base_net_rate) < flt(last_purchase_rate_in_sales_uom):
diff --git a/erpnext/crm/desk_page/crm/crm.json b/erpnext/crm/desk_page/crm/crm.json
index d974beb..5497f3e 100644
--- a/erpnext/crm/desk_page/crm/crm.json
+++ b/erpnext/crm/desk_page/crm/crm.json
@@ -39,6 +39,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "crm",
"idx": 0,
"is_standard": 1,
"label": "CRM",
@@ -52,7 +53,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#ffe8cd",
+ "color": "Blue",
"format": "{} Open",
"label": "Lead",
"link_to": "Lead",
@@ -60,7 +61,7 @@
"type": "DocType"
},
{
- "color": "#cef6d1",
+ "color": "Blue",
"format": "{} Assigned",
"label": "Opportunity",
"link_to": "Opportunity",
diff --git a/erpnext/crm/doctype/contract/contract_list.js b/erpnext/crm/doctype/contract/contract_list.js
index 2ef5900..a09d123 100644
--- a/erpnext/crm/doctype/contract/contract_list.js
+++ b/erpnext/crm/doctype/contract/contract_list.js
@@ -6,7 +6,7 @@
} else if (doc.status == "Active") {
return [__(doc.status), "green", "status,=," + doc.status];
} else if (doc.status == "Inactive") {
- return [__(doc.status), "darkgrey", "status,=," + doc.status];
+ return [__(doc.status), "gray", "status,=," + doc.status];
}
},
};
\ No newline at end of file
diff --git a/erpnext/education/desk_page/education/education.json b/erpnext/education/desk_page/education/education.json
index 77ee8ec..0d51048 100644
--- a/erpnext/education/desk_page/education/education.json
+++ b/erpnext/education/desk_page/education/education.json
@@ -80,6 +80,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "education",
"idx": 0,
"is_standard": 1,
"label": "Education",
diff --git a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js
index 3cd4512..e213309 100644
--- a/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js
+++ b/erpnext/education/doctype/assessment_result_tool/assessment_result_tool.js
@@ -128,7 +128,7 @@
result_table.find(`span[data-student=${assessment_result.student}].total-score-grade`).html(assessment_result.grade);
let link_span = result_table.find(`span[data-student=${assessment_result.student}].total-result-link`);
$(link_span).css("display", "block");
- $(link_span).find("a").attr("href", "#Form/Assessment Result/"+assessment_result.name);
+ $(link_span).find("a").attr("href", "/desk/Form/Assessment Result/"+assessment_result.name);
}
});
}
diff --git a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js
index 20503f9..f408dae 100644
--- a/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js
+++ b/erpnext/education/doctype/course_scheduling_tool/course_scheduling_tool.js
@@ -25,7 +25,7 @@
<thead><tr><th>${__("Course")}</th><th>${__("Date")}</th></tr></thead>
<tbody>
${course_schedules.map(
- c => `<tr><td><a href="#Form/Course Schedule/${c.name}">${c.name}</a></td>
+ c => `<tr><td><a href="/desk/Form/Course Schedule/${c.name}">${c.name}</a></td>
<td>${c.schedule_date}</td></tr>`
).join('')}
</tbody>
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.js b/erpnext/education/doctype/fee_schedule/fee_schedule.js
index 75dd446..0b4c2cd 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.js
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.js
@@ -43,7 +43,7 @@
frm.reload_doc();
}
if (data.progress) {
- let progress_bar = $(cur_frm.dashboard.progress_area).find('.progress-bar');
+ let progress_bar = $(cur_frm.dashboard.progress_area.body).find('.progress-bar');
if (progress_bar) {
$(progress_bar).removeClass('progress-bar-danger').addClass('progress-bar-success progress-bar-striped');
$(progress_bar).css('width', data.progress+'%');
diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.py b/erpnext/education/doctype/program_enrollment/program_enrollment.py
index 6fbcd8a..3045db7 100644
--- a/erpnext/education/doctype/program_enrollment/program_enrollment.py
+++ b/erpnext/education/doctype/program_enrollment/program_enrollment.py
@@ -87,7 +87,7 @@
fees.submit()
fee_list.append(fees.name)
if fee_list:
- fee_list = ["""<a href="#Form/Fees/%s" target="_blank">%s</a>""" % \
+ fee_list = ["""<a href="/app/Form/Fees/%s" target="_blank">%s</a>""" % \
(fee, fee) for fee in fee_list]
msgprint(_("Fee Records Created - {0}").format(comma_and(fee_list)))
diff --git a/erpnext/education/doctype/student_admission/templates/student_admission.html b/erpnext/education/doctype/student_admission/templates/student_admission.html
index 7ff3906..f9ddac0 100644
--- a/erpnext/education/doctype/student_admission/templates/student_admission.html
+++ b/erpnext/education/doctype/student_admission/templates/student_admission.html
@@ -21,7 +21,7 @@
{% elif frappe.utils.getdate(doc.admission_start_date) > today %}
blue"> Application will open
{% else %}
- darkgrey
+ gray
{% endif %}
</span>
</div>
diff --git a/erpnext/education/doctype/student_admission/templates/student_admission_row.html b/erpnext/education/doctype/student_admission/templates/student_admission_row.html
index cf22436..99868d5 100644
--- a/erpnext/education/doctype/student_admission/templates/student_admission_row.html
+++ b/erpnext/education/doctype/student_admission/templates/student_admission_row.html
@@ -11,7 +11,7 @@
{% elif frappe.utils.getdate(doc.admission_start_date) > today %}
blue
{% else %}
- darkgrey
+ gray
{% endif %}
">{{ doc.title }}</span>
</div>
diff --git a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js
index fd16d1e..e864111 100644
--- a/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js
+++ b/erpnext/erpnext_integrations/doctype/tally_migration/tally_migration.js
@@ -23,10 +23,10 @@
frappe.msgprint({
message: __("An error has occurred during {0}. Check {1} for more details",
[
- repl("<a href='#Form/Tally Migration/%(tally_document)s' class='variant-click'>%(tally_document)s</a>", {
+ repl("<a href='/desk/Form/Tally Migration/%(tally_document)s' class='variant-click'>%(tally_document)s</a>", {
tally_document: frm.docname
}),
- "<a href='#List/Error Log' class='variant-click'>Error Log</a>"
+ "<a href='/desk/List/Error Log' class='variant-click'>Error Log</a>"
]
),
title: __("Tally Migration Error"),
diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json
index af601f3..c77d082 100644
--- a/erpnext/healthcare/desk_page/healthcare/healthcare.json
+++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json
@@ -66,6 +66,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "healthcare",
"idx": 0,
"is_standard": 1,
"label": "Healthcare",
@@ -80,7 +81,7 @@
"restrict_to_domain": "Healthcare",
"shortcuts": [
{
- "color": "#ffe8cd",
+ "color": "Orange",
"format": "{} Open",
"label": "Patient Appointment",
"link_to": "Patient Appointment",
@@ -88,7 +89,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Orange",
"format": "{} Active",
"label": "Patient",
"link_to": "Patient",
@@ -96,7 +97,7 @@
"type": "DocType"
},
{
- "color": "#cef6d1",
+ "color": "Green",
"format": "{} Vacant",
"label": "Healthcare Service Unit",
"link_to": "Healthcare Service Unit",
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
index 1d4411d..ff51646 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.js
@@ -85,7 +85,7 @@
callback: function(r) {
if (r.message) {
frappe.show_alert({
- message: __('Stock Entry {0} created', ['<a class="bold" href="#Form/Stock Entry/'+ r.message + '">' + r.message + '</a>']),
+ message: __('Stock Entry {0} created', ['<a class="bold" href="/app/stock-entry/'+ r.message + '">' + r.message + '</a>']),
indicator: 'green'
});
}
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.js b/erpnext/healthcare/doctype/exercise_type/exercise_type.js
index 68db047..b49b00e 100644
--- a/erpnext/healthcare/doctype/exercise_type/exercise_type.js
+++ b/erpnext/healthcare/doctype/exercise_type/exercise_type.js
@@ -71,7 +71,7 @@
$('.btn-del').on('click', function() {
let id = $(this).attr('data-id');
- $('#card-'+id).addClass("zoomOutDelete");
+ $('#card-'+id).addClass("zoom-out");
setTimeout(() => {
// not using grid_rows[id].remove because
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
index a03b579..bfb0ba1 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit/healthcare_service_unit_tree.js
@@ -13,19 +13,19 @@
ignore_fields:["parent_healthcare_service_unit"],
onrender: function(node) {
if (node.data.occupied_out_of_vacant!==undefined){
- $('<span class="balance-area pull-right text-muted small">'
+ $('<span class="balance-area pull-right">'
+ " " + node.data.occupied_out_of_vacant
+ '</span>').insertBefore(node.$ul);
}
if (node.data && node.data.inpatient_occupancy!==undefined) {
if (node.data.inpatient_occupancy == 1){
if (node.data.occupancy_status == "Occupied"){
- $('<span class="balance-area pull-right small">'
+ $('<span class="balance-area pull-right">'
+ " " + node.data.occupancy_status
+ '</span>').insertBefore(node.$ul);
}
if (node.data.occupancy_status == "Vacant"){
- $('<span class="balance-area pull-right text-muted small">'
+ $('<span class="balance-area pull-right">'
+ " " + node.data.occupancy_status
+ '</span>').insertBefore(node.$ul);
}
diff --git a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
index bc76970..c7ab447 100644
--- a/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
+++ b/erpnext/healthcare/doctype/inpatient_record/inpatient_record.py
@@ -50,7 +50,7 @@
if ip_record:
msg = _(("Already {0} Patient {1} with Inpatient Record ").format(ip_record[0].status, self.patient) \
- + """ <b><a href="#Form/Inpatient Record/{0}">{0}</a></b>""".format(ip_record[0].name))
+ + """ <b><a href="/app/Form/Inpatient Record/{0}">{0}</a></b>""".format(ip_record[0].name))
frappe.throw(msg)
def admit(self, service_unit, check_in, expected_discharge=None):
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index e685b20..90d9023 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -63,7 +63,7 @@
if overlaps:
overlapping_details = _('Appointment overlaps with ')
- overlapping_details += "<b><a href='#Form/Patient Appointment/{0}'>{0}</a></b><br>".format(overlaps[0][0])
+ overlapping_details += "<b><a href='/app/Form/Patient Appointment/{0}'>{0}</a></b><br>".format(overlaps[0][0])
overlapping_details += _('{0} has appointment scheduled with {1} at {2} having {3} minute(s) duration.').format(
overlaps[0][1], overlaps[0][2], overlaps[0][3], overlaps[0][4])
frappe.throw(overlapping_details, title=_('Appointments Overlapping'))
@@ -75,7 +75,7 @@
if frappe.db.get_single_value('Healthcare Settings', 'automate_appointment_invoicing'):
if not frappe.db.get_value('Patient', self.patient, 'customer'):
msg = _("Please set a Customer linked to the Patient")
- msg += " <b><a href='#Form/Patient/{0}'>{0}</a></b>".format(self.patient)
+ msg += " <b><a href='/app/Form/Patient/{0}'>{0}</a></b>".format(self.patient)
frappe.throw(msg, title=_('Customer Not Found'))
def update_prescription_details(self):
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 96282f5..2486923 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -32,7 +32,7 @@
def validate_customer_created(patient):
if not frappe.db.get_value('Patient', patient.name, 'customer'):
msg = _("Please set a Customer linked to the Patient")
- msg += " <b><a href='#Form/Patient/{0}'>{0}</a></b>".format(patient.name)
+ msg += " <b><a href='/app/Form/Patient/{0}'>{0}</a></b>".format(patient.name)
frappe.throw(msg, title=_('Customer Not Found'))
@@ -169,7 +169,7 @@
service_item = get_healthcare_service_item('clinical_procedure_consumable_item')
if not service_item:
msg = _('Please Configure Clinical Procedure Consumable Item in ')
- msg += '''<b><a href='#Form/Healthcare Settings'>Healthcare Settings</a></b>'''
+ msg += '''<b><a href='/app/Form/Healthcare Settings'>Healthcare Settings</a></b>'''
frappe.throw(msg, title=_('Missing Configuration'))
clinical_procedures_to_invoice.append({
@@ -324,7 +324,7 @@
service_item_label = _('Inpatient Visit Charge Item')
msg = _(('Please Configure {0} in ').format(service_item_label) \
- + '''<b><a href='#Form/Healthcare Settings'>Healthcare Settings</a></b>''')
+ + '''<b><a href='/app/Form/Healthcare Settings'>Healthcare Settings</a></b>''')
frappe.throw(msg, title=_('Missing Configuration'))
@@ -334,7 +334,7 @@
charge_name = _('Inpatient Visit Charge')
msg = _(('Please Configure {0} for Healthcare Practitioner').format(charge_name) \
- + ''' <b><a href='#Form/Healthcare Practitioner/{0}'>{0}</a></b>'''.format(practitioner))
+ + ''' <b><a href='/app/Form/Healthcare Practitioner/{0}'>{0}</a></b>'''.format(practitioner))
frappe.throw(msg, title=_('Missing Configuration'))
@@ -654,6 +654,6 @@
><div class='col-md-12 col-sm-12'>" \
+ section_html + html +'</div></div>'
if doc_html:
- doc_html = "<div class='small'><div class='col-md-12 text-right'><a class='btn btn-default btn-xs' href='#Form/%s/%s'></a></div>" %(doctype, docname) + doc_html + '</div>'
+ doc_html = "<div class='small'><div class='col-md-12 text-right'><a class='btn btn-default btn-xs' href='/app/Form/%s/%s'></a></div>" %(doctype, docname) + doc_html + '</div>'
return {'html': doc_html}
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 1e3bb6a..b0de3a0 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -10,7 +10,7 @@
app_email = "info@erpnext.com"
app_license = "GNU General Public License (v3)"
source_link = "https://github.com/frappe/erpnext"
-app_logo_url = '/assets/erpnext/images/erp-icon.svg'
+app_logo_url = "/assets/erpnext/images/erpnext-logo.svg"
develop_version = '13.x.x-develop'
@@ -46,6 +46,7 @@
get_help_messages = "erpnext.utilities.activation.get_help_messages"
leaderboards = "erpnext.startup.leaderboard.get_leaderboards"
filters_config = "erpnext.startup.filters.get_filters_config"
+additional_print_settings = "erpnext.controllers.print_settings.get_print_settings"
on_session_creation = [
"erpnext.portal.utils.create_customer_or_supplier",
@@ -78,7 +79,7 @@
website_context = {
"favicon": "/assets/erpnext/images/favicon.png",
- "splash_image": "/assets/erpnext/images/erp-icon.svg"
+ "splash_image": "/assets/erpnext/images/erpnext-logo.svg"
}
website_route_rules = [
diff --git a/erpnext/hr/desk_page/hr/hr.json b/erpnext/hr/desk_page/hr/hr.json
index 895cf72..217b94a 100644
--- a/erpnext/hr/desk_page/hr/hr.json
+++ b/erpnext/hr/desk_page/hr/hr.json
@@ -22,6 +22,11 @@
},
{
"hidden": 0,
+ "label": "Payroll",
+ "links": "[\n {\n \"label\": \"Salary Structure\",\n \"name\": \"Salary Structure\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Structure\",\n \"Employee\"\n ],\n \"label\": \"Salary Structure Assignment\",\n \"name\": \"Salary Structure Assignment\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Entry\",\n \"name\": \"Payroll Entry\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Slip\",\n \"name\": \"Salary Slip\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Payroll Period\",\n \"name\": \"Payroll Period\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Income Tax Slab\",\n \"name\": \"Income Tax Slab\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Salary Component\",\n \"name\": \"Salary Component\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Additional Salary\",\n \"name\": \"Additional Salary\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Retention Bonus\",\n \"name\": \"Retention Bonus\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Incentive\",\n \"name\": \"Employee Incentive\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Salary Slip\"\n ],\n \"doctype\": \"Salary Slip\",\n \"is_query_report\": true,\n \"label\": \"Salary Register\",\n \"name\": \"Salary Register\",\n \"type\": \"report\"\n }\n]"
+ },
+ {
+ "hidden": 0,
"label": "Attendance",
"links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Attendance Tool\",\n \"name\": \"Employee Attendance Tool\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance\",\n \"name\": \"Attendance\",\n \"onboard\": 1,\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Attendance Request\",\n \"name\": \"Attendance Request\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Upload Attendance\",\n \"name\": \"Upload Attendance\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"hide_count\": true,\n \"label\": \"Employee Checkin\",\n \"name\": \"Employee Checkin\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Attendance\"\n ],\n \"doctype\": \"Attendance\",\n \"is_query_report\": true,\n \"label\": \"Monthly Attendance Sheet\",\n \"name\": \"Monthly Attendance Sheet\",\n \"type\": \"report\"\n }\n]"
},
@@ -47,6 +52,11 @@
},
{
"hidden": 0,
+ "label": "Loans",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Loan Application\",\n \"name\": \"Loan Application\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan\",\n \"name\": \"Loan\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Loan Type\",\n \"name\": \"Loan Type\",\n \"type\": \"doctype\"\n }\n]"
+ },
+ {
+ "hidden": 0,
"label": "Training",
"links": "[\n {\n \"label\": \"Training Program\",\n \"name\": \"Training Program\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Event\",\n \"name\": \"Training Event\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Result\",\n \"name\": \"Training Result\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Training Feedback\",\n \"name\": \"Training Feedback\",\n \"type\": \"doctype\"\n }\n]"
},
@@ -59,13 +69,18 @@
"hidden": 0,
"label": "Performance",
"links": "[\n {\n \"label\": \"Appraisal\",\n \"name\": \"Appraisal\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Appraisal Template\",\n \"name\": \"Appraisal Template\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Rule\",\n \"name\": \"Energy Point Rule\",\n \"type\": \"doctype\"\n },\n {\n \"label\": \"Energy Point Log\",\n \"name\": \"Energy Point Log\",\n \"type\": \"doctype\"\n }\n]"
+ },
+ {
+ "hidden": 0,
+ "label": "Employee Tax and Benefits",
+ "links": "[\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Declaration\",\n \"name\": \"Employee Tax Exemption Declaration\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Proof Submission\",\n \"name\": \"Employee Tax Exemption Proof Submission\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\",\n \"Payroll Period\"\n ],\n \"label\": \"Employee Other Income\",\n \"name\": \"Employee Other Income\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Application\",\n \"name\": \"Employee Benefit Application\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Benefit Claim\",\n \"name\": \"Employee Benefit Claim\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Category\",\n \"name\": \"Employee Tax Exemption Category\",\n \"type\": \"doctype\"\n },\n {\n \"dependencies\": [\n \"Employee\"\n ],\n \"label\": \"Employee Tax Exemption Sub Category\",\n \"name\": \"Employee Tax Exemption Sub Category\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Modules",
"charts": [
{
- "chart_name": "Attendance Count",
- "label": "Attendance Count"
+ "chart_name": "Outgoing Salary",
+ "label": "Outgoing Salary"
}
],
"creation": "2020-03-02 15:48:58.322521",
@@ -75,6 +90,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "hr",
"idx": 0,
"is_standard": 1,
"label": "HR",
@@ -88,7 +104,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#cef6d1",
+ "color": "Green",
"format": "{} Active",
"label": "Employee",
"link_to": "Employee",
@@ -96,7 +112,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} Open",
"label": "Leave Application",
"link_to": "Leave Application",
diff --git a/erpnext/hr/doctype/employee/employee_list.js b/erpnext/hr/doctype/employee/employee_list.js
index 7a66d12..4483703 100644
--- a/erpnext/hr/doctype/employee/employee_list.js
+++ b/erpnext/hr/doctype/employee/employee_list.js
@@ -3,7 +3,7 @@
filters: [["status","=", "Active"]],
get_indicator: function(doc) {
var indicator = [__(doc.status), frappe.utils.guess_colour(doc.status), "status,=," + doc.status];
- indicator[1] = {"Active": "green", "Temporary Leave": "red", "Left": "darkgrey"}[doc.status];
+ indicator[1] = {"Active": "green", "Temporary Leave": "red", "Left": "gray"}[doc.status];
return indicator;
}
};
diff --git a/erpnext/hr/doctype/employee_transfer/employee_transfer.py b/erpnext/hr/doctype/employee_transfer/employee_transfer.py
index c730e02..37d616f 100644
--- a/erpnext/hr/doctype/employee_transfer/employee_transfer.py
+++ b/erpnext/hr/doctype/employee_transfer/employee_transfer.py
@@ -50,7 +50,7 @@
employee = frappe.get_doc("Employee", self.employee)
if self.create_new_employee_id:
if self.new_employee_id:
- frappe.throw(_("Please delete the Employee <a href='#Form/Employee/{0}'>{0}</a>\
+ frappe.throw(_("Please delete the Employee <a href='/app/Form/Employee/{0}'>{0}</a>\
to cancel this document").format(self.new_employee_id))
#mark the employee as active
employee.status = "Active"
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation.py b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
index a09cd2e..5e3822e 100755
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation.py
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation.py
@@ -92,7 +92,7 @@
frappe.msgprint(_("{0} already allocated for Employee {1} for period {2} to {3}")
.format(self.leave_type, self.employee, formatdate(self.from_date), formatdate(self.to_date)))
- frappe.throw(_('Reference') + ': <a href="#Form/Leave Allocation/{0}">{0}</a>'
+ frappe.throw(_('Reference') + ': <a href="/app/Form/Leave Allocation/{0}">{0}</a>'
.format(leave_allocation[0][0]), OverlapError)
def validate_back_dated_allocation(self):
diff --git a/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js b/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js
index 93f7b83..3ab176f 100644
--- a/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js
+++ b/erpnext/hr/doctype/leave_allocation/leave_allocation_list.js
@@ -5,7 +5,7 @@
frappe.listview_settings['Leave Allocation'] = {
get_indicator: function(doc) {
if(doc.status==="Expired") {
- return [__("Expired"), "darkgrey", "expired, =, 1"];
+ return [__("Expired"), "gray", "expired, =, 1"];
}
},
};
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index d62e418..9ccb915 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -75,7 +75,8 @@
frm.dashboard.add_section(
frappe.render_template('leave_application_dashboard', {
data: leave_details
- })
+ }),
+ __("Allocated Leaves")
);
frm.dashboard.show();
let allowed_leave_types = Object.keys(leave_details);
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 4f3e462..132c3bd 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -245,7 +245,7 @@
def throw_overlap_error(self, d):
msg = _("Employee {0} has already applied for {1} between {2} and {3} : ").format(self.employee,
d['leave_type'], formatdate(d['from_date']), formatdate(d['to_date'])) \
- + """ <b><a href="#Form/Leave Application/{0}">{0}</a></b>""".format(d["name"])
+ + """ <b><a href="/app/Form/Leave Application/{0}">{0}</a></b>""".format(d["name"])
frappe.throw(msg, OverlapError)
def get_total_leaves_on_half_day(self):
diff --git a/erpnext/hr/doctype/leave_application/leave_application_dashboard.html b/erpnext/hr/doctype/leave_application/leave_application_dashboard.html
index d30e3b9..6324b04 100644
--- a/erpnext/hr/doctype/leave_application/leave_application_dashboard.html
+++ b/erpnext/hr/doctype/leave_application/leave_application_dashboard.html
@@ -1,6 +1,5 @@
{% if not jQuery.isEmptyObject(data) %}
-<h5 style="margin-top: 20px;"> {{ __("Allocated Leaves") }} </h5>
<table class="table table-bordered small">
<thead>
<tr>
diff --git a/erpnext/hr/doctype/shift_request/shift_request.py b/erpnext/hr/doctype/shift_request/shift_request.py
index 1c2801b..473193d 100644
--- a/erpnext/hr/doctype/shift_request/shift_request.py
+++ b/erpnext/hr/doctype/shift_request/shift_request.py
@@ -87,5 +87,5 @@
def throw_overlap_error(self, d):
msg = _("Employee {0} has already applied for {1} between {2} and {3} : ").format(self.employee,
d['shift_type'], formatdate(d['from_date']), formatdate(d['to_date'])) \
- + """ <b><a href="#Form/Shift Request/{0}">{0}</a></b>""".format(d["name"])
+ + """ <b><a href="/app/Form/Shift Request/{0}">{0}</a></b>""".format(d["name"])
frappe.throw(msg, OverlapError)
\ No newline at end of file
diff --git a/erpnext/hr/page/team_updates/team_updates.js b/erpnext/hr/page/team_updates/team_updates.js
index da1f531..29780b8 100644
--- a/erpnext/hr/page/team_updates/team_updates.js
+++ b/erpnext/hr/page/team_updates/team_updates.js
@@ -41,7 +41,7 @@
me.add_row(d);
});
} else {
- frappe.show_alert({message:__('No more updates'), indicator:'darkgrey'});
+ frappe.show_alert({message:__('No more updates'), indicator:'gray'});
me.more.parent().addClass('hidden');
}
}
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index d700e7f..e2aa7a4 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -211,7 +211,7 @@
def throw_overlap_error(doc, exists_for, overlap_doc, from_date, to_date):
msg = _("A {0} exists between {1} and {2} (").format(doc.doctype,
formatdate(from_date), formatdate(to_date)) \
- + """ <b><a href="#Form/{0}/{1}">{1}</a></b>""".format(doc.doctype, overlap_doc) \
+ + """ <b><a href="/app/Form/{0}/{1}">{1}</a></b>""".format(doc.doctype, overlap_doc) \
+ _(") for {0}").format(exists_for)
frappe.throw(msg)
diff --git a/erpnext/loan_management/desk_page/loan/loan.json b/erpnext/loan_management/desk_page/loan/loan.json
index fc59c19..7f59348 100644
--- a/erpnext/loan_management/desk_page/loan/loan.json
+++ b/erpnext/loan_management/desk_page/loan/loan.json
@@ -35,6 +35,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "loan",
"idx": 0,
"is_standard": 1,
"label": "Loan",
@@ -47,7 +48,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#ffe8cd",
+ "color": "Green",
"format": "{} Open",
"label": "Loan Application",
"link_to": "Loan Application",
diff --git a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
index 8d11294..3dd86a3 100644
--- a/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
+++ b/erpnext/manufacturing/desk_page/manufacturing/manufacturing.json
@@ -44,10 +44,11 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "organization",
"idx": 0,
"is_standard": 1,
"label": "Manufacturing",
- "modified": "2020-05-28 13:54:02.048419",
+ "modified": "2020-06-30 18:40:04.454826",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing",
@@ -58,7 +59,7 @@
"restrict_to_domain": "Manufacturing",
"shortcuts": [
{
- "color": "#cef6d1",
+ "color": "Green",
"format": "{} Active",
"label": "Item",
"link_to": "Item",
@@ -67,7 +68,7 @@
"type": "DocType"
},
{
- "color": "#cef6d1",
+ "color": "Green",
"format": "{} Active",
"label": "BOM",
"link_to": "BOM",
@@ -76,7 +77,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} Open",
"label": "Work Order",
"link_to": "Work Order",
@@ -85,7 +86,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} Open",
"label": "Production Plan",
"link_to": "Production Plan",
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 1c4b7a1..55f7a1b 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -134,7 +134,7 @@
frm.set_intro(__('This is a Template BOM and will be used to make the work order for {0} of the item {1}',
[
`<a class="variants-intro">variants</a>`,
- `<a href="#Form/Item/${frm.doc.item}">${frm.doc.item}</a>`,
+ `<a href="/desk/Form/Item/${frm.doc.item}">${frm.doc.item}</a>`,
]), true);
frm.$wrapper.find(".variants-intro").on("click", () => {
diff --git a/erpnext/manufacturing/doctype/bom/bom_item_preview.html b/erpnext/manufacturing/doctype/bom/bom_item_preview.html
index c782f7b..6cd5f8c 100644
--- a/erpnext/manufacturing/doctype/bom/bom_item_preview.html
+++ b/erpnext/manufacturing/doctype/bom/bom_item_preview.html
@@ -12,11 +12,11 @@
<hr style="margin: 15px -15px;">
<p>
{% if data.value %}
- <a style="margin-right: 7px; margin-bottom: 7px" class="btn btn-default btn-xs" href="#Form/BOM/{{ data.value }}">
+ <a style="margin-right: 7px; margin-bottom: 7px" class="btn btn-default btn-xs" href="/app/Form/BOM/{{ data.value }}">
{{ __("Open BOM {0}", [data.value.bold()]) }}</a>
{% endif %}
{% if data.item_code %}
- <a class="btn btn-default btn-xs" href="#Form/Item/{{ data.item_code }}">
+ <a class="btn btn-default btn-xs" href="/app/Form/Item/{{ data.item_code }}">
{{ __("Open Item {0}", [data.item_code.bold()]) }}</a>
{% endif %}
</p>
diff --git a/erpnext/manufacturing/doctype/bom/bom_list.js b/erpnext/manufacturing/doctype/bom/bom_list.js
index 94cb466..4b5887f 100644
--- a/erpnext/manufacturing/doctype/bom/bom_list.js
+++ b/erpnext/manufacturing/doctype/bom/bom_list.js
@@ -8,7 +8,7 @@
} else if(doc.is_active) {
return [__("Active"), "blue", "is_active,=,Yes"];
} else if(!doc.is_active) {
- return [__("Not active"), "darkgrey", "is_active,=,No"];
+ return [__("Not active"), "gray", "is_active,=,No"];
}
}
};
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 3833e86..8f9dd05 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -319,7 +319,7 @@
frappe.flags.mute_messages = False
if wo_list:
- wo_list = ["""<a href="#Form/Work Order/%s" target="_blank">%s</a>""" % \
+ wo_list = ["""<a href="/app/Form/Work Order/%s" target="_blank">%s</a>""" % \
(p, p) for p in wo_list]
msgprint(_("{0} created").format(comma_and(wo_list)))
else :
@@ -423,7 +423,7 @@
frappe.flags.mute_messages = False
if material_request_list:
- material_request_list = ["""<a href="#Form/Material Request/{0}">{1}</a>""".format(m.name, m.name) \
+ material_request_list = ["""<a href="/app/Form/Material Request/{0}">{1}</a>""".format(m.name, m.name) \
for m in material_request_list]
msgprint(_("{0} created").format(comma_and(material_request_list)))
else :
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js
index 165b66f..c2e3e6d 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan_list.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan_list.js
@@ -1,16 +1,16 @@
frappe.listview_settings['Production Plan'] = {
add_fields: ["status"],
filters: [["status", "!=", "Closed"]],
- get_indicator: function(doc) {
- if(doc.status==="Submitted") {
+ get_indicator: function (doc) {
+ if (doc.status === "Submitted") {
return [__("Not Started"), "orange", "status,=,Submitted"];
} else {
return [__(doc.status), {
"Draft": "red",
"In Process": "orange",
"Completed": "green",
- "Material Requested": "darkgrey",
- "Cancelled": "darkgrey",
+ "Material Requested": "yellow",
+ "Cancelled": "gray",
"Closed": "grey"
}[doc.status], "status,=," + doc.status];
}
diff --git a/erpnext/manufacturing/doctype/work_order/work_order_list.js b/erpnext/manufacturing/doctype/work_order/work_order_list.js
index 8d18395..81c23bb 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order_list.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order_list.js
@@ -12,7 +12,7 @@
"Not Started": "red",
"In Process": "orange",
"Completed": "green",
- "Cancelled": "darkgrey"
+ "Cancelled": "gray"
}[doc.status], "status,=," + doc.status];
}
}
diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json
index ebe6194..24d655a 100644
--- a/erpnext/non_profit/desk_page/non_profit/non_profit.json
+++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json
@@ -39,10 +39,12 @@
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
+ "hide_custom": 0,
+ "icon": "non-profit",
"idx": 0,
"is_standard": 1,
"label": "Non Profit",
- "modified": "2020-04-13 13:41:52.373705",
+ "modified": "2020-06-30 18:35:52.770917",
"modified_by": "Administrator",
"module": "Non Profit",
"name": "Non Profit",
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 86ac613..e80bd64 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -730,6 +730,7 @@
erpnext.patches.v13_0.rename_issue_doctype_fields
erpnext.patches.v13_0.change_default_pos_print_format
erpnext.patches.v13_0.set_youtube_video_id
+erpnext.patches.v13_0.set_app_name
erpnext.patches.v13_0.print_uom_after_quantity_patch
erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail
diff --git a/erpnext/patches/v13_0/set_app_name.py b/erpnext/patches/v13_0/set_app_name.py
new file mode 100644
index 0000000..0c78b65
--- /dev/null
+++ b/erpnext/patches/v13_0/set_app_name.py
@@ -0,0 +1,8 @@
+import frappe
+from frappe import _
+
+def execute():
+ frappe.reload_doctype("System Settings")
+ settings = frappe.get_doc("System Settings")
+ settings.app_name = _("ERPNext")
+ settings.save()
\ No newline at end of file
diff --git a/erpnext/payroll/desk_page/payroll/payroll.json b/erpnext/payroll/desk_page/payroll/payroll.json
index 285e3b3..8fe8c44 100644
--- a/erpnext/payroll/desk_page/payroll/payroll.json
+++ b/erpnext/payroll/desk_page/payroll/payroll.json
@@ -35,6 +35,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "money-coins-1",
"idx": 0,
"is_standard": 1,
"label": "Payroll",
diff --git a/erpnext/payroll/doctype/payroll_period/payroll_period.py b/erpnext/payroll/doctype/payroll_period/payroll_period.py
index d7893d0..1c8cc53 100644
--- a/erpnext/payroll/doctype/payroll_period/payroll_period.py
+++ b/erpnext/payroll/doctype/payroll_period/payroll_period.py
@@ -41,7 +41,7 @@
if overlap_doc:
msg = _("A {0} exists between {1} and {2} (").format(self.doctype,
formatdate(self.start_date), formatdate(self.end_date)) \
- + """ <b><a href="#Form/{0}/{1}">{1}</a></b>""".format(self.doctype, overlap_doc[0].name) \
+ + """ <b><a href="/app/Form/{0}/{1}">{1}</a></b>""".format(self.doctype, overlap_doc[0].name) \
+ _(") for {0}").format(self.company)
frappe.throw(msg)
diff --git a/erpnext/projects/desk_page/projects/projects.json b/erpnext/projects/desk_page/projects/projects.json
index e24cf30..3756c5b 100644
--- a/erpnext/projects/desk_page/projects/projects.json
+++ b/erpnext/projects/desk_page/projects/projects.json
@@ -30,10 +30,11 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "project",
"idx": 0,
"is_standard": 1,
"label": "Projects",
- "modified": "2020-05-28 13:38:19.934937",
+ "modified": "2020-06-30 18:38:40.130763",
"modified_by": "Administrator",
"module": "Projects",
"name": "Projects",
@@ -42,7 +43,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#cef6d1",
+ "color": "Blue",
"format": "{} Assigned",
"label": "Task",
"link_to": "Task",
@@ -50,7 +51,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Blue",
"format": "{} Open",
"label": "Project",
"link_to": "Project",
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 5bbd29c..24d0dc1 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -26,7 +26,7 @@
self.update_costing()
- def before_print(self):
+ def before_print(self, settings=None):
self.onload()
diff --git a/erpnext/projects/doctype/task/task_list.js b/erpnext/projects/doctype/task/task_list.js
index 941fe97..7c62031 100644
--- a/erpnext/projects/doctype/task/task_list.js
+++ b/erpnext/projects/doctype/task/task_list.js
@@ -26,7 +26,7 @@
},
gantt_custom_popup_html: function(ganttobj, task) {
var html = `<h5><a style="text-decoration:underline"\
- href="#Form/Task/${ganttobj.id}""> ${ganttobj.name} </a></h5>`;
+ href="/desk/Form/Task/${ganttobj.id}""> ${ganttobj.name} </a></h5>`;
if(task.project) html += `<p>Project: ${task.project}</p>`;
html += `<p>Progress: ${ganttobj.progress}</p>`;
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 2f15cbc..d30bc8c 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -2,7 +2,8 @@
"css/erpnext.css": [
"public/less/erpnext.less",
"public/less/hub.less",
- "public/less/call_popup.less"
+ "public/less/call_popup.less",
+ "public/scss/point-of-sale.scss"
],
"css/marketplace.css": [
"public/less/hub.less"
@@ -27,16 +28,6 @@
"public/js/payment/payments.js",
"public/js/controllers/taxes_and_totals.js",
"public/js/controllers/transaction.js",
- "public/js/pos/pos.html",
- "public/js/pos/pos_bill_item.html",
- "public/js/pos/pos_bill_item_new.html",
- "public/js/pos/pos_selected_item.html",
- "public/js/pos/pos_item.html",
- "public/js/pos/pos_tax_row.html",
- "public/js/pos/customer_toolbar.html",
- "public/js/pos/pos_invoice_list.html",
- "public/js/payment/pos_payment.html",
- "public/js/payment/payment_details.html",
"public/js/templates/item_selector.html",
"public/js/templates/employees_to_mark_attendance.html",
"public/js/utils/item_selector.js",
@@ -56,5 +47,15 @@
"stock/dashboard/item_dashboard.html",
"stock/dashboard/item_dashboard_list.html",
"stock/dashboard/item_dashboard.js"
+ ],
+ "js/point-of-sale.min.js": [
+ "selling/page/point_of_sale/pos_item_selector.js",
+ "selling/page/point_of_sale/pos_item_cart.js",
+ "selling/page/point_of_sale/pos_item_details.js",
+ "selling/page/point_of_sale/pos_number_pad.js",
+ "selling/page/point_of_sale/pos_payment.js",
+ "selling/page/point_of_sale/pos_past_order_list.js",
+ "selling/page/point_of_sale/pos_past_order_summary.js",
+ "selling/page/point_of_sale/pos_controller.js"
]
}
diff --git a/erpnext/public/css/pos.css b/erpnext/public/css/pos.css
deleted file mode 100644
index 47f5771..0000000
--- a/erpnext/public/css/pos.css
+++ /dev/null
@@ -1,217 +0,0 @@
-[data-route="point-of-sale"] .layout-main-section { border: none; font-size: 12px; }
-[data-route="point-of-sale"] .layout-main-section-wrapper { margin-bottom: 0; }
-[data-route="point-of-sale"] .pos-items-wrapper { max-height: calc(100vh - 210px); }
-:root { --border-color: #d1d8dd; --text-color: #8d99a6; --primary: #5e64ff; }
-[data-route="point-of-sale"] .flex { display: flex; }
-[data-route="point-of-sale"] .grid { display: grid; }
-[data-route="point-of-sale"] .absolute { position: absolute; }
-[data-route="point-of-sale"] .relative { position: relative; }
-[data-route="point-of-sale"] .abs-center { top: 50%; left: 50%; transform: translate(-50%, -50%); }
-[data-route="point-of-sale"] .inline { display: inline; }
-[data-route="point-of-sale"] .float-right { float: right; }
-[data-route="point-of-sale"] .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
-[data-route="point-of-sale"] .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
-[data-route="point-of-sale"] .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
-[data-route="point-of-sale"] .grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
-[data-route="point-of-sale"] .grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
-[data-route="point-of-sale"] .grid-cols-10 { grid-template-columns: repeat(10, minmax(0, 1fr)); }
-[data-route="point-of-sale"] .gap-2 { grid-gap: 0.5rem; gap: 0.5rem; }
-[data-route="point-of-sale"] .gap-4 { grid-gap: 1rem; gap: 1rem; }
-[data-route="point-of-sale"] .gap-6 { grid-gap: 1.25rem; gap: 1.25rem; }
-[data-route="point-of-sale"] .gap-8 { grid-gap: 1.5rem; gap: 1.5rem; }
-[data-route="point-of-sale"] .row-gap-2 { grid-row-gap: 0.5rem; row-gap: 0.5rem; }
-[data-route="point-of-sale"] .col-gap-4 { grid-column-gap: 1rem; column-gap: 1rem; }
-[data-route="point-of-sale"] .col-span-2 { grid-column: span 2 / span 2; }
-[data-route="point-of-sale"] .col-span-3 { grid-column: span 3 / span 3; }
-[data-route="point-of-sale"] .col-span-4 { grid-column: span 4 / span 4; }
-[data-route="point-of-sale"] .col-span-6 { grid-column: span 6 / span 6; }
-[data-route="point-of-sale"] .col-span-10 { grid-column: span 10 / span 10; }
-[data-route="point-of-sale"] .row-span-2 { grid-row: span 2 / span 2; }
-[data-route="point-of-sale"] .grid-auto-row { grid-auto-rows: 5.5rem; }
-[data-route="point-of-sale"] .d-none { display: none; }
-[data-route="point-of-sale"] .flex-wrap { flex-wrap: wrap; }
-[data-route="point-of-sale"] .flex-row { flex-direction: row; }
-[data-route="point-of-sale"] .flex-col { flex-direction: column; }
-[data-route="point-of-sale"] .flex-row-rev { flex-direction: row-reverse; }
-[data-route="point-of-sale"] .flex-col-rev { flex-direction: column-reverse; }
-[data-route="point-of-sale"] .flex-1 { flex: 1 1 0%; }
-[data-route="point-of-sale"] .items-center { align-items: center; }
-[data-route="point-of-sale"] .items-end { align-items: flex-end; }
-[data-route="point-of-sale"] .f-grow-1 { flex-grow: 1; }
-[data-route="point-of-sale"] .f-grow-2 { flex-grow: 2; }
-[data-route="point-of-sale"] .f-grow-3 { flex-grow: 3; }
-[data-route="point-of-sale"] .f-grow-4 { flex-grow: 4; }
-[data-route="point-of-sale"] .f-shrink-0 { flex-shrink: 0; }
-[data-route="point-of-sale"] .f-shrink-1 { flex-shrink: 1; }
-[data-route="point-of-sale"] .f-shrink-2 { flex-shrink: 2; }
-[data-route="point-of-sale"] .f-shrink-3 { flex-shrink: 3; }
-[data-route="point-of-sale"] .shadow { box-shadow: 0 0px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 2px 0 rgba(0, 0, 0, 0.06); }
-[data-route="point-of-sale"] .shadow-sm { box-shadow: 0 0.5px 3px 0 rgba(0, 0, 0, 0.125); }
-[data-route="point-of-sale"] .shadow-inner { box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.1); }
-[data-route="point-of-sale"] .rounded { border-radius: 0.3rem; }
-[data-route="point-of-sale"] .rounded-b { border-bottom-left-radius: 0.3rem; border-bottom-right-radius: 0.3rem; }
-[data-route="point-of-sale"] .p-8 { padding: 2rem; }
-[data-route="point-of-sale"] .p-16 { padding: 4rem; }
-[data-route="point-of-sale"] .p-32 { padding: 8rem; }
-[data-route="point-of-sale"] .p-6 { padding: 1.5rem; }
-[data-route="point-of-sale"] .p-4 { padding: 1rem; }
-[data-route="point-of-sale"] .p-3 { padding: 0.75rem; }
-[data-route="point-of-sale"] .p-2 { padding: 0.5rem; }
-[data-route="point-of-sale"] .m-8 { margin: 2rem; }
-[data-route="point-of-sale"] .p-1 { padding: 0.25rem; }
-[data-route="point-of-sale"] .pr-0 { padding-right: 0rem; }
-[data-route="point-of-sale"] .pl-0 { padding-left: 0rem; }
-[data-route="point-of-sale"] .pt-0 { padding-top: 0rem; }
-[data-route="point-of-sale"] .pb-0 { padding-bottom: 0rem; }
-[data-route="point-of-sale"] .mr-0 { margin-right: 0rem; }
-[data-route="point-of-sale"] .ml-0 { margin-left: 0rem; }
-[data-route="point-of-sale"] .mt-0 { margin-top: 0rem; }
-[data-route="point-of-sale"] .mb-0 { margin-bottom: 0rem; }
-[data-route="point-of-sale"] .pr-2 { padding-right: 0.5rem; }
-[data-route="point-of-sale"] .pl-2 { padding-left: 0.5rem; }
-[data-route="point-of-sale"] .pt-2 { padding-top: 0.5rem; }
-[data-route="point-of-sale"] .pb-2 { padding-bottom: 0.5rem; }
-[data-route="point-of-sale"] .pr-3 { padding-right: 0.75rem; }
-[data-route="point-of-sale"] .pl-3 { padding-left: 0.75rem; }
-[data-route="point-of-sale"] .pt-3 { padding-top: 0.75rem; }
-[data-route="point-of-sale"] .pb-3 { padding-bottom: 0.75rem; }
-[data-route="point-of-sale"] .pr-4 { padding-right: 1rem; }
-[data-route="point-of-sale"] .pl-4 { padding-left: 1rem; }
-[data-route="point-of-sale"] .pt-4 { padding-top: 1rem; }
-[data-route="point-of-sale"] .pb-4 { padding-bottom: 1rem; }
-[data-route="point-of-sale"] .mr-4 { margin-right: 1rem; }
-[data-route="point-of-sale"] .ml-4 { margin-left: 1rem; }
-[data-route="point-of-sale"] .mt-4 { margin-top: 1rem; }
-[data-route="point-of-sale"] .mb-4 { margin-bottom: 1rem; }
-[data-route="point-of-sale"] .mr-2 { margin-right: 0.5rem; }
-[data-route="point-of-sale"] .ml-2 { margin-left: 0.5rem; }
-[data-route="point-of-sale"] .mt-2 { margin-top: 0.5rem; }
-[data-route="point-of-sale"] .mb-2 { margin-bottom: 0.5rem; }
-[data-route="point-of-sale"] .mr-1 { margin-right: 0.25rem; }
-[data-route="point-of-sale"] .ml-1 { margin-left: 0.25rem; }
-[data-route="point-of-sale"] .mt-1 { margin-top: 0.25rem; }
-[data-route="point-of-sale"] .mb-1 { margin-bottom: 0.25rem; }
-[data-route="point-of-sale"] .mr-auto { margin-right: auto; }
-[data-route="point-of-sale"] .ml-auto { margin-left: auto; }
-[data-route="point-of-sale"] .mt-auto { margin-top: auto; }
-[data-route="point-of-sale"] .mb-auto { margin-bottom: auto; }
-[data-route="point-of-sale"] .pr-6 { padding-right: 1.5rem; }
-[data-route="point-of-sale"] .pl-6 { padding-left: 1.5rem; }
-[data-route="point-of-sale"] .pt-6 { padding-top: 1.5rem; }
-[data-route="point-of-sale"] .pb-6 { padding-bottom: 1.5rem; }
-[data-route="point-of-sale"] .mr-6 { margin-right: 1.5rem; }
-[data-route="point-of-sale"] .ml-6 { margin-left: 1.5rem; }
-[data-route="point-of-sale"] .mt-6 { margin-top: 1.5rem; }
-[data-route="point-of-sale"] .mb-6 { margin-bottom: 1.5rem; }
-[data-route="point-of-sale"] .mr-8 { margin-right: 2rem; }
-[data-route="point-of-sale"] .ml-8 { margin-left: 2rem; }
-[data-route="point-of-sale"] .mt-8 { margin-top: 2rem; }
-[data-route="point-of-sale"] .mb-8 { margin-bottom: 2rem; }
-[data-route="point-of-sale"] .pr-8 { padding-right: 2rem; }
-[data-route="point-of-sale"] .pl-8 { padding-left: 2rem; }
-[data-route="point-of-sale"] .pt-8 { padding-top: 2rem; }
-[data-route="point-of-sale"] .pb-8 { padding-bottom: 2rem; }
-[data-route="point-of-sale"] .pr-16 { padding-right: 4rem; }
-[data-route="point-of-sale"] .pl-16 { padding-left: 4rem; }
-[data-route="point-of-sale"] .pt-16 { padding-top: 4rem; }
-[data-route="point-of-sale"] .pb-16 { padding-bottom: 4rem; }
-[data-route="point-of-sale"] .w-full { width: 100%; }
-[data-route="point-of-sale"] .h-full { height: 100%; }
-[data-route="point-of-sale"] .w-quarter { width: 25%; }
-[data-route="point-of-sale"] .w-half { width: 50%; }
-[data-route="point-of-sale"] .w-66 { width: 66.66%; }
-[data-route="point-of-sale"] .w-33 { width: 33.33%; }
-[data-route="point-of-sale"] .w-60 { width: 60%; }
-[data-route="point-of-sale"] .w-40 { width: 40%; }
-[data-route="point-of-sale"] .w-fit { width: fit-content; }
-[data-route="point-of-sale"] .w-6 { width: 2rem; }
-[data-route="point-of-sale"] .h-6 { min-height: 2rem; height: 2rem; }
-[data-route="point-of-sale"] .w-8 { width: 2.5rem; }
-[data-route="point-of-sale"] .h-8 { min-height: 2.5rem; height: 2.5rem; }
-[data-route="point-of-sale"] .w-10 { width: 3rem; }
-[data-route="point-of-sale"] .h-10 { min-height:3rem; height: 3rem; }
-[data-route="point-of-sale"] .h-12 { min-height: 3.3rem; height: 3.3rem; }
-[data-route="point-of-sale"] .w-12 { width: 3.3rem; }
-[data-route="point-of-sale"] .h-14 { min-height: 4.2rem; height: 4.2rem; }
-[data-route="point-of-sale"] .h-16 { min-height: 4.6rem; height: 4.6rem; }
-[data-route="point-of-sale"] .h-18 { min-height: 5rem; height: 5rem; }
-[data-route="point-of-sale"] .w-18 { width: 5.4rem; }
-[data-route="point-of-sale"] .w-24 { width: 7.2rem; }
-[data-route="point-of-sale"] .w-26 { width: 8.4rem; }
-[data-route="point-of-sale"] .h-24 { min-height: 7.2rem; height: 7.2rem; }
-[data-route="point-of-sale"] .h-32 { min-height: 9.6rem; height: 9.6rem; }
-[data-route="point-of-sale"] .w-46 { width: 15rem; }
-[data-route="point-of-sale"] .h-46 { min-height:15rem; height: 15rem; }
-[data-route="point-of-sale"] .h-100 { height: 100vh; }
-[data-route="point-of-sale"] .mx-h-70 { max-height: 67rem; }
-[data-route="point-of-sale"] .border-grey-300 { border-color: #e2e8f0; }
-[data-route="point-of-sale"] .border-grey { border: 1px solid #d1d8dd; }
-[data-route="point-of-sale"] .border-white { border: 1px solid #fff; }
-[data-route="point-of-sale"] .border-b-grey { border-bottom: 1px solid #d1d8dd; }
-[data-route="point-of-sale"] .border-t-grey { border-top: 1px solid #d1d8dd; }
-[data-route="point-of-sale"] .border-r-grey { border-right: 1px solid #d1d8dd; }
-[data-route="point-of-sale"] .text-dark-grey { color: #5f5f5f; }
-[data-route="point-of-sale"] .text-grey { color: #8d99a6; }
-[data-route="point-of-sale"] .text-grey-100 { color: #d1d8dd; }
-[data-route="point-of-sale"] .text-grey-200 { color: #a0aec0; }
-[data-route="point-of-sale"] .bg-green-200 { background-color: #c6f6d5; }
-[data-route="point-of-sale"] .text-bold { font-weight: bold; }
-[data-route="point-of-sale"] .italic { font-style: italic; }
-[data-route="point-of-sale"] .font-weight-450 { font-weight: 450; }
-[data-route="point-of-sale"] .justify-around { justify-content: space-around; }
-[data-route="point-of-sale"] .justify-between { justify-content: space-between; }
-[data-route="point-of-sale"] .justify-center { justify-content: center; }
-[data-route="point-of-sale"] .justify-end { justify-content: flex-end; }
-[data-route="point-of-sale"] .bg-white { background-color: white; }
-[data-route="point-of-sale"] .bg-light-grey { background-color: #f0f4f7; }
-[data-route="point-of-sale"] .bg-grey-100 { background-color: #f7fafc; }
-[data-route="point-of-sale"] .bg-grey-200 { background-color: #edf2f7; }
-[data-route="point-of-sale"] .bg-grey { background-color: #f4f5f6; }
-[data-route="point-of-sale"] .text-center { text-align: center; }
-[data-route="point-of-sale"] .text-right { text-align: right; }
-[data-route="point-of-sale"] .text-sm { font-size: 1rem; }
-[data-route="point-of-sale"] .text-md-0 { font-size: 1.25rem; }
-[data-route="point-of-sale"] .text-md { font-size: 1.4rem; }
-[data-route="point-of-sale"] .text-lg { font-size: 1.6rem; }
-[data-route="point-of-sale"] .text-xl { font-size: 2.2rem; }
-[data-route="point-of-sale"] .text-2xl { font-size: 2.8rem; }
-[data-route="point-of-sale"] .text-2-5xl { font-size: 3rem; }
-[data-route="point-of-sale"] .text-3xl { font-size: 3.8rem; }
-[data-route="point-of-sale"] .text-6xl { font-size: 4.8rem; }
-[data-route="point-of-sale"] .line-through { text-decoration: line-through; }
-[data-route="point-of-sale"] .text-primary { color: #5e64ff; }
-[data-route="point-of-sale"] .text-white { color: #fff; }
-[data-route="point-of-sale"] .text-green-500 { color: #48bb78; }
-[data-route="point-of-sale"] .bg-primary { background-color: #5e64ff; }
-[data-route="point-of-sale"] .border-primary { border-color: #5e64ff; }
-[data-route="point-of-sale"] .text-danger { color: #e53e3e; }
-[data-route="point-of-sale"] .scroll-x { overflow-x: scroll;overflow-y: hidden; }
-[data-route="point-of-sale"] .scroll-y { overflow-y: scroll;overflow-x: hidden; }
-[data-route="point-of-sale"] .overflow-hidden { overflow: hidden; }
-[data-route="point-of-sale"] .whitespace-nowrap { white-space: nowrap; }
-[data-route="point-of-sale"] .sticky { position: sticky; top: -1px; }
-[data-route="point-of-sale"] .bg-white { background-color: #fff; }
-[data-route="point-of-sale"] .bg-selected { background-color: #fffdf4; }
-[data-route="point-of-sale"] .border-dashed { border-width:1px; border-style: dashed; }
-[data-route="point-of-sale"] .z-100 { z-index: 100; }
-
-[data-route="point-of-sale"] .frappe-control { margin: 0 !important; width: 100%; }
-[data-route="point-of-sale"] .form-control { font-size: 12px; }
-[data-route="point-of-sale"] .form-group { margin: 0 !important; }
-[data-route="point-of-sale"] .pointer { cursor: pointer; }
-[data-route="point-of-sale"] .no-select { user-select: none; }
-[data-route="point-of-sale"] .item-wrapper:hover { transform: scale(1.02, 1.02); }
-[data-route="point-of-sale"] .hover-underline:hover { text-decoration: underline; }
-[data-route="point-of-sale"] .item-wrapper { transition: scale 0.2s ease-in-out; }
-[data-route="point-of-sale"] .cart-items-section .cart-item-wrapper:not(:first-child) { border-top: none; }
-[data-route="point-of-sale"] .customer-transactions .invoice-wrapper:not(:first-child) { border-top: none; }
-
-[data-route="point-of-sale"] .payment-summary-wrapper:last-child { border-bottom: none; }
-[data-route="point-of-sale"] .item-summary-wrapper:last-child { border-bottom: none; }
-[data-route="point-of-sale"] .total-summary-wrapper:last-child { border-bottom: none; }
-[data-route="point-of-sale"] .invoices-container .invoice-wrapper:last-child { border-bottom: none; }
-[data-route="point-of-sale"] .new-btn { background-color: #5e64ff; color: white; border: none;}
-[data-route="point-of-sale"] .summary-btns:last-child { margin-right: 0px; }
-[data-route="point-of-sale"] ::-webkit-scrollbar { width: 1px }
-
-[data-route="point-of-sale"] .indicator.grey::before { background-color: #8d99a6; }
\ No newline at end of file
diff --git a/erpnext/public/images/erpnext-logo.svg b/erpnext/public/images/erpnext-logo.svg
new file mode 100644
index 0000000..a3ac3bb
--- /dev/null
+++ b/erpnext/public/images/erpnext-logo.svg
@@ -0,0 +1,5 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 12C0 5.37258 5.37258 0 12 0H88C94.6274 0 100 5.37258 100 12V88C100 94.6274 94.6274 100 88 100H12C5.37258 100 0 94.6274 0 88V12Z" fill="#0089FF"/>
+<path d="M65.7097 32.9462H67.3871V24H33V32.9462H43.9032H65.7097Z" fill="white"/>
+<path d="M43.9032 66.2151V53.914H65.7097V44.9677H43.9032H33V75.1613H67.6667V66.2151H43.9032Z" fill="white"/>
+</svg>
\ No newline at end of file
diff --git a/erpnext/public/images/erpnext_logo.svg b/erpnext/public/images/erpnext_logo.svg
new file mode 100644
index 0000000..af3a849
--- /dev/null
+++ b/erpnext/public/images/erpnext_logo.svg
@@ -0,0 +1,4 @@
+<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.45455 0H30.5454C33.5673 0 36 2.43272 36 5.45454V30.5455C36 33.5673 33.5673 36 30.5454 36H5.45455C2.43276 36 0 33.5673 0 30.5455V5.45454C0 2.43272 2.43276 0 5.45455 0Z" fill="#2996F1"/>
+ <path d="M12.277 8.99994C12.1637 8.99994 12.0532 9.01145 11.9465 9.03318C11.8398 9.0549 11.7368 9.08691 11.6389 9.12821C11.5899 9.14885 11.5423 9.17189 11.4959 9.19703C11.4031 9.24729 11.3158 9.30622 11.2351 9.37281C10.8717 9.67247 10.6406 10.1264 10.6406 10.6363V10.736V25.2641V25.3636C10.6406 26.2701 11.3704 26.9999 12.277 26.9999H23.7215C24.6281 26.9999 25.3579 26.2701 25.3579 25.3636V25.2641C25.3579 24.3575 24.6281 23.6277 23.7215 23.6277H14.0131V19.5519H21.2316C22.1381 19.5519 22.868 18.8221 22.868 17.9156V17.8161C22.868 16.9095 22.1381 16.1797 21.2316 16.1797H14.0131V12.3724H23.7215C24.6281 12.3724 25.3579 11.6426 25.3579 10.736V10.6363C25.3579 9.72976 24.6281 8.99994 23.7215 8.99994H12.277Z" fill="white"/>
+</svg>
\ No newline at end of file
diff --git a/erpnext/public/js/call_popup/call_popup.js b/erpnext/public/js/call_popup/call_popup.js
index aeb3b38..16e9cdb 100644
--- a/erpnext/public/js/call_popup/call_popup.js
+++ b/erpnext/public/js/call_popup/call_popup.js
@@ -85,7 +85,7 @@
<br>
<a
class="text-small text-muted"
- href="#Form/Call Log/${this.call_log.name}">
+ href="/desk/Form/Call Log/${this.call_log.name}">
${__('View call log')}
</a>
`,
@@ -167,7 +167,7 @@
const issue_field = this.dialog.get_field("last_issue");
issue_field.set_value(issue.subject);
issue_field.$wrapper.append(`
- <a class="text-medium" href="#List/Issue?customer=${issue.customer}">
+ <a class="text-medium" href="/desk/List/Issue?customer=${issue.customer}">
${__('View all issues from {0}', [issue.customer])}
</a>
`);
diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js
index 26e5ab8..38778e2 100644
--- a/erpnext/public/js/communication.js
+++ b/erpnext/public/js/communication.js
@@ -84,7 +84,7 @@
frm.reload_doc();
frappe.show_alert({
message: __("Opportunity {0} created",
- ['<a href="#Form/Opportunity/'+r.message+'">' + r.message + '</a>']),
+ ['<a href="/desk/Form/Opportunity/'+r.message+'">' + r.message + '</a>']),
indicator: 'green'
});
}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 3bc20f8..1c84e55 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -446,9 +446,10 @@
method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges",
args: {
"master_doctype": taxes_and_charges_field.options,
- "tax_template": me.frm.doc.taxes_and_charges,
+ "tax_template": me.frm.doc.taxes_and_charges || "",
"company": me.frm.doc.company
},
+ debounce: 2000,
callback: function(r) {
if(!r.exc && r.message) {
frappe.run_serially([
diff --git a/erpnext/public/js/education/assessment_result_tool.html b/erpnext/public/js/education/assessment_result_tool.html
index 9fc17f7..b591010 100644
--- a/erpnext/public/js/education/assessment_result_tool.html
+++ b/erpnext/public/js/education/assessment_result_tool.html
@@ -19,7 +19,7 @@
</thead>
<tbody>
{% for s in students %}
- <tr
+ <tr
{% if(s.assessment_details && s.docstatus && s.docstatus == 1) { %} class="text-muted" {% } %}
data-student="{{s.student}}">
@@ -29,7 +29,7 @@
<td>
<span data-student="{{s.student}}" data-criteria="{{c.assessment_criteria}}" class="student-result-grade badge" >
{% if(s.assessment_details) { %}
- {{s.assessment_details[c.assessment_criteria][1]}}
+ {{s.assessment_details[c.assessment_criteria][1]}}
{% } %}
</span>
<input type="number" class="student-result-data" style="width:70%; float:right;"
@@ -61,7 +61,7 @@
{% } %}
</span>
<span data-student="{{s.student}}" class="total-result-link" style="width: 10%; display:{% if(!s.assessment_details) { %}None{% } %}; float:right;">
- <a class="btn-open no-decoration" title="Open Link" href="#Form/Assessment Result/{% if(s.assessment_details) { %}{{s.name}}{% } %}">
+ <a class="btn-open no-decoration" title="Open Link" href="/app/Form/Assessment Result/{% if(s.assessment_details) { %}{{s.name}}{% } %}">
<i class="octicon octicon-arrow-right"></i>
</a>
</span>
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 459c01b..b2f7afe 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -57,18 +57,22 @@
});
});
- report.page.add_inner_button(__("Balance Sheet"), function() {
+ const views_menu = report.page.add_custom_button_group(__('Financial Statements'));
+
+ report.page.add_custom_menu_item(views_menu, __("Balance Sheet"), function() {
var filters = report.get_values();
frappe.set_route('query-report', 'Balance Sheet', {company: filters.company});
- }, __('Financial Statements'));
- report.page.add_inner_button(__("Profit and Loss"), function() {
+ });
+
+ report.page.add_custom_menu_item(views_menu, __("Profit and Loss"), function() {
var filters = report.get_values();
frappe.set_route('query-report', 'Profit and Loss Statement', {company: filters.company});
- }, __('Financial Statements'));
- report.page.add_inner_button(__("Cash Flow Statement"), function() {
+ });
+
+ report.page.add_custom_menu_item(views_menu, __("Cash Flow Statement"), function() {
var filters = report.get_values();
frappe.set_route('query-report', 'Cash Flow', {company: filters.company});
- }, __('Financial Statements'));
+ });
}
};
diff --git a/erpnext/public/js/payment/payment_details.html b/erpnext/public/js/payment/payment_details.html
deleted file mode 100644
index 3e63944..0000000
--- a/erpnext/public/js/payment/payment_details.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<div class="row pos-payment-row" type="{{type}}" idx={{idx}}>
- <div class="col-xs-6" style="padding:20px">{{mode_of_payment}}</div>
- <div class="col-xs-6">
- <div class="input-group">
- <input disabled class="form-control text-right amount" idx="{{idx}}" type="text" value="{%= format_currency(amount, currency) %}">
- <span class="input-group-btn">
- <button type="button" class="btn btn-default clr" idx="{{idx}}" style="border:1px solid #d1d8dd">C</button>
- </span>
- </div>
- </div>
-</div>
\ No newline at end of file
diff --git a/erpnext/public/js/payment/pos_payment.html b/erpnext/public/js/payment/pos_payment.html
deleted file mode 100644
index cb6971b..0000000
--- a/erpnext/public/js/payment/pos_payment.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<div class="pos_payment row">
- <div class="row" style="padding: 0px 30px;">
- <h3>{{ __("Total Amount") }}: <span class="label label-default" style="font-size:20px;padding:5px">{%= format_currency(grand_total, currency) %}</span></h3>
- </div>
- <div class="row amount-row">
- <div class="col-xs-6 col-sm-3 text-center">
- <p class="amount-label"> {{ __("Paid") }} <h3 class="paid_amount">{%= format_currency(paid_amount, currency) %}</h3></p>
- </div>
- <div class="col-xs-6 col-sm-3 text-center">
- <p class="amount-label"> {{ __("Outstanding") }} <h3 class="outstanding_amount">{%= format_currency(outstanding_amount, currency) %} </h3></p>
- </div>
- <div class="col-xs-6 col-sm-3 text-center">
- <p class="amount-label"> {{ __("Change") }} <input class="form-control text-right change_amount bold" type="text" idx="change_amount" value="{{format_number(change_amount, null, 2)}}">
- </p>
- </div>
- <div class="col-xs-6 col-sm-3 text-center">
- <p class="amount-label"> {{ __("Write off") }} <input class="form-control text-right write_off_amount bold" type="text" idx="write_off_amount" value="{{format_number(write_off_amount, null, 2)}}">
- </p>
- </div>
- </div>
- <hr>
- <div class="row">
- <div class="col-sm-6 ">
- <div class ="row multimode-payments" style = "margin-right:10px">
- </div>
- </div>
- <div class="col-sm-6 payment-toolbar">
- {% for(var i=0; i<3; i++) { %}
- <div class="row">
- {% for(var j=i*3; j<(i+1)*3; j++) { %}
- <button type="button" class="btn btn-default pos-keyboard-key">{{j+1}}</button>
- {% } %}
- </div>
- {% } %}
- <div class="row">
- <button type="button" class="btn btn-default delete-btn">{{ __("Del") }}</button>
- <button type="button" class="btn btn-default pos-keyboard-key">0</button>
- <button type="button" class="btn btn-default pos-keyboard-key">.</button>
- </div>
- </div>
- </div>
-</div>
diff --git a/erpnext/public/js/pos/clusterize.js b/erpnext/public/js/pos/clusterize.js
deleted file mode 100644
index 075c9ca..0000000
--- a/erpnext/public/js/pos/clusterize.js
+++ /dev/null
@@ -1,330 +0,0 @@
-/* eslint-disable */
-/*! Clusterize.js - v0.17.6 - 2017-03-05
-* http://NeXTs.github.com/Clusterize.js/
-* Copyright (c) 2015 Denis Lukov; Licensed GPLv3 */
-
-;(function(name, definition) {
- if (typeof module != 'undefined') module.exports = definition();
- else if (typeof define == 'function' && typeof define.amd == 'object') define(definition);
- else this[name] = definition();
-}('Clusterize', function() {
- "use strict"
-
- // detect ie9 and lower
- // https://gist.github.com/padolsey/527683#comment-786682
- var ie = (function(){
- for( var v = 3,
- el = document.createElement('b'),
- all = el.all || [];
- el.innerHTML = '<!--[if gt IE ' + (++v) + ']><i><![endif]-->',
- all[0];
- ){}
- return v > 4 ? v : document.documentMode;
- }()),
- is_mac = navigator.platform.toLowerCase().indexOf('mac') + 1;
- var Clusterize = function(data) {
- if( ! (this instanceof Clusterize))
- return new Clusterize(data);
- var self = this;
-
- var defaults = {
- rows_in_block: 50,
- blocks_in_cluster: 4,
- tag: null,
- show_no_data_row: true,
- no_data_class: 'clusterize-no-data',
- no_data_text: 'No data',
- keep_parity: true,
- callbacks: {}
- }
-
- // public parameters
- self.options = {};
- var options = ['rows_in_block', 'blocks_in_cluster', 'show_no_data_row', 'no_data_class', 'no_data_text', 'keep_parity', 'tag', 'callbacks'];
- for(var i = 0, option; option = options[i]; i++) {
- self.options[option] = typeof data[option] != 'undefined' && data[option] != null
- ? data[option]
- : defaults[option];
- }
-
- var elems = ['scroll', 'content'];
- for(var i = 0, elem; elem = elems[i]; i++) {
- self[elem + '_elem'] = data[elem + 'Id']
- ? document.getElementById(data[elem + 'Id'])
- : data[elem + 'Elem'];
- if( ! self[elem + '_elem'])
- throw new Error("Error! Could not find " + elem + " element");
- }
-
- // tabindex forces the browser to keep focus on the scrolling list, fixes #11
- if( ! self.content_elem.hasAttribute('tabindex'))
- self.content_elem.setAttribute('tabindex', 0);
-
- // private parameters
- var rows = isArray(data.rows)
- ? data.rows
- : self.fetchMarkup(),
- cache = {},
- scroll_top = self.scroll_elem.scrollTop;
-
- // append initial data
- self.insertToDOM(rows, cache);
-
- // restore the scroll position
- self.scroll_elem.scrollTop = scroll_top;
-
- // adding scroll handler
- var last_cluster = false,
- scroll_debounce = 0,
- pointer_events_set = false,
- scrollEv = function() {
- // fixes scrolling issue on Mac #3
- if (is_mac) {
- if( ! pointer_events_set) self.content_elem.style.pointerEvents = 'none';
- pointer_events_set = true;
- clearTimeout(scroll_debounce);
- scroll_debounce = setTimeout(function () {
- self.content_elem.style.pointerEvents = 'auto';
- pointer_events_set = false;
- }, 50);
- }
- if (last_cluster != (last_cluster = self.getClusterNum()))
- self.insertToDOM(rows, cache);
- if (self.options.callbacks.scrollingProgress)
- self.options.callbacks.scrollingProgress(self.getScrollProgress());
- },
- resize_debounce = 0,
- resizeEv = function() {
- clearTimeout(resize_debounce);
- resize_debounce = setTimeout(self.refresh, 100);
- }
- on('scroll', self.scroll_elem, scrollEv);
- on('resize', window, resizeEv);
-
- // public methods
- self.destroy = function(clean) {
- off('scroll', self.scroll_elem, scrollEv);
- off('resize', window, resizeEv);
- self.html((clean ? self.generateEmptyRow() : rows).join(''));
- }
- self.refresh = function(force) {
- if(self.getRowsHeight(rows) || force) self.update(rows);
- }
- self.update = function(new_rows) {
- rows = isArray(new_rows)
- ? new_rows
- : [];
- var scroll_top = self.scroll_elem.scrollTop;
- // fixes #39
- if(rows.length * self.options.item_height < scroll_top) {
- self.scroll_elem.scrollTop = 0;
- last_cluster = 0;
- }
- self.insertToDOM(rows, cache);
- self.scroll_elem.scrollTop = scroll_top;
- }
- self.clear = function() {
- self.update([]);
- }
- self.getRowsAmount = function() {
- return rows.length;
- }
- self.getScrollProgress = function() {
- return this.options.scroll_top / (rows.length * this.options.item_height) * 100 || 0;
- }
-
- var add = function(where, _new_rows) {
- var new_rows = isArray(_new_rows)
- ? _new_rows
- : [];
- if( ! new_rows.length) return;
- rows = where == 'append'
- ? rows.concat(new_rows)
- : new_rows.concat(rows);
- self.insertToDOM(rows, cache);
- }
- self.append = function(rows) {
- add('append', rows);
- }
- self.prepend = function(rows) {
- add('prepend', rows);
- }
- }
-
- Clusterize.prototype = {
- constructor: Clusterize,
- // fetch existing markup
- fetchMarkup: function() {
- var rows = [], rows_nodes = this.getChildNodes(this.content_elem);
- while (rows_nodes.length) {
- rows.push(rows_nodes.shift().outerHTML);
- }
- return rows;
- },
- // get tag name, content tag name, tag height, calc cluster height
- exploreEnvironment: function(rows, cache) {
- var opts = this.options;
- opts.content_tag = this.content_elem.tagName.toLowerCase();
- if( ! rows.length) return;
- if(ie && ie <= 9 && ! opts.tag) opts.tag = rows[0].match(/<([^>\s/]*)/)[1].toLowerCase();
- if(this.content_elem.children.length <= 1) cache.data = this.html(rows[0] + rows[0] + rows[0]);
- if( ! opts.tag) opts.tag = this.content_elem.children[0].tagName.toLowerCase();
- this.getRowsHeight(rows);
- },
- getRowsHeight: function(rows) {
- var opts = this.options,
- prev_item_height = opts.item_height;
- opts.cluster_height = 0;
- if( ! rows.length) return;
- var nodes = this.content_elem.children;
- var node = nodes[Math.floor(nodes.length / 2)];
- opts.item_height = node.offsetHeight;
- // consider table's border-spacing
- if(opts.tag == 'tr' && getStyle('borderCollapse', this.content_elem) != 'collapse')
- opts.item_height += parseInt(getStyle('borderSpacing', this.content_elem), 10) || 0;
- // consider margins (and margins collapsing)
- if(opts.tag != 'tr') {
- var marginTop = parseInt(getStyle('marginTop', node), 10) || 0;
- var marginBottom = parseInt(getStyle('marginBottom', node), 10) || 0;
- opts.item_height += Math.max(marginTop, marginBottom);
- }
- opts.block_height = opts.item_height * opts.rows_in_block;
- opts.rows_in_cluster = opts.blocks_in_cluster * opts.rows_in_block;
- opts.cluster_height = opts.blocks_in_cluster * opts.block_height;
- return prev_item_height != opts.item_height;
- },
- // get current cluster number
- getClusterNum: function () {
- this.options.scroll_top = this.scroll_elem.scrollTop;
- return Math.floor(this.options.scroll_top / (this.options.cluster_height - this.options.block_height)) || 0;
- },
- // generate empty row if no data provided
- generateEmptyRow: function() {
- var opts = this.options;
- if( ! opts.tag || ! opts.show_no_data_row) return [];
- var empty_row = document.createElement(opts.tag),
- no_data_content = document.createTextNode(opts.no_data_text), td;
- empty_row.className = opts.no_data_class;
- if(opts.tag == 'tr') {
- td = document.createElement('td');
- // fixes #53
- td.colSpan = 100;
- td.appendChild(no_data_content);
- }
- empty_row.appendChild(td || no_data_content);
- return [empty_row.outerHTML];
- },
- // generate cluster for current scroll position
- generate: function (rows, cluster_num) {
- var opts = this.options,
- rows_len = rows.length;
- if (rows_len < opts.rows_in_block) {
- return {
- top_offset: 0,
- bottom_offset: 0,
- rows_above: 0,
- rows: rows_len ? rows : this.generateEmptyRow()
- }
- }
- var items_start = Math.max((opts.rows_in_cluster - opts.rows_in_block) * cluster_num, 0),
- items_end = items_start + opts.rows_in_cluster,
- top_offset = Math.max(items_start * opts.item_height, 0),
- bottom_offset = Math.max((rows_len - items_end) * opts.item_height, 0),
- this_cluster_rows = [],
- rows_above = items_start;
- if(top_offset < 1) {
- rows_above++;
- }
- for (var i = items_start; i < items_end; i++) {
- rows[i] && this_cluster_rows.push(rows[i]);
- }
- return {
- top_offset: top_offset,
- bottom_offset: bottom_offset,
- rows_above: rows_above,
- rows: this_cluster_rows
- }
- },
- renderExtraTag: function(class_name, height) {
- var tag = document.createElement(this.options.tag),
- clusterize_prefix = 'clusterize-';
- tag.className = [clusterize_prefix + 'extra-row', clusterize_prefix + class_name].join(' ');
- height && (tag.style.height = height + 'px');
- return tag.outerHTML;
- },
- // if necessary verify data changed and insert to DOM
- insertToDOM: function(rows, cache) {
- // explore row's height
- if( ! this.options.cluster_height) {
- this.exploreEnvironment(rows, cache);
- }
- var data = this.generate(rows, this.getClusterNum()),
- this_cluster_rows = data.rows.join(''),
- this_cluster_content_changed = this.checkChanges('data', this_cluster_rows, cache),
- top_offset_changed = this.checkChanges('top', data.top_offset, cache),
- only_bottom_offset_changed = this.checkChanges('bottom', data.bottom_offset, cache),
- callbacks = this.options.callbacks,
- layout = [];
-
- if(this_cluster_content_changed || top_offset_changed) {
- if(data.top_offset) {
- this.options.keep_parity && layout.push(this.renderExtraTag('keep-parity'));
- layout.push(this.renderExtraTag('top-space', data.top_offset));
- }
- layout.push(this_cluster_rows);
- data.bottom_offset && layout.push(this.renderExtraTag('bottom-space', data.bottom_offset));
- callbacks.clusterWillChange && callbacks.clusterWillChange();
- this.html(layout.join(''));
- this.options.content_tag == 'ol' && this.content_elem.setAttribute('start', data.rows_above);
- callbacks.clusterChanged && callbacks.clusterChanged();
- } else if(only_bottom_offset_changed) {
- this.content_elem.lastChild.style.height = data.bottom_offset + 'px';
- }
- },
- // unfortunately ie <= 9 does not allow to use innerHTML for table elements, so make a workaround
- html: function(data) {
- var content_elem = this.content_elem;
- if(ie && ie <= 9 && this.options.tag == 'tr') {
- var div = document.createElement('div'), last;
- div.innerHTML = '<table><tbody>' + data + '</tbody></table>';
- while((last = content_elem.lastChild)) {
- content_elem.removeChild(last);
- }
- var rows_nodes = this.getChildNodes(div.firstChild.firstChild);
- while (rows_nodes.length) {
- content_elem.appendChild(rows_nodes.shift());
- }
- } else {
- content_elem.innerHTML = data;
- }
- },
- getChildNodes: function(tag) {
- var child_nodes = tag.children, nodes = [];
- for (var i = 0, ii = child_nodes.length; i < ii; i++) {
- nodes.push(child_nodes[i]);
- }
- return nodes;
- },
- checkChanges: function(type, value, cache) {
- var changed = value != cache[type];
- cache[type] = value;
- return changed;
- }
- }
-
- // support functions
- function on(evt, element, fnc) {
- return element.addEventListener ? element.addEventListener(evt, fnc, false) : element.attachEvent("on" + evt, fnc);
- }
- function off(evt, element, fnc) {
- return element.removeEventListener ? element.removeEventListener(evt, fnc, false) : element.detachEvent("on" + evt, fnc);
- }
- function isArray(arr) {
- return Object.prototype.toString.call(arr) === '[object Array]';
- }
- function getStyle(prop, elem) {
- return window.getComputedStyle ? window.getComputedStyle(elem)[prop] : elem.currentStyle[prop];
- }
-
- return Clusterize;
-}));
\ No newline at end of file
diff --git a/erpnext/public/js/pos/customer_toolbar.html b/erpnext/public/js/pos/customer_toolbar.html
deleted file mode 100644
index 3ba5ccb..0000000
--- a/erpnext/public/js/pos/customer_toolbar.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<div class="pos-bill-toolbar col-xs-9" style="display: flex; width: 70%;">
- <div class="party-area" style="flex: 1;">
- <span class="edit-customer-btn text-muted" style="display: inline;">
- <a class="btn-open no-decoration" title="Edit Customer">
- <i class="octicon octicon-pencil"></i>
- </a>
- </span>
- </div>
- <button class="btn btn-default list-customers-btn" style="margin-left: 12px">
- <i class="octicon octicon-organization"></i>
- </button>
- </button> {% if (allow_delete) { %}
- <button class="btn btn-default btn-danger" style="margin: 0 5px 0 5px">
- <i class="octicon octicon-trashcan"></i>
- </button> {% } %}
-</div>
\ No newline at end of file
diff --git a/erpnext/public/js/pos/pos.html b/erpnext/public/js/pos/pos.html
deleted file mode 100644
index 89e2940..0000000
--- a/erpnext/public/js/pos/pos.html
+++ /dev/null
@@ -1,136 +0,0 @@
-<div class="pos">
- <div class="row">
- <div class="col-sm-5 pos-bill-wrapper">
- <div class="col-sm-12"><h6 class="form-section-heading uppercase">{{ __("Item Cart") }}</h6></div>
- <div class="pos-bill">
- <div class="item-cart">
- <div class="pos-list-row pos-bill-header text-muted h6">
- <span class="cell subject">
- <!--<input class="list-select-all" type="checkbox" title="{%= __("Select All") %}">-->
- {{ __("Item Name")}}
- </span>
- <span class="cell text-right">{{ __("Quantity") }}</span>
- <span class="cell text-right">{{ __("Discount") }}</span>
- <span class="cell text-right">{{ __("Rate") }}</span>
- </div>
- <div class="item-cart-items">
- <div class="no-items-message text-extra-muted">
- <span class="text-center">
- <i class="fa fa-2x fa-shopping-cart"></i>
- <p>{{ __("Tap items to add them here") }}</p>
- </span>
- </div>
- <div class="items">
- </div>
- </div>
- </div>
- </div>
- <div class="totals-area">
- <div class="pos-list-row net-total-area">
- <div class="cell"></div>
- <div class="cell text-right">{%= __("Net Total") %}</div>
- <div class="cell price-cell bold net-total text-right"></div>
- </div>
- <div class="pos-list-row tax-area">
- <div class="cell"></div>
- <div class="cell text-right">{%= __("Taxes") %}</div>
- <div class="cell price-cell text-right tax-table">
- </div>
- </div>
- {% if(allow_user_to_edit_discount) { %}
- <div class="pos-list-row discount-amount-area">
- <div class="cell"></div>
- <div class="cell text-right">{%= __("Discount") %}</div>
- <div class="cell price-cell discount-field-col">
- <div class="input-group input-group-sm">
- <span class="input-group-addon">%</span>
- <input type="text" class="form-control discount-percentage text-right">
- </div>
- <div class="input-group input-group-sm">
- <span class="input-group-addon">{%= get_currency_symbol(currency) %}</span>
- <input type="text" class="form-control discount-amount text-right" placeholder="{%= 0.00 %}">
- </div>
- </div>
- </div>
- {% } %}
- <div class="pos-list-row grand-total-area collapse-btn" style="border-bottom:1px solid #d1d8dd;">
- <div class="cell">
- <a class="">
- <i class="octicon octicon-chevron-down"></i>
- </a>
- </div>
- <div class="cell text-right bold">{%= __("Grand Total") %}</div>
- <div class="cell price-cell grand-total text-right lead"></div>
- </div>
- <div class="pos-list-row qty-total-area collapse-btn" style="border-bottom:1px solid #d1d8dd;">
- <div class="cell">
- <a class="">
- <i class="octicon octicon-chevron-down"></i>
- </a>
- </div>
- <div class="cell text-right bold">{%= __("Qty Total") %}</div>
- <div class="cell price-cell qty-total text-right lead"></div>
- </div>
- </div>
- <div class="row" style="margin-top: 30px">
- <div class="col-sm-6 selected-item">
-
- </div>
- <div class="col-xs-6 numeric_keypad hidden-xs" style="display:none">
- {% var chartData = ["Qty", "Disc", "Price"] %} {% for(var i=0; i
- <3; i++) { %} <div class="row text-right">
- {% for(var j=i*3; j
- <(i+1)*3; j++) { %} <button type="button" class="btn btn-default numeric-keypad" val="{{j+1}}">{{j+1}}</button>
- {% } %}
- <button type="button" {% if((!allow_user_to_edit_rate && __(chartData[i]) == __("Price")) || (!allow_user_to_edit_discount && __(chartData[i]) == __("Disc"))) { %} disabled {% } %} id="pos-item-{{ chartData[i].toLowerCase() }}" class="btn text-center btn-default numeric-keypad pos-operation">{{ __(chartData[i]) }}</button>
- </div>
- {% } %}
- <div class="row text-right">
- <button type="button" class="btn btn-default numeric-keypad numeric-del">{{ __("Del") }}</button>
- <button type="button" class="btn btn-default numeric-keypad" val="0">0</button>
- <button type="button" class="btn btn-default numeric-keypad" val=".">.</button>
- <button type="button" class="btn btn-primary numeric-keypad pos-pay">{{ __("Pay") }}</button>
- </div>
- </div>
- </div>
- </div>
- <div class="col-sm-5 list-customers">
- <div class="col-sm-12"><h6 class="form-section-heading uppercase">{{ __("Customers in Queue") }}</h6></div>
- <div class="pos-list-row pos-bill-header">
- <div class="cell subject"><input class="list-select-all" type="checkbox">{{ __("Customer") }}</div>
- <div class="cell text-left">{{ __("Status") }}</div>
- <div class="cell text-right">{{ __("Amount") }}</div>
- <div class="cell text-right">{{ __("Grand Total") }}</div>
- </div>
- <div class="list-customers-table border-left border-right border-bottom">
- <div class="no-items-message text-extra-muted">
- <span class="text-center">
- <i class="fa fa-2x fa-user"></i>
- <p>{{ __("No Customers yet!") }}</p>
- </span>
- </div>
- </div>
- </div>
- <div class="col-sm-7 pos-items-section">
- <div class="col-sm-12"><h6 class="form-section-heading uppercase">{{ __("Stock Items") }}</h6></div>
- <div class="row pos-item-area">
-
- </div>
- <span id="customer-results" style="color:#68a;"></span>
- <div class="item-list-area">
- <div class="pos-list-row pos-bill-header text-muted h6">
- <div class="cell subject search-item-group">
- <div class="dropdown">
- <a class="text-muted dropdown-toggle" data-toggle="dropdown"><span class="dropdown-text">{{ __("All Item Groups") }}</span><i class="caret"></i></a>
- <ul class="dropdown-menu">
- </ul>
- </div>
- </div>
- <div class="cell search-item"></div>
- </div>
- <div class="app-listing item-list image-view-container">
-
- </div>
- </div>
- </div>
-</div>
diff --git a/erpnext/public/js/pos/pos_bill_item.html b/erpnext/public/js/pos/pos_bill_item.html
deleted file mode 100644
index 21868a6..0000000
--- a/erpnext/public/js/pos/pos_bill_item.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<div class="row pos-bill-row pos-bill-item" data-item-code="{%= item_code %}">
- <div class="col-xs-4"><h6>{%= item_code || "" %}{%= __(item_name) || "" %}</h6></div>
- <div class="col-xs-3">
- <div class="row pos-qty-row">
- <div class="col-xs-2 text-center pos-qty-btn" data-action="decrease-qty"><i class="fa fa-minus text-muted" style="font-size:12px"></i></div>
- <div class="col-xs-8">
- <div>
- <input type="tel" value="{%= qty %}" class="form-control pos-item-qty text-right">
- </div>
- {% if(actual_qty != null) { %}
- <div style="margin-top: 5px;" class="text-muted small text-right">
- {%= __("In Stock: ") %} <span>{%= actual_qty || 0.0 %}</span>
- </div>
- {% } %}
- </div>
- <div class="col-xs-2 text-center pos-qty-btn" data-action="increase-qty"><i class="fa fa-plus text-muted" style="font-size:12px"></i></div>
- </div>
- </div>
- <div class="col-xs-2 text-right">
- <div class="row input-sm">
- <input type="tel" value="{%= discount_percentage %}" class="form-control text-right pos-item-disc">
- </div>
- </div>
- <div class="col-xs-3 text-right">
- <div class="text-muted" style="margin-top: 5px;">
- {% if(enabled) { %}
- <input type="tel" value="{%= rate %}" class="form-control input-sm pos-item-price text-right">
- {% } else { %}
- <h6>{%= format_currency(rate) %}</h6>
- {% } %}
- </div>
- <p><h6>{%= amount %}</h6></p>
- </div>
-</div>
diff --git a/erpnext/public/js/pos/pos_bill_item_new.html b/erpnext/public/js/pos/pos_bill_item_new.html
deleted file mode 100644
index cb626ce..0000000
--- a/erpnext/public/js/pos/pos_bill_item_new.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<div class="pos-list-row pos-bill-item {{ selected_class }}" data-item-code="{{ item_code }}">
- <div class="cell subject">
- <!--<input class="list-row-checkbox" type="checkbox" data-name="{{item_code}}">-->
- <a class="grey list-id" title="{{ item_name }}">{{ strip_html(__(item_name)) || item_code }}</a>
- </div>
- <div class="cell text-right">{%= qty %}</div>
- <div class="cell text-right">{%= discount_percentage %}</div>
- <div class="cell text-right">{%= format_currency(rate) %}</div>
-</div>
diff --git a/erpnext/public/js/pos/pos_invoice_list.html b/erpnext/public/js/pos/pos_invoice_list.html
deleted file mode 100644
index 13aa520..0000000
--- a/erpnext/public/js/pos/pos_invoice_list.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<div class="pos-list-row" invoice-name = "{{name}}">
- <div class="list-column cell subject" invoice-name = "{{name}}">
- <input class="list-delete text-left" type="checkbox" style = "margin-right:5px">
- <a class="grey list-id text-left customer-row" title="{{ customer }}">{%= customer %}</a>
- </div>
- <div class="list-column cell text-left customer-row"><span class="indicator {{data.indicator}}">{{ data.status }}</span></div>
- <div class="list-column cell text-right customer-row">{%= paid_amount %}</div>
- <div class="list-column cell text-right customer-row">{%= grand_total %}</div>
-</div>
diff --git a/erpnext/public/js/pos/pos_item.html b/erpnext/public/js/pos/pos_item.html
deleted file mode 100755
index 52f3cf6..0000000
--- a/erpnext/public/js/pos/pos_item.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<div class="pos-item-wrapper image-view-item" data-item-code="{{item_code}}">
- <div class="image-view-header doclist-row">
- <div class="list-value">
- <a class="grey list-id" data-name="{{item_code}}" title="{{ item_name || item_code}}">{{item_name || item_code}}<br>({{ __(item_stock) }})</a>
- </div>
- </div>
- <div class="image-view-body">
- <a data-item-code="{{ item_code }}"
- title="{{ item_name || item_code }}"
- >
- <div class="image-field"
- style="
- {% if (!item_image) { %}
- background-color: #fafbfc;
- {% } %}
- border: 0px;"
- >
- {% if (!item_image) { %}
- <span class="placeholder-text">
- {%= frappe.get_abbr(item_name || item_code) %}
- </span>
- {% } %}
- {% if (item_image) { %}
- <img src="{{ item_image }}" alt="{{item_name || item_code}}">
- {% } %}
- </div>
- <span class="price-info">
- {{item_price}} / {{item_uom}}
- </span>
- </a>
- </div>
-</div>
\ No newline at end of file
diff --git a/erpnext/public/js/pos/pos_selected_item.html b/erpnext/public/js/pos/pos_selected_item.html
deleted file mode 100644
index 03c7341..0000000
--- a/erpnext/public/js/pos/pos_selected_item.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<div class="pos-selected-item-action" data-item-code="{%= item_code %}" data-idx="{%= idx %}">
- <div class="pos-list-row">
- <div class="cell">{{ __("Quantity") }}:</div>
- <input type="tel" class="form-control cell pos-item-qty" value="{%= qty %}"/>
- </div>
- <div class="pos-list-row">
- <div class="cell">{{ __("Price List Rate") }}:</div>
- <input type="tel" class="form-control cell" disabled value="{%= price_list_rate %}"/>
- </div>
- <div class="pos-list-row">
- <div class="cell">{{ __("Discount") }}: %</div>
- <input type="tel" class="form-control cell pos-item-disc" {% if !allow_user_to_edit_discount %} disabled {% endif %} value="{%= discount_percentage %}">
- </div>
- <div class="pos-list-row">
- <div class="cell">{{ __("Price") }}:</div>
- <input type="tel" class="form-control cell pos-item-price" {% if !allow_user_to_edit_rate %} disabled {% endif %} value="{%= rate %}"/>
- </div>
- <div class="pos-list-row">
- <div class="cell">{{ __("Amount") }}:</div>
- <input type="tel" class="form-control cell pos-amount" disabled value="{%= amount %}"/>
- </div>
-</div>
\ No newline at end of file
diff --git a/erpnext/public/js/pos/pos_tax_row.html b/erpnext/public/js/pos/pos_tax_row.html
deleted file mode 100644
index 3752a89..0000000
--- a/erpnext/public/js/pos/pos_tax_row.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<div class="pos-list-row" style="padding-right: 0;">
- <div class="cell">{%= description %}</div>
- <div class="cell text-right bold">{%= tax_amount %}</div>
-</div>
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index 8685837..4076ebe 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -39,8 +39,9 @@
.dashboard-list-item {
background-color: inherit;
- padding: 5px 0px;
- border-bottom: 1px solid @border-color;
+ border-bottom: 1px solid var(--border-color);
+ font-size: var(--text-md);
+ color: var(--text-color);
}
#page-stock-balance .dashboard-list-item {
@@ -446,20 +447,6 @@
}
-// Leaderboard
-
-.leaderboard {
- .result {
- border-top: 1px solid #d1d8dd;
- }
- .list-item {
- padding-left: 45px;
- }
- .list-item_content {
- padding-right: 45px;
- }
-}
-
// Healthcare
.exercise-card {
diff --git a/erpnext/public/scss/point-of-sale.scss b/erpnext/public/scss/point-of-sale.scss
new file mode 100644
index 0000000..3e7d5da
--- /dev/null
+++ b/erpnext/public/scss/point-of-sale.scss
@@ -0,0 +1,1111 @@
+.point-of-sale-app {
+ display: grid;
+ grid-template-columns: repeat(10, minmax(0, 1fr));
+ gap: var(--margin-md);
+
+ section {
+ min-height: 45rem;
+ height: calc(100vh - 200px);
+ max-height: calc(100vh - 200px);
+ }
+
+ .frappe-control {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ .form-group {
+ margin-bottom: 0px !important;
+ }
+
+ .pointer-no-select {
+ cursor: pointer;
+ user-select: none;
+ }
+
+ .nowrap {
+ overflow: hidden;
+ white-space: nowrap;
+ }
+
+ .image {
+ height: 100% !important;
+ object-fit: cover;
+ }
+
+ .abbr {
+ background-color: var(--gray-50);
+ font-size: var(--text-3xl);
+ }
+
+ .label {
+ display: flex;
+ align-items: center;
+ font-weight: 700;
+ font-size: var(--text-lg);
+ }
+
+ .pos-card {
+ background-color: var(--fg-color);
+ box-shadow: var(--shadow-base);
+ border-radius: var(--border-radius-md);
+ }
+
+ .seperator {
+ margin-left: var(--margin-sm);
+ margin-right: var(--margin-sm);
+ border-bottom: 1px solid var(--gray-300);
+ }
+
+ .primary-action {
+ @extend .pointer-no-select;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: var(--padding-sm);
+ margin-top: var(--margin-sm);
+ border-radius: var(--border-radius-md);
+ font-size: var(--text-lg);
+ font-weight: 700;
+ }
+
+ .highlighted-numpad-btn {
+ box-shadow: inset 0 0px 4px 0px rgba(0, 0, 0, 0.15) !important;
+ font-weight: 700;
+ background-color: var(--gray-50);
+ }
+
+ > .items-selector {
+ @extend .pos-card;
+ grid-column: span 6 / span 6;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+
+ > .filter-section {
+ display: grid;
+ grid-template-columns: repeat(12, minmax(0, 1fr));
+ background-color: var(--fg-color);
+ padding: var(--padding-lg);
+ padding-bottom: var(--padding-sm);
+ align-items: center;
+
+ > .label {
+ @extend .label;
+ grid-column: span 4 / span 4;
+ padding-bottom: var(--padding-xs);
+ }
+
+ > .search-field {
+ grid-column: span 5 / span 5;
+ display: flex;
+ align-items: center;
+ margin: 0px var(--margin-sm);
+ }
+
+ > .item-group-field {
+ grid-column: span 3 / span 3;
+ display: flex;
+ align-items: center;
+ }
+ }
+
+ > .items-container {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: var(--margin-lg);
+ padding: var(--padding-lg);
+ padding-top: var(--padding-xs);
+ overflow-y: scroll;
+ overflow-x: hidden;
+
+ &:after {
+ content: "";
+ display: block;
+ height: 1px;
+ }
+
+ > .item-wrapper {
+ @extend .pointer-no-select;
+ border-radius: var(--border-radius-md);
+ box-shadow: var(--shadow-base);
+
+ &:hover {
+ transform: scale(1.02, 1.02);
+ }
+
+ .item-display {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--border-radius-md);
+ margin: var(--margin-sm);
+ margin-bottom: 0px;
+ min-height: 8rem;
+ height: 8rem;
+ color: var(--gray-500);
+
+ > img {
+ @extend .image;
+ }
+ }
+
+ > .item-detail {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ min-height: 3.5rem;
+ height: 3.5rem;
+ padding-left: var(--padding-sm);
+ padding-right: var(--padding-sm);
+
+ > .item-name {
+ @extend .nowrap;
+ display: flex;
+ align-items: center;
+ font-size: var(--text-md);
+ }
+
+ > .item-rate {
+ font-weight: 700;
+ }
+ }
+
+ }
+ }
+ }
+
+ > .customer-cart-container {
+ grid-column: span 4 / span 4;
+ display: flex;
+ flex-direction: column;
+
+ > .customer-section {
+ @extend .pos-card;
+ display: flex;
+ flex-direction: column;
+ padding: var(--padding-md) var(--padding-lg);
+ overflow: hidden;
+
+ > .customer-field {
+ display: flex;
+ align-items: center;
+ padding-top: var(--padding-xs);
+ }
+
+ > .customer-details {
+ display: flex;
+ flex-direction: column;
+ background-color: var(--fg-color);
+
+ > .header {
+ display: flex;
+ margin-bottom: var(--margin-md);
+ justify-content: space-between;
+ padding-top: var(--padding-md);
+
+ > .label {
+ @extend .label;
+ }
+
+ > .close-details-btn {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ }
+ }
+
+ > .customer-display {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+
+ > .customer-image {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 3rem;
+ height: 3rem;
+ border-radius: 50%;
+ color: var(--gray-500);
+ margin-right: var(--margin-md);
+
+ > img {
+ @extend .image;
+ border-radius: 50%;
+ }
+ }
+
+ > .customer-abbr {
+ @extend .abbr;
+ font-size: var(--text-2xl);
+ }
+
+ > .customer-name-desc {
+ @extend .nowrap;
+ display: flex;
+ flex-direction: column;
+ margin-right: auto;
+
+ >.customer-name {
+ font-weight: 700;
+ font-size: var(--text-lg);
+ }
+
+ >.customer-desc {
+ color: var(--gray-600);
+ font-weight: 500;
+ font-size: var(--text-sm);
+ }
+ }
+
+ > .reset-customer-btn {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ }
+
+ }
+
+ > .customer-fields-container {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ margin-top: var(--margin-md);
+ column-gap: var(--padding-sm);
+ row-gap: var(--padding-xs);
+ }
+
+ > .transactions-label {
+ @extend .label;
+ margin-top: var(--margin-md);
+ margin-bottom: var(--margin-sm);
+ }
+ }
+
+ > .customer-transactions {
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ margin-right: -12px;
+ padding-right: 12px;
+ margin-left: -10px;
+
+ > .no-transactions-placeholder {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--gray-50);
+ border-radius: var(--border-radius-md);
+ }
+ }
+ }
+
+ > .cart-container {
+ @extend .pos-card;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: var(--margin-md);
+ position: relative;
+ height: 100%;
+
+ > .abs-cart-container {
+ position: absolute;
+ display: flex;
+ flex-direction: column;
+ padding: var(--padding-lg);
+ width: 100%;
+ height: 100%;
+
+ > .cart-label {
+ @extend .label;
+ padding-bottom: var(--padding-md);
+ }
+
+ > .cart-header {
+ display: flex;
+ width: 100%;
+ font-size: var(--text-md);
+ padding-bottom: var(--padding-md);
+
+ > .name-header {
+ flex: 1 1 0%;
+ }
+
+ > .qty-header {
+ margin-right: var(--margin-lg);
+ text-align: center;
+ }
+
+ > .rate-amount-header {
+ text-align: right;
+ margin-right: var(--margin-sm);
+ }
+ }
+
+ .no-item-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: var(--gray-50);
+ border-radius: var(--border-radius-md);
+ font-size: var(--text-md);
+ font-weight: 500;
+ width: 100%;
+ height: 100%;
+ }
+
+ > .cart-items-section {
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 0%;
+ overflow-y: scroll;
+
+ > .cart-item-wrapper {
+ @extend .pointer-no-select;
+ display: flex;
+ align-items: center;
+ padding: var(--padding-sm);
+ border-radius: var(--border-radius-md);
+
+ &:hover {
+ background-color: var(--gray-50);
+ }
+
+ > .item-image {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 2rem;
+ height: 2rem;
+ border-radius: var(--border-radius-md);
+ color: var(--gray-500);
+ margin-right: var(--margin-md);
+
+ > img {
+ @extend .image;
+ }
+ }
+
+ > .item-abbr {
+ @extend .abbr;
+ font-size: var(--text-lg);
+ }
+
+
+ > .item-name-desc {
+ @extend .nowrap;
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 0%;
+ flex-shrink: 1;
+
+ > .item-name {
+ font-weight: 700;
+ }
+
+ > .item-desc {
+ font-size: var(--text-sm);
+ color: var(--gray-600);
+ font-weight: 500;
+ }
+ }
+
+ > .item-qty-rate {
+ display: flex;
+ flex-shrink: 0;
+ text-align: right;
+ margin-left: var(--margin-md);
+
+ > .item-qty {
+ display: flex;
+ align-items: center;
+ margin-right: var(--margin-lg);
+ font-weight: 700;
+ }
+
+ > .item-rate-amount {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ text-align: right;
+
+ > .item-rate {
+ font-weight: 700;
+ }
+
+ > .item-amount {
+ font-size: var(--text-md);
+ font-weight: 600;
+ }
+ }
+ }
+
+ }
+ }
+
+ > .cart-totals-section {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ width: 100%;
+ margin-top: var(--margin-md);
+
+ > .add-discount-wrapper {
+ @extend .pointer-no-select;
+ display: none;
+ align-items: center;
+ border-radius: var(--border-radius-md);
+ border: 1px dashed var(--gray-500);
+ padding: var(--padding-sm) var(--padding-md);
+ margin-bottom: var(--margin-sm);
+
+ > .add-discount-field {
+ width: 100%;
+ }
+
+ .discount-icon {
+ margin-right: var(--margin-sm);
+ }
+
+ .edit-discount-btn {
+ display: flex;
+ align-items: center;
+ font-weight: 500;
+ color: var(--dark-green-500);
+ }
+ }
+
+ > .net-total-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: var(--padding-sm) 0px;
+ font-weight: 500;
+ font-size: var(--text-md);
+ }
+
+ > .taxes-container {
+ display: none;
+ flex-direction: column;
+ font-weight: 500;
+ font-size: var(--text-md);
+
+ > .tax-row {
+ display: flex;
+ justify-content: space-between;
+ line-height: var(--text-3xl);
+ }
+ }
+
+ > .grand-total-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: var(--padding-sm) 0px;
+ font-weight: 700;
+ font-size: var(--text-lg);
+ }
+
+ > .checkout-btn {
+ @extend .primary-action;
+ background-color: var(--blue-200);
+ color: white;
+ }
+
+ > .edit-cart-btn {
+ @extend .primary-action;
+ display: none;
+ background-color: var(--gray-300);
+ font-weight: 500;
+ transition: all 0.15s ease-in-out;
+
+ &:hover {
+ background-color: var(--gray-600);
+ color: white;
+ font-weight: 700;
+ }
+ }
+ }
+
+ > .numpad-section {
+ display: none;
+ flex-direction: column;
+ flex-shrink: 0;
+ margin-top: var(--margin-sm);
+ padding: var(--padding-sm);
+ padding-bottom: 0px;
+ width: 100%;
+
+ > .numpad-totals {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: var(--margin-md);
+ font-size: var(--text-md);
+ font-weight: 700;
+ }
+
+ > .numpad-container {
+ display: grid;
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+ gap: var(--margin-md);
+ margin-bottom: var(--margin-md);
+
+ > .numpad-btn {
+ @extend .pointer-no-select;
+ border-radius: var(--border-radius-md);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: var(--padding-md);
+ box-shadow: var(--shadow-sm);
+ }
+
+ > .col-span-2 {
+ grid-column: span 2 / span 2;
+ }
+
+ > .remove-btn {
+ font-weight: 700;
+ color: var(--red-500);
+ }
+ }
+
+ > .checkout-btn {
+ @extend .primary-action;
+ margin: 0px;
+ margin-bottom: var(--margin-sm);
+ background-color: var(--blue-200);
+ color: white;
+ }
+ }
+ }
+ }
+ }
+
+ .invoice-wrapper {
+ @extend .pointer-no-select;
+ display: flex;
+ justify-content: space-between;
+ border-radius: var(--border-radius-md);
+ padding: var(--padding-sm);
+
+ &:hover {
+ background-color: var(--gray-50);
+ }
+
+ > .invoice-name-date {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-around;
+
+ > .invoice-name {
+ @extend .nowrap;
+ font-size: var(--text-md);
+ font-weight: 700;
+ }
+
+ > .invoice-date {
+ @extend .nowrap;
+ font-size: var(--text-sm);
+ display: flex;
+ align-items: center;
+ }
+ }
+
+ > .invoice-total-status {
+ display: flex;
+ flex-direction: column;
+ font-weight: 500;
+ font-size: var(--text-sm);
+ margin-left: var(--margin-md);
+
+ > .invoice-total {
+ margin-bottom: var(--margin-xs);
+ font-size: var(--text-base);
+ font-weight: 700;
+ text-align: right;
+ }
+
+ > .invoice-status {
+ display: flex;
+ align-items: center;
+ justify-content: right;
+ }
+ }
+ }
+
+ > .item-details-container {
+ @extend .pos-card;
+ grid-column: span 4 / span 4;
+ display: none;
+ flex-direction: column;
+ padding: var(--padding-lg);
+ padding-top: var(--padding-md);
+
+ > .item-details-header {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: var(--margin-md);
+
+ > .close-btn {
+ @extend .pointer-no-select;
+ }
+ }
+
+ > .item-display {
+ display: flex;
+
+ > .item-name-desc-price {
+ flex: 1 1 0%;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ margin-right: var(--margin-md);
+
+ > .item-name {
+ font-size: var(--text-3xl);
+ font-weight: 600;
+ }
+
+ > .item-desc {
+ font-size: var(--text-md);
+ font-weight: 500;
+ }
+
+ > .item-price {
+ font-size: var(--text-3xl);
+ font-weight: 700;
+ }
+ }
+
+ > .item-image {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 11rem;
+ height: 11rem;
+ border-radius: var(--border-radius-md);
+ margin-left: var(--margin-md);
+ color: var(--gray-500);
+
+ > img {
+ @extend .image;
+ }
+
+ > .item-abbr {
+ @extend .abbr;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--border-radius-md);
+ font-size: var(--text-3xl);
+ width: 100%;
+ height: 100%;
+ }
+ }
+ }
+
+ > .discount-section {
+ display: flex;
+ align-items: center;
+ margin-bottom: var(--margin-sm);
+
+ > .item-rate {
+ font-weight: 500;
+ margin-right: var(--margin-sm);
+ text-decoration: line-through;
+ }
+
+ > .item-discount {
+ padding: 3px var(--padding-sm);
+ border-radius: var(--border-radius-sm);
+ background-color: var(--green-100);
+ color: var(--dark-green-500);
+ font-size: var(--text-sm);
+ font-weight: 700;
+ }
+ }
+
+ > .form-container {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ column-gap: var(--padding-md);
+
+ > .auto-fetch-btn {
+ @extend .pointer-no-select;
+ margin: var(--margin-xs);
+ }
+ }
+ }
+
+ > .payment-container {
+ @extend .pos-card;
+ grid-column: span 6 / span 6;
+ display: none;
+ flex-direction: column;
+ padding: var(--padding-lg);
+
+ .border-primary {
+ border: 1px solid var(--blue-500);
+ }
+
+ .submit-order-btn {
+ @extend .primary-action;
+ background-color: var(--blue-500);
+ color: white;
+ }
+
+ .section-label {
+ @extend .label;
+ @extend .pointer-no-select;
+ margin-bottom: var(--margin-md);
+ }
+
+ > .payment-modes {
+ display: flex;
+ padding-bottom: var(--padding-sm);
+ margin-bottom: var(--margin-xs);
+ overflow-x: scroll;
+ overflow-y: hidden;
+
+ > .payment-mode-wrapper {
+ min-width: 40%;
+ padding: var(--padding-xs);
+
+ > .mode-of-payment {
+ @extend .pos-card;
+ @extend .pointer-no-select;
+ padding: var(--padding-md) var(--padding-lg);
+
+ > .pay-amount {
+ display: inline;
+ float: right;
+ font-weight: 700;
+ }
+
+ > .mode-of-payment-control {
+ display: none;
+ align-items: center;
+ margin-top: var(--margin-sm);
+ margin-bottom: var(--margin-xs);
+ }
+
+ > .loyalty-amount-name {
+ display: none;
+ float: right;
+ font-weight: 700;
+ }
+
+ > .cash-shortcuts {
+ display: none;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: var(--margin-sm);
+ font-size: var(--text-sm);
+ text-align: center;
+
+ > .shortcut {
+ @extend .pointer-no-select;
+ border-radius: var(--border-radius-sm);
+ background-color: var(--gray-100);
+ font-weight: 500;
+ padding: var(--padding-xs) var(--padding-sm);
+ transition: all 0.15s ease-in-out;
+
+ &:hover {
+ background-color: var(--gray-300);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ > .fields-numpad-container {
+ display: flex;
+ flex: 1;
+
+ > .fields-section {
+ flex: 1;
+ }
+
+ > .number-pad {
+ flex: 1;
+ display: flex;
+ justify-content: flex-end;
+ align-items: flex-end;
+
+ .numpad-container {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: var(--margin-md);
+ margin-bottom: var(--margin-md);
+
+ > .numpad-btn {
+ @extend .pointer-no-select;
+ border-radius: var(--border-radius-md);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: var(--padding-md);
+ box-shadow: var(--shadow-sm);
+ }
+ }
+ }
+ }
+
+ > .totals-section {
+ display: flex;
+ margin-top: auto;
+ margin-bottom: var(--margin-sm);
+ justify-content: center;
+ flex-direction: column;
+
+ > .totals {
+ display: flex;
+ padding-top: var(--padding-md);
+ background-color: var(--gray-100);
+ justify-content: center;
+ padding: var(--padding-md);
+ border-radius: var(--border-radius-md);
+
+ > .col {
+ flex-grow: 1;
+ text-align: center;
+
+ > .total-label {
+ font-size: var(--text-md);
+ font-weight: 500;
+ color: var(--gray-600);
+ }
+
+ > .value {
+ font-size: var(--text-2xl);
+ font-weight: 700;
+ }
+ }
+
+ > .seperator-y {
+ margin-left: var(--margin-sm);
+ margin-right: var(--margin-sm);
+ border-right: 1px solid var(--gray-300);
+ }
+ }
+
+ > .number-pad {
+ display: none;
+ }
+ }
+ }
+
+ > .past-order-list {
+ @extend .pos-card;
+ grid-column: span 4 / span 4;
+ display: none;
+ flex-direction: column;
+ overflow: hidden;
+
+ > .filter-section {
+ display: flex;
+ flex-direction: column;
+ background-color: var(--fg-color);
+ padding: var(--padding-lg);
+
+ > .search-field {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ margin-top: var(--margin-md);
+ margin-bottom: var(--margin-xs);
+ }
+
+ > .status-field {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ }
+ }
+
+ > .invoices-container {
+ padding: var(--padding-lg);
+ padding-top: 0px;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ }
+ }
+
+ > .past-order-summary {
+ display: none;
+ grid-column: span 6 / span 6;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ > .no-summary-placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ background-color: var(--gray-50);
+ font-weight: 500;
+ border-radius: var(--border-radius-md);
+ }
+
+ > .invoice-summary-wrapper {
+ @extend .pos-card;
+ display: none;
+ position: relative;
+ width: 31rem;
+ height: 100%;
+
+ > .abs-container {
+ position: absolute;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ height: 100%;
+ padding: var(--padding-lg);
+
+ > .upper-section {
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ margin-bottom: var(--margin-md);
+
+ > .left-section {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-end;
+ padding-right: var(--padding-sm);
+
+ > .customer-name {
+ font-size: var(--text-2xl);
+ font-weight: 700;
+ }
+
+ > .customer-email {
+ font-size: var(--text-md);
+ font-weight: 500;
+ color: var(--gray-600);
+ }
+
+ > .cashier {
+ font-size: var(--text-md);
+ font-weight: 500;
+ color: var(--gray-600);
+ margin-top: auto;
+ }
+ }
+
+ > .right-section {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ justify-content: space-between;
+
+ > .paid-amount {
+ font-size: var(--text-2xl);
+ font-weight: 700;
+ }
+
+ > .invoice-name {
+ font-size: var(--text-md);
+ font-weight: 500;
+ color: var(--gray-600);
+ margin-bottom: var(--margin-sm);
+ }
+ }
+ }
+
+ > .summary-container {
+ display: flex;
+ flex-direction: column;
+ border-radius: var(--border-radius-md);
+ background-color: var(--gray-50);
+ margin: var(--margin-md) 0px;
+
+ > .summary-row-wrapper {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: var(--padding-sm) var(--padding-md);
+ }
+
+ > .taxes-wrapper {
+ display: flex;
+ flex-direction: column;
+ padding: 0px var(--padding-md);
+
+ > .tax-row {
+ display: flex;
+ justify-content: space-between;
+ font-size: var(--text-md);
+ line-height: var(--text-3xl);
+ }
+ }
+
+ > .item-row-wrapper {
+ display: flex;
+ align-items: center;
+ padding: var(--padding-sm) var(--padding-md);
+
+ > .item-name {
+ @extend .nowrap;
+ font-weight: 500;
+ margin-right: var(--margin-md);
+ }
+
+ > .item-qty {
+ font-weight: 500;
+ margin-left: auto;
+ }
+
+ > .item-rate-disc {
+ display: flex;
+ text-align: right;
+ margin-left: var(--margin-md);
+ justify-content: flex-end;
+
+ > .item-disc {
+ color: var(--dark-green-500);
+ }
+
+ > .item-rate {
+ font-weight: 500;
+ margin-left: var(--margin-md);
+ }
+ }
+ }
+
+ > .grand-total {
+ font-weight: 700;
+ }
+
+ > .payments {
+ font-weight: 700;
+ }
+ }
+
+
+ > .summary-btns {
+ display: flex;
+ justify-content: space-between;
+
+ > .summary-btn {
+ flex: 1;
+ margin: 0px var(--margin-xs);
+ }
+
+ > .new-btn {
+ background-color: var(--blue-500);
+ color:white;
+ font-weight: 500;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/erpnext/public/scss/website.scss b/erpnext/public/scss/website.scss
index 617e916..24a1b37 100644
--- a/erpnext/public/scss/website.scss
+++ b/erpnext/public/scss/website.scss
@@ -1,4 +1,4 @@
-@import "frappe/public/scss/variables";
+@import "frappe/public/scss/website/variables";
.product-image img {
min-height: 20rem;
diff --git a/erpnext/quality_management/desk_page/quality/quality.json b/erpnext/quality_management/desk_page/quality/quality.json
index 7a049b2..474f052 100644
--- a/erpnext/quality_management/desk_page/quality/quality.json
+++ b/erpnext/quality_management/desk_page/quality/quality.json
@@ -30,6 +30,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "quality",
"idx": 0,
"is_standard": 1,
"label": "Quality",
diff --git a/erpnext/selling/desk_page/retail/retail.json b/erpnext/selling/desk_page/retail/retail.json
index c4ddf26..cdafaea 100644
--- a/erpnext/selling/desk_page/retail/retail.json
+++ b/erpnext/selling/desk_page/retail/retail.json
@@ -25,6 +25,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "retail",
"idx": 0,
"is_standard": 1,
"label": "Retail",
diff --git a/erpnext/selling/desk_page/selling/selling.json b/erpnext/selling/desk_page/selling/selling.json
index b15df98..82831ab 100644
--- a/erpnext/selling/desk_page/selling/selling.json
+++ b/erpnext/selling/desk_page/selling/selling.json
@@ -41,10 +41,11 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 1,
+ "icon": "sell",
"idx": 0,
"is_standard": 1,
"label": "Selling",
- "modified": "2020-10-08 10:23:09.984377",
+ "modified": "2020-10-21 12:30:12.164433",
"modified_by": "Administrator",
"module": "Selling",
"name": "Selling",
@@ -54,7 +55,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#cef6d1",
+ "color": "Grey",
"format": "{} Available",
"label": "Item",
"link_to": "Item",
@@ -62,7 +63,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} To Deliver",
"label": "Sales Order",
"link_to": "Sales Order",
@@ -70,7 +71,7 @@
"type": "DocType"
},
{
- "color": "#cef6d1",
+ "color": "Grey",
"format": "{} Open",
"label": "Sales Analytics",
"link_to": "Sales Analytics",
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 20ae19f..d5428e2 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -19,7 +19,7 @@
self.indicator_color = 'blue'
self.indicator_title = 'Submitted'
if self.valid_till and getdate(self.valid_till) < getdate(nowdate()):
- self.indicator_color = 'darkgrey'
+ self.indicator_color = 'gray'
self.indicator_title = 'Expired'
def validate(self):
diff --git a/erpnext/selling/doctype/quotation/quotation_list.js b/erpnext/selling/doctype/quotation/quotation_list.js
index f425acf..b631685 100644
--- a/erpnext/selling/doctype/quotation/quotation_list.js
+++ b/erpnext/selling/doctype/quotation/quotation_list.js
@@ -20,9 +20,9 @@
} else if(doc.status==="Ordered") {
return [__("Ordered"), "green", "status,=,Ordered"];
} else if(doc.status==="Lost") {
- return [__("Lost"), "darkgrey", "status,=,Lost"];
+ return [__("Lost"), "gray", "status,=,Lost"];
} else if(doc.status==="Expired") {
- return [__("Expired"), "darkgrey", "status,=,Expired"];
+ return [__("Expired"), "gray", "status,=,Expired"];
}
}
};
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.py b/erpnext/selling/doctype/quotation_item/quotation_item.py
index 966b542..7384871 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.py
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.py
@@ -5,8 +5,6 @@
import frappe
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
class QuotationItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index d4fb07c..df812ad 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -436,7 +436,7 @@
callback: function(r) {
if(r.message) {
frappe.msgprint(__('Material Request {0} submitted.',
- ['<a href="#Form/Material Request/'+r.message.name+'">' + r.message.name+ '</a>']));
+ ['<a href="/desk/Form/Material Request/'+r.message.name+'">' + r.message.name+ '</a>']));
}
d.hide();
me.frm.reload_doc();
diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.py b/erpnext/selling/doctype/sales_order_item/sales_order_item.py
index 4a87a0c..27f303d 100644
--- a/erpnext/selling/doctype/sales_order_item/sales_order_item.py
+++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.py
@@ -5,11 +5,9 @@
import frappe
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
class SalesOrderItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
def on_doctype_update():
frappe.db.add_index("Sales Order Item", ["item_code", "warehouse"])
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/onscan.js b/erpnext/selling/page/point_of_sale/onscan.js
deleted file mode 100644
index 428dc75..0000000
--- a/erpnext/selling/page/point_of_sale/onscan.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t()):e.onScan=t()}(this,function(){var d={attachTo:function(e,t){if(void 0!==e.scannerDetectionData)throw new Error("onScan.js is already initialized for DOM element "+e);var n={onScan:function(e,t){},onScanError:function(e){},onKeyProcess:function(e,t){},onKeyDetect:function(e,t){},onPaste:function(e,t){},keyCodeMapper:function(e){return d.decodeKeyEvent(e)},onScanButtonLongPress:function(){},scanButtonKeyCode:!1,scanButtonLongPressTime:500,timeBeforeScanTest:100,avgTimeByChar:30,minLength:6,suffixKeyCodes:[9,13],prefixKeyCodes:[],ignoreIfFocusOn:!1,stopPropagation:!1,preventDefault:!1,captureEvents:!1,reactToKeydown:!0,reactToPaste:!1,singleScanQty:1};return t=this._mergeOptions(n,t),e.scannerDetectionData={options:t,vars:{firstCharTime:0,lastCharTime:0,accumulatedString:"",testTimer:!1,longPressTimeStart:0,longPressed:!1}},!0===t.reactToPaste&&e.addEventListener("paste",this._handlePaste,t.captureEvents),!1!==t.scanButtonKeyCode&&e.addEventListener("keyup",this._handleKeyUp,t.captureEvents),!0!==t.reactToKeydown&&!1===t.scanButtonKeyCode||e.addEventListener("keydown",this._handleKeyDown,t.captureEvents),this},detachFrom:function(e){e.scannerDetectionData.options.reactToPaste&&e.removeEventListener("paste",this._handlePaste),!1!==e.scannerDetectionData.options.scanButtonKeyCode&&e.removeEventListener("keyup",this._handleKeyUp),e.removeEventListener("keydown",this._handleKeyDown),e.scannerDetectionData=void 0},getOptions:function(e){return e.scannerDetectionData.options},setOptions:function(e,t){switch(e.scannerDetectionData.options.reactToPaste){case!0:!1===t.reactToPaste&&e.removeEventListener("paste",this._handlePaste);break;case!1:!0===t.reactToPaste&&e.addEventListener("paste",this._handlePaste)}switch(e.scannerDetectionData.options.scanButtonKeyCode){case!1:!1!==t.scanButtonKeyCode&&e.addEventListener("keyup",this._handleKeyUp);break;default:!1===t.scanButtonKeyCode&&e.removeEventListener("keyup",this._handleKeyUp)}return e.scannerDetectionData.options=this._mergeOptions(e.scannerDetectionData.options,t),this._reinitialize(e),this},decodeKeyEvent:function(e){var t=this._getNormalizedKeyNum(e);switch(!0){case 48<=t&&t<=90:case 106<=t&&t<=111:if(void 0!==e.key&&""!==e.key)return e.key;var n=String.fromCharCode(t);switch(e.shiftKey){case!1:n=n.toLowerCase();break;case!0:n=n.toUpperCase()}return n;case 96<=t&&t<=105:return t-96}return""},simulate:function(e,t){return this._reinitialize(e),Array.isArray(t)?t.forEach(function(e){var t={};"object"!=typeof e&&"function"!=typeof e||null===e?t.keyCode=parseInt(e):t=e;var n=new KeyboardEvent("keydown",t);document.dispatchEvent(n)}):this._validateScanCode(e,t),this},_reinitialize:function(e){var t=e.scannerDetectionData.vars;t.firstCharTime=0,t.lastCharTime=0,t.accumulatedString=""},_isFocusOnIgnoredElement:function(e){var t=e.scannerDetectionData.options.ignoreIfFocusOn;if(!t)return!1;var n=document.activeElement;if(Array.isArray(t)){for(var a=0;a<t.length;a++)if(!0===n.matches(t[a]))return!0}else if(n.matches(t))return!0;return!1},_validateScanCode:function(e,t){var n,a=e.scannerDetectionData,i=a.options,o=a.options.singleScanQty,r=a.vars.firstCharTime,s=a.vars.lastCharTime,c={};switch(!0){case t.length<i.minLength:c={message:"Receieved code is shorter then minimal length"};break;case s-r>t.length*i.avgTimeByChar:c={message:"Receieved code was not entered in time"};break;default:return i.onScan.call(e,t,o),n=new CustomEvent("scan",{detail:{scanCode:t,qty:o}}),e.dispatchEvent(n),d._reinitialize(e),!0}return c.scanCode=t,c.scanDuration=s-r,c.avgTimeByChar=i.avgTimeByChar,c.minLength=i.minLength,i.onScanError.call(e,c),n=new CustomEvent("scanError",{detail:c}),e.dispatchEvent(n),d._reinitialize(e),!1},_mergeOptions:function(e,t){var n,a={};for(n in e)Object.prototype.hasOwnProperty.call(e,n)&&(a[n]=e[n]);for(n in t)Object.prototype.hasOwnProperty.call(t,n)&&(a[n]=t[n]);return a},_getNormalizedKeyNum:function(e){return e.which||e.keyCode},_handleKeyDown:function(e){var t=d._getNormalizedKeyNum(e),n=this.scannerDetectionData.options,a=this.scannerDetectionData.vars,i=!1;if(!1!==n.onKeyDetect.call(this,t,e)&&!d._isFocusOnIgnoredElement(this))if(!1===n.scanButtonKeyCode||t!=n.scanButtonKeyCode){switch(!0){case a.firstCharTime&&-1!==n.suffixKeyCodes.indexOf(t):e.preventDefault(),e.stopImmediatePropagation(),i=!0;break;case!a.firstCharTime&&-1!==n.prefixKeyCodes.indexOf(t):e.preventDefault(),e.stopImmediatePropagation(),i=!1;break;default:var o=n.keyCodeMapper.call(this,e);if(null===o)return;a.accumulatedString+=o,n.preventDefault&&e.preventDefault(),n.stopPropagation&&e.stopImmediatePropagation(),i=!1}a.firstCharTime||(a.firstCharTime=Date.now()),a.lastCharTime=Date.now(),a.testTimer&&clearTimeout(a.testTimer),i?(d._validateScanCode(this,a.accumulatedString),a.testTimer=!1):a.testTimer=setTimeout(d._validateScanCode,n.timeBeforeScanTest,this,a.accumulatedString),n.onKeyProcess.call(this,o,e)}else a.longPressed||(a.longPressTimer=setTimeout(n.onScanButtonLongPress,n.scanButtonLongPressTime,this),a.longPressed=!0)},_handlePaste:function(e){if(!d._isFocusOnIgnoredElement(this)){e.preventDefault(),oOptions.stopPropagation&&e.stopImmediatePropagation();var t=(event.clipboardData||window.clipboardData).getData("text");this.scannerDetectionData.options.onPaste.call(this,t,event);var n=this.scannerDetectionData.vars;n.firstCharTime=0,n.lastCharTime=0,d._validateScanCode(this,t)}},_handleKeyUp:function(e){d._isFocusOnIgnoredElement(this)||d._getNormalizedKeyNum(e)==this.scannerDetectionData.options.scanButtonKeyCode&&(clearTimeout(this.scannerDetectionData.vars.longPressTimer),this.scannerDetectionData.vars.longPressed=!1)},isScanInProgressFor:function(e){return 0<e.scannerDetectionData.vars.firstCharTime}};return d});
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index 9d44a9f..6d8ad7e 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -1,7 +1,4 @@
-/* global Clusterize */
frappe.provide('erpnext.PointOfSale');
-{% include "erpnext/selling/page/point_of_sale/pos_controller.js" %}
-frappe.provide('erpnext.queries');
frappe.pages['point-of-sale'].on_page_load = function(wrapper) {
frappe.ui.make_app_page({
@@ -10,8 +7,10 @@
single_column: true
});
- wrapper.pos = new erpnext.PointOfSale.Controller(wrapper);
- window.cur_pos = wrapper.pos;
+ frappe.require('assets/js/point-of-sale.min.js', function() {
+ wrapper.pos = new erpnext.PointOfSale.Controller(wrapper);
+ window.cur_pos = wrapper.pos;
+ })
};
frappe.pages['point-of-sale'].refresh = function(wrapper) {
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index d4cde43..07f58ae 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -1,23 +1,9 @@
-{% include "erpnext/selling/page/point_of_sale/onscan.js" %}
-{% include "erpnext/selling/page/point_of_sale/pos_item_selector.js" %}
-{% include "erpnext/selling/page/point_of_sale/pos_item_cart.js" %}
-{% include "erpnext/selling/page/point_of_sale/pos_item_details.js" %}
-{% include "erpnext/selling/page/point_of_sale/pos_payment.js" %}
-{% include "erpnext/selling/page/point_of_sale/pos_number_pad.js" %}
-{% include "erpnext/selling/page/point_of_sale/pos_past_order_list.js" %}
-{% include "erpnext/selling/page/point_of_sale/pos_past_order_summary.js" %}
-
erpnext.PointOfSale.Controller = class {
constructor(wrapper) {
this.wrapper = $(wrapper).find('.layout-main-section');
this.page = wrapper.page;
- this.load_assets();
- }
-
- load_assets() {
- // after loading assets first check if opening entry has been made
- frappe.require(['assets/erpnext/css/pos.css'], this.check_opening_entry.bind(this));
+ this.check_opening_entry();
}
fetch_opening_entry() {
@@ -36,6 +22,7 @@
}
create_opening_voucher() {
+ const me = this;
const table_fields = [
{
fieldname: "mode_of_payment", fieldtype: "Link",
@@ -45,7 +32,7 @@
{
fieldname: "opening_amount", fieldtype: "Currency",
in_list_view: 1, label: "Opening Amount",
- options: "company:company_currency",
+ options: "company:company_currency",
change: function () {
dialog.fields_dict.balance_details.df.data.some(d => {
if (d.idx == this.doc.idx) {
@@ -93,7 +80,7 @@
fields: table_fields
}
],
- primary_action: async ({ company, pos_profile, balance_details }) => {
+ primary_action: async function({ company, pos_profile, balance_details }) {
if (!balance_details.length) {
frappe.show_alert({
message: __("Please add Mode of payments and opening balance details."),
@@ -103,7 +90,7 @@
}
const method = "erpnext.selling.page.point_of_sale.point_of_sale.create_opening_voucher";
const res = await frappe.call({ method, args: { pos_profile, company, balance_details }, freeze:true });
- !res.exc && this.prepare_app_defaults(res.message);
+ !res.exc && me.prepare_app_defaults(res.message);
dialog.hide();
},
primary_action_label: __('Submit')
@@ -131,36 +118,19 @@
});
}
- set_opening_entry_status() {
- this.page.set_title_sub(
- `<span class="indicator orange">
- <a class="text-muted" href="#Form/POS%20Opening%20Entry/${this.pos_opening}">
- Opened at ${moment(this.pos_opening_time).format("Do MMMM, h:mma")}
- </a>
- </span>`);
- }
-
make_app() {
- return frappe.run_serially([
- () => frappe.dom.freeze(),
- () => {
- this.set_opening_entry_status();
- this.prepare_dom();
- this.prepare_components();
- this.prepare_menu();
- },
- () => this.make_new_invoice(),
- () => frappe.dom.unfreeze(),
- () => this.page.set_title(__('Point of Sale')),
- ]);
+ this.prepare_dom();
+ this.prepare_components();
+ this.prepare_menu();
+ this.make_new_invoice();
}
prepare_dom() {
this.wrapper.append(
- `<div class="app grid grid-cols-10 pt-8 gap-6"></div>`
+ `<div class="point-of-sale-app"></div>`
);
- this.$components_wrapper = this.wrapper.find('.app');
+ this.$components_wrapper = this.wrapper.find('.point-of-sale-app');
}
prepare_components() {
@@ -190,7 +160,7 @@
}
toggle_recent_order() {
- const show = this.recent_order_list.$component.hasClass('d-none');
+ const show = this.recent_order_list.$component.is(':hidden');
this.toggle_recent_order_list(show);
}
@@ -199,7 +169,7 @@
if (this.frm.doc.items.length == 0) {
frappe.show_alert({
- message:__("You must add atleast one item to save it as draft."),
+ message:__("You must add atleast one item to save it as draft."),
indicator:'red'
});
frappe.utils.play_sound("error");
@@ -208,7 +178,7 @@
this.frm.save(undefined, undefined, undefined, () => {
frappe.show_alert({
- message:__("There was an error saving the document."),
+ message:__("There was an error saving the document."),
indicator:'red'
});
frappe.utils.play_sound("error");
@@ -256,7 +226,7 @@
cart_item_clicked: (item_code, batch_no, uom) => {
const item_row = this.frm.doc.items.find(
- i => i.item_code === item_code
+ i => i.item_code === item_code
&& i.uom === uom
&& (!batch_no || (batch_no && i.batch_no === batch_no))
);
@@ -354,10 +324,10 @@
toggle_other_sections: (show) => {
if (show) {
- this.item_details.$component.hasClass('d-none') ? '' : this.item_details.$component.addClass('d-none');
- this.item_selector.$component.addClass('d-none');
+ this.item_details.$component.is(':visible') ? this.item_details.$component.css('display', 'none') : '';
+ this.item_selector.$component.css('display', 'none');
} else {
- this.item_selector.$component.removeClass('d-none');
+ this.item_selector.$component.css('display', 'flex');
}
},
@@ -386,7 +356,7 @@
this.order_summary.load_summary_of(doc);
});
},
- reset_summary: () => this.order_summary.show_summary_placeholder()
+ reset_summary: () => this.order_summary.toggle_summary_placeholder(true)
}
})
}
@@ -427,8 +397,6 @@
})
}
-
-
toggle_recent_order_list(show) {
this.toggle_components(!show);
this.recent_order_list.toggle_component(show);
@@ -445,10 +413,12 @@
make_new_invoice() {
return frappe.run_serially([
+ () => frappe.dom.freeze(),
() => this.make_sales_invoice_frm(),
() => this.set_pos_profile_data(),
() => this.set_pos_profile_status(),
() => this.cart.load_invoice(),
+ () => frappe.dom.unfreeze()
]);
}
@@ -505,16 +475,6 @@
return this.frm.trigger("set_pos_data");
}
- raise_exception_for_pos_profile() {
- setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
- frappe.throw(__("POS Profile is required to use Point-of-Sale"));
- }
-
- set_invoice_status() {
- const [status, indicator] = frappe.listview_settings["POS Invoice"].get_indicator(this.frm.doc);
- this.page.set_indicator(status, indicator);
- }
-
set_pos_profile_status() {
this.page.set_indicator(this.pos_profile, "blue");
}
@@ -537,7 +497,7 @@
const qty_needed = field === 'qty' ? value * item_row.conversion_factor : item_row.qty * value;
await this.check_stock_availability(item_row, qty_needed, this.frm.doc.set_warehouse);
}
-
+
if (this.is_current_item_being_edited(item_row) || item_selected_from_selector) {
await frappe.model.set_value(item_row.doctype, item_row.name, field, value);
this.update_cart_html(item_row);
@@ -575,7 +535,7 @@
this.check_serial_batch_selection_needed(item_row) && this.edit_item_details_of(item_row);
this.update_cart_html(item_row);
- }
+ }
} catch (error) {
console.log(error);
} finally {
@@ -586,7 +546,7 @@
get_item_from_frm(item_code, batch_no, uom) {
const has_batch_no = batch_no;
return this.frm.doc.items.find(
- i => i.item_code === item_code
+ i => i.item_code === item_code
&& (!has_batch_no || (has_batch_no && i.batch_no === batch_no))
&& (i.uom === uom)
);
@@ -615,7 +575,7 @@
const no_serial_selected = !item_row.serial_no;
const no_batch_selected = !item_row.batch_no;
- if ((serialized && no_serial_selected) || (batched && no_batch_selected) ||
+ if ((serialized && no_serial_selected) || (batched && no_batch_selected) ||
(serialized && batched && (no_batch_selected || no_serial_selected))) {
return true;
}
diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js
index 3938300..0c8ee70 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_cart.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js
@@ -5,10 +5,10 @@
this.customer_info = undefined;
this.hide_images = settings.hide_images;
this.allowed_customer_groups = settings.customer_groups;
-
+
this.init_component();
}
-
+
init_component() {
this.prepare_dom();
this.init_child_components();
@@ -18,10 +18,10 @@
prepare_dom() {
this.wrapper.append(
- `<section class="col-span-4 flex flex-col shadow rounded item-cart bg-white mx-h-70 h-100"></section>`
+ `<section class="customer-cart-container"></section>`
)
- this.$component = this.wrapper.find('.item-cart');
+ this.$component = this.wrapper.find('.customer-cart-container');
}
init_child_components() {
@@ -31,33 +31,33 @@
init_customer_selector() {
this.$component.append(
- `<div class="customer-section rounded flex flex-col m-8 mb-0"></div>`
+ `<div class="customer-section"></div>`
)
this.$customer_section = this.$component.find('.customer-section');
this.make_customer_selector();
}
-
+
reset_customer_selector() {
const frm = this.events.get_frm();
frm.set_value('customer', '');
- this.$customer_section.removeClass('border pr-4 pl-4');
this.make_customer_selector();
this.customer_field.set_focus();
}
-
+
init_cart_components() {
this.$component.append(
- `<div class="cart-container flex flex-col items-center rounded flex-1 relative">
- <div class="absolute flex flex-col p-8 pt-0 w-full h-full">
- <div class="flex text-grey cart-header pt-2 pb-2 p-4 mt-2 mb-2 w-full f-shrink-0">
- <div class="flex-1">Item</div>
- <div class="mr-4">Qty</div>
- <div class="rate-list-header mr-1 text-right">Amount</div>
+ `<div class="cart-container">
+ <div class="abs-cart-container">
+ <div class="cart-label">Item Cart</div>
+ <div class="cart-header">
+ <div class="name-header">Item</div>
+ <div class="qty-header">Qty</div>
+ <div class="rate-amount-header">Amount</div>
</div>
- <div class="cart-items-section flex flex-col flex-1 scroll-y rounded w-full"></div>
- <div class="cart-totals-section flex flex-col w-full mt-4 f-shrink-0"></div>
- <div class="numpad-section flex flex-col mt-4 d-none w-full p-8 pt-0 pb-0 f-shrink-0"></div>
- </div>
+ <div class="cart-items-section"></div>
+ <div class="cart-totals-section"></div>
+ <div class="numpad-section"></div>
+ </div>
</div>`
);
this.$cart_container = this.$component.find('.cart-container');
@@ -73,54 +73,48 @@
this.make_no_items_placeholder();
}
-
+
make_no_items_placeholder() {
- this.$cart_header.addClass('d-none');
+ this.$cart_header.css('display', 'none');
this.$cart_items_wrapper.html(
- `<div class="no-item-wrapper flex items-center h-18">
- <div class="flex-1 text-center text-grey">No items in cart</div>
- </div>`
- )
- this.$cart_items_wrapper.addClass('mt-4 border-grey border-dashed');
+ `<div class="no-item-wrapper">No items in cart</div>`
+ );
+ }
+
+ get_discount_icon() {
+ return (
+ `<svg class="discount-icon" width="24" height="24" viewBox="0 0 24 24" stroke="currentColor" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M19 15.6213C19 15.2235 19.158 14.842 19.4393 14.5607L20.9393 13.0607C21.5251 12.4749 21.5251 11.5251 20.9393 10.9393L19.4393 9.43934C19.158 9.15804 19 8.7765 19 8.37868V6.5C19 5.67157 18.3284 5 17.5 5H15.6213C15.2235 5 14.842 4.84196 14.5607 4.56066L13.0607 3.06066C12.4749 2.47487 11.5251 2.47487 10.9393 3.06066L9.43934 4.56066C9.15804 4.84196 8.7765 5 8.37868 5H6.5C5.67157 5 5 5.67157 5 6.5V8.37868C5 8.7765 4.84196 9.15804 4.56066 9.43934L3.06066 10.9393C2.47487 11.5251 2.47487 12.4749 3.06066 13.0607L4.56066 14.5607C4.84196 14.842 5 15.2235 5 15.6213V17.5C5 18.3284 5.67157 19 6.5 19H8.37868C8.7765 19 9.15804 19.158 9.43934 19.4393L10.9393 20.9393C11.5251 21.5251 12.4749 21.5251 13.0607 20.9393L14.5607 19.4393C14.842 19.158 15.2235 19 15.6213 19H17.5C18.3284 19 19 18.3284 19 17.5V15.6213Z" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
+ <path d="M15 9L9 15" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
+ <path d="M10.5 9.5C10.5 10.0523 10.0523 10.5 9.5 10.5C8.94772 10.5 8.5 10.0523 8.5 9.5C8.5 8.94772 8.94772 8.5 9.5 8.5C10.0523 8.5 10.5 8.94772 10.5 9.5Z" fill="white" stroke-linecap="round" stroke-linejoin="round"/>
+ <path d="M15.5 14.5C15.5 15.0523 15.0523 15.5 14.5 15.5C13.9477 15.5 13.5 15.0523 13.5 14.5C13.5 13.9477 13.9477 13.5 14.5 13.5C15.0523 13.5 15.5 13.9477 15.5 14.5Z" fill="white" stroke-linecap="round" stroke-linejoin="round"/>
+ </svg>`
+ );
}
make_cart_totals_section() {
this.$totals_section = this.$component.find('.cart-totals-section');
this.$totals_section.append(
- `<div class="add-discount flex items-center pt-4 pb-4 pr-4 pl-4 text-grey pointer no-select d-none">
- + Add Discount
+ `<div class="add-discount-wrapper">
+ ${this.get_discount_icon()} Add Discount
</div>
- <div class="border border-grey rounded">
- <div class="net-total flex justify-between items-center h-16 pr-8 pl-8 border-b-grey">
- <div class="flex flex-col">
- <div class="text-md text-dark-grey text-bold">Net Total</div>
- </div>
- <div class="flex flex-col text-right">
- <div class="text-md text-dark-grey text-bold">0.00</div>
- </div>
- </div>
- <div class="taxes"></div>
- <div class="grand-total flex justify-between items-center h-16 pr-8 pl-8 border-b-grey">
- <div class="flex flex-col">
- <div class="text-md text-dark-grey text-bold">Grand Total</div>
- </div>
- <div class="flex flex-col text-right">
- <div class="text-md text-dark-grey text-bold">0.00</div>
- </div>
- </div>
- <div class="checkout-btn flex items-center justify-center h-16 pr-8 pl-8 text-center text-grey no-select pointer rounded-b text-md text-bold">
- Checkout
- </div>
- <div class="edit-cart-btn flex items-center justify-center h-16 pr-8 pl-8 text-center text-grey no-select pointer d-none text-md text-bold">
- Edit Cart
- </div>
- </div>`
+ <div class="net-total-container">
+ <div class="net-total-label">Net Total</div>
+ <div class="net-total-value">0.00</div>
+ </div>
+ <div class="taxes-container"></div>
+ <div class="grand-total-container">
+ <div>Grand Total</div>
+ <div>0.00</div>
+ </div>
+ <div class="checkout-btn">Checkout</div>
+ <div class="edit-cart-btn">Edit Cart</div>`
)
- this.$add_discount_elem = this.$component.find(".add-discount");
+ this.$add_discount_elem = this.$component.find(".add-discount-wrapper");
}
-
+
make_cart_numpad() {
this.$numpad_section = this.$component.find('.numpad-section');
@@ -140,39 +134,37 @@
[ '', '', '', 'col-span-2' ],
[ '', '', '', 'col-span-2' ],
[ '', '', '', 'col-span-2' ],
- [ '', '', '', 'col-span-2 text-bold text-danger' ]
+ [ '', '', '', 'col-span-2 remove-btn' ]
],
fieldnames_map: { 'Quantity': 'qty', 'Discount': 'discount_percentage' }
})
this.$numpad_section.prepend(
- `<div class="flex mb-2 justify-between">
+ `<div class="numpad-totals">
<span class="numpad-net-total"></span>
<span class="numpad-grand-total"></span>
</div>`
)
this.$numpad_section.append(
- `<div class="numpad-btn checkout-btn flex items-center justify-center h-16 pr-8 pl-8 bg-primary
- text-center text-white no-select pointer rounded text-md text-bold mt-4" data-button-value="checkout">
- Checkout
- </div>`
+ `<div class="numpad-btn checkout-btn" data-button-value="checkout">Checkout</div>`
)
}
-
+
bind_events() {
const me = this;
- this.$customer_section.on('click', '.add-remove-customer', function (e) {
- const customer_info_is_visible = me.$cart_container.hasClass('d-none');
- customer_info_is_visible ?
- me.toggle_customer_info(false) : me.reset_customer_selector();
+ this.$customer_section.on('click', '.reset-customer-btn', function (e) {
+ me.reset_customer_selector();
});
- this.$customer_section.on('click', '.customer-header', function(e) {
- // don't triggger the event if .add-remove-customer btn is clicked which is under .customer-header
- if ($(e.target).closest('.add-remove-customer').length) return;
+ this.$customer_section.on('click', '.close-details-btn', function (e) {
+ me.toggle_customer_info(false);
+ });
- const show = !me.$cart_container.hasClass('d-none');
+ this.$customer_section.on('click', '.customer-display', function(e) {
+ if ($(e.target).closest('.reset-customer-btn').length) return;
+
+ const show = me.$cart_container.is(':visible');
me.toggle_customer_info(show);
});
@@ -181,7 +173,7 @@
me.toggle_item_highlight(this);
- const payment_section_hidden = me.$totals_section.find('.edit-cart-btn').hasClass('d-none');
+ const payment_section_hidden = !me.$totals_section.find('.edit-cart-btn').is(':visible');
if (!payment_section_hidden) {
// payment section is visible
// edit cart first and then open item details section
@@ -196,23 +188,19 @@
});
this.$component.on('click', '.checkout-btn', function() {
- if (!$(this).hasClass('bg-primary')) return;
-
+ if ($(this).attr('style').indexOf('--blue-500') == -1) return;
+
me.events.checkout();
me.toggle_checkout_btn(false);
-
- me.$add_discount_elem.removeClass("d-none");
});
this.$totals_section.on('click', '.edit-cart-btn', () => {
this.events.edit_cart();
this.toggle_checkout_btn(true);
-
- this.$add_discount_elem.addClass("d-none");
});
- this.$component.on('click', '.add-discount', () => {
- const can_edit_discount = this.$add_discount_elem.find('.edit-discount').length;
+ this.$component.on('click', '.add-discount-wrapper', () => {
+ const can_edit_discount = this.$add_discount_elem.find('.edit-discount-btn').length;
if(!this.discount_field || can_edit_discount) this.show_discount_control();
});
@@ -234,7 +222,7 @@
if (btn === '.') shortcut_key = 'ctrl+>';
// to account for fieldname map
- const fieldname = this.number_pad.fieldnames[btn] ? this.number_pad.fieldnames[btn] :
+ const fieldname = this.number_pad.fieldnames[btn] ? this.number_pad.fieldnames[btn] :
typeof btn === 'string' ? frappe.scrub(btn) : btn;
let shortcut_label = shortcut_key.split('+').map(frappe.utils.to_title_case).join('+');
@@ -245,7 +233,7 @@
const cart_is_visible = this.$component.is(":visible");
if (cart_is_visible && this.item_is_selected && this.$numpad_section.is(":visible")) {
this.$numpad_section.find(`.numpad-btn[data-button-value="${fieldname}"]`).click();
- }
+ }
})
}
}
@@ -254,7 +242,7 @@
frappe.ui.keys.add_shortcut({
shortcut: "ctrl+enter",
action: () => this.$component.find(".checkout-btn").click(),
- condition: () => this.$component.is(":visible") && this.$totals_section.find('.edit-cart-btn').hasClass('d-none'),
+ condition: () => this.$component.is(":visible") && !this.$totals_section.find('.edit-cart-btn').is(':visible'),
description: __("Checkout Order / Submit Order / New Order"),
ignore_inputs: true,
page: cur_page.page.page
@@ -262,14 +250,15 @@
this.$component.find(".edit-cart-btn").attr("title", `${ctrl_label}+E`);
frappe.ui.keys.on("ctrl+e", () => {
const item_cart_visible = this.$component.is(":visible");
- if (item_cart_visible && this.$totals_section.find('.checkout-btn').hasClass('d-none')) {
- this.$component.find(".edit-cart-btn").click()
+ const checkout_btn_invisible = !this.$totals_section.find('.checkout-btn').is('visible');
+ if (item_cart_visible && checkout_btn_invisible) {
+ this.$component.find(".edit-cart-btn").click();
}
});
- this.$component.find(".add-discount").attr("title", `${ctrl_label}+D`);
+ this.$component.find(".add-discount-wrapper").attr("title", `${ctrl_label}+D`);
frappe.ui.keys.add_shortcut({
shortcut: "ctrl+d",
- action: () => this.$component.find(".add-discount").click(),
+ action: () => this.$component.find(".add-discount-wrapper").click(),
condition: () => this.$add_discount_elem.is(":visible"),
description: __("Add Order Discount"),
ignore_inputs: true,
@@ -282,27 +271,25 @@
}
});
}
-
+
toggle_item_highlight(item) {
const $cart_item = $(item);
- const item_is_highlighted = $cart_item.hasClass("shadow");
+ const item_is_highlighted = $cart_item.attr("style") == "background-color:var(--gray-50);";
if (!item || item_is_highlighted) {
this.item_is_selected = false;
- this.$cart_container.find('.cart-item-wrapper').removeClass("shadow").css("opacity", "1");
+ this.$cart_container.find('.cart-item-wrapper').css("background-color", "");
} else {
- $cart_item.addClass("shadow");
+ $cart_item.css("background-color", "var(--gray-50)");
this.item_is_selected = true;
- this.$cart_container.find('.cart-item-wrapper').css("opacity", "1");
- this.$cart_container.find('.cart-item-wrapper').not(item).removeClass("shadow").css("opacity", "0.65");
+ this.$cart_container.find('.cart-item-wrapper').not(item).css("background-color", "");
}
- // highlight with inner shadow
- // $cart_item.addClass("shadow-inner bg-selected");
- // me.$cart_container.find('.cart-item-wrapper').not(this).removeClass("shadow-inner bg-selected");
}
make_customer_selector() {
- this.$customer_section.html(`<div class="customer-search-field flex flex-1 items-center"></div>`);
+ this.$customer_section.html(`
+ <div class="customer-field"></div>
+ `);
const me = this;
const query = { query: 'erpnext.controllers.queries.customer_query' };
const allowed_customer_group = this.allowed_customer_groups || [];
@@ -335,12 +322,12 @@
}
},
},
- parent: this.$customer_section.find('.customer-search-field'),
+ parent: this.$customer_section.find('.customer-field'),
render_input: true,
});
this.customer_field.toggle_label(false);
}
-
+
fetch_customer_details(customer) {
if (customer) {
return new Promise((resolve) => {
@@ -374,9 +361,9 @@
}
show_discount_control() {
- this.$add_discount_elem.removeClass("pr-4 pl-4");
+ this.$add_discount_elem.css({ 'padding': '0px', 'border': 'none' })
this.$add_discount_elem.html(
- `<div class="add-discount-field flex flex-1 items-center"></div>`
+ `<div class="add-discount-field"></div>`
);
const me = this;
@@ -385,14 +372,19 @@
label: __('Discount'),
fieldtype: 'Data',
placeholder: __('Enter discount percentage.'),
+ input_class: 'input-xs',
onchange: function() {
const frm = me.events.get_frm();
- if (this.value.length || this.value === 0) {
+ if (flt(this.value) != 0) {
frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', flt(this.value));
me.hide_discount_control(this.value);
} else {
frappe.model.set_value(frm.doc.doctype, frm.doc.name, 'additional_discount_percentage', 0);
- me.$add_discount_elem.html(`+ Add Discount`);
+ me.$add_discount_elem.css({
+ 'border': '1px dashed var(--gray-500)',
+ 'padding': 'var(--padding-sm) var(--padding-md)'
+ });
+ me.$add_discount_elem.html(`${me.get_discount_icon()} Add Discount`);
me.discount_field = undefined;
}
},
@@ -406,39 +398,36 @@
hide_discount_control(discount) {
if (!discount) {
- this.$add_discount_elem.removeClass("pr-4 pl-4");
+ this.$add_discount_elem.css({ 'padding': '0px', 'border': 'none' });
this.$add_discount_elem.html(
- `<div class="add-discount-field flex flex-1 items-center"></div>`
+ `<div class="add-discount-field"></div>`
);
} else {
- this.$add_discount_elem.addClass('pr-4 pl-4');
+ this.$add_discount_elem.css({
+ 'border': '1px dashed var(--dark-green-500)',
+ 'padding': 'var(--padding-sm) var(--padding-md)'
+ });
this.$add_discount_elem.html(
- `<svg class="mr-2" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1"
- stroke-linecap="round" stroke-linejoin="round">
- <path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/>
- </svg>
- <div class="edit-discount p-1 pr-3 pl-3 text-dark-grey rounded w-fit bg-green-200 mb-2">
- ${String(discount).bold()}% off
- </div>
- `
+ `<div class="edit-discount-btn">
+ ${this.get_discount_icon()} Additional ${String(discount).bold()}% discount applied
+ </div>`
);
}
}
-
+
update_customer_section() {
- const me = this;
const { customer, email_id='', mobile_no='', image } = this.customer_info || {};
if (customer) {
- this.$customer_section.addClass('border pr-4 pl-4').html(
- `<div class="customer-details flex flex-col">
- <div class="customer-header flex items-center rounded h-18 pointer">
- ${get_customer_image()}
- <div class="customer-name flex flex-col flex-1 f-shrink-1 overflow-hidden whitespace-nowrap">
- <div class="text-md text-dark-grey text-bold">${customer}</div>
+ this.$customer_section.html(
+ `<div class="customer-details">
+ <div class="customer-display">
+ ${this.get_customer_image()}
+ <div class="customer-name-desc">
+ <div class="customer-name">${customer}</div>
${get_customer_description()}
</div>
- <div class="f-shrink-0 add-remove-customer flex items-center pointer" data-customer="${escape(customer)}">
+ <div class="reset-customer-btn" data-customer="${escape(customer)}">
<svg width="32" height="32" viewBox="0 0 14 14" fill="none">
<path d="M4.93764 4.93759L7.00003 6.99998M9.06243 9.06238L7.00003 6.99998M7.00003 6.99998L4.93764 9.06238L9.06243 4.93759" stroke="#8D99A6"/>
</svg>
@@ -453,29 +442,27 @@
function get_customer_description() {
if (!email_id && !mobile_no) {
- return `<div class="text-grey-200 italic">Click to add email / phone</div>`
+ return `<div class="customer-desc">Click to add email / phone</div>`
} else if (email_id && !mobile_no) {
- return `<div class="text-grey">${email_id}</div>`
+ return `<div class="customer-desc">${email_id}</div>`
} else if (mobile_no && !email_id) {
- return `<div class="text-grey">${mobile_no}</div>`
+ return `<div class="customer-desc">${mobile_no}</div>`
} else {
- return `<div class="text-grey">${email_id} | ${mobile_no}</div>`
+ return `<div class="customer-desc">${email_id} - ${mobile_no}</div>`
}
}
- function get_customer_image() {
- if (!me.hide_images && image) {
- return `<div class="icon flex items-center justify-center w-12 h-12 rounded bg-light-grey mr-4 text-grey-200">
- <img class="h-full" src="${image}" alt="${image}" style="object-fit: cover;">
- </div>`
- } else {
- return `<div class="icon flex items-center justify-center w-12 h-12 rounded bg-light-grey mr-4 text-grey-200 text-md">
- ${frappe.get_abbr(customer)}
- </div>`
- }
+ }
+
+ get_customer_image() {
+ const { customer, image } = this.customer_info || {};
+ if (image) {
+ return `<div class="customer-image"><img src="${image}" alt="${image}""></div>`
+ } else {
+ return `<div class="customer-image customer-abbr">${frappe.get_abbr(customer)}</div>`
}
}
-
+
update_totals_section(frm) {
if (!frm) frm = this.events.get_frm();
@@ -485,60 +472,47 @@
const taxes = frm.doc.taxes.map(t => { return { description: t.description, rate: t.rate }})
this.render_taxes(frm.doc.base_total_taxes_and_charges, taxes);
}
-
+
render_net_total(value) {
const currency = this.events.get_frm().doc.currency;
- this.$totals_section.find('.net-total').html(
- `<div class="flex flex-col">
- <div class="text-md text-dark-grey text-bold">Net Total</div>
- </div>
- <div class="flex flex-col text-right">
- <div class="text-md text-dark-grey text-bold">${format_currency(value, currency)}</div>
- </div>`
+ this.$totals_section.find('.net-total-container').html(
+ `<div>Net Total</div><div>${format_currency(value, currency)}</div>`
)
- this.$numpad_section.find('.numpad-net-total').html(`Net Total: <span class="text-bold">${format_currency(value, currency)}</span>`)
+ this.$numpad_section.find('.numpad-net-total').html(
+ `<div>Net Total: <span>${format_currency(value, currency)}</span></div>`
+ );
}
-
+
render_grand_total(value) {
const currency = this.events.get_frm().doc.currency;
- this.$totals_section.find('.grand-total').html(
- `<div class="flex flex-col">
- <div class="text-md text-dark-grey text-bold">Grand Total</div>
- </div>
- <div class="flex flex-col text-right">
- <div class="text-md text-dark-grey text-bold">${format_currency(value, currency)}</div>
- </div>`
+ this.$totals_section.find('.grand-total-container').html(
+ `<div>Grand Total</div><div>${format_currency(value, currency)}</div>`
)
- this.$numpad_section.find('.numpad-grand-total').html(`Grand Total: <span class="text-bold">${format_currency(value, currency)}</span>`)
+ this.$numpad_section.find('.numpad-grand-total').html(
+ `<div>Grand Total: <span>${format_currency(value, currency)}</span></div>`
+ )
}
render_taxes(value, taxes) {
if (taxes.length) {
const currency = this.events.get_frm().doc.currency;
- this.$totals_section.find('.taxes').html(
- `<div class="flex items-center justify-between h-16 pr-8 pl-8 border-b-grey">
- <div class="flex overflow-hidden whitespace-nowrap">
- <div class="text-md text-dark-grey text-bold w-fit">Tax Charges</div>
- <div class="flex ml-4 text-dark-grey">
- ${
- taxes.map((t, i) => {
- let margin_left = '';
- if (i !== 0) margin_left = 'ml-2';
- const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`;
- return `<span class="border-grey p-1 pl-2 pr-2 rounded ${margin_left}">${description}</span>`
- }).join('')
- }
- </div>
- </div>
- <div class="flex flex-col text-right f-shrink-0 ml-4">
- <div class="text-md text-dark-grey text-bold">${format_currency(value, currency)}</div>
- </div>
- </div>`
+ this.$totals_section.find('.taxes-container').css('display', 'flex').html(
+ `${
+ taxes.map((t, i) => {
+ const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`;
+ return `<div class="tax-row">
+ <div class="tax-label">
+ ${description}
+ </div>
+ <div class="tax-value">${format_currency(value, currency)}</div>
+ </div>`
+ }).join('')
+ }`
)
} else {
- this.$totals_section.find('.taxes').html('')
+ this.$totals_section.find('.taxes-container').css('display', 'none').html('');
}
}
@@ -547,64 +521,65 @@
const item_code_attr = `[data-item-code="${escape(item_code)}"]`;
const uom_attr = `[data-uom=${escape(uom)}]`;
- const item_selector = batch_no ?
+ const item_selector = batch_no ?
`.cart-item-wrapper${batch_attr}${uom_attr}` : `.cart-item-wrapper${item_code_attr}${uom_attr}`;
-
+
return this.$cart_items_wrapper.find(item_selector);
}
-
+
update_item_html(item, remove_item) {
const $item = this.get_cart_item(item);
if (remove_item) {
- $item && $item.remove();
+ $item && $item.next().remove() && $item.remove();
} else {
const { item_code, batch_no, uom } = item;
const search_field = batch_no ? 'batch_no' : 'item_code';
const search_value = batch_no || item_code;
const item_row = this.events.get_frm().doc.items.find(i => i[search_field] === search_value && i.uom === uom);
-
+
this.render_cart_item(item_row, $item);
}
- const no_of_cart_items = this.$cart_items_wrapper.children().length;
- no_of_cart_items > 0 && this.highlight_checkout_btn(no_of_cart_items > 0);
-
+ const no_of_cart_items = this.$cart_items_wrapper.find('.cart-item-wrapper').length;
+ this.highlight_checkout_btn(no_of_cart_items > 0);
+
this.update_empty_cart_section(no_of_cart_items);
}
-
+
render_cart_item(item_data, $item_to_update) {
const currency = this.events.get_frm().doc.currency;
const me = this;
-
+
if (!$item_to_update.length) {
this.$cart_items_wrapper.append(
- `<div class="cart-item-wrapper flex items-center h-18 pr-4 pl-4 rounded border-grey pointer no-select"
+ `<div class="cart-item-wrapper"
data-item-code="${escape(item_data.item_code)}" data-uom="${escape(item_data.uom)}"
data-batch-no="${escape(item_data.batch_no || '')}">
- </div>`
+ </div>
+ <div class="seperator"></div>`
)
$item_to_update = this.get_cart_item(item_data);
}
$item_to_update.html(
- `<div class="flex flex-col flex-1 f-shrink-1 overflow-hidden whitespace-nowrap">
- <div class="text-md text-dark-grey text-bold">
+ `${get_item_image_html()}
+ <div class="item-name-desc">
+ <div class="item-name">
${item_data.item_name}
</div>
${get_description_html()}
</div>
- ${get_rate_discount_html()}
- </div>`
+ ${get_rate_discount_html()}`
)
set_dynamic_rate_header_width();
this.scroll_to_item($item_to_update);
function set_dynamic_rate_header_width() {
- const rate_cols = Array.from(me.$cart_items_wrapper.find(".rate-col"));
- me.$cart_header.find(".rate-list-header").css("width", "");
- me.$cart_items_wrapper.find(".rate-col").css("width", "");
+ const rate_cols = Array.from(me.$cart_items_wrapper.find(".item-rate-amount"));
+ me.$cart_header.find(".rate-amount-header").css("width", "");
+ me.$cart_items_wrapper.find(".item-rate-amount").css("width", "");
let max_width = rate_cols.reduce((max_width, elm) => {
if ($(elm).width() > max_width)
max_width = $(elm).width();
@@ -614,30 +589,26 @@
max_width += 1;
if (max_width == 1) max_width = "";
- me.$cart_header.find(".rate-list-header").css("width", max_width);
- me.$cart_items_wrapper.find(".rate-col").css("width", max_width);
+ me.$cart_header.find(".rate-amount-header").css("width", max_width);
+ me.$cart_items_wrapper.find(".item-rate-amount").css("width", max_width);
}
-
+
function get_rate_discount_html() {
if (item_data.rate && item_data.amount && item_data.rate !== item_data.amount) {
return `
- <div class="flex f-shrink-0 ml-4 items-center">
- <div class="flex w-8 h-8 rounded bg-light-grey mr-4 items-center justify-center font-bold f-shrink-0">
- <span>${item_data.qty || 0}</span>
- </div>
- <div class="rate-col flex flex-col f-shrink-0 text-right">
- <div class="text-md text-dark-grey text-bold">${format_currency(item_data.amount, currency)}</div>
- <div class="text-md-0 text-dark-grey">${format_currency(item_data.rate, currency)}</div>
+ <div class="item-qty-rate">
+ <div class="item-qty"><span>${item_data.qty || 0}</span></div>
+ <div class="item-rate-amount">
+ <div class="item-rate">${format_currency(item_data.amount, currency)}</div>
+ <div class="item-amount">${format_currency(item_data.rate, currency)}</div>
</div>
</div>`
} else {
return `
- <div class="flex f-shrink-0 ml-4 text-right">
- <div class="flex w-8 h-8 rounded bg-light-grey mr-4 items-center justify-center font-bold f-shrink-0">
- <span>${item_data.qty || 0}</span>
- </div>
- <div class="rate-col flex flex-col f-shrink-0 text-right">
- <div class="text-md text-dark-grey text-bold">${format_currency(item_data.rate, currency)}</div>
+ <div class="item-qty-rate">
+ <div class="item-qty"><span>${item_data.qty || 0}</span></div>
+ <div class="item-rate-amount">
+ <div class="item-rate">${format_currency(item_data.rate, currency)}</div>
</div>
</div>`
}
@@ -653,10 +624,19 @@
}
}
item_data.description = frappe.ellipsis(item_data.description, 45);
- return `<div class="text-grey">${item_data.description}</div>`
+ return `<div class="item-desc">${item_data.description}</div>`
}
return ``;
}
+
+ function get_item_image_html() {
+ const { image, item_name } = item_data;
+ if (image) {
+ return `<div class="item-image"><img src="${image}" alt="${image}""></div>`
+ } else {
+ return `<div class="item-image item-abbr">${frappe.get_abbr(item_name)}</div>`
+ }
+ }
}
scroll_to_item($item) {
@@ -664,7 +644,7 @@
const scrollTop = $item.offset().top - this.$cart_items_wrapper.offset().top + this.$cart_items_wrapper.scrollTop();
this.$cart_items_wrapper.animate({ scrollTop });
}
-
+
update_selector_value_in_cart_item(selector, value, item) {
const $item_to_update = this.get_cart_item(item);
$item_to_update.attr(`data-${selector}`, value);
@@ -672,33 +652,37 @@
toggle_checkout_btn(show_checkout) {
if (show_checkout) {
- this.$totals_section.find('.checkout-btn').removeClass('d-none');
- this.$totals_section.find('.edit-cart-btn').addClass('d-none');
+ this.$totals_section.find('.checkout-btn').css('display', 'flex');
+ this.$totals_section.find('.edit-cart-btn').css('display', 'none');
} else {
- this.$totals_section.find('.checkout-btn').addClass('d-none');
- this.$totals_section.find('.edit-cart-btn').removeClass('d-none');
+ this.$totals_section.find('.checkout-btn').css('display', 'none');
+ this.$totals_section.find('.edit-cart-btn').css('display', 'flex');
}
}
highlight_checkout_btn(toggle) {
- const has_primary_class = this.$totals_section.find('.checkout-btn').hasClass('bg-primary');
- if (toggle && !has_primary_class) {
- this.$totals_section.find('.checkout-btn').addClass('bg-primary text-white text-lg');
- } else if (!toggle && has_primary_class) {
- this.$totals_section.find('.checkout-btn').removeClass('bg-primary text-white text-lg');
+ if (toggle) {
+ this.$add_discount_elem.css('display', 'flex');
+ this.$cart_container.find('.checkout-btn').css({
+ 'background-color': 'var(--blue-500)'
+ });
+ } else {
+ this.$add_discount_elem.css('display', 'none');
+ this.$cart_container.find('.checkout-btn').css({
+ 'background-color': 'var(--blue-200)'
+ });
}
}
-
+
update_empty_cart_section(no_of_cart_items) {
const $no_item_element = this.$cart_items_wrapper.find('.no-item-wrapper');
// if cart has items and no item is present
- no_of_cart_items > 0 && $no_item_element && $no_item_element.remove()
- && this.$cart_items_wrapper.removeClass('mt-4 border-grey border-dashed') && this.$cart_header.removeClass('d-none');
+ no_of_cart_items > 0 && $no_item_element && $no_item_element.remove() && this.$cart_header.css('display', 'flex');
no_of_cart_items === 0 && !$no_item_element.length && this.make_no_items_placeholder();
}
-
+
on_numpad_event($btn) {
const current_action = $btn.attr('data-button-value');
const action_is_field_edit = ['qty', 'discount_percentage', 'rate'].includes(current_action);
@@ -717,7 +701,7 @@
this.prev_action = undefined;
}
this.numpad_value = '';
-
+
} else if (current_action === 'checkout') {
this.prev_action = undefined;
this.toggle_item_highlight();
@@ -743,7 +727,7 @@
frappe.utils.play_sound("error");
return;
}
-
+
if (flt(this.numpad_value) > 100 && this.prev_action === 'discount_percentage') {
frappe.show_alert({
message: __('Discount cannot be greater than 100%'),
@@ -755,38 +739,38 @@
this.events.numpad_event(this.numpad_value, this.prev_action);
}
-
+
highlight_numpad_btn($btn, curr_action) {
- const curr_action_is_highlighted = $btn.hasClass('shadow-inner');
+ const curr_action_is_highlighted = $btn.hasClass('highlighted-numpad-btn');
const curr_action_is_action = ['qty', 'discount_percentage', 'rate', 'done'].includes(curr_action);
if (!curr_action_is_highlighted) {
- $btn.addClass('shadow-inner bg-selected');
+ $btn.addClass('highlighted-numpad-btn');
}
if (this.prev_action === curr_action && curr_action_is_highlighted) {
// if Qty is pressed twice
- $btn.removeClass('shadow-inner bg-selected');
+ $btn.removeClass('highlighted-numpad-btn');
}
if (this.prev_action && this.prev_action !== curr_action && curr_action_is_action) {
// Order: Qty -> Rate then remove Qty highlight
const prev_btn = $(`[data-button-value='${this.prev_action}']`);
- prev_btn.removeClass('shadow-inner bg-selected');
+ prev_btn.removeClass('highlighted-numpad-btn');
}
if (!curr_action_is_action || curr_action === 'done') {
// if numbers are clicked
setTimeout(() => {
- $btn.removeClass('shadow-inner bg-selected');
- }, 100);
+ $btn.removeClass('highlighted-numpad-btn');
+ }, 200);
}
}
toggle_numpad(show) {
if (show) {
- this.$totals_section.addClass('d-none');
- this.$numpad_section.removeClass('d-none');
+ this.$totals_section.css('display', 'none');
+ this.$numpad_section.css('display', 'flex');
} else {
- this.$totals_section.removeClass('d-none');
- this.$numpad_section.addClass('d-none');
+ this.$totals_section.css('display', 'flex');
+ this.$numpad_section.css('display', 'none');
}
this.reset_numpad();
}
@@ -794,7 +778,7 @@
reset_numpad() {
this.numpad_value = '';
this.prev_action = undefined;
- this.$numpad_section.find('.shadow-inner').removeClass('shadow-inner bg-selected');
+ this.$numpad_section.find('.highlighted-numpad-btn').removeClass('highlighted-numpad-btn');
}
toggle_numpad_field_edit(fieldname) {
@@ -805,48 +789,56 @@
toggle_customer_info(show) {
if (show) {
- this.$cart_container.addClass('d-none')
- this.$customer_section.addClass('flex-1 scroll-y').removeClass('mb-0 border pr-4 pl-4')
- this.$customer_section.find('.icon').addClass('w-24 h-24 text-2xl').removeClass('w-12 h-12 text-md')
- this.$customer_section.find('.customer-header').removeClass('h-18');
- this.$customer_section.find('.customer-details').addClass('sticky z-100 bg-white');
+ const { customer } = this.customer_info || {};
- this.$customer_section.find('.customer-name').html(
- `<div class="text-md text-dark-grey text-bold">${this.customer_info.customer}</div>
- <div class="last-transacted-on text-grey-200"></div>`
- )
-
- this.$customer_section.find('.customer-details').append(
- `<div class="customer-form">
- <div class="text-grey mt-4 mb-6">CONTACT DETAILS</div>
- <div class="grid grid-cols-2 gap-4">
- <div class="email_id-field"></div>
- <div class="mobile_no-field"></div>
- <div class="loyalty_program-field"></div>
- <div class="loyalty_points-field"></div>
+ this.$cart_container.css('display', 'none');
+ this.$customer_section.css({
+ 'height': '100%',
+ 'padding-top': '0px'
+ });
+ this.$customer_section.find('.customer-details').html(
+ `<div class="header">
+ <div class="label">Contact Details</div>
+ <div class="close-details-btn">
+ <svg width="32" height="32" viewBox="0 0 14 14" fill="none">
+ <path d="M4.93764 4.93759L7.00003 6.99998M9.06243 9.06238L7.00003 6.99998M7.00003 6.99998L4.93764 9.06238L9.06243 4.93759" stroke="#8D99A6"/>
+ </svg>
</div>
- <div class="text-grey mt-4 mb-6">RECENT TRANSACTIONS</div>
- </div>`
- )
+ </div>
+ <div class="customer-display">
+ ${this.get_customer_image()}
+ <div class="customer-name-desc">
+ <div class="customer-name">${customer}</div>
+ <div class="customer-desc"></div>
+ </div>
+ </div>
+ <div class="customer-fields-container">
+ <div class="email_id-field"></div>
+ <div class="mobile_no-field"></div>
+ <div class="loyalty_program-field"></div>
+ <div class="loyalty_points-field"></div>
+ </div>
+ <div class="transactions-label">Recent Transactions</div>`
+ );
// transactions need to be in diff div from sticky elem for scrolling
- this.$customer_section.append(`<div class="customer-transactions flex-1 rounded"></div>`)
+ this.$customer_section.append(`<div class="customer-transactions"></div>`)
- this.render_customer_info_form();
+ this.render_customer_fields();
this.fetch_customer_transactions();
} else {
- this.$cart_container.removeClass('d-none');
- this.$customer_section.removeClass('flex-1 scroll-y').addClass('mb-0 border pr-4 pl-4');
- this.$customer_section.find('.icon').addClass('w-12 h-12 text-md').removeClass('w-24 h-24 text-2xl');
- this.$customer_section.find('.customer-header').addClass('h-18')
- this.$customer_section.find('.customer-details').removeClass('sticky z-100 bg-white');
+ this.$cart_container.css('display', 'flex');
+ this.$customer_section.css({
+ 'height': '',
+ 'padding-top': ''
+ });
this.update_customer_section();
}
}
- render_customer_info_form() {
- const $customer_form = this.$customer_section.find('.customer-form');
+ render_customer_fields() {
+ const $customer_form = this.$customer_section.find('.customer-fields-container');
const dfs = [{
fieldname: 'email_id',
@@ -868,7 +860,7 @@
},{
fieldname: 'loyalty_points',
label: __('Loyalty Points'),
- fieldtype: 'Int',
+ fieldtype: 'Data',
read_only: 1
}];
@@ -912,7 +904,7 @@
}
fetch_customer_transactions() {
- frappe.db.get_list('POS Invoice', {
+ frappe.db.get_list('POS Invoice', {
filters: { customer: this.customer_info.customer, docstatus: 1 },
fields: ['name', 'grand_total', 'status', 'posting_date', 'posting_time', 'currency'],
limit: 20
@@ -920,41 +912,45 @@
const transaction_container = this.$customer_section.find('.customer-transactions');
if (!res.length) {
- transaction_container.removeClass('flex-1 border rounded').html(
- `<div class="text-grey text-center">No recent transactions found</div>`
+ transaction_container.html(
+ `<div class="no-transactions-placeholder">No recent transactions found</div>`
)
return;
};
const elapsed_time = moment(res[0].posting_date+" "+res[0].posting_time).fromNow();
- this.$customer_section.find('.last-transacted-on').html(`Last transacted ${elapsed_time}`);
+ this.$customer_section.find('.customer-desc').html(`Last transacted ${elapsed_time}`);
res.forEach(invoice => {
const posting_datetime = moment(invoice.posting_date+" "+invoice.posting_time).format("Do MMMM, h:mma");
- let indicator_color = '';
-
- if (in_list(['Paid', 'Consolidated'], invoice.status)) (indicator_color = 'green');
- if (invoice.status === 'Draft') (indicator_color = 'red');
- if (invoice.status === 'Return') (indicator_color = 'grey');
+ let indicator_color = {
+ 'Paid': 'green',
+ 'Draft': 'red',
+ 'Return': 'gray',
+ 'Consolidated': 'blue'
+ };
transaction_container.append(
- `<div class="invoice-wrapper flex p-3 justify-between border-grey rounded pointer no-select" data-invoice-name="${escape(invoice.name)}">
- <div class="flex flex-col justify-end">
- <div class="text-dark-grey text-bold overflow-hidden whitespace-nowrap mb-2">${invoice.name}</div>
- <div class="flex items-center f-shrink-1 text-dark-grey overflow-hidden whitespace-nowrap">
- ${posting_datetime}
- </div>
+ `<div class="invoice-wrapper" data-invoice-name="${escape(invoice.name)}">
+ <div class="invoice-name-date">
+ <div class="invoice-name">${invoice.name}</div>
+ <div class="invoice-date">${posting_datetime}</div>
</div>
- <div class="flex flex-col text-right">
- <div class="f-shrink-0 text-md text-dark-grey text-bold ml-4">
+ <div class="invoice-total-status">
+ <div class="invoice-total">
${format_currency(invoice.grand_total, invoice.currency, 0) || 0}
</div>
- <div class="f-shrink-0 text-grey ml-4 text-bold indicator ${indicator_color}">${invoice.status}</div>
+ <div class="invoice-status">
+ <span class="indicator-pill whitespace-nowrap ${indicator_color[invoice.status]}">
+ <span>${invoice.status}</span>
+ </span>
+ </div>
</div>
- </div>`
+ </div>
+ <div class="seperator"></div>`
)
});
- })
+ });
}
load_invoice() {
@@ -963,7 +959,7 @@
this.events.customer_details_updated(this.customer_info);
this.update_customer_section();
})
-
+
this.$cart_items_wrapper.html('');
if (frm.doc.items.length) {
frm.doc.items.forEach(item => {
@@ -977,20 +973,18 @@
this.update_totals_section(frm);
if(frm.doc.docstatus === 1) {
- this.$totals_section.find('.checkout-btn').addClass('d-none');
- this.$totals_section.find('.edit-cart-btn').addClass('d-none');
- this.$totals_section.find('.grand-total').removeClass('border-b-grey');
+ this.$totals_section.find('.checkout-btn').css('display', 'none');
+ this.$totals_section.find('.edit-cart-btn').css('display', 'none');
} else {
- this.$totals_section.find('.checkout-btn').removeClass('d-none');
- this.$totals_section.find('.edit-cart-btn').addClass('d-none');
- this.$totals_section.find('.grand-total').addClass('border-b-grey');
+ this.$totals_section.find('.checkout-btn').css('display', 'flex');
+ this.$totals_section.find('.edit-cart-btn').css('display', 'none');
}
this.toggle_component(true);
}
toggle_component(show) {
- show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none');
+ show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none');
}
-
+
}
diff --git a/erpnext/selling/page/point_of_sale/pos_item_details.js b/erpnext/selling/page/point_of_sale/pos_item_details.js
index a4de9f1..5461543 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_details.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_details.js
@@ -16,35 +16,36 @@
prepare_dom() {
this.wrapper.append(
- `<section class="col-span-4 flex shadow rounded item-details bg-white mx-h-70 h-100 d-none"></section>`
+ `<section class="item-details-container"></section>`
)
- this.$component = this.wrapper.find('.item-details');
+ this.$component = this.wrapper.find('.item-details-container');
}
init_child_components() {
this.$component.html(
- `<div class="details-container flex flex-col p-8 rounded w-full">
- <div class="flex justify-between mb-2">
- <div class="text-grey">ITEM DETAILS</div>
- <div class="close-btn text-grey hover-underline pointer no-select">Close</div>
+ `<div class="item-details-header">
+ <div class="label">Item Details</div>
+ <div class="close-btn">
+ <svg width="32" height="32" viewBox="0 0 14 14" fill="none">
+ <path d="M4.93764 4.93759L7.00003 6.99998M9.06243 9.06238L7.00003 6.99998M7.00003 6.99998L4.93764 9.06238L9.06243 4.93759" stroke="#8D99A6"/>
+ </svg>
</div>
- <div class="item-defaults flex">
- <div class="flex-1 flex flex-col justify-end mr-4 mb-2">
- <div class="item-name text-xl font-weight-450"></div>
- <div class="item-description text-md-0 text-grey-200"></div>
- <div class="item-price text-xl font-bold"></div>
- </div>
- <div class="item-image flex items-center justify-center w-46 h-46 bg-light-grey rounded ml-4 text-6xl text-grey-100"></div>
+ </div>
+ <div class="item-display">
+ <div class="item-name-desc-price">
+ <div class="item-name"></div>
+ <div class="item-desc"></div>
+ <div class="item-price"></div>
</div>
- <div class="discount-section flex items-center"></div>
- <div class="text-grey mt-4 mb-6">STOCK DETAILS</div>
- <div class="form-container grid grid-cols-2 row-gap-2 col-gap-4 grid-auto-row"></div>
- </div>`
+ <div class="item-image"></div>
+ </div>
+ <div class="discount-section"></div>
+ <div class="form-container"></div>`
)
this.$item_name = this.$component.find('.item-name');
- this.$item_description = this.$component.find('.item-description');
+ this.$item_description = this.$component.find('.item-desc');
this.$item_price = this.$component.find('.item-price');
this.$item_image = this.$component.find('.item-image');
this.$form_container = this.$component.find('.form-container');
@@ -52,7 +53,7 @@
}
toggle_item_details_section(item) {
- const { item_code, batch_no, uom } = this.current_item;
+ const { item_code, batch_no, uom } = this.current_item;
const item_code_is_same = item && item_code === item.item_code;
const batch_is_same = item && batch_no == item.batch_no;
const uom_is_same = item && uom === item.uom;
@@ -104,11 +105,11 @@
}
render_dom(item) {
- let { item_code ,item_name, description, image, price_list_rate } = item;
+ let { item_name, description, image, price_list_rate } = item;
function get_description_html() {
if (description) {
- description = description.indexOf('...') === -1 && description.length > 75 ? description.substr(0, 73) + '...' : description;
+ description = description.indexOf('...') === -1 && description.length > 140 ? description.substr(0, 139) + '...' : description;
return description;
}
return ``;
@@ -118,11 +119,9 @@
this.$item_description.html(get_description_html());
this.$item_price.html(format_currency(price_list_rate, this.currency));
if (image) {
- this.$item_image.html(
- `<img class="h-full" src="${image}" alt="${image}" style="object-fit: cover;">`
- );
+ this.$item_image.html(`<img src="${image}" alt="${image}">`);
} else {
- this.$item_image.html(frappe.get_abbr(item_code));
+ this.$item_image.html(`<div class="item-abbr">${frappe.get_abbr(item_name)}</div>`);
}
}
@@ -130,12 +129,8 @@
render_discount_dom(item) {
if (item.discount_percentage) {
this.$dicount_section.html(
- `<div class="text-grey line-through mr-4 text-md mb-2">
- ${format_currency(item.price_list_rate, this.currency)}
- </div>
- <div class="p-1 pr-3 pl-3 rounded w-fit text-bold bg-green-200 mb-2">
- ${item.discount_percentage}% off
- </div>`
+ `<div class="item-rate">${format_currency(item.price_list_rate, this.currency)}</div>
+ <div class="item-discount">${item.discount_percentage}% off</div>`
)
this.$item_price.html(format_currency(item.rate, this.currency));
} else {
@@ -149,9 +144,7 @@
fields_to_display.forEach((fieldname, idx) => {
this.$form_container.append(
- `<div class="">
- <div class="item_detail_field ${fieldname}-control" data-fieldname="${fieldname}"></div>
- </div>`
+ `<div class="${fieldname}-control" data-fieldname="${fieldname}"></div>`
)
const field_meta = this.item_meta.fields.find(df => df.fieldname === fieldname);
@@ -185,22 +178,15 @@
make_auto_serial_selection_btn(item) {
if (item.has_serial_no) {
- this.$form_container.append(
- `<div class="grid-filler no-select"></div>`
- )
if (!item.has_batch_no) {
this.$form_container.append(
`<div class="grid-filler no-select"></div>`
)
}
this.$form_container.append(
- `<div class="auto-fetch-btn bg-grey-100 border border-grey text-bold rounded pt-3 pb-3 pl-6 pr-8 text-grey pointer no-select mt-2"
- style="height: 3.3rem">
- Auto Fetch Serial Numbers
- </div>`
+ `<div class="btn btn-sm btn-secondary auto-fetch-btn">Auto Fetch Serial Numbers</div>`
)
- this.$form_container.find('.serial_no-control').find('textarea').css('height', '9rem');
- this.$form_container.find('.serial_no-control').parent().addClass('row-span-2');
+ this.$form_container.find('.serial_no-control').find('textarea').css('height', '6rem');
}
}
@@ -294,8 +280,13 @@
}
frappe.model.on("POS Invoice Item", "*", (fieldname, value, item_row) => {
- const field_control = me[`${fieldname}_control`];
- if (field_control) {
+ const field_control = this[`${fieldname}_control`];
+ const { item_code, batch_no, uom } = this.current_item;
+ const item_code_is_same = item_code === item_row.item_code;
+ const batch_is_same = batch_no == item_row.batch_no;
+ const uom_is_same = uom === item_row.uom;
+
+ if (field_control && item_code_is_same && batch_is_same && uom_is_same) {
field_control.set_value(value);
cur_pos.update_cart_html(item_row);
}
@@ -409,6 +400,6 @@
}
toggle_component(show) {
- show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none');
+ show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none');
}
}
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js
index a06b394..740fd01 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_selector.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js
@@ -1,3 +1,5 @@
+import onScan from 'onscan.js';
+
erpnext.PointOfSale.ItemSelector = class {
constructor({ frm, wrapper, events, pos_profile, settings }) {
this.wrapper = wrapper;
@@ -5,10 +7,10 @@
this.pos_profile = pos_profile;
this.hide_images = settings.hide_images;
this.auto_add_item = settings.auto_add_item_to_cart;
-
+
this.inti_component();
}
-
+
inti_component() {
this.prepare_dom();
this.make_search_bar();
@@ -19,21 +21,16 @@
prepare_dom() {
this.wrapper.append(
- `<section class="col-span-6 flex shadow rounded items-selector bg-white mx-h-70 h-100">
- <div class="flex flex-col rounded w-full scroll-y">
- <div class="filter-section flex p-8 pb-2 bg-white sticky z-100">
- <div class="search-field flex f-grow-3 mr-8 items-center text-grey"></div>
- <div class="item-group-field flex f-grow-1 items-center text-grey text-bold"></div>
- </div>
- <div class="flex flex-1 flex-col p-8 pt-2">
- <div class="text-grey mb-6">ALL ITEMS</div>
- <div class="items-container grid grid-cols-4 gap-8">
- </div>
- </div>
+ `<section class="items-selector">
+ <div class="filter-section">
+ <div class="label">All Items</div>
+ <div class="search-field"></div>
+ <div class="item-group-field"></div>
</div>
+ <div class="items-container"></div>
</section>`
);
-
+
this.$component = this.wrapper.find('.items-selector');
this.$items_container = this.$component.find('.items-container');
}
@@ -54,11 +51,12 @@
}
get_items({start = 0, page_length = 40, search_value=''}) {
- const price_list = this.events.get_frm().doc?.selling_price_list || this.price_list;
+ const doc = this.events.get_frm().doc;
+ const price_list = (doc && doc.selling_price_list) || this.price_list;
let { item_group, pos_profile } = this;
!item_group && (item_group = this.parent_item_group);
-
+
return frappe.call({
method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items",
freeze: true,
@@ -87,23 +85,24 @@
<img class="h-full" src="${item_image}" alt="${frappe.get_abbr(item.item_name)}" style="object-fit: cover;">
</div>`
} else {
- return `<div class="flex items-center justify-center h-32 bg-light-grey text-6xl text-grey-100">
- ${frappe.get_abbr(item.item_name)}
- </div>`
+ return `<div class="item-display abbr">${frappe.get_abbr(item.item_name)}</div>`;
}
}
return (
- `<div class="item-wrapper rounded shadow pointer no-select" data-item-code="${escape(item.item_code)}"
- data-serial-no="${escape(serial_no)}" data-batch-no="${escape(batch_no)}" data-uom="${escape(stock_uom)}"
+ `<div class="item-wrapper"
+ data-item-code="${escape(item.item_code)}" data-serial-no="${escape(serial_no)}"
+ data-batch-no="${escape(batch_no)}" data-uom="${escape(stock_uom)}"
title="Avaiable Qty: ${actual_qty}">
+
${get_item_image_html()}
- <div class="flex items-center pr-4 pl-4 h-10 justify-between">
- <div class="flex items-center f-shrink-1 text-dark-grey overflow-hidden whitespace-nowrap">
+
+ <div class="item-detail">
+ <div class="item-name">
<span class="indicator ${indicator_color}"></span>
${frappe.ellipsis(item.item_name, 18)}
</div>
- <div class="f-shrink-0 text-dark-grey text-bold ml-4">${format_currency(item.price_list_rate, item.currency, 0) || 0}</div>
+ <div class="item-rate">${format_currency(item.price_list_rate, item.currency, 0) || 0}</div>
</div>
</div>`
)
@@ -111,6 +110,7 @@
make_search_bar() {
const me = this;
+ const doc = me.events.get_frm().doc;
this.$component.find('.search-field').html('');
this.$component.find('.item-group-field').html('');
@@ -118,7 +118,7 @@
df: {
label: __('Search'),
fieldtype: 'Data',
- placeholder: __('Search by item code, serial number, batch no or barcode')
+ placeholder: __('Search by item code, serial number or barcode')
},
parent: this.$component.find('.search-field'),
render_input: true,
@@ -138,7 +138,7 @@
return {
query: 'erpnext.selling.page.point_of_sale.point_of_sale.item_group_query',
filters: {
- pos_profile: me.events.get_frm().doc?.pos_profile
+ pos_profile: doc ? doc.pos_profile : ''
}
}
},
@@ -152,6 +152,7 @@
bind_events() {
const me = this;
+ window.onScan = onScan;
onScan.attachTo(document, {
onScan: (sScancode) => {
if (this.search_field && this.$component.is(':visible')) {
@@ -168,7 +169,7 @@
let batch_no = unescape($item.attr('data-batch-no'));
let serial_no = unescape($item.attr('data-serial-no'));
let uom = unescape($item.attr('data-uom'));
-
+
// escape(undefined) returns "undefined" then unescape returns "undefined"
batch_no = batch_no === "undefined" ? undefined : batch_no;
serial_no = serial_no === "undefined" ? undefined : serial_no;
@@ -228,7 +229,7 @@
}
});
}
-
+
filter_items({ search_term='' }={}) {
if (search_term) {
search_term = search_term.toLowerCase();
@@ -259,26 +260,26 @@
add_filtered_item_to_cart() {
this.$items_container.find(".item-wrapper").click();
}
-
+
resize_selector(minimize) {
- minimize ?
- this.$component.find('.search-field').removeClass('mr-8') :
- this.$component.find('.search-field').addClass('mr-8');
-
- minimize ?
- this.$component.find('.filter-section').addClass('flex-col') :
- this.$component.find('.filter-section').removeClass('flex-col');
+ minimize ?
+ this.$component.find('.filter-section').css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') :
+ this.$component.find('.filter-section').css('grid-template-columns', 'repeat(12, minmax(0, 1fr))');
minimize ?
- this.$component.removeClass('col-span-6').addClass('col-span-2') :
- this.$component.removeClass('col-span-2').addClass('col-span-6')
+ this.$component.find('.search-field').css('margin', 'var(--margin-sm) 0px') :
+ this.$component.find('.search-field').css('margin', '0px var(--margin-sm)');
minimize ?
- this.$items_container.removeClass('grid-cols-4').addClass('grid-cols-1') :
- this.$items_container.removeClass('grid-cols-1').addClass('grid-cols-4')
+ this.$component.css('grid-column', 'span 2 / span 2') :
+ this.$component.css('grid-column', 'span 6 / span 6')
+
+ minimize ?
+ this.$items_container.css('grid-template-columns', 'repeat(1, minmax(0, 1fr))') :
+ this.$items_container.css('grid-template-columns', 'repeat(4, minmax(0, 1fr))')
}
toggle_component(show) {
- show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none');
+ show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none');
}
}
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/pos_number_pad.js b/erpnext/selling/page/point_of_sale/pos_number_pad.js
index 4b8e841..edde7d8 100644
--- a/erpnext/selling/page/point_of_sale/pos_number_pad.js
+++ b/erpnext/selling/page/point_of_sale/pos_number_pad.js
@@ -25,14 +25,13 @@
const fieldname = fieldnames && fieldnames[number] ?
fieldnames[number] : typeof number === 'string' ? frappe.scrub(number) : number;
- return a2 + `<div class="numpad-btn pointer no-select rounded ${class_to_append}
- flex items-center justify-center h-16 text-md border-grey border" data-button-value="${fieldname}">${number}</div>`
+ return a2 + `<div class="numpad-btn ${class_to_append}" data-button-value="${fieldname}">${number}</div>`
}, '')
}, '');
}
this.wrapper.html(
- `<div class="grid grid-cols-${cols} gap-4">
+ `<div class="numpad-container">
${get_keys()}
</div>`
)
diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_list.js b/erpnext/selling/page/point_of_sale/pos_past_order_list.js
index b256247..ec39231 100644
--- a/erpnext/selling/page/point_of_sale/pos_past_order_list.js
+++ b/erpnext/selling/page/point_of_sale/pos_past_order_list.js
@@ -14,17 +14,13 @@
prepare_dom() {
this.wrapper.append(
- `<section class="col-span-4 flex flex-col shadow rounded past-order-list bg-white mx-h-70 h-100 d-none">
- <div class="flex flex-col rounded w-full scroll-y">
- <div class="filter-section flex flex-col p-8 pb-2 bg-white sticky z-100">
- <div class="search-field flex items-center text-grey"></div>
- <div class="status-field flex items-center text-grey text-bold"></div>
- </div>
- <div class="flex flex-1 flex-col p-8 pt-2">
- <div class="text-grey mb-6">RECENT ORDERS</div>
- <div class="invoices-container rounded border grid grid-cols-1"></div>
- </div>
+ `<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>
+ <div class="invoices-container"></div>
</section>`
);
@@ -66,7 +62,7 @@
options: `Draft\nPaid\nConsolidated\nReturn`,
placeholder: __('Filter by invoice status'),
onchange: function() {
- me.refresh_list(me.search_field.get_value(), this.value);
+ if (me.$component.is(':visible')) me.refresh_list();
}
},
parent: this.$component.find('.status-field'),
@@ -77,10 +73,6 @@
this.status_field.set_value('Draft');
}
- toggle_component(show) {
- show ? this.$component.removeClass('d-none') && this.refresh_list() : this.$component.addClass('d-none');
- }
-
refresh_list() {
frappe.dom.freeze();
this.events.reset_summary();
@@ -106,23 +98,26 @@
get_invoice_html(invoice) {
const posting_datetime = moment(invoice.posting_date+" "+invoice.posting_time).format("Do MMMM, h:mma");
return (
- `<div class="invoice-wrapper flex p-4 justify-between border-b-grey pointer no-select" data-invoice-name="${escape(invoice.name)}">
- <div class="flex flex-col justify-end">
- <div class="text-dark-grey text-bold overflow-hidden whitespace-nowrap mb-2">${invoice.name}</div>
- <div class="flex items-center">
- <div class="flex items-center f-shrink-1 text-dark-grey overflow-hidden whitespace-nowrap">
- <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>
- ${invoice.customer}
- </div>
+ `<div class="invoice-wrapper" data-invoice-name="${escape(invoice.name)}">
+ <div class="invoice-name-date">
+ <div class="invoice-name">${invoice.name}</div>
+ <div class="invoice-date">
+ <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>
+ ${invoice.customer}
</div>
</div>
- <div class="flex flex-col text-right">
- <div class="f-shrink-0 text-lg text-dark-grey text-bold ml-4">${format_currency(invoice.grand_total, invoice.currency, 0) || 0}</div>
- <div class="f-shrink-0 text-grey ml-4">${posting_datetime}</div>
+ <div class="invoice-total-status">
+ <div class="invoice-total">${format_currency(invoice.grand_total, invoice.currency, 0) || 0}</div>
+ <div class="invoice-date">${posting_datetime}</div>
</div>
- </div>`
+ </div>
+ <div class="seperator"></div>`
);
}
+
+ toggle_component(show) {
+ show ? this.$component.css('display', 'flex') && this.refresh_list() : this.$component.css('display', 'none');
+ }
};
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js
index 6fd4c26..eb29976 100644
--- a/erpnext/selling/page/point_of_sale/pos_past_order_summary.js
+++ b/erpnext/selling/page/point_of_sale/pos_past_order_summary.js
@@ -8,85 +8,39 @@
init_component() {
this.prepare_dom();
- this.init_child_components();
+ this.init_email_print_dialog();
this.bind_events();
this.attach_shortcuts();
}
prepare_dom() {
this.wrapper.append(
- `<section class="col-span-6 flex flex-col items-center shadow rounded past-order-summary bg-white mx-h-70 h-100 d-none">
- <div class="no-summary-placeholder flex flex-1 items-center justify-center p-16">
- <div class="no-item-wrapper flex items-center h-18 pr-4 pl-4">
- <div class="flex-1 text-center text-grey">Select an invoice to load summary data</div>
- </div>
+ `<section class="past-order-summary">
+ <div class="no-summary-placeholder">
+ Select an invoice to load summary data
</div>
- <div class="summary-wrapper d-none flex-1 w-66 text-dark-grey relative">
- <div class="summary-container absolute flex flex-col pt-16 pb-16 pr-8 pl-8 w-full h-full"></div>
+ <div class="invoice-summary-wrapper">
+ <div class="abs-container">
+ <div class="upper-section"></div>
+ <div class="label">Items</div>
+ <div class="items-container summary-container"></div>
+ <div class="label">Totals</div>
+ <div class="totals-container summary-container"></div>
+ <div class="label">Payments</div>
+ <div class="payments-container summary-container"></div>
+ <div class="summary-btns"></div>
+ </div>
</div>
</section>`
);
this.$component = this.wrapper.find('.past-order-summary');
- this.$summary_wrapper = this.$component.find('.summary-wrapper');
- this.$summary_container = this.$component.find('.summary-container');
- }
-
- init_child_components() {
- this.init_upper_section();
- this.init_items_summary();
- this.init_totals_summary();
- this.init_payments_summary();
- this.init_summary_buttons();
- this.init_email_print_dialog();
- }
-
- init_upper_section() {
- this.$summary_container.append(
- `<div class="flex upper-section justify-between w-full h-24"></div>`
- );
-
+ this.$summary_wrapper = this.$component.find('.invoice-summary-wrapper');
+ this.$summary_container = this.$component.find('.abs-container');
this.$upper_section = this.$summary_container.find('.upper-section');
- }
-
- init_items_summary() {
- this.$summary_container.append(
- `<div class="flex flex-col flex-1 mt-6 w-full scroll-y">
- <div class="text-grey mb-4 sticky bg-white">ITEMS</div>
- <div class="items-summary-container border rounded flex flex-col w-full"></div>
- </div>`
- );
-
- this.$items_summary_container = this.$summary_container.find('.items-summary-container');
- }
-
- init_totals_summary() {
- this.$summary_container.append(
- `<div class="flex flex-col mt-6 w-full f-shrink-0">
- <div class="text-grey mb-4">TOTALS</div>
- <div class="summary-totals-container border rounded flex flex-col w-full"></div>
- </div>`
- );
-
- this.$totals_summary_container = this.$summary_container.find('.summary-totals-container');
- }
-
- init_payments_summary() {
- this.$summary_container.append(
- `<div class="flex flex-col mt-6 w-full f-shrink-0">
- <div class="text-grey mb-4">PAYMENTS</div>
- <div class="payments-summary-container border rounded flex flex-col w-full mb-4"></div>
- </div>`
- );
-
- this.$payment_summary_container = this.$summary_container.find('.payments-summary-container');
- }
-
- init_summary_buttons() {
- this.$summary_container.append(
- `<div class="summary-btns flex summary-btns justify-between w-full f-shrink-0"></div>`
- );
-
+ this.$items_container = this.$summary_container.find('.items-container');
+ this.$totals_container = this.$summary_container.find('.totals-container');
+ this.$payment_container = this.$summary_container.find('.payments-container');
this.$summary_btns = this.$summary_container.find('.summary-btns');
}
@@ -121,132 +75,88 @@
}
get_upper_section_html(doc) {
- const { status } = doc; let indicator_color = '';
+ const { status } = doc;
+ let indicator_color = '';
in_list(['Paid', 'Consolidated'], status) && (indicator_color = 'green');
status === 'Draft' && (indicator_color = 'red');
status === 'Return' && (indicator_color = 'grey');
- return `<div class="flex flex-col items-start justify-end pr-4">
- <div class="text-lg text-bold pt-2">${doc.customer}</div>
- <div class="text-grey">${this.customer_email}</div>
- <div class="text-grey mt-auto">Sold by: ${doc.owner}</div>
+ return `<div class="left-section">
+ <div class="customer-name">${doc.customer}</div>
+ <div class="customer-email">${this.customer_email}</div>
+ <div class="cashier">Sold by: ${doc.owner}</div>
</div>
- <div class="flex flex-col flex-1 items-end justify-between">
- <div class="text-2-5xl text-bold">${format_currency(doc.paid_amount, doc.currency)}</div>
- <div class="flex justify-between">
- <div class="text-grey mr-4">${doc.name}</div>
- <div class="text-grey text-bold indicator ${indicator_color}">${doc.status}</div>
- </div>
+ <div class="right-section">
+ <div class="paid-amount">${format_currency(doc.paid_amount, doc.currency)}</div>
+ <div class="invoice-name">${doc.name}</div>
+ <span class="indicator-pill whitespace-nowrap ${indicator_color}"><span>${doc.status}</span></span>
</div>`;
}
+ get_item_html(doc, item_data) {
+ return `<div class="item-row-wrapper">
+ <div class="item-name">${item_data.item_name}</div>
+ <div class="item-qty">${item_data.qty || 0}</div>
+ <div class="item-rate-disc">${get_rate_discount_html()}</div>
+ </div>`;
+
+ function get_rate_discount_html() {
+ if (item_data.rate && item_data.price_list_rate && item_data.rate !== item_data.price_list_rate) {
+ return `<span class="item-disc">(${item_data.discount_percentage}% off)</span>
+ <div class="item-rate">${format_currency(item_data.rate, doc.currency)}</div>`;
+ } else {
+ return `<div class="item-rate">${format_currency(item_data.price_list_rate || item_data.rate, doc.currency)}</div>`;
+ }
+ }
+ }
+
get_discount_html(doc) {
if (doc.discount_amount) {
- return `<div class="total-summary-wrapper flex items-center h-12 pr-4 pl-4 pointer border-b-grey no-select">
- <div class="flex f-shrink-1 items-center">
- <div class="text-md-0 text-dark-grey text-bold overflow-hidden whitespace-nowrap mr-2">
- Discount
- </div>
- <span class="text-grey">(${doc.additional_discount_percentage} %)</span>
- </div>
- <div class="flex flex-col f-shrink-0 ml-auto text-right">
- <div class="text-md-0 text-dark-grey text-bold">${format_currency(doc.discount_amount, doc.currency)}</div>
- </div>
- </div>`;
+ return `<div class="summary-row-wrapper">
+ <div>Discount (${doc.additional_discount_percentage} %)</div>
+ <div>${format_currency(doc.discount_amount, doc.currency)}</div>
+ </div>`;
} else {
return ``;
}
}
get_net_total_html(doc) {
- return `<div class="total-summary-wrapper flex items-center h-12 pr-4 pl-4 pointer border-b-grey no-select">
- <div class="flex f-shrink-1 items-center">
- <div class="text-md-0 text-dark-grey text-bold overflow-hidden whitespace-nowrap">
- Net Total
- </div>
- </div>
- <div class="flex flex-col f-shrink-0 ml-auto text-right">
- <div class="text-md-0 text-dark-grey text-bold">${format_currency(doc.net_total, doc.currency)}</div>
- </div>
+ return `<div class="summary-row-wrapper">
+ <div>Net Total</div>
+ <div>${format_currency(doc.net_total, doc.currency)}</div>
</div>`;
}
get_taxes_html(doc) {
- const taxes = doc.taxes.map((t, i) => {
- let margin_left = '';
- if (i !== 0) margin_left = 'ml-2';
- return `<span class="pl-2 pr-2 ${margin_left}">${t.description} @${t.rate}%</span>`;
- }).join('');
+ if (!doc.taxes.length) return '';
return `
- <div class="total-summary-wrapper flex items-center justify-between h-12 pr-4 pl-4 border-b-grey">
- <div class="flex">
- <div class="text-md-0 text-dark-grey text-bold w-fit">Tax Charges</div>
- <div class="flex ml-6 text-dark-grey">${taxes}</div>
- </div>
- <div class="flex flex-col text-right">
- <div class="text-md-0 text-dark-grey text-bold">
- ${format_currency(doc.base_total_taxes_and_charges, doc.currency)}
- </div>
- </div>
+ <div class="taxes-wrapper">
+ ${
+ doc.taxes.map((t, i) => {
+ const description = /[0-9]+/.test(t.description) ? t.description : `${t.description} @ ${t.rate}%`;
+ return `<div class="tax-row">
+ <div class="tax-label">${description}</div>
+ <div class="tax-value">${format_currency(t.tax_amount_after_discount_amount, doc.currency)}</div>
+ </div>`
+ }).join('')
+ }
</div>`;
}
get_grand_total_html(doc) {
- return `<div class="total-summary-wrapper flex items-center h-12 pr-4 pl-4 pointer border-b-grey no-select">
- <div class="flex f-shrink-1 items-center">
- <div class="text-md-0 text-dark-grey text-bold overflow-hidden whitespace-nowrap">
- Grand Total
- </div>
- </div>
- <div class="flex flex-col f-shrink-0 ml-auto text-right">
- <div class="text-md-0 text-dark-grey text-bold">${format_currency(doc.grand_total, doc.currency)}</div>
- </div>
+ return `<div class="summary-row-wrapper grand-total">
+ <div>Grand Total</div>
+ <div>${format_currency(doc.grand_total, doc.currency)}</div>
</div>`;
}
- get_item_html(doc, item_data) {
- return `<div class="item-summary-wrapper flex items-center h-12 pr-4 pl-4 border-b-grey pointer no-select">
- <div class="flex w-6 h-6 rounded bg-light-grey mr-4 items-center justify-center font-bold f-shrink-0">
- <span>${item_data.qty || 0}</span>
- </div>
- <div class="flex flex-col f-shrink-1">
- <div class="text-md text-dark-grey text-bold overflow-hidden whitespace-nowrap">
- ${item_data.item_name}
- </div>
- </div>
- <div class="flex f-shrink-0 ml-auto text-right">
- ${get_rate_discount_html()}
- </div>
- </div>`;
-
- function get_rate_discount_html() {
- if (item_data.rate && item_data.price_list_rate && item_data.rate !== item_data.price_list_rate) {
- return `<span class="text-grey mr-2">
- (${item_data.discount_percentage}% off)
- </span>
- <div class="text-md-0 text-dark-grey text-bold">
- ${format_currency(item_data.rate, doc.currency)}
- </div>`;
- } else {
- return `<div class="text-md-0 text-dark-grey text-bold">
- ${format_currency(item_data.price_list_rate || item_data.rate, doc.currency)}
- </div>`;
- }
- }
- }
-
get_payment_html(doc, payment) {
- return `<div class="payment-summary-wrapper flex items-center h-12 pr-4 pl-4 pointer border-b-grey no-select">
- <div class="flex f-shrink-1 items-center">
- <div class="text-md-0 text-dark-grey text-bold overflow-hidden whitespace-nowrap">
- ${payment.mode_of_payment}
- </div>
- </div>
- <div class="flex flex-col f-shrink-0 ml-auto text-right">
- <div class="text-md-0 text-dark-grey text-bold">${format_currency(payment.amount, doc.currency)}</div>
- </div>
+ return `<div class="summary-row-wrapper payments">
+ <div>${payment.mode_of_payment}</div>
+ <div>${format_currency(payment.amount, doc.currency)}</div>
</div>`;
}
@@ -254,22 +164,22 @@
this.$summary_container.on('click', '.return-btn', () => {
this.events.process_return(this.doc.name);
this.toggle_component(false);
- this.$component.find('.no-summary-placeholder').removeClass('d-none');
- this.$summary_wrapper.addClass('d-none');
+ this.$component.find('.no-summary-placeholder').css('display', 'flex');
+ this.$summary_wrapper.css('display', 'none');
});
this.$summary_container.on('click', '.edit-btn', () => {
this.events.edit_order(this.doc.name);
this.toggle_component(false);
- this.$component.find('.no-summary-placeholder').removeClass('d-none');
- this.$summary_wrapper.addClass('d-none');
+ this.$component.find('.no-summary-placeholder').css('display', 'flex');
+ this.$summary_wrapper.css('display', 'none');
});
this.$summary_container.on('click', '.new-btn', () => {
this.events.new_order();
this.toggle_component(false);
- this.$component.find('.no-summary-placeholder').removeClass('d-none');
- this.$summary_wrapper.addClass('d-none');
+ this.$component.find('.no-summary-placeholder').css('display', 'flex');
+ this.$summary_wrapper.css('display', 'none');
});
this.$summary_container.on('click', '.email-btn', () => {
@@ -312,10 +222,6 @@
});
}
- toggle_component(show) {
- show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none');
- }
-
send_email() {
const frm = this.events.get_frm();
const recipients = this.email_dialog.get_values().recipients;
@@ -338,8 +244,10 @@
if(!r.exc) {
frappe.utils.play_sound("email");
if(r.message["emails_not_sent_to"]) {
- frappe.msgprint(__("Email not sent to {0} (unsubscribed / disabled)",
- [ frappe.utils.escape_html(r.message["emails_not_sent_to"]) ]) );
+ frappe.msgprint(__(
+ "Email not sent to {0} (unsubscribed / disabled)",
+ [ frappe.utils.escape_html(r.message["emails_not_sent_to"]) ]
+ ));
} else {
frappe.show_alert({
message: __('Email sent successfully.'),
@@ -361,9 +269,7 @@
m.visible_btns.forEach(b => {
const class_name = b.split(' ')[0].toLowerCase();
this.$summary_btns.append(
- `<div class="${class_name}-btn border rounded h-14 flex flex-1 items-center mr-4 justify-center text-md text-bold no-select pointer">
- ${b}
- </div>`
+ `<div class="summary-btn btn btn-default ${class_name}-btn">${b}</div>`
);
});
}
@@ -371,29 +277,14 @@
this.$summary_btns.children().last().removeClass('mr-4');
}
- show_summary_placeholder() {
- this.$summary_wrapper.addClass("d-none");
- this.$component.find('.no-summary-placeholder').removeClass('d-none');
- }
-
- switch_to_post_submit_summary() {
- // switch to full width view
- this.$component.removeClass('col-span-6').addClass('col-span-10');
- this.$summary_wrapper.removeClass('w-66').addClass('w-40');
-
- // switch place holder with summary container
- this.$component.find('.no-summary-placeholder').addClass('d-none');
- this.$summary_wrapper.removeClass('d-none');
- }
-
- switch_to_recent_invoice_summary() {
- // switch full width view with 60% view
- this.$component.removeClass('col-span-10').addClass('col-span-6');
- this.$summary_wrapper.removeClass('w-40').addClass('w-66');
-
- // switch place holder with summary container
- this.$component.find('.no-summary-placeholder').addClass('d-none');
- this.$summary_wrapper.removeClass('d-none');
+ toggle_summary_placeholder(show) {
+ if (show) {
+ this.$summary_wrapper.css('display', 'none');
+ this.$component.find('.no-summary-placeholder').css('display', 'flex');
+ } else {
+ this.$summary_wrapper.css('display', 'flex');
+ this.$component.find('.no-summary-placeholder').css('display', 'none');
+ }
}
get_condition_btn_map(after_submission) {
@@ -408,14 +299,15 @@
}
load_summary_of(doc, after_submission=false) {
- this.$summary_wrapper.removeClass("d-none");
-
after_submission ?
- this.switch_to_post_submit_summary() : this.switch_to_recent_invoice_summary();
-
+ this.$component.css('grid-column', 'span 10 / span 10') :
+ this.$component.css('grid-column', 'span 6 / span 6')
+
+ this.toggle_summary_placeholder(false)
+
this.doc = doc;
- this.attach_basic_info(doc);
+ this.attach_document_info(doc);
this.attach_items_info(doc);
@@ -428,7 +320,7 @@
this.add_summary_btns(condition_btns_map);
}
- attach_basic_info(doc) {
+ attach_document_info(doc) {
frappe.db.get_value('Customer', this.doc.customer, 'email_id').then(({ message }) => {
this.customer_email = message.email_id || '';
const upper_section_dom = this.get_upper_section_html(doc);
@@ -437,19 +329,35 @@
}
attach_items_info(doc) {
- this.$items_summary_container.html('');
- doc.items.forEach(item => {
+ this.$items_container.html('');
+ doc.items.forEach((item, i) => {
const item_dom = this.get_item_html(doc, item);
- this.$items_summary_container.append(item_dom);
+ this.$items_container.append(item_dom);
+ this.set_dynamic_rate_header_width();
});
}
+ set_dynamic_rate_header_width() {
+ const rate_cols = Array.from(this.$items_container.find(".item-rate-disc"));
+ this.$items_container.find(".item-rate-disc").css("width", "");
+ let max_width = rate_cols.reduce((max_width, elm) => {
+ if ($(elm).width() > max_width)
+ max_width = $(elm).width();
+ return max_width;
+ }, 0);
+
+ max_width += 1;
+ if (max_width == 1) max_width = "";
+
+ this.$items_container.find(".item-rate-disc").css("width", max_width);
+ }
+
attach_payments_info(doc) {
- this.$payment_summary_container.html('');
+ this.$payment_container.html('');
doc.payments.forEach(p => {
if (p.amount) {
const payment_dom = this.get_payment_html(doc, p);
- this.$payment_summary_container.append(payment_dom);
+ this.$payment_container.append(payment_dom);
}
});
if (doc.redeem_loyalty_points && doc.loyalty_amount) {
@@ -457,20 +365,24 @@
mode_of_payment: 'Loyalty Points',
amount: doc.loyalty_amount,
});
- this.$payment_summary_container.append(payment_dom);
+ this.$payment_container.append(payment_dom);
}
}
attach_totals_info(doc) {
- this.$totals_summary_container.html('');
+ this.$totals_container.html('');
- const discount_dom = this.get_discount_html(doc);
const net_total_dom = this.get_net_total_html(doc);
const taxes_dom = this.get_taxes_html(doc);
+ const discount_dom = this.get_discount_html(doc);
const grand_total_dom = this.get_grand_total_html(doc);
- this.$totals_summary_container.append(discount_dom);
- this.$totals_summary_container.append(net_total_dom);
- this.$totals_summary_container.append(taxes_dom);
- this.$totals_summary_container.append(grand_total_dom);
+ this.$totals_container.append(net_total_dom);
+ this.$totals_container.append(taxes_dom);
+ this.$totals_container.append(discount_dom);
+ this.$totals_container.append(grand_total_dom);
+ }
+
+ toggle_component(show) {
+ show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none');
}
};
\ No newline at end of file
diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js
index e4d8965..365c27b 100644
--- a/erpnext/selling/page/point_of_sale/pos_payment.js
+++ b/erpnext/selling/page/point_of_sale/pos_payment.js
@@ -1,5 +1,3 @@
-{% include "erpnext/selling/page/point_of_sale/pos_number_pad.js" %}
-
erpnext.PointOfSale.Payment = class {
constructor({ events, wrapper }) {
this.wrapper = wrapper;
@@ -18,52 +16,37 @@
prepare_dom() {
this.wrapper.append(
- `<section class="col-span-6 flex shadow rounded payment-section bg-white mx-h-70 h-100 d-none">
- <div class="flex flex-col p-16 pt-8 pb-8 w-full">
- <div class="text-grey mb-6 payment-section no-select pointer">
- PAYMENT METHOD<span class="octicon octicon-chevron-down collapse-indicator"></span>
+ `<section class="payment-container">
+ <div class="section-label payment-section">Payment Method</div>
+ <div class="payment-modes"></div>
+ <div class="fields-numpad-container">
+ <div class="fields-section">
+ <div class="section-label">Additional Information</div>
+ <div class="invoice-fields"></div>
</div>
- <div class="payment-modes flex flex-wrap"></div>
- <div class="invoice-details-section"></div>
- <div class="flex mt-auto justify-center w-full">
- <div class="flex flex-col justify-center flex-1 ml-4">
- <div class="flex w-full">
- <div class="totals-remarks items-end justify-end flex flex-1">
- <div class="remarks text-md-0 text-grey mr-auto"></div>
- <div class="totals flex justify-end pt-4"></div>
- </div>
- <div class="number-pad w-40 mb-4 ml-8 d-none"></div>
- </div>
- <div class="flex items-center justify-center mt-4 submit-order h-16 w-full rounded bg-primary text-md text-white no-select pointer text-bold">
- Complete Order
- </div>
- <div class="order-time flex items-center justify-end mt-2 pt-2 pb-2 w-full text-md-0 text-grey no-select pointer d-none"></div>
- </div>
- </div>
+ <div class="number-pad"></div>
</div>
+ <div class="totals-section">
+ <div class="totals"></div>
+ </div>
+ <div class="submit-order-btn">Complete Order</div>
</section>`
)
- this.$component = this.wrapper.find('.payment-section');
+ this.$component = this.wrapper.find('.payment-container');
this.$payment_modes = this.$component.find('.payment-modes');
- this.$totals_remarks = this.$component.find('.totals-remarks');
+ this.$totals_section = this.$component.find('.totals-section');
this.$totals = this.$component.find('.totals');
- this.$remarks = this.$component.find('.remarks');
this.$numpad = this.$component.find('.number-pad');
- this.$invoice_details_section = this.$component.find('.invoice-details-section');
+ this.$invoice_fields_section = this.$component.find('.fields-section');
}
make_invoice_fields_control() {
frappe.db.get_doc("POS Settings", undefined).then((doc) => {
const fields = doc.invoice_fields;
if (!fields.length) return;
-
- this.$invoice_details_section.html(
- `<div class="text-grey pb-6 mt-2 pointer no-select">
- ADDITIONAL INFORMATION<span class="octicon octicon-chevron-down collapse-indicator"></span>
- </div>
- <div class="invoice-fields grid grid-cols-2 gap-4 mb-6 d-none"></div>`
- );
- this.$invoice_fields = this.$invoice_details_section.find('.invoice-fields');
+
+ this.$invoice_fields = this.$invoice_fields_section.find('.invoice-fields');
+ this.$invoice_fields.html('');
const frm = this.events.get_frm();
fields.forEach(df => {
@@ -127,9 +110,9 @@
this.selected_mode.set_value(this.numpad_value);
function highlight_numpad_btn($btn) {
- $btn.addClass('shadow-inner bg-selected');
+ $btn.addClass('shadow-base-inner bg-selected');
setTimeout(() => {
- $btn.removeClass('shadow-inner bg-selected');
+ $btn.removeClass('shadow-base-inner bg-selected');
}, 100);
}
}
@@ -142,13 +125,16 @@
// if clicked element doesn't have .mode-of-payment class then return
if (!$(e.target).is(mode_clicked)) return;
+ const scrollLeft = mode_clicked.offset().left - me.$payment_modes.offset().left + me.$payment_modes.scrollLeft();
+ me.$payment_modes.animate({ scrollLeft });
+
const mode = mode_clicked.attr('data-mode');
// hide all control fields and shortcuts
- $(`.mode-of-payment-control`).addClass('d-none');
- $(`.cash-shortcuts`).addClass('d-none');
- me.$payment_modes.find(`.pay-amount`).removeClass('d-none');
- me.$payment_modes.find(`.loyalty-amount-name`).addClass('d-none');
+ $(`.mode-of-payment-control`).css('display', 'none');
+ $(`.cash-shortcuts`).css('display', 'none');
+ me.$payment_modes.find(`.pay-amount`).css('display', 'inline');
+ me.$payment_modes.find(`.loyalty-amount-name`).css('display', 'none');
// remove highlight from all mode-of-payments
$('.mode-of-payment').removeClass('border-primary');
@@ -157,21 +143,20 @@
// clicked one is selected then unselect it
mode_clicked.removeClass('border-primary');
me.selected_mode = '';
- me.toggle_numpad(false);
} else {
// clicked one is not selected then select it
mode_clicked.addClass('border-primary');
- mode_clicked.find('.mode-of-payment-control').removeClass('d-none');
- mode_clicked.find('.cash-shortcuts').removeClass('d-none');
- me.$payment_modes.find(`.${mode}-amount`).addClass('d-none');
- me.$payment_modes.find(`.${mode}-name`).removeClass('d-none');
- me.toggle_numpad(true);
+ mode_clicked.find('.mode-of-payment-control').css('display', 'flex');
+ mode_clicked.find('.cash-shortcuts').css('display', 'grid');
+ me.$payment_modes.find(`.${mode}-amount`).css('display', 'none');
+ me.$payment_modes.find(`.${mode}-name`).css('display', 'inline');
- me.selected_mode = me[`${mode}_control`];
const doc = me.events.get_frm().doc;
- me.selected_mode?.$input?.get(0).focus();
- const current_value = me.selected_mode?.get_value()
- !current_value && doc.grand_total > doc.paid_amount ? me.selected_mode?.set_value(doc.grand_total - doc.paid_amount) : '';
+ me.selected_mode = me[`${mode}_control`];
+ me.selected_mode && me.selected_mode.$input.get(0).focus();
+ const current_value = me.selected_mode ? me.selected_mode.get_value() : undefined;
+ !current_value && doc.grand_total > doc.paid_amount && me.selected_mode ?
+ me.selected_mode.set_value(doc.grand_total - doc.paid_amount) : '';
}
})
@@ -198,7 +183,7 @@
me.selected_mode.set_value(value);
})
- this.$component.on('click', '.submit-order', () => {
+ this.$component.on('click', '.submit-order-btn', () => {
const doc = this.events.get_frm().doc;
const paid_amount = doc.paid_amount;
const items = doc.items;
@@ -217,9 +202,9 @@
this.update_totals_section(frm.doc);
// need to re calculate cash shortcuts after discount is applied
- const is_cash_shortcuts_invisible = this.$payment_modes.find('.cash-shortcuts').hasClass('d-none');
+ const is_cash_shortcuts_invisible = !this.$payment_modes.find('.cash-shortcuts').is(':visible');
this.attach_cash_shortcuts(frm.doc);
- !is_cash_shortcuts_invisible && this.$payment_modes.find('.cash-shortcuts').removeClass('d-none');
+ !is_cash_shortcuts_invisible && this.$payment_modes.find('.cash-shortcuts').css('display', 'grid');
})
frappe.ui.form.on('POS Invoice', 'loyalty_amount', (frm) => {
@@ -235,29 +220,16 @@
this[`${mode}_control`].set_value(default_mop.amount);
}
});
-
- this.$component.on('click', '.invoice-details-section', function(e) {
- if ($(e.target).closest('.invoice-fields').length) return;
-
- me.$payment_modes.addClass('d-none');
- me.$invoice_fields.toggleClass("d-none");
- me.toggle_numpad(false);
- });
- this.$component.on('click', '.payment-section', () => {
- this.$invoice_fields.addClass("d-none");
- this.$payment_modes.toggleClass('d-none');
- this.toggle_numpad(true);
- })
}
attach_shortcuts() {
const ctrl_label = frappe.utils.is_mac() ? '⌘' : 'Ctrl';
- this.$component.find('.submit-order').attr("title", `${ctrl_label}+Enter`);
+ this.$component.find('.submit-order-btn').attr("title", `${ctrl_label}+Enter`);
frappe.ui.keys.on("ctrl+enter", () => {
const payment_is_visible = this.$component.is(":visible");
const active_mode = this.$payment_modes.find(".border-primary");
if (payment_is_visible && active_mode.length) {
- this.$component.find('.submit-order').click();
+ this.$component.find('.submit-order-btn').click();
}
});
@@ -287,15 +259,13 @@
}
toggle_numpad(show) {
- if (show) {
- this.$numpad.removeClass('d-none');
- this.$remarks.addClass('d-none');
- this.$totals_remarks.addClass('w-60 justify-center').removeClass('justify-end w-full');
- } else {
- this.$numpad.addClass('d-none');
- this.$remarks.removeClass('d-none');
- this.$totals_remarks.removeClass('w-60 justify-center').addClass('justify-end w-full');
- }
+ // if (show) {
+ // this.$numpad.css('display', 'flex');
+ // this.$totals_section.addClass('w-60 justify-center').removeClass('justify-end w-full');
+ // } else {
+ // this.$numpad.css('display', 'none');
+ // this.$totals_section.removeClass('w-60 justify-center').addClass('justify-end w-full');
+ // }
}
render_payment_section() {
@@ -327,7 +297,7 @@
fieldtype: 'Data',
onchange: function() {}
},
- parent: this.$totals_remarks.find(`.remarks`),
+ parent: this.$totals_section.find(`.remarks`),
render_input: true,
});
this[`remark_control`].set_value('');
@@ -348,12 +318,11 @@
const amount = p.amount > 0 ? format_currency(p.amount, currency) : '';
return (
- `<div class="w-half ${margin} bg-white">
- <div class="mode-of-payment rounded border border-grey text-grey text-md
- mb-4 p-8 pt-4 pb-4 no-select pointer" data-mode="${mode}" data-payment-type="${payment_type}">
+ `<div class="payment-mode-wrapper">
+ <div class="mode-of-payment" data-mode="${mode}" data-payment-type="${payment_type}">
${p.mode_of_payment}
- <div class="${mode}-amount pay-amount inline float-right text-bold">${amount}</div>
- <div class="${mode} mode-of-payment-control mt-4 flex flex-1 items-center d-none"></div>
+ <div class="${mode}-amount pay-amount">${amount}</div>
+ <div class="${mode} mode-of-payment-control"></div>
</div>
</div>`
)
@@ -405,12 +374,10 @@
this.$payment_modes.find('.cash-shortcuts').remove();
this.$payment_modes.find('[data-payment-type="Cash"]').find('.mode-of-payment-control').after(
- `<div class="cash-shortcuts grid grid-cols-3 gap-2 flex-1 text-center text-md-0 mb-2 d-none">
+ `<div class="cash-shortcuts">
${
shortcuts.map(s => {
- return `<div class="shortcut rounded bg-light-grey text-dark-grey pt-2 pb-2 no-select pointer" data-value="${s}">
- ${format_currency(s, currency, 0)}
- </div>`
+ return `<div class="shortcut" data-value="${s}">${format_currency(s, currency, 0)}</div>`
}).join('')
}
</div>`
@@ -457,13 +424,12 @@
const margin = this.$payment_modes.children().length % 2 === 0 ? 'pr-2' : 'pl-2';
const amount = doc.loyalty_amount > 0 ? format_currency(doc.loyalty_amount, doc.currency) : '';
this.$payment_modes.append(
- `<div class="w-half ${margin} bg-white">
- <div class="mode-of-payment rounded border border-grey text-grey text-md
- mb-4 p-8 pt-4 pb-4 no-select pointer" data-mode="loyalty-amount" data-payment-type="loyalty-amount">
+ `<div class="payment-mode-wrapper">
+ <div class="mode-of-payment" data-mode="loyalty-amount" data-payment-type="loyalty-amount">
Redeem Loyalty Points
- <div class="loyalty-amount-amount pay-amount inline float-right text-bold">${amount}</div>
- <div class="loyalty-amount-name inline float-right text-bold text-md-0 d-none">${loyalty_program}</div>
- <div class="loyalty-amount mode-of-payment-control mt-4 flex flex-1 items-center d-none"></div>
+ <div class="loyalty-amount-amount pay-amount">${amount}</div>
+ <div class="loyalty-amount-name">${loyalty_program}</div>
+ <div class="loyalty-amount mode-of-payment-control"></div>
</div>
</div>`
)
@@ -520,18 +486,24 @@
const label = change ? __('Change') : __('To Be Paid');
this.$totals.html(
- `<div>
- <div class="pr-8 border-r-grey">Paid Amount</div>
- <div class="pr-8 border-r-grey text-bold text-2xl">${format_currency(paid_amount, currency)}</div>
+ `<div class="col">
+ <div class="total-label">Grand Total</div>
+ <div class="value">${format_currency(doc.grand_total, currency)}</div>
</div>
- <div>
- <div class="pl-8">${label}</div>
- <div class="pl-8 text-green-400 text-bold text-2xl">${format_currency(change || remaining, currency)}</div>
+ <div class="seperator-y"></div>
+ <div class="col">
+ <div class="total-label">Paid Amount</div>
+ <div class="value">${format_currency(paid_amount, currency)}</div>
+ </div>
+ <div class="seperator-y"></div>
+ <div class="col">
+ <div class="total-label">${label}</div>
+ <div class="value">${format_currency(change || remaining, currency)}</div>
</div>`
)
}
toggle_component(show) {
- show ? this.$component.removeClass('d-none') : this.$component.addClass('d-none');
+ show ? this.$component.css('display', 'flex') : this.$component.css('display', 'none');
}
}
\ No newline at end of file
diff --git a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json
index 253d711..5c8cd69 100644
--- a/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json
+++ b/erpnext/setup/desk_page/erpnext_settings/erpnext_settings.json
@@ -9,10 +9,12 @@
"doctype": "Desk Page",
"extends": "Settings",
"extends_another_page": 1,
+ "hide_custom": 0,
+ "icon": "settings",
"idx": 0,
"is_standard": 1,
"label": "ERPNext Settings",
- "modified": "2020-04-01 11:28:51.400851",
+ "modified": "2020-07-08 12:53:44.904241",
"modified_by": "Administrator",
"module": "Setup",
"name": "ERPNext Settings",
@@ -21,89 +23,89 @@
"pin_to_top": 0,
"shortcuts": [
{
- "icon": "octicon octicon-rocket",
+ "icon": "project",
"label": "Projects Settings",
"link_to": "Projects Settings",
"type": "DocType"
},
{
- "icon": "octicon octicon-repo",
+ "icon": "accounting",
"label": "Accounts Settings",
"link_to": "Accounts Settings",
"type": "DocType"
},
{
- "icon": "octicon octicon-package",
+ "icon": "stock",
"label": "Stock Settings",
"link_to": "Stock Settings",
"type": "DocType"
},
{
- "icon": "octicon octicon-organization",
+ "icon": "hr",
"label": "HR Settings",
"link_to": "HR Settings",
"type": "DocType"
},
{
- "icon": "octicon octicon-tag",
+ "icon": "sell",
"label": "Selling Settings",
"link_to": "Selling Settings",
"type": "DocType"
},
{
- "icon": "octicon octicon-briefcase",
+ "icon": "buying",
"label": "Buying Settings",
"link_to": "Buying Settings",
"type": "DocType"
},
{
- "icon": "fa fa-life-ring",
+ "icon": "support",
"label": "Support Settings",
"link_to": "Support Settings",
"type": "DocType"
},
{
- "icon": "fa fa-shopping-cart",
+ "icon": "retail",
"label": "Shopping Cart Settings",
"link_to": "Shopping Cart Settings",
"type": "DocType"
},
{
- "icon": "fa fa-globe",
+ "icon": "website",
"label": "Portal Settings",
"link_to": "Portal Settings",
"type": "DocType"
},
{
- "icon": "octicon octicon-tools",
+ "icon": "organization",
"label": "Manufacturing Settings",
"link_to": "Manufacturing Settings",
"restrict_to_domain": "Manufacturing",
"type": "DocType"
},
{
- "icon": "octicon octicon-mortar-board",
+ "icon": "education",
"label": "Education Settings",
"link_to": "Education Settings",
"restrict_to_domain": "Education",
"type": "DocType"
},
{
- "icon": "fa fa-bed",
+ "icon": "organization",
"label": "Hotel Settings",
"link_to": "Hotel Settings",
"restrict_to_domain": "Hospitality",
"type": "DocType"
},
{
- "icon": "fa fa-heartbeat",
+ "icon": "non-profit",
"label": "Healthcare Settings",
"link_to": "Healthcare Settings",
"restrict_to_domain": "Healthcare",
"type": "DocType"
},
{
- "icon": "fa fa-cog",
+ "icon": "setting",
"label": "Domain Settings",
"link_to": "Domain Settings",
"type": "DocType"
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 4a438f7..dc45cc1 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -75,7 +75,7 @@
def validate_default_accounts(self):
accounts = [
- ["Default Bank Account", "default_bank_account"], ["Default Cash Account", "default_cash_account"],
+ ["Default Bank Account", "default_bank_account"], ["Default Cash Account", "default_cash_account"],
["Default Receivable Account", "default_receivable_account"], ["Default Payable Account", "default_payable_account"],
["Default Expense Account", "default_expense_account"], ["Default Income Account", "default_income_account"],
["Stock Received But Not Billed Account", "stock_received_but_not_billed"], ["Stock Adjustment Account", "stock_adjustment_account"],
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 2225fe1..0bb480b 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -28,6 +28,7 @@
create_default_energy_point_rules()
add_company_to_session_defaults()
add_standard_navbar_items()
+ add_app_name()
frappe.db.commit()
@@ -158,3 +159,7 @@
})
navbar_settings.save()
+
+def add_app_name():
+ settings = frappe.get_doc("System Settings")
+ settings.app_name = _("ERPNext")
\ No newline at end of file
diff --git a/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html b/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html
index 5808ce7..7166ba3 100644
--- a/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html
+++ b/erpnext/setup/page/welcome_to_erpnext/welcome_to_erpnext.html
@@ -21,7 +21,6 @@
<h3>{%= __("Next Steps") %}</h3>
<ul class="list-unstyled">
<li><a class="text-muted" href="#">{%= __("Go to the Desktop and start using ERPNext") %}</a></li>
- <li><a class="text-muted" href="#modules/Learn">{%= __("View a list of all the help videos") %}</a></li>
<li><a class="text-muted" href="https://erpnext.com/docs/user" target="_blank">{%= __("Read the ERPNext Manual") %}</a></li>
<li><a class="text-muted" href="https://discuss.erpnext.com" target="_blank">{%= __("Community Forum") %}</a></li>
</ul>
diff --git a/erpnext/startup/filters.py b/erpnext/startup/filters.py
index a99e49b..ec07329 100644
--- a/erpnext/startup/filters.py
+++ b/erpnext/startup/filters.py
@@ -2,13 +2,13 @@
import frappe
def get_filters_config():
- filters_config = {
+ filters_config = {
"fiscal year": {
"label": "Fiscal Year",
"get_field": "erpnext.accounts.utils.get_fiscal_year_filter_field",
"valid_for_fieldtypes": ["Date", "Datetime", "DateRange"],
"depends_on": "company",
}
- }
+ }
- return filters_config
\ No newline at end of file
+ return filters_config
\ No newline at end of file
diff --git a/erpnext/startup/leaderboard.py b/erpnext/startup/leaderboard.py
index ef238f1..8819a55 100644
--- a/erpnext/startup/leaderboard.py
+++ b/erpnext/startup/leaderboard.py
@@ -12,6 +12,7 @@
{'fieldname': 'outstanding_amount', 'fieldtype': 'Currency'}
],
"method": "erpnext.startup.leaderboard.get_all_customers",
+ "icon": "customer"
},
"Item": {
"fields": [
@@ -23,6 +24,7 @@
{'fieldname': 'available_stock_value', 'fieldtype': 'Currency'}
],
"method": "erpnext.startup.leaderboard.get_all_items",
+ "icon": "stock"
},
"Supplier": {
"fields": [
@@ -31,6 +33,7 @@
{'fieldname': 'outstanding_amount', 'fieldtype': 'Currency'}
],
"method": "erpnext.startup.leaderboard.get_all_suppliers",
+ "icon": "buying"
},
"Sales Partner": {
"fields": [
@@ -38,12 +41,14 @@
{'fieldname': 'total_commission', 'fieldtype': 'Currency'}
],
"method": "erpnext.startup.leaderboard.get_all_sales_partner",
+ "icon": "hr"
},
"Sales Person": {
"fields": [
{'fieldname': 'total_sales_amount', 'fieldtype': 'Currency'}
],
"method": "erpnext.startup.leaderboard.get_all_sales_person",
+ "icon": "customer"
}
}
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 9bd03d4..faa9b5d 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -198,7 +198,7 @@
freeze: true,
callback: function(r) {
frappe.show_alert(__('Stock Entry {0} created',
- ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+ ['<a href="/desk/Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
dialog.hide();
callback(r);
},
diff --git a/erpnext/stock/dashboard/item_dashboard_list.html b/erpnext/stock/dashboard/item_dashboard_list.html
index e1914ed..0c10be4 100644
--- a/erpnext/stock/dashboard/item_dashboard_list.html
+++ b/erpnext/stock/dashboard/item_dashboard_list.html
@@ -1,10 +1,10 @@
{% for d in data %}
<div class="dashboard-list-item">
<div class="row">
- <div class="col-sm-3 small" style="margin-top: 8px;">
+ <div class="col-sm-3" style="margin-top: 8px;">
<a data-type="warehouse" data-name="{{ d.warehouse }}">{{ d.warehouse }}</a>
</div>
- <div class="col-sm-3 small" style="margin-top: 8px;">
+ <div class="col-sm-3" style="margin-top: 8px;">
{% if show_item %}
<a data-type="item"
data-name="{{ d.item_code }}">{{ d.item_code }}
@@ -12,7 +12,7 @@
</a>
{% endif %}
</div>
- <div class="col-sm-4 small">
+ <div class="col-sm-4">
<span class="inline-graph">
<span class="inline-graph-half" title="{{ __("Reserved Qty") }}">
<span class="inline-graph-count">{{ d.total_reserved }}</span>
@@ -40,7 +40,7 @@
</span>
</div>
{% if can_write %}
- <div class="col-sm-2 text-right" style="margin-top: 8px;">
+ <div class="col-sm-2 text-right" style="margin: var(--margin-sm) 0;">
{% if d.actual_qty %}
<button class="btn btn-default btn-xs btn-move"
data-disable_quick_entry="{{ d.disable_quick_entry }}"
diff --git a/erpnext/stock/desk_page/stock/stock.json b/erpnext/stock/desk_page/stock/stock.json
index 9068e33..ae832b3 100644
--- a/erpnext/stock/desk_page/stock/stock.json
+++ b/erpnext/stock/desk_page/stock/stock.json
@@ -55,6 +55,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "stock",
"idx": 0,
"is_standard": 1,
"label": "Stock",
@@ -68,7 +69,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#cef6d1",
+ "color": "Green",
"format": "{} Available",
"label": "Item",
"link_to": "Item",
@@ -76,7 +77,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} Pending",
"label": "Material Request",
"link_to": "Material Request",
@@ -89,7 +90,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} To Bill",
"label": "Purchase Receipt",
"link_to": "Purchase Receipt",
@@ -97,7 +98,7 @@
"type": "DocType"
},
{
- "color": "#ffe8cd",
+ "color": "Yellow",
"format": "{} To Bill",
"label": "Delivery Note",
"link_to": "Delivery Note",
diff --git a/erpnext/stock/doctype/batch/batch.js b/erpnext/stock/doctype/batch/batch.js
index e2ea7f9..7b2edff 100644
--- a/erpnext/stock/doctype/batch/batch.js
+++ b/erpnext/stock/doctype/batch/batch.js
@@ -47,8 +47,7 @@
return;
}
- var section = frm.dashboard.add_section(`<h5 style="margin-top: 0px;">
- ${ __("Stock Levels") }</a></h5>`);
+ const section = frm.dashboard.add_section('', __("Stock Levels"));
// sort by qty
r.message.sort(function(a, b) { a.qty > b.qty ? 1 : -1 });
@@ -103,7 +102,7 @@
},
callback: (r) => {
frappe.show_alert(__('Stock Entry {0} created',
- ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+ ['<a href="/desk/Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
frm.refresh();
},
});
diff --git a/erpnext/stock/doctype/batch/batch_list.js b/erpnext/stock/doctype/batch/batch_list.js
index d4f74c3..0de9fd0 100644
--- a/erpnext/stock/doctype/batch/batch_list.js
+++ b/erpnext/stock/doctype/batch/batch_list.js
@@ -2,9 +2,9 @@
add_fields: ["item", "expiry_date", "batch_qty", "disabled"],
get_indicator: (doc) => {
if (doc.disabled) {
- return [__("Disabled"), "darkgrey", "disabled,=,1"];
+ return [__("Disabled"), "gray", "disabled,=,1"];
} else if (!doc.batch_qty) {
- return [__("Empty"), "darkgrey", "batch_qty,=,0|disabled,=,0"];
+ return [__("Empty"), "gray", "batch_qty,=,0|disabled,=,0"];
} else if (doc.expiry_date && frappe.datetime.get_diff(doc.expiry_date, frappe.datetime.nowdate()) <= 0) {
return [__("Expired"), "red", "expiry_date,not in,|expiry_date,<=,Today|batch_qty,>,0|disabled,=,0"]
} else {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 3f3407e..8bed16d 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -83,7 +83,7 @@
}
])
- def before_print(self):
+ def before_print(self, settings=None):
def toggle_print_hide(meta, fieldname):
df = meta.get_field(fieldname)
if self.get("print_without_amount"):
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
index 4a6500c..f08125b 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
@@ -3,7 +3,7 @@
"transporter_name", "grand_total", "is_return", "status", "currency"],
get_indicator: function(doc) {
if(cint(doc.is_return)==1) {
- return [__("Return"), "darkgrey", "is_return,=,Yes"];
+ return [__("Return"), "gray", "is_return,=,Yes"];
} else if (doc.status === "Closed") {
return [__("Closed"), "green", "status,=,Closed"];
} else if (flt(doc.per_returned, 2) === 100) {
diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
index aaca802..5030595 100644
--- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
+++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.py
@@ -5,8 +5,6 @@
import frappe
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
class DeliveryNoteItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index faeeb57..43e18d1 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -85,7 +85,7 @@
}
if (frm.doc.variant_of) {
frm.set_intro(__('This Item is a Variant of {0} (Template).',
- [`<a href="#Form/Item/${frm.doc.variant_of}">${frm.doc.variant_of}</a>`]), true);
+ [`<a href="/desk/Form/Item/${frm.doc.variant_of}">${frm.doc.variant_of}</a>`]), true);
}
if (frappe.defaults.get_default("item_naming_by")!="Naming Series" || frm.doc.variant_of) {
@@ -380,8 +380,7 @@
// Show Stock Levels only if is_stock_item
if (frm.doc.is_stock_item) {
frappe.require('assets/js/item-dashboard.min.js', function() {
- var section = frm.dashboard.add_section('<h5 style="margin-top: 0px;">\
- <a href="#stock-balance">' + __("Stock Levels") + '</a></h5>');
+ const section = frm.dashboard.add_section('', __("Stock Levels"));
erpnext.item.item_dashboard = new erpnext.stock.ItemDashboard({
parent: section,
item_code: frm.doc.name
@@ -650,7 +649,7 @@
if (r.message) {
var variant = r.message;
frappe.msgprint_dialog = frappe.msgprint(__("Item Variant {0} already exists with same attributes",
- [repl('<a href="#Form/Item/%(item_encoded)s" class="strong variant-click">%(item)s</a>', {
+ [repl('<a href="/desk/Form/Item/%(item_encoded)s" class="strong variant-click">%(item)s</a>', {
item_encoded: encodeURIComponent(variant),
item: variant
})]
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index be845d9..86ce5cc 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -860,7 +860,7 @@
rows = ''
for docname, attr_list in not_included.items():
- link = "<a href='#Form/Item/{0}'>{0}</a>".format(frappe.bold(_(docname)))
+ link = "<a href='/app/Form/Item/{0}'>{0}</a>".format(frappe.bold(_(docname)))
rows += table_row(link, body(attr_list))
error_description = _('The following deleted attributes exist in Variants but not in the Template. You can either delete the Variants or keep the attribute(s) in template.')
diff --git a/erpnext/stock/doctype/item/item_dashboard.py b/erpnext/stock/doctype/item/item_dashboard.py
index dd4676a..b3e4796 100644
--- a/erpnext/stock/doctype/item/item_dashboard.py
+++ b/erpnext/stock/doctype/item/item_dashboard.py
@@ -32,16 +32,16 @@
'Purchase Order', 'Purchase Receipt', 'Purchase Invoice']
},
{
+ 'label': _('Manufacture'),
+ 'items': ['Production Plan', 'Work Order', 'Item Manufacturer']
+ },
+ {
'label': _('Traceability'),
'items': ['Serial No', 'Batch']
},
{
'label': _('Move'),
'items': ['Stock Entry']
- },
- {
- 'label': _('Manufacture'),
- 'items': ['Production Plan', 'Work Order', 'Item Manufacturer']
}
]
}
diff --git a/erpnext/stock/doctype/item_price/item_price.js b/erpnext/stock/doctype/item_price/item_price.js
index 2729f4b..773fddc 100644
--- a/erpnext/stock/doctype/item_price/item_price.js
+++ b/erpnext/stock/doctype/item_price/item_price.js
@@ -14,6 +14,6 @@
frm.add_fetch("item_code", "stock_uom", "uom");
frm.set_df_property("bulk_import_help", "options",
- '<a href="#data-import-tool/Item Price">' + __("Import in Bulk") + '</a>');
+ '<a href="/desk/data-import-tool/Item Price">' + __("Import in Bulk") + '</a>');
}
});
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.py b/erpnext/stock/doctype/material_request_item/material_request_item.py
index 6c6ecfe..16f007f 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.py
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.py
@@ -6,12 +6,10 @@
from __future__ import unicode_literals
import frappe
-from erpnext.controllers.print_settings import print_settings_for_item_table
from frappe.model.document import Document
class MaterialRequestItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
def on_doctype_update():
frappe.db.add_index("Material Request Item", ["item_code", "warehouse"])
\ No newline at end of file
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
index c9501a4..77711de 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
@@ -3,7 +3,7 @@
"transporter_name", "is_return", "status", "per_billed", "currency"],
get_indicator: function(doc) {
if(cint(doc.is_return)==1) {
- return [__("Return"), "darkgrey", "is_return,=,Yes"];
+ return [__("Return"), "gray", "is_return,=,Yes"];
} else if (doc.status === "Closed") {
return [__("Closed"), "green", "status,=,Closed"];
} else if (flt(doc.per_returned, 2) === 100) {
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
index 679bd1e..b79bb5d 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.py
@@ -5,8 +5,6 @@
import frappe
from frappe.model.document import Document
-from erpnext.controllers.print_settings import print_settings_for_item_table
class PurchaseReceiptItem(Document):
- def __setup__(self):
- print_settings_for_item_table(self)
+ pass
diff --git a/erpnext/stock/doctype/warehouse/warehouse_tree.js b/erpnext/stock/doctype/warehouse/warehouse_tree.js
index 918d2f1..3665c05 100644
--- a/erpnext/stock/doctype/warehouse/warehouse_tree.js
+++ b/erpnext/stock/doctype/warehouse/warehouse_tree.js
@@ -19,7 +19,7 @@
ignore_fields:["parent_warehouse"],
onrender: function(node) {
if (node.data && node.data.balance!==undefined) {
- $('<span class="balance-area pull-right text-muted small">'
+ $('<span class="balance-area pull-right">'
+ format_currency(Math.abs(node.data.balance), node.data.company_currency)
+ '</span>').insertBefore(node.$ul);
}
diff --git a/erpnext/stock/module_onboarding/stock/stock.json b/erpnext/stock/module_onboarding/stock/stock.json
index 1d5bf8c..8474648 100644
--- a/erpnext/stock/module_onboarding/stock/stock.json
+++ b/erpnext/stock/module_onboarding/stock/stock.json
@@ -19,7 +19,7 @@
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/stock",
"idx": 0,
"is_complete": 0,
- "modified": "2020-07-08 14:22:07.951891",
+ "modified": "2020-10-14 14:54:42.741971",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock",
diff --git a/erpnext/stock/onboarding_step/create_a_product/create_a_product.json b/erpnext/stock/onboarding_step/create_a_product/create_a_product.json
index d2068e1..335137d 100644
--- a/erpnext/stock/onboarding_step/create_a_product/create_a_product.json
+++ b/erpnext/stock/onboarding_step/create_a_product/create_a_product.json
@@ -8,7 +8,7 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-12 18:30:02.489949",
+ "modified": "2020-10-14 14:53:00.133574",
"modified_by": "Administrator",
"name": "Create a Product",
"owner": "Administrator",
diff --git a/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json b/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json
index b7811a4..9012493 100644
--- a/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json
+++ b/erpnext/stock/onboarding_step/create_a_purchase_receipt/create_a_purchase_receipt.json
@@ -8,7 +8,7 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-19 18:59:13.266713",
+ "modified": "2020-10-14 14:53:25.618434",
"modified_by": "Administrator",
"name": "Create a Purchase Receipt",
"owner": "Administrator",
diff --git a/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json b/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json
index 2b83f65..09902b8 100644
--- a/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json
+++ b/erpnext/stock/onboarding_step/create_a_stock_entry/create_a_stock_entry.json
@@ -8,7 +8,7 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-15 03:30:58.047696",
+ "modified": "2020-10-14 14:53:00.105905",
"modified_by": "Administrator",
"name": "Create a Stock Entry",
"owner": "Administrator",
diff --git a/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json b/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json
index 7a64224..ef61fa3 100644
--- a/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json
+++ b/erpnext/stock/onboarding_step/create_a_supplier/create_a_supplier.json
@@ -8,7 +8,7 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-14 22:09:10.043554",
+ "modified": "2020-10-14 14:53:00.120455",
"modified_by": "Administrator",
"name": "Create a Supplier",
"owner": "Administrator",
diff --git a/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json b/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json
index 009a44f..212e505 100644
--- a/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json
+++ b/erpnext/stock/onboarding_step/introduction_to_stock_entry/introduction_to_stock_entry.json
@@ -8,7 +8,7 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-26 15:55:41.457289",
+ "modified": "2020-10-14 14:53:00.075177",
"modified_by": "Administrator",
"name": "Introduction to Stock Entry",
"owner": "Administrator",
diff --git a/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json b/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json
index 9457dee..75940ed 100644
--- a/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json
+++ b/erpnext/stock/onboarding_step/setup_your_warehouse/setup_your_warehouse.json
@@ -8,7 +8,7 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-07-04 12:33:16.970031",
+ "modified": "2020-10-14 14:53:25.538900",
"modified_by": "Administrator",
"name": "Setup your Warehouse",
"owner": "Administrator",
diff --git a/erpnext/stock/onboarding_step/stock_settings/stock_settings.json b/erpnext/stock/onboarding_step/stock_settings/stock_settings.json
index 7591bff..ae34afa 100644
--- a/erpnext/stock/onboarding_step/stock_settings/stock_settings.json
+++ b/erpnext/stock/onboarding_step/stock_settings/stock_settings.json
@@ -8,7 +8,7 @@
"is_mandatory": 0,
"is_single": 1,
"is_skipped": 0,
- "modified": "2020-05-15 03:55:15.444151",
+ "modified": "2020-10-14 14:53:00.092504",
"modified_by": "Administrator",
"name": "Stock Settings",
"owner": "Administrator",
diff --git a/erpnext/support/desk_page/support/support.json b/erpnext/support/desk_page/support/support.json
index 28410f3..f676ce5 100644
--- a/erpnext/support/desk_page/support/support.json
+++ b/erpnext/support/desk_page/support/support.json
@@ -40,6 +40,7 @@
"doctype": "Desk Page",
"extends_another_page": 0,
"hide_custom": 0,
+ "icon": "support",
"idx": 0,
"is_standard": 1,
"label": "Support",
@@ -52,7 +53,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "#ffc4c4",
+ "color": "Yellow",
"format": "{} Assigned",
"label": "Issue",
"link_to": "Issue",
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index 086755b..5b295d7 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -176,8 +176,8 @@
${split_issue}
</button>`)
.appendTo(frm.timeline.wrapper.find('.comment-header .asset-details:not([data-communication-type="Comment"])'))
- if (!frm.timeline.wrapper.data("split-issue-event-attached")){
- frm.timeline.wrapper.on("click", ".btn-split-issue", (e) => {
+ if (!frm.timeline.wrapper.data("split-issue-event-attached")) {
+ frm.timeline.wrapper.on('click', '.btn-split-issue', (e) => {
var dialog = new frappe.ui.Dialog({
title: __("Split Issue"),
fields: [
@@ -192,7 +192,7 @@
let url = window.location.href
let arr = url.split("/");
let result = arr[0] + "//" + arr[2]
- frappe.msgprint(`New issue created: <a href="${result}/desk#Form/Issue/${r.message}">${r.message}</a>`)
+ frappe.msgprint(`New issue created: <a href="${result}//desk/Form/Issue/${r.message}">${r.message}</a>`)
frm.reload_doc();
dialog.hide();
});
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 62b39cc..e4e7b25 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -207,7 +207,7 @@
"comment_type": "Info",
"reference_doctype": "Issue",
"reference_name": replicated_issue.name,
- "content": " - Split the Issue from <a href='#Form/Issue/{0}'>{1}</a>".format(self.name, frappe.bold(self.name)),
+ "content": " - Split the Issue from <a href='/app/Form/Issue/{0}'>{1}</a>".format(self.name, frappe.bold(self.name)),
}).insert(ignore_permissions=True)
return replicated_issue.name
diff --git a/erpnext/support/doctype/issue/issue_list.js b/erpnext/support/doctype/issue/issue_list.js
index 513a8dc..e04498e 100644
--- a/erpnext/support/doctype/issue/issue_list.js
+++ b/erpnext/support/doctype/issue/issue_list.js
@@ -28,7 +28,7 @@
} else if (doc.status === 'Closed') {
return [__(doc.status), "green", "status,=," + doc.status];
} else {
- return [__(doc.status), "darkgrey", "status,=," + doc.status];
+ return [__(doc.status), "gray", "status,=," + doc.status];
}
}
}
diff --git a/erpnext/templates/includes/address_row.html b/erpnext/templates/includes/address_row.html
index dadd2df..6d4dd54 100644
--- a/erpnext/templates/includes/address_row.html
+++ b/erpnext/templates/includes/address_row.html
@@ -2,7 +2,7 @@
<a href="/addresses?name={{ doc.name | urlencode }}" class="no-underline text-reset">
<div class="row">
<div class="col-3">
- <span class="indicator {{ "red" if doc.address_type=="Office" else "green" if doc.address_type=="Billing" else "blue" if doc.address_type=="Shipping" else "darkgrey" }}">{{ doc.address_title }}</span>
+ <span class="indicator {{ "red" if doc.address_type=="Office" else "green" if doc.address_type=="Billing" else "blue" if doc.address_type=="Shipping" else "gray" }}">{{ doc.address_title }}</span>
</div>
<div class="col-2"> {{ _(doc.address_type) }} </div>
<div class="col-2"> {{ doc.city }} </div>
diff --git a/erpnext/templates/includes/issue_row.html b/erpnext/templates/includes/issue_row.html
index ff868fa..d909c5f 100644
--- a/erpnext/templates/includes/issue_row.html
+++ b/erpnext/templates/includes/issue_row.html
@@ -2,7 +2,7 @@
<a href="/issues?name={{ doc.name }}" class="no-underline">
<div class="row py-4 border-bottom">
<div class="col-3 d-flex align-items-center">
- {% set indicator = 'red' if doc.status == 'Open' else 'darkgrey' %}
+ {% set indicator = 'red' if doc.status == 'Open' else 'gray' %}
{% set indicator = 'green' if doc.status == 'Closed' else indicator %}
<span class="d-inline-flex indicator {{ indicator }}"></span>
{{ doc.name }}
@@ -10,7 +10,7 @@
<div class="col-5 text-muted">
{{ doc.subject }}</div>
<div class="col-2 d-flex align-items-center text-muted">
- {% set indicator = 'red' if doc.status == 'Open' else 'darkgrey' %}
+ {% set indicator = 'red' if doc.status == 'Open' else 'gray' %}
{% set indicator = 'green' if doc.status == 'Closed' else indicator %}
{% set indicator = 'orange' if doc.status == 'Open' and doc.priority == 'Medium' else indicator %}
{% set indicator = 'yellow' if doc.status == 'Open' and doc.priority == 'Low' else indicator %}
diff --git a/erpnext/templates/includes/projects/project_row.html b/erpnext/templates/includes/projects/project_row.html
index 73c83ef..4c8c40d 100644
--- a/erpnext/templates/includes/projects/project_row.html
+++ b/erpnext/templates/includes/projects/project_row.html
@@ -15,7 +15,7 @@
</div>
</div>
{% else %}
- <span class="indicator {{ "red" if doc.status=="Open" else "darkgrey" }}">
+ <span class="indicator {{ "red" if doc.status=="Open" else "gray" }}">
{{ doc.status }}</span>
{% endif %}
</div>
diff --git a/erpnext/templates/includes/projects/project_tasks.html b/erpnext/templates/includes/projects/project_tasks.html
index 94c692c..50b9f4b 100644
--- a/erpnext/templates/includes/projects/project_tasks.html
+++ b/erpnext/templates/includes/projects/project_tasks.html
@@ -3,7 +3,7 @@
<a class="no-decoration task-link {{ task.css_seen }}" href="/tasks?name={{ task.name }}">
<div class='row project-item'>
<div class='col-xs-9'>
- <span class="indicator {{ "red" if task.status=="Open" else "green" if task.status=="Closed" else "darkgrey" }}" title="{{ task.status }}" > {{ task.subject }}</span>
+ <span class="indicator {{ "red" if task.status=="Open" else "green" if task.status=="Closed" else "gray" }}" title="{{ task.status }}" > {{ task.subject }}</span>
<div class="small text-muted item-timestamp"
title="{{ frappe.utils.pretty_date(task.modified) }}">
{{ _("modified") }} {{ frappe.utils.pretty_date(task.modified) }}
@@ -16,9 +16,9 @@
</span>
{% else %}
<span class="avatar avatar-small standard-image" title="Assigned to {{ task.todo.owner }}">
-
+
</span>
- {% endif %}
+ {% endif %}
{% endif %} </div>
<div class='col-xs-2'>
<span class="pull-right list-comment-count small {{ "text-extra-muted" if task.comment_count==0 else "text-muted" }}">
diff --git a/erpnext/templates/includes/projects/project_timesheets.html b/erpnext/templates/includes/projects/project_timesheets.html
index fb3806c..05a07c1 100644
--- a/erpnext/templates/includes/projects/project_timesheets.html
+++ b/erpnext/templates/includes/projects/project_timesheets.html
@@ -3,19 +3,19 @@
<a class="no-decoration timesheet-link {{ timesheet.css_seen }}" href="/timesheet/{{ timesheet.info.name}}">
<div class='row project-item'>
<div class='col-xs-10'>
- <span class="indicator {{ "blue" if timesheet.info.status=="Submitted" else "red" if timesheet.info.status=="Draft" else "darkgrey" }}" title="{{ timesheet.info.status }}" > {{ timesheet.info.name }} </span>
+ <span class="indicator {{ "blue" if timesheet.info.status=="Submitted" else "red" if timesheet.info.status=="Draft" else "gray" }}" title="{{ timesheet.info.status }}" > {{ timesheet.info.name }} </span>
<div class="small text-muted item-timestamp">
{{ _("From") }} {{ frappe.format_date(timesheet.from_time) }} {{ _("to") }} {{ frappe.format_date(timesheet.to_time) }}
</div>
</div>
<div class='col-xs-1' style="margin-right:-30px;">
<span class="avatar avatar-small" title="{{ timesheet.info.modified_by }}"> <img src="{{ timesheet.info.user_image }}" style="display:flex;"></span>
- </div>
+ </div>
<div class='col-xs-1'>
<span class="pull-right list-comment-count small {{ "text-extra-muted" if timesheet.comment_count==0 else "text-muted" }}">
<i class="octicon octicon-comment-discussion"></i>
{{ timesheet.info.comment_count }}
- </span>
+ </span>
</div>
</div>
</a>
diff --git a/erpnext/templates/includes/timesheet/timesheet_row.html b/erpnext/templates/includes/timesheet/timesheet_row.html
index 4852f59..0f9cc77 100644
--- a/erpnext/templates/includes/timesheet/timesheet_row.html
+++ b/erpnext/templates/includes/timesheet/timesheet_row.html
@@ -1,7 +1,7 @@
<div class="web-list-item transaction-list-item">
<div class="row">
<div class="col-xs-3">
- <span class='indicator {{ "red" if doc.status=="Cancelled" else "green" if doc.status=="Billed" else "blue" if doc.status=="Submitted" else "darkgrey" }} small'>
+ <span class='indicator {{ "red" if doc.status=="Cancelled" else "green" if doc.status=="Billed" else "blue" if doc.status=="Submitted" else "gray" }} small'>
{{ doc.name }}
</span>
</div>
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html
index fd4835e..930d0c2 100644
--- a/erpnext/templates/includes/transaction_row.html
+++ b/erpnext/templates/includes/transaction_row.html
@@ -1,7 +1,7 @@
<div class="web-list-item transaction-list-item">
<div class="row">
<div class="col-sm-4">
- <span class="indicator small {{ doc.indicator_color or ("blue" if doc.docstatus==1 else "darkgrey") }}">
+ <span class="indicator small {{ doc.indicator_color or ("blue" if doc.docstatus==1 else "gray") }}">
{{ doc.name }}</span>
<div class="small text-muted transaction-time"
title="{{ frappe.utils.format_datetime(doc.modified, "medium") }}">
diff --git a/erpnext/templates/pages/material_request_info.html b/erpnext/templates/pages/material_request_info.html
index c7a7802..0c2772e 100644
--- a/erpnext/templates/pages/material_request_info.html
+++ b/erpnext/templates/pages/material_request_info.html
@@ -20,7 +20,7 @@
<div class="row transaction-subheading">
<div class="col-xs-6">
- <span class="indicator {{ doc.indicator_color or ("blue" if doc.docstatus==1 else "darkgrey") }}">
+ <span class="indicator {{ doc.indicator_color or ("blue" if doc.docstatus==1 else "gray") }}">
{{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
</span>
</div>
diff --git a/erpnext/templates/pages/rfq.html b/erpnext/templates/pages/rfq.html
index 5b27a94..6e2edb6 100644
--- a/erpnext/templates/pages/rfq.html
+++ b/erpnext/templates/pages/rfq.html
@@ -77,13 +77,13 @@
<div class="web-list-item transaction-list-item quotations" idx="{{d.name}}">
<div class="row">
<div class="col-sm-6">
- <span class="indicator darkgrey">{{d.name}}</span>
+ <span class="indicator gray">{{d.name}}</span>
</div>
<div class="col-sm-3">
- <span class="small darkgrey">{{d.status}}</span>
+ <span class="small gray">{{d.status}}</span>
</div>
<div class="col-sm-3">
- <span class="small darkgrey">{{d.transaction_date}}</span>
+ <span class="small gray">{{d.transaction_date}}</span>
</div>
</div>
<a class="transaction-item-link" href="/quotations/{{d.name}}">Link</a>
diff --git a/erpnext/templates/print_formats/includes/item_table_description.html b/erpnext/templates/print_formats/includes/item_table_description.html
index 070cca5..7569e50 100644
--- a/erpnext/templates/print_formats/includes/item_table_description.html
+++ b/erpnext/templates/print_formats/includes/item_table_description.html
@@ -1,7 +1,7 @@
-{%- set compact = doc.flags.compact_item_print -%}
-{%- set compact_fields = doc.flags.compact_item_fields -%}
+{%- set compact = print_settings.compact_item_print -%}
+{%- set compact_fields = parent_doc.flags.compact_item_fields -%}
{%- set display_columns = visible_columns|map(attribute="fieldname")| list -%}
-{%- set columns = doc.flags.format_columns(display_columns, compact_fields) -%}
+{%- set columns = parent_doc.flags.format_columns(display_columns, compact_fields) -%}
{% if doc.in_format_data("image") and doc.get("image") and "image" in display_columns -%}
<div class="pull-left" style="max-width: 40%; margin-right: 10px;">
@@ -11,11 +11,11 @@
<div>
{% if doc.in_format_data("item_code") and "item_code" in display_columns -%}
- <div class="primary">
- {% if compact %}<strong>{% endif %}
- {{ _(doc.item_code) }}
- {% if compact %}</strong>{% endif %}
+ {% if compact %}
+ <div class="primary compact-item">
+ {{ _(doc.item_code) }}
</div>
+ {% endif %}
{%- endif %}
{%- if doc.in_format_data("item_name") and "item_name" in display_columns and
diff --git a/erpnext/templates/print_formats/includes/item_table_qty.html b/erpnext/templates/print_formats/includes/item_table_qty.html
index ecaaef4..8e68f1c 100644
--- a/erpnext/templates/print_formats/includes/item_table_qty.html
+++ b/erpnext/templates/print_formats/includes/item_table_qty.html
@@ -1,4 +1,4 @@
-{% set qty_first=frappe.db.get_single_value("Print Settings", "print_uom_after_quantity") %}
+{% set qty_first=print_settings.print_uom_after_quantity %}
{% if qty_first %}
{{ doc.get_formatted("qty", doc) }}
{% if (doc.uom and not doc.is_print_hide("uom")) %} {{ _(doc.uom) }}
diff --git a/erpnext/templates/print_formats/includes/items.html b/erpnext/templates/print_formats/includes/items.html
new file mode 100644
index 0000000..55598e7
--- /dev/null
+++ b/erpnext/templates/print_formats/includes/items.html
@@ -0,0 +1,37 @@
+{%- if data -%}
+ {%- set visible_columns = get_visible_columns(doc.get(df.fieldname),
+ table_meta, df) -%}
+ <div {{ fieldmeta(df) }}>
+ <table class="table table-bordered table-condensed">
+ <thead>
+ <tr>
+ <th style="width: 40px" class="table-sr">{{ _("Sr") }}</th>
+ {% for tdf in visible_columns %}
+ {% if (data and not print_settings.compact_item_print) or tdf.fieldname in doc.flags.compact_item_fields %}
+ <th style="width: {{ get_width(tdf) }};" class="{{ get_align_class(tdf) }}" {{ fieldmeta(df) }}>
+ {{ _(tdf.label) }}</th>
+ {% endif %}
+ {% endfor %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for d in data %}
+ <tr>
+ <td class="table-sr">{{ d.idx }}</td>
+ {% for tdf in visible_columns %}
+ {% if not print_settings.compact_item_print or tdf.fieldname in doc.flags.compact_item_fields %}
+ <td class="{{ get_align_class(tdf) }}" {{ fieldmeta(df) }}>
+ {% if doc.child_print_templates %}
+ {%- set child_templates = doc.child_print_templates.get(df.fieldname) %}
+ <div class="value">{{ print_value(tdf, d, doc, visible_columns, child_templates) }}</div></td>
+ {% else %}
+ <div class="value">{{ print_value(tdf, d, doc, visible_columns) }}</div></td>
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+{%- endif -%}
diff --git a/erpnext/templates/print_formats/includes/taxes.html b/erpnext/templates/print_formats/includes/taxes.html
index 304e845..1935542 100644
--- a/erpnext/templates/print_formats/includes/taxes.html
+++ b/erpnext/templates/print_formats/includes/taxes.html
@@ -17,7 +17,7 @@
{{ render_discount_amount(doc) }}
{%- endif -%}
{%- for charge in data -%}
- {%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
+ {%- if (charge.tax_amount or print_settings.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
<div class="row">
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ charge.get_formatted("description") }}</label>
diff --git a/erpnext/utilities/bot.py b/erpnext/utilities/bot.py
index 0e5e95d..b2e74da 100644
--- a/erpnext/utilities/bot.py
+++ b/erpnext/utilities/bot.py
@@ -26,12 +26,12 @@
for warehouse in warehouses:
qty = frappe.db.get_value("Bin", {'item_code': item[0], 'warehouse': warehouse.name}, 'actual_qty')
if qty:
- out.append(_('{0} units of [{1}](#Form/Item/{1}) found in [{2}](#Form/Warehouse/{2})').format(qty,
+ out.append(_('{0} units of [{1}](/app/Form/Item/{1}) found in [{2}](/app/Form/Warehouse/{2})').format(qty,
item[0], warehouse.name))
found = True
if not found:
- out.append(_('[{0}](#Form/Item/{0}) is out of stock').format(item[0]))
+ out.append(_('[{0}](/app/Form/Item/{0}) is out of stock').format(item[0]))
return "\n\n".join(out)
diff --git a/package.json b/package.json
index 1b2dc9e..d12661b 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"snyk": "^1.290.1"
},
"dependencies": {
+ "onscan.js": "^1.5.2"
},
"scripts": {
"snyk-protect": "snyk protect",
diff --git a/yarn.lock b/yarn.lock
index 97a0635..e5a2da1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1217,6 +1217,11 @@
dependencies:
mimic-fn "^1.0.0"
+onscan.js@^1.5.2:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/onscan.js/-/onscan.js-1.5.2.tgz#14ed636e5f4c3f0a78bacbf9a505dad3140ee341"
+ integrity sha512-9oGYy2gXYRjvXO9GYqqVca0VuCTAmWhbmX3egBSBP13rXiMNb+dKPJzKFEeECGqPBpf0m40Zoo+GUQ7eCackdw==
+
opn@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"