mirror of
https://github.com/frappe/erpnext.git
synced 2026-04-14 20:35:09 +00:00
Merge branch 'version-12-hotfix' into item-edit-hotfix
This commit is contained in:
@@ -24,26 +24,6 @@ frappe.ui.form.on('Asset Maintenance', {
|
||||
return indicator;
|
||||
}
|
||||
);
|
||||
|
||||
frm.set_query('select_serial_no', function(doc){
|
||||
return {
|
||||
asset: frm.doc.asset_name
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
select_serial_no: (frm) => {
|
||||
let serial_nos = frm.doc.serial_no || frm.doc.select_serial_no;
|
||||
if (serial_nos) {
|
||||
serial_nos = serial_nos.split('\n');
|
||||
serial_nos.push(frm.doc.select_serial_no);
|
||||
|
||||
const unique_sn = serial_nos.filter(function(elem, index, self) {
|
||||
return index === self.indexOf(elem);
|
||||
});
|
||||
|
||||
frm.set_value("serial_no", unique_sn.join('\n'));
|
||||
}
|
||||
},
|
||||
|
||||
refresh: (frm) => {
|
||||
@@ -93,25 +73,6 @@ frappe.ui.form.on('Asset Maintenance Task', {
|
||||
},
|
||||
end_date: (frm, cdt, cdn) => {
|
||||
get_next_due_date(frm, cdt, cdn);
|
||||
},
|
||||
assign_to: (frm, cdt, cdn) => {
|
||||
var d = locals[cdt][cdn];
|
||||
if (frm.doc.__islocal) {
|
||||
frappe.model.set_value(cdt, cdn, "assign_to", "");
|
||||
frappe.model.set_value(cdt, cdn, "assign_to_name", "");
|
||||
frappe.throw(__("Please save before assigning task."));
|
||||
}
|
||||
if (d.assign_to) {
|
||||
return frappe.call({
|
||||
method: 'erpnext.assets.doctype.asset_maintenance.asset_maintenance.assign_tasks',
|
||||
args: {
|
||||
asset_maintenance_name: frm.doc.name,
|
||||
assign_to_member: d.assign_to,
|
||||
maintenance_task: d.maintenance_task,
|
||||
next_due_date: d.next_due_date
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -16,12 +16,11 @@ class AssetMaintenance(Document):
|
||||
throw(_("Start date should be less than end date for task {0}").format(task.maintenance_task))
|
||||
if getdate(task.next_due_date) < getdate(nowdate()):
|
||||
task.maintenance_status = "Overdue"
|
||||
if not task.assign_to and self.docstatus == 0:
|
||||
throw(_("Row #{}: Please asign task to a member.").format(task.idx))
|
||||
|
||||
def on_update(self):
|
||||
for task in self.get('asset_maintenance_tasks'):
|
||||
if not task.assign_to:
|
||||
task.db_set("assign_to", self.maintenance_manager)
|
||||
task.db_set("assign_to_name", self.maintenance_manager_name)
|
||||
assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date)
|
||||
self.sync_maintenance_tasks()
|
||||
|
||||
@@ -108,7 +107,7 @@ def update_maintenance_log(asset_maintenance, item_code, item_name, task):
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_team_members(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.get_values('Maintenance Team Member', {'parent':filters.get("maintenance_team")})
|
||||
return frappe.db.get_values('Maintenance Team Member', { 'parent': filters.get("maintenance_team") })
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_maintenance_log(asset_name):
|
||||
|
||||
@@ -125,13 +125,15 @@ def get_maintenance_tasks():
|
||||
"start_date": nowdate(),
|
||||
"periodicity": "Monthly",
|
||||
"maintenance_type": "Preventive Maintenance",
|
||||
"maintenance_status": "Planned"
|
||||
"maintenance_status": "Planned",
|
||||
"assign_to": "marcus@abc.com"
|
||||
},
|
||||
{"maintenance_task": "Check Gears",
|
||||
"start_date": nowdate(),
|
||||
"periodicity": "Yearly",
|
||||
"maintenance_type": "Calibration",
|
||||
"maintenance_status": "Planned"
|
||||
"maintenance_status": "Planned",
|
||||
"assign_to": "thalia@abc.com"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -1194,11 +1194,11 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
action = "add" if perm_type == 'create' else "update"
|
||||
frappe.throw(_("You do not have permissions to {} items in a Sales Order.").format(action), title=_("Insufficient Permissions"))
|
||||
|
||||
def get_new_child_item():
|
||||
def get_new_child_item(item_row):
|
||||
if parent_doctype == "Sales Order":
|
||||
return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
||||
return set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||
if parent_doctype == "Purchase Order":
|
||||
return set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d)
|
||||
return set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_row)
|
||||
|
||||
def validate_quantity(child_item, d):
|
||||
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
|
||||
@@ -1219,7 +1219,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
if not d.get("docname"):
|
||||
new_child_flag = True
|
||||
check_permissions(parent, 'create')
|
||||
child_item = get_new_child_item()
|
||||
child_item = get_new_child_item(d)
|
||||
else:
|
||||
check_permissions(parent, 'write')
|
||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||
|
||||
@@ -102,7 +102,7 @@ def validate_item_attribute_value(attributes_list, attribute, attribute_value, i
|
||||
frappe.throw(_("{0} is not a valid Value for Attribute {1} of Item {2}.").format(
|
||||
frappe.bold(attribute_value), frappe.bold(attribute), frappe.bold(item)), InvalidItemAttributeValueError, title=_("Invalid Value"))
|
||||
else:
|
||||
msg = _("The value {0} is already assigned to an exisiting Item {1}.").format(
|
||||
msg = _("The value {0} is already assigned to an existing Item {1}.").format(
|
||||
frappe.bold(attribute_value), frappe.bold(item))
|
||||
msg += "<br>" + _("To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings.").format(frappe.bold("Allow Rename Attribute Value"))
|
||||
|
||||
|
||||
@@ -73,10 +73,16 @@ def link_customer_and_address(raw_billing_data, raw_shipping_data, customer_name
|
||||
|
||||
if customer_exists:
|
||||
frappe.rename_doc("Customer", old_name, customer_name)
|
||||
billing_address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": "Billing"})
|
||||
shipping_address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": "Shipping"})
|
||||
rename_address(billing_address, customer)
|
||||
rename_address(shipping_address, customer)
|
||||
for address_type in ("Billing", "Shipping",):
|
||||
try:
|
||||
address = frappe.get_doc("Address", {"woocommerce_email": customer_woo_com_email, "address_type": address_type})
|
||||
rename_address(address, customer)
|
||||
except (
|
||||
frappe.DoesNotExistError,
|
||||
frappe.DuplicateEntryError,
|
||||
frappe.ValidationError,
|
||||
):
|
||||
pass
|
||||
else:
|
||||
create_address(raw_billing_data, customer, "Billing")
|
||||
create_address(raw_shipping_data, customer, "Shipping")
|
||||
|
||||
@@ -8,6 +8,7 @@ import json
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_request_session
|
||||
from requests.exceptions import HTTPError
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||
from erpnext.erpnext_integrations.utils import get_webhook_address
|
||||
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log
|
||||
@@ -29,19 +30,24 @@ class ShopifySettings(Document):
|
||||
webhooks = ["orders/create", "orders/paid", "orders/fulfilled"]
|
||||
# url = get_shopify_url('admin/webhooks.json', self)
|
||||
created_webhooks = [d.method for d in self.webhooks]
|
||||
url = get_shopify_url('admin/api/2019-04/webhooks.json', self)
|
||||
url = get_shopify_url('admin/api/2020-04/webhooks.json', self)
|
||||
for method in webhooks:
|
||||
session = get_request_session()
|
||||
try:
|
||||
d = session.post(url, data=json.dumps({
|
||||
res = session.post(url, data=json.dumps({
|
||||
"webhook": {
|
||||
"topic": method,
|
||||
"address": get_webhook_address(connector_name='shopify_connection', method='store_request_data'),
|
||||
"format": "json"
|
||||
}
|
||||
}), headers=get_header(self))
|
||||
d.raise_for_status()
|
||||
self.update_webhook_table(method, d.json())
|
||||
res.raise_for_status()
|
||||
self.update_webhook_table(method, res.json())
|
||||
|
||||
except HTTPError as e:
|
||||
error_message = res.json().get('errors', e)
|
||||
make_shopify_log(status="Warning", exception=error_message, rollback=True)
|
||||
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Warning", exception=e, rollback=True)
|
||||
|
||||
@@ -50,13 +56,18 @@ class ShopifySettings(Document):
|
||||
deleted_webhooks = []
|
||||
|
||||
for d in self.webhooks:
|
||||
url = get_shopify_url('admin/api/2019-04/webhooks/{0}.json'.format(d.webhook_id), self)
|
||||
url = get_shopify_url('admin/api/2020-04/webhooks/{0}.json'.format(d.webhook_id), self)
|
||||
try:
|
||||
res = session.delete(url, headers=get_header(self))
|
||||
res.raise_for_status()
|
||||
deleted_webhooks.append(d)
|
||||
|
||||
except HTTPError as e:
|
||||
error_message = res.json().get('errors', e)
|
||||
make_shopify_log(status="Warning", exception=error_message, rollback=True)
|
||||
|
||||
except Exception as e:
|
||||
frappe.log_error(message=frappe.get_traceback(), title=e)
|
||||
frappe.log_error(message=e, title='Shopify Webhooks Issue')
|
||||
|
||||
for d in deleted_webhooks:
|
||||
self.remove(d)
|
||||
@@ -125,4 +136,3 @@ def setup_custom_fields():
|
||||
}
|
||||
|
||||
create_custom_fields(custom_fields)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings impo
|
||||
shopify_variants_attr_list = ["option1", "option2", "option3"]
|
||||
|
||||
def sync_item_from_shopify(shopify_settings, item):
|
||||
url = get_shopify_url("admin/api/2019-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
|
||||
url = get_shopify_url("admin/api/2020-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
|
||||
session = get_request_session()
|
||||
|
||||
try:
|
||||
|
||||
@@ -67,6 +67,7 @@ def validate_service_item(item, msg):
|
||||
if frappe.db.get_value("Item", item, "is_stock_item") == 1:
|
||||
frappe.throw(_(msg))
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_practitioner_list(doctype, txt, searchfield, start, page_len, filters=None):
|
||||
fields = ["name", "first_name", "mobile_phone"]
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ def get_data(filters, leave_types):
|
||||
conditions = get_conditions(filters)
|
||||
|
||||
if filters.to_date <= filters.from_date:
|
||||
frappe.throw(_("From date can not be greater than than To date"))
|
||||
frappe.throw(_("'From Date should be less than To Date"))
|
||||
|
||||
active_employees = frappe.get_all("Employee",
|
||||
filters=conditions,
|
||||
@@ -160,4 +160,4 @@ def get_department_leave_approver_map(department=None):
|
||||
for k, v in approver_list:
|
||||
approvers.setdefault(k, []).append(v)
|
||||
|
||||
return approvers
|
||||
return approvers
|
||||
|
||||
@@ -10,7 +10,7 @@ from erpnext.hr.report.employee_leave_balance.employee_leave_balance import calc
|
||||
|
||||
def execute(filters=None):
|
||||
if filters.to_date <= filters.from_date:
|
||||
frappe.throw(_('From date can not be greater than than To date'))
|
||||
frappe.throw(_('From Date should be less than To Date'))
|
||||
|
||||
columns = get_columns()
|
||||
data = get_data(filters)
|
||||
|
||||
@@ -2,4 +2,13 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Quality Procedure', {
|
||||
refresh: function(frm) {
|
||||
frm.set_query("procedure","processes", (frm) =>{
|
||||
return {
|
||||
filters: {
|
||||
name: ["not in", [frm.parent_quality_procedure, frm.name]]
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "format:PRC-{quality_procedure_name}",
|
||||
"creation": "2018-10-06 00:06:29.756804",
|
||||
"doctype": "DocType",
|
||||
@@ -72,7 +73,7 @@
|
||||
],
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-18 18:26:05.511984",
|
||||
"modified": "2020-06-17 17:25:03.434953",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Quality Management",
|
||||
"name": "Quality Procedure",
|
||||
|
||||
@@ -10,13 +10,8 @@ from frappe import _
|
||||
class QualityProcedure(NestedSet):
|
||||
nsm_parent_field = 'parent_quality_procedure'
|
||||
|
||||
def on_save(self):
|
||||
for process in self.processes:
|
||||
if process.procedure:
|
||||
doc = frappe.get_doc("Quality Procedure", process.procedure)
|
||||
if doc.parent_quality_procedure:
|
||||
frappe.throw(_("{0} already has a Parent Procedure {1}.".format(process.procedure, doc.parent_quality_procedure)))
|
||||
self.is_group = 1
|
||||
def before_save(self):
|
||||
self.check_for_incorrect_child()
|
||||
|
||||
def on_update(self):
|
||||
self.set_parent()
|
||||
@@ -47,11 +42,21 @@ class QualityProcedure(NestedSet):
|
||||
doc.save(ignore_permissions=True)
|
||||
|
||||
def set_parent(self):
|
||||
for process in self.processes:
|
||||
# Set parent for only those children who don't have a parent
|
||||
parent_quality_procedure = frappe.db.get_value("Quality Procedure", process.procedure, "parent_quality_procedure")
|
||||
if not parent_quality_procedure and process.procedure:
|
||||
frappe.db.set_value(self.doctype, process.procedure, "parent_quality_procedure", self.name)
|
||||
|
||||
def check_for_incorrect_child(self):
|
||||
for process in self.processes:
|
||||
if process.procedure:
|
||||
doc = frappe.get_doc("Quality Procedure", process.procedure)
|
||||
doc.parent_quality_procedure = self.name
|
||||
doc.save(ignore_permissions=True)
|
||||
# Check if any child process belongs to another parent.
|
||||
parent_quality_procedure = frappe.db.get_value("Quality Procedure", process.procedure, "parent_quality_procedure")
|
||||
if parent_quality_procedure and parent_quality_procedure != self.name:
|
||||
frappe.throw(_("{0} already has a Parent Procedure {1}.".format(frappe.bold(process.procedure), frappe.bold(parent_quality_procedure))),
|
||||
title=_("Invalid Child Procedure"))
|
||||
self.is_group = 1
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_children(doctype, parent=None, parent_quality_procedure=None, is_root=False):
|
||||
|
||||
@@ -16,6 +16,7 @@ frappe.treeview_settings["Quality Procedure"] = {
|
||||
},
|
||||
],
|
||||
breadcrumb: "Setup",
|
||||
disable_add_node: true,
|
||||
root_label: "All Quality Procedures",
|
||||
get_tree_root: false,
|
||||
menu_items: [
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2019-05-26 00:10:00.248885",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"process_description",
|
||||
@@ -23,7 +25,8 @@
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2019-05-26 22:05:49.007189",
|
||||
"links": [],
|
||||
"modified": "2020-06-17 15:44:38.937915",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Quality Management",
|
||||
"name": "Quality Procedure Process",
|
||||
|
||||
@@ -299,6 +299,7 @@ def get_loyalty_programs(doc):
|
||||
|
||||
return lp_details
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_customer_list(doctype, txt, searchfield, start, page_len, filters=None):
|
||||
from erpnext.controllers.queries import get_fields
|
||||
|
||||
|
||||
@@ -868,7 +868,8 @@ def make_purchase_order(source_name, for_supplier=None, selected_items=[], targe
|
||||
],
|
||||
"field_no_map": [
|
||||
"rate",
|
||||
"price_list_rate"
|
||||
"price_list_rate",
|
||||
"item_tax_template"
|
||||
],
|
||||
"postprocess": update_item,
|
||||
"condition": lambda doc: doc.ordered_qty < doc.qty and doc.supplier == supplier and doc.item_code in selected_items
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
@@ -49,7 +50,7 @@
|
||||
"fieldname": "terms_and_conditions_help",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Terms and Conditions Help",
|
||||
"options": "<h4>Standard Terms and Conditions Example</h4>\n\n<pre>Delivery Terms for Order number {{ name }}\n\n-Order Date : {{ transaction_date }} \n-Expected Delivery Date : {{ delivery_date }}\n</pre>\n\n<h4>How to get fieldnames</h4>\n\n<p>The fieldnames you can use in your email template are the fields in the document from which you are sending the email. You can find out the fields of any documents via Setup > Customize Form View and selecting the document type (e.g. Sales Invoice)</p>\n\n<h4>Templating</h4>\n\n<p>Templates are compiled using the Jinja Templating Langauge. To learn more about Jinja, <a class=\"strong\" href=\"http://jinja.pocoo.org/docs/dev/templates/\">read this documentation.</a></p>"
|
||||
"options": "<h4>Standard Terms and Conditions Example</h4>\n\n<pre>Delivery Terms for Order number {{ name }}\n\n-Order Date : {{ transaction_date }} \n-Expected Delivery Date : {{ delivery_date }}\n</pre>\n\n<h4>How to get fieldnames</h4>\n\n<p>The fieldnames you can use in your email template are the fields in the document from which you are sending the email. You can find out the fields of any documents via Setup > Customize Form View and selecting the document type (e.g. Sales Invoice)</p>\n\n<h4>Templating</h4>\n\n<p>Templates are compiled using the Jinja Templating Language. To learn more about Jinja, <a class=\"strong\" href=\"http://jinja.pocoo.org/docs/dev/templates/\">read this documentation.</a></p>"
|
||||
},
|
||||
{
|
||||
"fieldname": "applicable_modules_section",
|
||||
@@ -81,7 +82,8 @@
|
||||
],
|
||||
"icon": "icon-legal",
|
||||
"idx": 1,
|
||||
"modified": "2019-07-04 13:31:30.393425",
|
||||
"links": [],
|
||||
"modified": "2020-06-16 22:54:38.094844",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Terms and Conditions",
|
||||
|
||||
Reference in New Issue
Block a user