diff --git a/erpnext/demo/data/drug_list.json b/erpnext/demo/data/drug_list.json index f34ca572d23..9b101cb1c81 100644 --- a/erpnext/demo/data/drug_list.json +++ b/erpnext/demo/data/drug_list.json @@ -48,7 +48,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -133,7 +132,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -218,7 +216,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -303,7 +300,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -388,7 +384,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -473,7 +468,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -558,7 +552,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -643,7 +636,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -728,7 +720,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -813,7 +804,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -898,7 +888,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -983,7 +972,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1068,7 +1056,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1153,7 +1140,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1238,7 +1224,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1323,7 +1308,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1408,7 +1392,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1493,7 +1476,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1578,7 +1560,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1663,7 +1644,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1748,7 +1728,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1833,7 +1812,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -1918,7 +1896,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2003,7 +1980,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2088,7 +2064,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2173,7 +2148,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2258,7 +2232,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2343,7 +2316,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2428,7 +2400,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2513,7 +2484,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2598,7 +2568,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2683,7 +2652,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2768,7 +2736,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2853,7 +2820,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -2938,7 +2904,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3023,7 +2988,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3108,7 +3072,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3193,7 +3156,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3278,7 +3240,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3363,7 +3324,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3448,7 +3408,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3533,7 +3492,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3618,7 +3576,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3703,7 +3660,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3788,7 +3744,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3873,7 +3828,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -3958,7 +3912,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4043,7 +3996,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4128,7 +4080,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4213,7 +4164,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4298,7 +4248,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4383,7 +4332,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4468,7 +4416,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4553,7 +4500,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4638,7 +4584,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4723,7 +4668,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4808,7 +4752,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4893,7 +4836,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -4978,7 +4920,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -5063,7 +5004,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -5148,7 +5088,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -5233,7 +5172,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, @@ -5318,7 +5256,6 @@ "naming_series": null, "net_weight": 0.0, "opening_stock": 0.0, - "publish_in_hub": 1, "quality_parameters": [], "reorder_levels": [], "route": null, diff --git a/erpnext/hub_node/__init__.py b/erpnext/hub_node/__init__.py index 65b1386466f..634746caf22 100644 --- a/erpnext/hub_node/__init__.py +++ b/erpnext/hub_node/__init__.py @@ -2,10 +2,7 @@ # For license information, please see license.txt from __future__ import unicode_literals -import frappe, requests, json -from frappe.utils import now, nowdate, cint -from frappe.utils.nestedset import get_root_of -from frappe.contacts.doctype.contact.contact import get_default_contact +import frappe @frappe.whitelist() def enable_hub(): @@ -13,265 +10,3 @@ def enable_hub(): hub_settings.register() frappe.db.commit() return hub_settings - -@frappe.whitelist() -def get_list(doctype, start=0, limit=20, fields=["*"], filters="{}", order_by=None): - connection = get_client_connection() - filters = json.loads(filters) - - response = connection.get_list(doctype, - limit_start=start, limit_page_length=limit, - filters=filters, fields=fields) - - # Bad, need child tables in response - listing = [] - for obj in response: - doc = connection.get_doc(doctype, obj['name']) - listing.append(doc) - - return listing - -@frappe.whitelist() -def get_item_favourites(start=0, limit=20, fields=["*"], order_by=None): - doctype = 'Hub Item' - hub_settings = frappe.get_doc('Hub Settings') - item_names_str = hub_settings.get('custom_data') or '[]' - item_names = json.loads(item_names_str) - filters = json.dumps({ - 'hub_item_code': ['in', item_names] - }) - return get_list(doctype, start, limit, fields, filters, order_by) - -@frappe.whitelist() -def update_wishlist_item(item_name, remove=0): - remove = int(remove) - hub_settings = frappe.get_doc('Hub Settings') - data = hub_settings.get('custom_data') - if not data or not json.loads(data): - data = '[]' - hub_settings.custom_data = data - hub_settings.save() - - item_names_str = data - item_names = json.loads(item_names_str) - if not remove and item_name not in item_names: - item_names.append(item_name) - if remove and item_name in item_names: - item_names.remove(item_name) - - item_names_str = json.dumps(item_names) - - hub_settings.custom_data = item_names_str - hub_settings.save() - -@frappe.whitelist() -def get_meta(doctype): - connection = get_client_connection() - meta = connection.get_doc('DocType', doctype) - categories = connection.get_list('Hub Category', - limit_start=0, limit_page_length=300, - filters={}, fields=['name']) - - categories = [d.get('name') for d in categories] - return { - 'meta': meta, - 'companies': connection.get_list('Hub Company', - limit_start=0, limit_page_length=300, - filters={}, fields=['name']), - 'categories': categories - } - -@frappe.whitelist() -def get_categories(parent='All Categories'): - # get categories info with parent category and stuff - connection = get_client_connection() - categories = connection.get_list('Hub Category', filters={'parent_hub_category': parent}) - - response = [{'value': c.get('name'), 'expandable': c.get('is_group')} for c in categories] - return response - -@frappe.whitelist() -def update_category(hub_item_code, category): - connection = get_hub_connection() - - # args = frappe._dict(dict( - # doctype='Hub Category', - # hub_category_name=category - # )) - # response = connection.insert('Hub Category', args) - - response = connection.update('Hub Item', frappe._dict(dict( - doctype='Hub Item', - hub_category = category - )), hub_item_code) - - return response - -@frappe.whitelist() -def send_review(hub_item_code, review): - review = json.loads(review) - hub_connection = get_hub_connection() - - item_doc = hub_connection.connection.get_doc('Hub Item', hub_item_code) - existing_reviews = item_doc.get('reviews') - - reviews = [review] - review.setdefault('idx', 0) - for r in existing_reviews: - if r.get('user') != review.get('user'): - reviews.append(r) - - response = hub_connection.update('Hub Item', dict( - doctype='Hub Item', - reviews = reviews - ), hub_item_code) - - return response - -@frappe.whitelist() -def get_details(hub_sync_id=None, doctype='Hub Item'): - if not hub_sync_id: - return - connection = get_client_connection() - details = connection.get_doc(doctype, hub_sync_id) - reviews = details.get('reviews') - if reviews and len(reviews): - for r in reviews: - r.setdefault('pretty_date', frappe.utils.pretty_date(r.get('modified'))) - details.setdefault('reviews', reviews) - return details - -def get_client_connection(): - # frappeclient connection - hub_connection = get_hub_connection() - return hub_connection.connection - -def get_hub_connection(): - hub_connector = frappe.get_doc( - 'Data Migration Connector', 'Hub Connector') - hub_connection = hub_connector.get_connection() - return hub_connection - -def make_opportunity(buyer_name, email_id): - buyer_name = "HUB-" + buyer_name - - if not frappe.db.exists('Lead', {'email_id': email_id}): - lead = frappe.new_doc("Lead") - lead.lead_name = buyer_name - lead.email_id = email_id - lead.save(ignore_permissions=True) - - o = frappe.new_doc("Opportunity") - o.enquiry_from = "Lead" - o.lead = frappe.get_all("Lead", filters={"email_id": email_id}, fields = ["name"])[0]["name"] - o.save(ignore_permissions=True) - -@frappe.whitelist() -def make_rfq_and_send_opportunity(item, supplier): - supplier = make_supplier(supplier) - contact = make_contact(supplier) - item = make_item(item) - rfq = make_rfq(item, supplier, contact) - status = send_opportunity(contact) - - return { - 'rfq': rfq, - 'hub_document_created': status - } - -def make_supplier(supplier): - # make supplier if not already exists - supplier = frappe._dict(json.loads(supplier)) - - if not frappe.db.exists('Supplier', {'supplier_name': supplier.supplier_name}): - supplier_doc = frappe.get_doc({ - 'doctype': 'Supplier', - 'supplier_name': supplier.supplier_name, - 'supplier_group': supplier.supplier_group, - 'supplier_email': supplier.supplier_email - }).insert() - else: - supplier_doc = frappe.get_doc('Supplier', supplier.supplier_name) - - return supplier_doc - -def make_contact(supplier): - contact_name = get_default_contact('Supplier', supplier.supplier_name) - # make contact if not already exists - if not contact_name: - contact = frappe.get_doc({ - 'doctype': 'Contact', - 'first_name': supplier.supplier_name, - 'email_id': supplier.supplier_email, - 'is_primary_contact': 1, - 'links': [ - {'link_doctype': 'Supplier', 'link_name': supplier.supplier_name} - ] - }).insert() - else: - contact = frappe.get_doc('Contact', contact_name) - - return contact - -def make_item(item): - # make item if not already exists - item = frappe._dict(json.loads(item)) - - if not frappe.db.exists('Item', {'item_code': item.item_code}): - item_doc = frappe.get_doc({ - 'doctype': 'Item', - 'item_code': item.item_code, - 'item_group': item.item_group, - 'is_item_from_hub': 1 - }).insert() - else: - item_doc = frappe.get_doc('Item', item.item_code) - - return item_doc - -def make_rfq(item, supplier, contact): - # make rfq - rfq = frappe.get_doc({ - 'doctype': 'Request for Quotation', - 'transaction_date': nowdate(), - 'status': 'Draft', - 'company': frappe.db.get_single_value('Hub Settings', 'company'), - 'message_for_supplier': 'Please supply the specified items at the best possible rates', - 'suppliers': [ - { 'supplier': supplier.name, 'contact': contact.name } - ], - 'items': [ - { - 'item_code': item.item_code, - 'qty': 1, - 'schedule_date': nowdate(), - 'warehouse': item.default_warehouse or get_root_of("Warehouse"), - 'description': item.description, - 'uom': item.stock_uom - } - ] - }).insert() - - rfq.save() - rfq.submit() - return rfq - -def send_opportunity(contact): - # Make Hub Message on Hub with lead data - doc = { - 'doctype': 'Lead', - 'lead_name': frappe.db.get_single_value('Hub Settings', 'company'), - 'email_id': frappe.db.get_single_value('Hub Settings', 'user') - } - - args = frappe._dict(dict( - doctype='Hub Message', - reference_doctype='Lead', - data=json.dumps(doc), - user=contact.email_id - )) - - connection = get_hub_connection() - response = connection.insert('Hub Message', args) - - return response.ok diff --git a/erpnext/hub_node/api.py b/erpnext/hub_node/api.py new file mode 100644 index 00000000000..559e22a2c8d --- /dev/null +++ b/erpnext/hub_node/api.py @@ -0,0 +1,100 @@ +from __future__ import unicode_literals +import frappe, requests, json +from frappe.utils import now +from frappe.frappeclient import FrappeClient + +@frappe.whitelist() +def call_hub_method(method, params=None): + connection = get_hub_connection() + + if type(params) == unicode: + params = json.loads(params) + + params.update({ + 'cmd': 'hub.hub.api.' + method + }) + + response = connection.post_request(params) + return response + +@frappe.whitelist() +def get_valid_items(search_value=''): + items = frappe.get_list( + 'Item', + fields=["*"], + filters={ + 'item_name': ['like', '%' + search_value + '%'], + 'publish_in_hub': 0 + }, + order_by="modified desc" + ) + + valid_items = filter(lambda x: x.image and x.description, items) + + def attach_source_type(item): + item.source_type = "local" + return item + + valid_items = map(lambda x: attach_source_type(x), valid_items) + return valid_items + +@frappe.whitelist() +def publish_selected_items(items_to_publish): + items_to_publish = json.loads(items_to_publish) + if not len(items_to_publish): + return + + for item_code in items_to_publish: + frappe.db.set_value('Item', item_code, 'publish_in_hub', 1) + + try: + hub_settings = frappe.get_doc('Hub Settings') + item_sync_preprocess() + hub_settings.sync() + except Exception as e: + frappe.db.set_value("Hub Settings", "Hub Settings", "sync_in_progress", 0) + frappe.throw(e) + +def item_sync_preprocess(): + hub_seller = frappe.db.get_value("Hub Settings", "Hub Settings", "company_email") + + response = call_hub_method('add_hub_seller_activity', { + 'hub_seller': hub_seller, + 'activity_details': json.dumps({ + 'subject': 'Publishing items', + 'status': 'Success' + }) + }) + + if response: + frappe.db.set_value("Hub Settings", "Hub Settings", "sync_in_progress", 1) + return response + else: + frappe.throw('Unable to update remote activity') + +def item_sync_postprocess(sync_details): + hub_seller = frappe.db.get_value("Hub Settings", "Hub Settings", "company_email") + + response = call_hub_method('add_hub_seller_activity', { + 'hub_seller': hub_seller, + 'activity_details': json.dumps({ + 'subject': 'Publishing items:' + sync_details['status'], + 'content': json.dumps(sync_details['stats']) + }) + }) + + if response: + frappe.db.set_value('Hub Settings', 'Hub Settings', 'sync_in_progress', 0) + frappe.db.set_value('Hub Settings', 'Hub Settings', 'last_sync_datetime', frappe.utils.now()) + else: + frappe.throw('Unable to update remote activity') + +def get_hub_connection(): + if frappe.db.exists('Data Migration Connector', 'Hub Connector'): + hub_connector = frappe.get_doc('Data Migration Connector', 'Hub Connector') + hub_connection = hub_connector.get_connection() + return hub_connection.connection + + # read-only connection + hub_connection = FrappeClient(frappe.conf.hub_url) + return hub_connection diff --git a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py index e69de29bb2d..9445e3a8dc5 100644 --- a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py +++ b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/__init__.py @@ -0,0 +1,19 @@ +import io, base64, urllib, os + +def pre_process(doc): + + file_path = doc.image + file_name = os.path.basename(file_path) + + if file_path.startswith('http'): + url = file_path + file_path = os.path.join('/tmp', file_name) + urllib.urlretrieve(url, file_path) + + with io.open(file_path, 'rb') as f: + doc.image = base64.b64encode(f.read()) + + doc.image_file_name = file_name + + return doc + diff --git a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json index 7423f2e8a63..3ace088a808 100644 --- a/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json +++ b/erpnext/hub_node/data_migration_mapping/item_to_hub_item/item_to_hub_item.json @@ -1,55 +1,45 @@ { - "condition": "{\"publish_in_hub\": 1}", - "creation": "2017-09-07 13:27:52.726350", - "docstatus": 0, - "doctype": "Data Migration Mapping", + "condition": "{\"publish_in_hub\": 1}", + "creation": "2017-09-07 13:27:52.726350", + "docstatus": 0, + "doctype": "Data Migration Mapping", "fields": [ { - "is_child_table": 0, - "local_fieldname": "item_code", + "is_child_table": 0, + "local_fieldname": "item_code", "remote_fieldname": "item_code" - }, + }, { - "is_child_table": 0, - "local_fieldname": "item_name", + "is_child_table": 0, + "local_fieldname": "item_name", "remote_fieldname": "item_name" - }, + }, { - "is_child_table": 0, - "local_fieldname": "eval:frappe.db.get_default(\"company\")", - "remote_fieldname": "company_name" - }, + "is_child_table": 0, + "local_fieldname": "eval:frappe.db.get_value('Hub Settings' , 'Hub Settings', 'company_email')", + "remote_fieldname": "hub_seller" + }, { - "is_child_table": 0, - "local_fieldname": "image", + "is_child_table": 0, + "local_fieldname": "image", "remote_fieldname": "image" - }, + }, { - "is_child_table": 0, - "local_fieldname": "item_group", + "is_child_table": 0, + "local_fieldname": "item_group", "remote_fieldname": "item_group" - }, - { - "is_child_table": 0, - "local_fieldname": "eval:frappe.session.user", - "remote_fieldname": "seller" - }, - { - "is_child_table": 0, - "local_fieldname": "eval:frappe.db.get_default(\"country\")", - "remote_fieldname": "country" } - ], - "idx": 1, - "local_doctype": "Item", - "mapping_name": "Item to Hub Item", - "mapping_type": "Push", - "migration_id_field": "hub_sync_id", - "modified": "2018-02-14 15:57:05.595712", - "modified_by": "achilles@erpnext.com", - "name": "Item to Hub Item", - "owner": "Administrator", - "page_length": 10, - "remote_objectname": "Hub Item", + ], + "idx": 1, + "local_doctype": "Item", + "mapping_name": "Item to Hub Item", + "mapping_type": "Push", + "migration_id_field": "hub_sync_id", + "modified": "2018-08-01 16:37:09.170546", + "modified_by": "Administrator", + "name": "Item to Hub Item", + "owner": "Administrator", + "page_length": 10, + "remote_objectname": "Hub Item", "remote_primary_key": "item_code" } \ No newline at end of file diff --git a/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json b/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json index d66ac24b1c2..1f772b68f0b 100644 --- a/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json +++ b/erpnext/hub_node/data_migration_plan/hub_sync/hub_sync.json @@ -1,22 +1,19 @@ { - "creation": "2017-09-07 11:39:38.445902", - "docstatus": 0, - "doctype": "Data Migration Plan", - "idx": 1, + "creation": "2017-09-07 11:39:38.445902", + "docstatus": 0, + "doctype": "Data Migration Plan", + "idx": 1, "mappings": [ { - "enabled": 1, + "enabled": 1, "mapping": "Item to Hub Item" - }, - { - "enabled": 1, - "mapping": "Hub Message to Lead" } - ], - "modified": "2018-02-14 15:57:05.519715", - "modified_by": "achilles@erpnext.com", - "module": "Hub Node", - "name": "Hub Sync", - "owner": "Administrator", - "plan_name": "Hub Sync" + ], + "modified": "2018-08-01 16:37:09.027512", + "modified_by": "Administrator", + "module": "Hub Node", + "name": "Hub Sync", + "owner": "Administrator", + "plan_name": "Hub Sync", + "postprocess_method": "erpnext.hub_node.api.item_sync_postprocess" } \ No newline at end of file diff --git a/erpnext/hub_node/doctype/hub_settings/hub_settings.js b/erpnext/hub_node/doctype/hub_settings/hub_settings.js index 29d870b371b..4bd33332766 100644 --- a/erpnext/hub_node/doctype/hub_settings/hub_settings.js +++ b/erpnext/hub_node/doctype/hub_settings/hub_settings.js @@ -1,53 +1,23 @@ frappe.ui.form.on("Hub Settings", { refresh: function(frm) { + frm.disable_save(); frm.add_custom_button(__('Logs'), () => frappe.set_route('List', 'Data Migration Run', { data_migration_plan: 'Hub Sync' })); - frm.trigger("enabled"); - if (frm.doc.enabled) { frm.add_custom_button(__('Sync'), () => frm.call('sync')); } }, - onload: function(frm) { - let token = frappe.urllib.get_arg("access_token"); - if(token) { - let email = frm.get_field("user"); - console.log('token', frappe.urllib.get_arg("access_token")); - - get_user_details(frm, token, email); - let row = frappe.model.add_child(frm.doc, "Hub Users", "users"); - row.user = frappe.session.user; - } - - if(!frm.doc.country) { - frm.set_value("country", frappe.defaults.get_default("Country")); - } - if(!frm.doc.company) { - frm.set_value("company", frappe.defaults.get_default("Company")); - } - if(!frm.doc.user) { - frm.set_value("user", frappe.session.user); - } - }, + onload: function(frm) { }, onload_post_render: function(frm) { if(frm.get_field("unregister_from_hub").$input) frm.get_field("unregister_from_hub").$input.addClass("btn-danger"); }, on_update: function(frm) { }, - enabled: function(frm) { - if(!frm.doc.enabled) { - frm.trigger("set_enable_hub_primary_button"); - } else { - frm.page.set_primary_action(__("Save Settings"), () => { - frm.save(); - }); - } - }, hub_user_email: function(frm) { if(frm.doc.hub_user_email){ @@ -55,39 +25,6 @@ frappe.ui.form.on("Hub Settings", { } }, - set_enable_hub_primary_button: (frm) => { - frm.page.set_primary_action(__("Enable Hub"), () => { - if(frappe.session.user === "Administrator") { - frappe.msgprint(__("Please login as another user.")) - } else { - // frappe.verify_password(() => { - - // } ); - - frm.trigger("call_pre_reg"); - // frm.trigger("call_register"); - - } - }); - }, - - call_pre_reg: (frm) => { - this.frm.call({ - doc: this.frm.doc, - method: "pre_reg", - args: {}, - freeze: true, - callback: function(r) { - console.log(r.message); - authorize(frm, r.message.client_id, r.message.redirect_uri); - }, - onerror: function() { - frappe.msgprint(__("Wrong Password")); - frm.set_value("enabled", 0); - } - }); - }, - call_register: (frm) => { this.frm.call({ doc: this.frm.doc, @@ -111,67 +48,3 @@ frappe.ui.form.on("Hub Settings", { }); }, }); - -// let hub_url = 'https://hubmarket.org' -let hub_url = 'http://159.89.175.122' -// let hub_url = 'http://erpnext.hub:8000' - -function authorize(frm, client_id, redirect_uri) { - - // queryStringData is details of OAuth Client (Implicit Grant) on Custom App - var queryStringData = { - response_type : "token", - client_id : client_id, - redirect_uri : redirect_uri - } - - // Get current raw route and build url - const route = "/desk#" + frappe.get_raw_route_str(); - localStorage.removeItem("route"); // Clear previously set route if any - localStorage.setItem("route", route); - - // Go authorize! - let api_route = "/api/method/frappe.integrations.oauth2.authorize?"; - let url = hub_url + api_route + $.param(queryStringData); - window.location.replace(url, 'test'); -} - -function get_user_details(frm, token, email) { - console.log('user_details'); - var route = localStorage.getItem("route"); - if (token && route) { - // Clean up access token from route - frappe.set_route(frappe.get_route().join("/")) - - // query protected resource e.g. Hub Items with token - var call = { - "async": true, - "crossDomain": true, - "url": hub_url + "/api/resource/User", - "method": "GET", - "data": { - // "email": email, - "fields": '["name", "first_name", "language"]', - "limit_page_length": 1 - }, - "headers": { - "authorization": "Bearer " + token, - "content-type": "application/x-www-form-urlencoded" - } - } - $.ajax(call).done(function (response) { - // display openid profile - console.log('response', response); - - let data = response.data[0]; - frm.set_value("enabled", 1); - frm.set_value("hub_username", data.first_name); - frm.set_value("hub_user_status", "Starter"); - frm.set_value("language", data.language); - frm.save(); - - // clear route from localStorage - localStorage.removeItem("route"); - }); - } -} diff --git a/erpnext/hub_node/doctype/hub_settings/hub_settings.json b/erpnext/hub_node/doctype/hub_settings/hub_settings.json index 7c7109c64c1..a0d8188d445 100644 --- a/erpnext/hub_node/doctype/hub_settings/hub_settings.json +++ b/erpnext/hub_node/doctype/hub_settings/hub_settings.json @@ -14,20 +14,21 @@ "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "enabled", + "fieldname": "registered", "fieldtype": "Check", - "hidden": 1, + "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Enabled", + "label": "Registered", "length": 0, "no_copy": 0, "permlevel": 0, @@ -45,212 +46,21 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "suspended", + "fieldname": "sync_in_progress", "fieldtype": "Check", - "hidden": 1, + "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Suspended", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "enabled", - "fieldname": "hub_username", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Hub Username", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "user", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "User", - "length": 0, - "no_copy": 0, - "options": "User", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_0", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "enabled", - "fieldname": "hub_user_status", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Status", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "enabled", - "fieldname": "language", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Language", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 1, - "collapsible_depends_on": "eval:(!doc.enabled)", - "columns": 0, - "depends_on": "", - "fieldname": "seller_profile_section", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Company and Seller Profile", + "label": "Sync in Progress", "length": 0, "no_copy": 0, "permlevel": 0, @@ -268,6 +78,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -299,6 +110,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -331,6 +143,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -362,6 +175,39 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "site_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Site Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -394,11 +240,44 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "company_logo", + "fieldname": "currency", + "fieldtype": "Currency", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Currency", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "logo", "fieldtype": "Attach Image", "hidden": 0, "ignore_user_permissions": 0, @@ -425,11 +304,12 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "seller_description", + "fieldname": "company_description", "fieldtype": "Text Editor", "hidden": 0, "ignore_user_permissions": 0, @@ -456,6 +336,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -487,43 +368,12 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "users", - "fieldtype": "Table", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Users", - "length": 0, - "no_copy": 0, - "options": "Hub Users", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "enabled", + "depends_on": "", "fieldname": "publish_section", "fieldtype": "Section Break", "hidden": 0, @@ -551,6 +401,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -582,6 +433,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -614,6 +466,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -647,6 +500,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -679,11 +533,12 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "publish", + "depends_on": "", "fieldname": "last_sync_datetime", "fieldtype": "Datetime", "hidden": 0, @@ -700,7 +555,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -711,6 +566,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -744,6 +600,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 1, @@ -777,6 +634,7 @@ }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -817,8 +675,8 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2018-03-26 00:55:17.929140", - "modified_by": "test1@example.com", + "modified": "2018-07-30 10:43:28.818498", + "modified_by": "Administrator", "module": "Hub Node", "name": "Hub Settings", "name_case": "", @@ -826,7 +684,6 @@ "permissions": [ { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 0, diff --git a/erpnext/hub_node/doctype/hub_settings/hub_settings.py b/erpnext/hub_node/doctype/hub_settings/hub_settings.py index 15ee4b7da35..bfb332022a1 100644 --- a/erpnext/hub_node/doctype/hub_settings/hub_settings.py +++ b/erpnext/hub_node/doctype/hub_settings/hub_settings.py @@ -2,7 +2,7 @@ # For license information, please see license.txt from __future__ import unicode_literals -import frappe, requests, json +import frappe, requests, json, time from frappe.model.document import Document from frappe.utils import add_years, now, get_datetime, get_datetime_str @@ -10,33 +10,18 @@ from frappe import _ from erpnext.utilities.product import get_price, get_qty_in_stock from six import string_types -hub_url = "https://hubmarket.org" -# hub_url = "http://159.89.175.122" -# hub_url = "http://erpnext.hub:8000" - -class OAuth2Session(): - def __init__(self, headers): - self.headers = headers - def get(self, url, params, headers, verify): - res = requests.get(url, params=params, headers=self.headers, verify=verify) - return res - def post(self, url, data, verify): - res = requests.post(url, data=data, headers=self.headers, verify=verify) - return res - def put(self, url, data, verify): - res = requests.put(url, data=data, headers=self.headers, verify=verify) - return res - class HubSetupError(frappe.ValidationError): pass class HubSettings(Document): def validate(self): + protocol = 'http://' + self.site_name = protocol + frappe.local.site + ':' + str(frappe.conf.webserver_port) if self.publish_pricing and not self.selling_price_list: frappe.throw(_("Please select a Price List to publish pricing")) def get_hub_url(self): - return hub_url + return frappe.conf.hub_url def sync(self): """Create and execute Data Migration Run for Hub Sync plan""" @@ -45,68 +30,53 @@ class HubSettings(Document): doc = frappe.get_doc({ 'doctype': 'Data Migration Run', 'data_migration_plan': 'Hub Sync', - 'data_migration_connector': 'Hub Connector' + 'data_migration_connector': 'Hub Connector', + 'trigger_name': 'items-sync' }).insert() + self.sync_in_progress = 1 doc.run() - def pre_reg(self): - site_name = frappe.local.site + ':' + str(frappe.conf.webserver_port) - protocol = 'http://' - route = '/token' - data = { - 'site_name': site_name, - 'protocol': protocol, - 'route': route - } - - redirect_url = protocol + site_name + route - post_url = hub_url + '/api/method/hub.hub.api.pre_reg' - - response = requests.post(post_url, data=data) - response.raise_for_status() - message = response.json().get('message') - - if message and message.get('client_id'): - print("======CLIENT_ID======") - print(message.get('client_id')) - - return { - 'client_id': message.get('client_id'), - 'redirect_uri': redirect_url - } - - def register(self): """ Create a User on hub.erpnext.org and return username/password """ + + # TODO: site_name for cloud sites + protocol = 'http://' + self.site_name = protocol + frappe.local.site + ':' + str(frappe.conf.webserver_port) + data = { - 'email': frappe.session.user + 'profile': self.as_json() } - post_url = hub_url + '/api/method/hub.hub.api.register' + post_url = self.get_hub_url() + '/api/method/hub.hub.api.register' + + response = requests.post(post_url, data=data, headers = {'accept': 'application/json'}) - response = requests.post(post_url, data=data) response.raise_for_status() - message = response.json().get('message') - if message and message.get('password'): - self.user = frappe.session.user + if response.ok: + message = response.json().get('message') + else: + frappe.throw(json.loads(response.text)) + + if message.get('email'): self.create_hub_connector(message) - self.company = frappe.defaults.get_user_default('company') - self.enabled = 1 + self.registered = 1 self.save() - def unregister(self): - """ Disable the User on hub.erpnext.org""" + return message or None - hub_connector = frappe.get_doc( - 'Data Migration Connector', 'Hub Connector') + # def unregister(self): + # """ Disable the User on hub.erpnext.org""" - connection = hub_connector.get_connection() - response_doc = connection.update('User', frappe._dict({'enabled': 0}), hub_connector.username) + # hub_connector = frappe.get_doc( + # 'Data Migration Connector', 'Hub Connector') - if response_doc['enabled'] == 0: - self.enabled = 0 - self.save() + # connection = hub_connector.get_connection() + # response_doc = connection.update('User', frappe._dict({'enabled': 0}), hub_connector.username) + + # if response_doc['enabled'] == 0: + # self.enabled = 0 + # self.save() def create_hub_connector(self, message): if frappe.db.exists('Data Migration Connector', 'Hub Connector'): @@ -120,7 +90,7 @@ class HubSettings(Document): 'doctype': 'Data Migration Connector', 'connector_type': 'Frappe', 'connector_name': 'Hub Connector', - 'hostname': hub_url, + 'hostname': self.get_hub_url(), 'username': message['email'], 'password': message['password'] }).insert() @@ -143,3 +113,11 @@ def reset_hub_settings(last_sync_datetime = ""): def sync(): hub_settings = frappe.get_doc('Hub Settings') hub_settings.sync() + +@frappe.whitelist() +def register_seller(**kwargs): + settings = frappe.get_doc('Hub Settings') + settings.update(kwargs) + message = settings.register() + + return message.get('email') diff --git a/erpnext/hub_node/legacy.py b/erpnext/hub_node/legacy.py new file mode 100644 index 00000000000..87d4e1b4adc --- /dev/null +++ b/erpnext/hub_node/legacy.py @@ -0,0 +1,178 @@ +from __future__ import unicode_literals +import frappe, requests, json +from frappe.utils import now, nowdate +from frappe.frappeclient import FrappeClient + +@frappe.whitelist() +def get_item_favourites(start=0, limit=20, fields=["*"], order_by=None): + doctype = 'Hub Item' + hub_settings = frappe.get_doc('Hub Settings') + item_names_str = hub_settings.get('custom_data') or '[]' + item_names = json.loads(item_names_str) + filters = json.dumps({ + 'hub_item_code': ['in', item_names] + }) + return get_list(doctype, start, limit, fields, filters, order_by) + +@frappe.whitelist() +def update_wishlist_item(item_name, remove=0): + remove = int(remove) + hub_settings = frappe.get_doc('Hub Settings') + data = hub_settings.get('custom_data') + if not data or not json.loads(data): + data = '[]' + hub_settings.custom_data = data + hub_settings.save() + + item_names_str = data + item_names = json.loads(item_names_str) + if not remove and item_name not in item_names: + item_names.append(item_name) + if remove and item_name in item_names: + item_names.remove(item_name) + + item_names_str = json.dumps(item_names) + + hub_settings.custom_data = item_names_str + hub_settings.save() + +@frappe.whitelist() +def update_category(hub_item_code, category): + connection = get_hub_connection() + + # args = frappe._dict(dict( + # doctype='Hub Category', + # hub_category_name=category + # )) + # response = connection.insert('Hub Category', args) + + response = connection.update('Hub Item', frappe._dict(dict( + doctype='Hub Item', + hub_category = category + )), hub_item_code) + + return response + +def make_opportunity(buyer_name, email_id): + buyer_name = "HUB-" + buyer_name + + if not frappe.db.exists('Lead', {'email_id': email_id}): + lead = frappe.new_doc("Lead") + lead.lead_name = buyer_name + lead.email_id = email_id + lead.save(ignore_permissions=True) + + o = frappe.new_doc("Opportunity") + o.enquiry_from = "Lead" + o.lead = frappe.get_all("Lead", filters={"email_id": email_id}, fields = ["name"])[0]["name"] + o.save(ignore_permissions=True) + +@frappe.whitelist() +def make_rfq_and_send_opportunity(item, supplier): + supplier = make_supplier(supplier) + contact = make_contact(supplier) + item = make_item(item) + rfq = make_rfq(item, supplier, contact) + status = send_opportunity(contact) + + return { + 'rfq': rfq, + 'hub_document_created': status + } + +def make_supplier(supplier): + # make supplier if not already exists + supplier = frappe._dict(json.loads(supplier)) + + if not frappe.db.exists('Supplier', {'supplier_name': supplier.supplier_name}): + supplier_doc = frappe.get_doc({ + 'doctype': 'Supplier', + 'supplier_name': supplier.supplier_name, + 'supplier_group': supplier.supplier_group, + 'supplier_email': supplier.supplier_email + }).insert() + else: + supplier_doc = frappe.get_doc('Supplier', supplier.supplier_name) + + return supplier_doc + +def make_contact(supplier): + contact_name = get_default_contact('Supplier', supplier.supplier_name) + # make contact if not already exists + if not contact_name: + contact = frappe.get_doc({ + 'doctype': 'Contact', + 'first_name': supplier.supplier_name, + 'email_id': supplier.supplier_email, + 'is_primary_contact': 1, + 'links': [ + {'link_doctype': 'Supplier', 'link_name': supplier.supplier_name} + ] + }).insert() + else: + contact = frappe.get_doc('Contact', contact_name) + + return contact + +def make_item(item): + # make item if not already exists + item = frappe._dict(json.loads(item)) + + if not frappe.db.exists('Item', {'item_code': item.item_code}): + item_doc = frappe.get_doc({ + 'doctype': 'Item', + 'item_code': item.item_code, + 'item_group': item.item_group, + 'is_item_from_hub': 1 + }).insert() + else: + item_doc = frappe.get_doc('Item', item.item_code) + + return item_doc + +def make_rfq(item, supplier, contact): + # make rfq + rfq = frappe.get_doc({ + 'doctype': 'Request for Quotation', + 'transaction_date': nowdate(), + 'status': 'Draft', + 'company': frappe.db.get_single_value('Hub Settings', 'company'), + 'message_for_supplier': 'Please supply the specified items at the best possible rates', + 'suppliers': [ + { 'supplier': supplier.name, 'contact': contact.name } + ], + 'items': [ + { + 'item_code': item.item_code, + 'qty': 1, + 'schedule_date': nowdate(), + 'warehouse': item.default_warehouse or get_root_of("Warehouse"), + 'description': item.description, + 'uom': item.stock_uom + } + ] + }).insert() + + rfq.save() + rfq.submit() + return rfq + +def send_opportunity(contact): + # Make Hub Message on Hub with lead data + doc = { + 'doctype': 'Lead', + 'lead_name': frappe.db.get_single_value('Hub Settings', 'company'), + 'email_id': frappe.db.get_single_value('Hub Settings', 'user') + } + + args = frappe._dict(dict( + doctype='Hub Message', + reference_doctype='Lead', + data=json.dumps(doc), + user=contact.email_id + )) + + connection = get_hub_connection() + response = connection.insert('Hub Message', args) + + return response.ok diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 20def27ced0..154f4407406 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -559,3 +559,5 @@ erpnext.patches.v11_0.update_allow_transfer_for_manufacture erpnext.patches.v11_0.rename_healthcare_doctype_and_fields erpnext.patches.v11_0.add_item_group_defaults erpnext.patches.v10_0.update_address_template_for_india +execute:frappe.delete_doc("Page", "hub") +erpnext.patches.v11_0.reset_publish_in_hub_for_all_items diff --git a/erpnext/patches/v11_0/reset_publish_in_hub_for_all_items.py b/erpnext/patches/v11_0/reset_publish_in_hub_for_all_items.py new file mode 100644 index 00000000000..fac772ccdd9 --- /dev/null +++ b/erpnext/patches/v11_0/reset_publish_in_hub_for_all_items.py @@ -0,0 +1,5 @@ +import frappe + +def execute(): + frappe.reload_doc('stock', 'doctype', 'item') + frappe.db.sql("""update `tabItem` set publish_in_hub = 0""") diff --git a/erpnext/public/build.json b/erpnext/public/build.json index ed4ebababee..7bcf99bd2f3 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -7,6 +7,9 @@ "public/js/website_utils.js", "public/js/shopping_cart.js" ], + "js/marketplace.min.js": [ + "public/js/hub/marketplace.js" + ], "js/erpnext.min.js": [ "public/js/conf.js", "public/js/utils.js", diff --git a/erpnext/public/js/hub/helpers.js b/erpnext/public/js/hub/helpers.js new file mode 100644 index 00000000000..22e35c3d89e --- /dev/null +++ b/erpnext/public/js/hub/helpers.js @@ -0,0 +1,143 @@ +function get_empty_state(message, action) { + return `
${message}
+ ${action ? `${action}
`: ''} +${ __("Please check your network connection.") }
- -- ${data.subject} -
- -- ${ratingHtml} -
- -- ${data.content} -
-${ __("Your payment is cancelled.") }
- -
- Products by Blah blah
- Over 2000 products listed. Register your company to start selling.
-