Merge branch 'develop' into better-logging-for-membership
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 9fc44bc..e117471 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -12,9 +12,10 @@
setup: function(frm) {
frm.set_query("paid_from", function() {
+ frm.events.validate_company(frm);
+
var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
-
return {
filters: {
"account_type": ["in", account_types],
@@ -23,13 +24,16 @@
}
}
});
+
frm.set_query("party_type", function() {
+ frm.events.validate_company(frm);
return{
filters: {
"name": ["in", Object.keys(frappe.boot.party_account_types)],
}
}
});
+
frm.set_query("party_bank_account", function() {
return {
filters: {
@@ -39,6 +43,7 @@
}
}
});
+
frm.set_query("bank_account", function() {
return {
filters: {
@@ -47,6 +52,7 @@
}
}
});
+
frm.set_query("contact_person", function() {
if (frm.doc.party) {
return {
@@ -58,10 +64,12 @@
};
}
});
+
frm.set_query("paid_to", function() {
+ frm.events.validate_company(frm);
+
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
-
return {
filters: {
"account_type": ["in", account_types],
@@ -150,6 +158,12 @@
frm.events.show_general_ledger(frm);
},
+ validate_company: (frm) => {
+ if (!frm.doc.company){
+ frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")});
+ }
+ },
+
company: function(frm) {
frm.events.hide_unhide_fields(frm);
frm.events.set_dynamic_labels(frm);
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 72debb7..efdbdb1 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -6,7 +6,7 @@
import frappe, erpnext, math, json
from frappe import _
from six import string_types
-from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, month_diff, add_days, get_last_day
+from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff, month_diff, add_days, get_last_day, get_datetime
from frappe.model.document import Document
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
from erpnext.assets.doctype.asset.depreciation \
@@ -140,6 +140,10 @@
def make_asset_movement(self):
reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
reference_docname = self.purchase_receipt or self.purchase_invoice
+ transaction_date = getdate(self.purchase_date)
+ if reference_docname:
+ posting_date, posting_time = frappe.db.get_value(reference_doctype, reference_docname, ["posting_date", "posting_time"])
+ transaction_date = get_datetime("{} {}".format(posting_date, posting_time))
assets = [{
'asset': self.name,
'asset_name': self.asset_name,
@@ -151,7 +155,7 @@
'assets': assets,
'purpose': 'Receipt',
'company': self.company,
- 'transaction_date': getdate(self.purchase_date),
+ 'transaction_date': transaction_date,
'reference_doctype': reference_doctype,
'reference_name': reference_docname
}).insert()
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index ecf041e..801c405 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -25,7 +25,7 @@
if not filters: filters = []
- if doctype in ['Supplier Quotation', 'Purchase Invoice']:
+ if doctype in ['Supplier Quotation', 'Purchase Invoice', 'Quotation']:
filters.append((doctype, 'docstatus', '<', 2))
else:
filters.append((doctype, 'docstatus', '=', 1))
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 315d298..99fa703 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -27,9 +27,6 @@
def after_insert(self):
self.update_links()
- # after the address and contact are created, flush the field values
- # to avoid inconsistent reporting in case the documents are changed
- self.flush_address_and_contact_fields()
def validate(self):
self.set_lead_name()
@@ -210,14 +207,6 @@
})
self.contact_doc.save()
- def flush_address_and_contact_fields(self):
- fields = ['address_type', 'address_line1', 'address_line2', 'address_title',
- 'city', 'county', 'country', 'fax', 'pincode', 'state']
-
- for field in fields:
- self.set(field, None)
-
-
@frappe.whitelist()
def make_customer(source_name, target_doc=None):
return _make_customer(source_name, target_doc)
@@ -376,3 +365,8 @@
lead = leads[0].name if leads else None
return lead
+
+def daily_open_lead():
+ leads = frappe.get_all("Lead", filters = [["contact_date", "Between", [nowdate(), nowdate()]]])
+ for lead in leads:
+ frappe.db.set_value("Lead", lead.name, "status", "Open")
\ No newline at end of file
diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json
index b3a161d..e396760 100644
--- a/erpnext/education/doctype/question/question.json
+++ b/erpnext/education/doctype/question/question.json
@@ -13,7 +13,7 @@
"fields": [
{
"fieldname": "question",
- "fieldtype": "Small Text",
+ "fieldtype": "Text Editor",
"in_list_view": 1,
"label": "Question",
"reqd": 1
@@ -34,7 +34,7 @@
"read_only": 1
}
],
- "modified": "2019-05-30 18:39:21.880974",
+ "modified": "2020-09-24 18:39:21.880974",
"modified_by": "Administrator",
"module": "Education",
"name": "Question",
@@ -77,4 +77,4 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/education/doctype/quiz_question/quiz_question.json b/erpnext/education/doctype/quiz_question/quiz_question.json
index 0564482..aab07a3 100644
--- a/erpnext/education/doctype/quiz_question/quiz_question.json
+++ b/erpnext/education/doctype/quiz_question/quiz_question.json
@@ -20,14 +20,14 @@
{
"fetch_from": "question_link.question",
"fieldname": "question",
- "fieldtype": "Data",
+ "fieldtype": "Text Editor",
"in_list_view": 1,
"label": "Question",
"read_only": 1
}
],
"istable": 1,
- "modified": "2019-06-12 12:24:02.312577",
+ "modified": "2020-09-24 12:24:02.312577",
"modified_by": "Administrator",
"module": "Education",
"name": "Quiz Question",
@@ -37,4 +37,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index 512fb48..e685b20 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -6,7 +6,7 @@
import frappe
from frappe.model.document import Document
import json
-from frappe.utils import getdate, get_time
+from frappe.utils import getdate, get_time, flt
from frappe.model.mapper import get_mapped_doc
from frappe import _
import datetime
@@ -45,7 +45,7 @@
def validate_overlaps(self):
end_time = datetime.datetime.combine(getdate(self.appointment_date), get_time(self.appointment_time)) \
- + datetime.timedelta(minutes=float(self.duration))
+ + datetime.timedelta(minutes=flt(self.duration))
overlaps = frappe.db.sql("""
select
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index f8b6be7..4e05076 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -336,7 +336,8 @@
"erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry.process_expired_allocation",
"erpnext.hr.utils.generate_leave_encashment",
"erpnext.loan_management.doctype.loan_security_shortfall.loan_security_shortfall.create_process_loan_security_shortfall",
- "erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans"
+ "erpnext.loan_management.doctype.loan_interest_accrual.loan_interest_accrual.process_loan_interest_accrual_for_term_loans",
+ "erpnext.crm.doctype.lead.lead.daily_open_lead"
],
"monthly_long": [
"erpnext.accounts.deferred_revenue.process_deferred_accounting",
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index f4eaad5..6e97d81 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -120,7 +120,7 @@
var get_payment_mode_account = function(frm, mode_of_payment, callback) {
if(!frm.doc.company) {
- frappe.throw(__("Please select the Company first"));
+ frappe.throw({message:__("Please select a Company first."), title: __("Mandatory")});
}
if(!mode_of_payment) {
diff --git a/erpnext/public/js/education/lms/quiz.js b/erpnext/public/js/education/lms/quiz.js
index 91cbbf4..4a9d1e3 100644
--- a/erpnext/public/js/education/lms/quiz.js
+++ b/erpnext/public/js/education/lms/quiz.js
@@ -140,7 +140,7 @@
make_question() {
let question_wrapper = document.createElement('h5');
question_wrapper.classList.add('mt-3');
- question_wrapper.innerText = this.question;
+ question_wrapper.innerHTML = this.question;
this.wrapper.appendChild(question_wrapper);
}
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 87982f1..9ed5009 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -480,7 +480,7 @@
callback: r => {
if(!r.exc) {
if (this.doc.conversion_factor == r.message.conversion_factor) return;
-
+
const docname = this.doc.docname;
dialog.fields_dict.trans_items.df.data.some(doc => {
if (doc.docname == docname) {
@@ -677,6 +677,7 @@
date_field: opts.date_field || undefined,
setters: opts.setters,
get_query: opts.get_query,
+ add_filters_group: 1,
action: function(selections, args) {
let values = selections;
if(values.length === 0){
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index a7e8388..0ccc025 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -96,7 +96,9 @@
def request_for_quotation():
quotation = _get_cart_quotation()
quotation.flags.ignore_permissions = True
- quotation.submit()
+ quotation.save()
+ if not get_shopping_cart_settings().save_quotations_as_draft:
+ quotation.submit()
return quotation.name
@frappe.whitelist()
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
index 32004ef..9d61e7d 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
@@ -27,6 +27,7 @@
"enable_checkout",
"payment_success_url",
"column_break_11",
+ "save_quotations_as_draft",
"payment_gateway_account"
],
"fields": [
@@ -166,13 +167,20 @@
"fieldname": "enable_variants",
"fieldtype": "Check",
"label": "Enable Variants"
+ },
+ {
+ "default": "0",
+ "depends_on": "eval: doc.enable_checkout == 0",
+ "fieldname": "save_quotations_as_draft",
+ "fieldtype": "Check",
+ "label": "Save Quotations as Draft"
}
],
"icon": "fa fa-shopping-cart",
"idx": 1,
"issingle": 1,
"links": [],
- "modified": "2020-08-02 18:21:43.873303",
+ "modified": "2020-09-24 16:28:07.192525",
"modified_by": "Administrator",
"module": "Shopping Cart",
"name": "Shopping Cart Settings",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 1f95447..39fd029 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -156,6 +156,7 @@
mr_item.item_code = item.item_code;
mr_item.item_name = item.item_name;
mr_item.uom = item.uom;
+ mr_item.stock_uom = item.stock_uom;
mr_item.conversion_factor = item.conversion_factor;
mr_item.item_group = item.item_group;
mr_item.description = item.description;
diff --git a/erpnext/templates/generators/item/item_add_to_cart.html b/erpnext/templates/generators/item/item_add_to_cart.html
index 40bc0c7..dbf15de 100644
--- a/erpnext/templates/generators/item/item_add_to_cart.html
+++ b/erpnext/templates/generators/item/item_add_to_cart.html
@@ -10,7 +10,10 @@
{{ product_info.price.formatted_price_sales_uom }}
<small class="text-muted">({{ product_info.price.formatted_price }} / {{ product_info.uom }})</small>
</h4>
+ {% else %}
+ {{ _("Unit of Measurement") }} : {{ product_info.uom }}
{% endif %}
+
{% if cart_settings.show_stock_availability %}
<div>
{% if product_info.in_stock == 0 %}
diff --git a/erpnext/templates/includes/transaction_row.html b/erpnext/templates/includes/transaction_row.html
index 80a542f..fd4835e 100644
--- a/erpnext/templates/includes/transaction_row.html
+++ b/erpnext/templates/includes/transaction_row.html
@@ -14,7 +14,11 @@
</div>
</div>
<div class="col-sm-3 text-right bold">
- {{ doc.get_formatted("grand_total") }}
+ {% if doc.doctype == "Quotation" and not doc.docstatus %}
+ {{ _("Pending") }}
+ {% else %}
+ {{ doc.get_formatted("grand_total") }}
+ {% endif %}
</div>
</div>
<a class="transaction-item-link" href="/{{ pathname }}/{{ doc.name }}">Link</a>
diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html
index 9e3c58b..01b5f6d 100644
--- a/erpnext/templates/pages/order.html
+++ b/erpnext/templates/pages/order.html
@@ -12,22 +12,21 @@
{% endblock %}
{% block header_actions %}
-<div class="dropdown">
- <button class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
- <span>{{ _('Actions') }}</span>
- <b class="caret"></b>
- </button>
- <ul class="dropdown-menu dropdown-menu-right" role="menu">
- {% if doc.doctype == 'Purchase Order' %}
- <a class="dropdown-item" href="/api/method/erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice_from_portal?purchase_order_name={{ doc.name }}" data-action="make_purchase_invoice">{{ _("Make Purchase Invoice") }}</a>
- {% endif %}
- <a class="dropdown-item" href='/printview?doctype={{ doc.doctype}}&name={{ doc.name }}&format={{ print_format }}'
- target="_blank" rel="noopener noreferrer">
- {{ _("Print") }}
- </a>
- </ul>
-</div>
-
+ <div class="dropdown">
+ <button class="btn btn-outline-secondary dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
+ <span>{{ _('Actions') }}</span>
+ <b class="caret"></b>
+ </button>
+ <ul class="dropdown-menu dropdown-menu-right" role="menu">
+ {% if doc.doctype == 'Purchase Order' %}
+ <a class="dropdown-item" href="/api/method/erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice_from_portal?purchase_order_name={{ doc.name }}" data-action="make_purchase_invoice">{{ _("Make Purchase Invoice") }}</a>
+ {% endif %}
+ <a class="dropdown-item" href='/printview?doctype={{ doc.doctype}}&name={{ doc.name }}&format={{ print_format }}'
+ target="_blank" rel="noopener noreferrer">
+ {{ _("Print") }}
+ </a>
+ </ul>
+ </div>
{% endblock %}
{% block page_content %}
@@ -35,7 +34,11 @@
<div class="row transaction-subheading">
<div class="col-6">
<span class="indicator {{ doc.indicator_color or ("blue" if doc.docstatus==1 else "darkgrey") }}">
- {{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
+ {% if doc.doctype == "Quotation" and not doc.docstatus %}
+ {{ _("Pending") }}
+ {% else %}
+ {{ _(doc.get('indicator_title')) or _(doc.status) or _("Submitted") }}
+ {% endif %}
</span>
</div>
<div class="col-6 text-muted text-right small">
@@ -95,7 +98,6 @@
</div>
{% endfor %}
</div>
-
<!-- taxes -->
<div class="order-taxes d-flex justify-content-end">
<table>