commit
76f2430152
@ -1,11 +1,61 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
import io, base64, os, requests
|
||||
|
||||
import frappe
|
||||
import json
|
||||
import io
|
||||
import base64
|
||||
import os
|
||||
import requests
|
||||
|
||||
from frappe import _
|
||||
from frappe.frappeclient import FrappeClient
|
||||
from frappe.desk.form.load import get_attachments
|
||||
from frappe.utils.file_manager import get_file_path
|
||||
from six import string_types
|
||||
|
||||
current_user = frappe.session.user
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def register_marketplace(company, company_description):
|
||||
validate_registerer()
|
||||
|
||||
settings = frappe.get_single('Marketplace Settings')
|
||||
message = settings.register_seller(company, company_description)
|
||||
|
||||
if message.get('hub_seller_name'):
|
||||
settings.registered = 1
|
||||
settings.hub_seller_name = message.get('hub_seller_name')
|
||||
settings.save()
|
||||
|
||||
settings.add_hub_user(frappe.session.user)
|
||||
|
||||
return { 'ok': 1 }
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def register_users(user_list):
|
||||
user_list = json.loads(user_list)
|
||||
|
||||
settings = frappe.get_single('Marketplace Settings')
|
||||
|
||||
for user in user_list:
|
||||
settings.add_hub_user(user)
|
||||
|
||||
return user_list
|
||||
|
||||
|
||||
def validate_registerer():
|
||||
if current_user == 'Administrator':
|
||||
frappe.throw(_('Please login as another user to register on Marketplace'))
|
||||
|
||||
valid_roles = ['System Manager', 'Item Manager']
|
||||
|
||||
if not frappe.utils.is_subset(valid_roles, frappe.get_roles()):
|
||||
frappe.throw(_('Only users with {0} role can register on Marketplace').format(', '.join(valid_roles)),
|
||||
frappe.PermissionError)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def call_hub_method(method, params=None):
|
||||
connection = get_hub_connection()
|
||||
@ -20,11 +70,12 @@ def call_hub_method(method, params=None):
|
||||
response = connection.post_request(params)
|
||||
return response
|
||||
|
||||
|
||||
def map_fields(items):
|
||||
field_mappings = get_field_mappings()
|
||||
table_fields = [d.fieldname for d in frappe.get_meta('Item').get_table_fields()]
|
||||
|
||||
hub_seller = frappe.db.get_value('Marketplace Settings' , 'Marketplace Settings', 'company_email')
|
||||
hub_seller_name = frappe.db.get_value('Marketplace Settings' , 'Marketplace Settings', 'hub_seller_name')
|
||||
|
||||
for item in items:
|
||||
for fieldname in table_fields:
|
||||
@ -39,11 +90,12 @@ def map_fields(items):
|
||||
item[remote_fieldname] = value
|
||||
|
||||
item['doctype'] = 'Hub Item'
|
||||
item['hub_seller'] = hub_seller
|
||||
item['hub_seller'] = hub_seller_name
|
||||
item.pop('attachments', None)
|
||||
|
||||
return items
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_valid_items(search_value=''):
|
||||
items = frappe.get_list(
|
||||
@ -68,6 +120,7 @@ def get_valid_items(search_value=''):
|
||||
|
||||
return valid_items
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def publish_selected_items(items_to_publish):
|
||||
items_to_publish = json.loads(items_to_publish)
|
||||
@ -85,12 +138,11 @@ def publish_selected_items(items_to_publish):
|
||||
'image_list': item.get('image_list')
|
||||
}).insert(ignore_if_duplicate=True)
|
||||
|
||||
|
||||
items = map_fields(items_to_publish)
|
||||
|
||||
try:
|
||||
item_sync_preprocess(len(items))
|
||||
load_base64_image_from_items(items)
|
||||
convert_relative_image_urls_to_absolute(items)
|
||||
|
||||
# TODO: Publish Progress
|
||||
connection = get_hub_connection()
|
||||
@ -100,6 +152,15 @@ def publish_selected_items(items_to_publish):
|
||||
except Exception as e:
|
||||
frappe.log_error(message=e, title='Hub Sync Error')
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_unregistered_users():
|
||||
settings = frappe.get_single('Marketplace Settings')
|
||||
registered_users = [user.user for user in settings.users] + ['Administrator', 'Guest']
|
||||
all_users = [user.name for user in frappe.db.get_all('User', filters={'enabled': 1})]
|
||||
unregistered_users = [user for user in all_users if user not in registered_users]
|
||||
return unregistered_users
|
||||
|
||||
|
||||
def item_sync_preprocess(intended_item_publish_count):
|
||||
response = call_hub_method('pre_items_publish', {
|
||||
'intended_item_publish_count': intended_item_publish_count
|
||||
@ -111,6 +172,7 @@ def item_sync_preprocess(intended_item_publish_count):
|
||||
else:
|
||||
frappe.throw('Unable to update remote activity')
|
||||
|
||||
|
||||
def item_sync_postprocess():
|
||||
response = call_hub_method('post_items_publish', {})
|
||||
if response:
|
||||
@ -121,50 +183,29 @@ def item_sync_postprocess():
|
||||
frappe.db.set_value('Marketplace Settings', 'Marketplace Settings', 'sync_in_progress', 0)
|
||||
|
||||
|
||||
def load_base64_image_from_items(items):
|
||||
def convert_relative_image_urls_to_absolute(items):
|
||||
from urlparse import urljoin
|
||||
|
||||
for item in items:
|
||||
file_path = item['image']
|
||||
file_name = os.path.basename(file_path)
|
||||
base64content = None
|
||||
|
||||
if file_path.startswith('http'):
|
||||
# fetch content and then base64 it
|
||||
url = file_path
|
||||
response = requests.get(url)
|
||||
base64content = base64.b64encode(response.content)
|
||||
else:
|
||||
# read file then base64 it
|
||||
file_path = os.path.abspath(get_file_path(file_path))
|
||||
with io.open(file_path, 'rb') as f:
|
||||
base64content = base64.b64encode(f.read())
|
||||
|
||||
image_data = json.dumps({
|
||||
'file_name': file_name,
|
||||
'base64': base64content
|
||||
})
|
||||
|
||||
item['image'] = image_data
|
||||
if file_path.startswith('/files/'):
|
||||
item['image'] = urljoin(frappe.utils.get_url(), file_path)
|
||||
|
||||
|
||||
def get_hub_connection():
|
||||
read_only = True
|
||||
settings = frappe.get_single('Marketplace Settings')
|
||||
marketplace_url = settings.marketplace_url
|
||||
hub_user = settings.get_hub_user(frappe.session.user)
|
||||
|
||||
if frappe.db.exists('Data Migration Connector', 'Hub Connector'):
|
||||
hub_connector = frappe.get_doc('Data Migration Connector', 'Hub Connector')
|
||||
|
||||
# full rights to user who registered as hub_seller
|
||||
if hub_connector.username == frappe.session.user:
|
||||
read_only = False
|
||||
|
||||
if not read_only:
|
||||
hub_connection = hub_connector.get_connection()
|
||||
return hub_connection.connection
|
||||
|
||||
# read-only connection
|
||||
if read_only:
|
||||
hub_url = frappe.db.get_single_value('Marketplace Settings', 'hub_url')
|
||||
hub_connection = FrappeClient(hub_url)
|
||||
if hub_user:
|
||||
password = hub_user.get_password()
|
||||
hub_connection = FrappeClient(marketplace_url, hub_user.user, password)
|
||||
return hub_connection
|
||||
else:
|
||||
read_only_hub_connection = FrappeClient(marketplace_url)
|
||||
return read_only_hub_connection
|
||||
|
||||
|
||||
def get_field_mappings():
|
||||
return []
|
||||
|
0
erpnext/hub_node/doctype/hub_user/__init__.py
Normal file
0
erpnext/hub_node/doctype/hub_user/__init__.py
Normal file
140
erpnext/hub_node/doctype/hub_user/hub_user.json
Normal file
140
erpnext/hub_node/doctype/hub_user/hub_user.json
Normal file
@ -0,0 +1,140 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2018-08-31 12:36:45.627531",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 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": 1,
|
||||
"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": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "hub_user_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Hub User",
|
||||
"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,
|
||||
"columns": 0,
|
||||
"fieldname": "password",
|
||||
"fieldtype": "Password",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Hub Password",
|
||||
"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
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-09-01 13:56:07.816894",
|
||||
"modified_by": "netchamp@rawcoderz.com",
|
||||
"module": "Hub Node",
|
||||
"name": "Hub User",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
10
erpnext/hub_node/doctype/hub_user/hub_user.py
Normal file
10
erpnext/hub_node/doctype/hub_user/hub_user.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class HubUser(Document):
|
||||
pass
|
@ -95,7 +95,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Marketplace URL",
|
||||
"label": "Marketplace URL (to hide and update label)",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -215,16 +215,16 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company_email",
|
||||
"fieldname": "hub_seller_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"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 Email",
|
||||
"label": "Hub Seller Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -247,8 +247,8 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "site_name",
|
||||
"fieldtype": "Data",
|
||||
"fieldname": "users",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@ -256,138 +256,10 @@
|
||||
"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,
|
||||
"columns": 0,
|
||||
"fieldname": "country",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Country",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Country",
|
||||
"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": "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,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Company Logo",
|
||||
"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": "company_description",
|
||||
"fieldtype": "Text Editor",
|
||||
"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": "Description",
|
||||
"label": "Users",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Hub User",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -479,8 +351,8 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-08-31 17:30:37.305704",
|
||||
"modified_by": "netchamp@rawcoderz.com",
|
||||
"modified": "2018-09-01 17:05:59.600583",
|
||||
"modified_by": "cave@aperture.com",
|
||||
"module": "Hub Node",
|
||||
"name": "Marketplace Settings",
|
||||
"name_case": "",
|
||||
|
@ -7,98 +7,80 @@ import frappe, requests, json, time
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import add_years, now, get_datetime, get_datetime_str
|
||||
from frappe import _
|
||||
from frappe.frappeclient import FrappeClient
|
||||
from erpnext.utilities.product import get_price, get_qty_in_stock
|
||||
from six import string_types
|
||||
|
||||
class MarketplaceSettings(Document):
|
||||
|
||||
def validate(self):
|
||||
self.site_name = frappe.utils.get_url()
|
||||
def register_seller(self, company, company_description):
|
||||
|
||||
def get_marketplace_url(self):
|
||||
return self.marketplace_url
|
||||
country, currency, company_logo = frappe.db.get_value('Company', company,
|
||||
['country', 'default_currency', 'company_logo'])
|
||||
|
||||
def register(self):
|
||||
""" Create a User on hub.erpnext.org and return username/password """
|
||||
|
||||
if frappe.session.user == 'Administrator':
|
||||
frappe.throw(_('Please login as another user to register on Marketplace'))
|
||||
|
||||
if 'System Manager' not in frappe.get_roles():
|
||||
frappe.throw(_('Only users with System Manager role can register on Marketplace'), frappe.PermissionError)
|
||||
|
||||
self.site_name = frappe.utils.get_url()
|
||||
|
||||
data = {
|
||||
'profile': self.as_json()
|
||||
company_details = {
|
||||
'company': company,
|
||||
'country': country,
|
||||
'currency': currency,
|
||||
'company_description': company_description,
|
||||
'company_logo': company_logo,
|
||||
'site_name': frappe.utils.get_url()
|
||||
}
|
||||
post_url = self.get_marketplace_url() + '/api/method/hub.hub.api.register'
|
||||
|
||||
response = requests.post(post_url, data=data, headers = {'accept': 'application/json'})
|
||||
hub_connection = self.get_connection()
|
||||
|
||||
response.raise_for_status()
|
||||
response = hub_connection.post_request({
|
||||
'cmd': 'hub.hub.api.add_hub_seller',
|
||||
'company_details': json.dumps(company_details)
|
||||
})
|
||||
|
||||
if response.ok:
|
||||
message = response.json().get('message')
|
||||
else:
|
||||
frappe.throw(json.loads(response.text))
|
||||
return response
|
||||
|
||||
if message.get('email'):
|
||||
self.create_hub_connector(message)
|
||||
self.registered = 1
|
||||
self.save()
|
||||
|
||||
return message or None
|
||||
def add_hub_user(self, user_email):
|
||||
'''Create a Hub User and User record on hub server
|
||||
and if successfull append it to Hub User table
|
||||
'''
|
||||
|
||||
# def unregister(self):
|
||||
# """ Disable the User on hub.erpnext.org"""
|
||||
|
||||
# hub_connector = frappe.get_doc(
|
||||
# 'Data Migration Connector', 'Hub Connector')
|
||||
|
||||
# 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'):
|
||||
hub_connector = frappe.get_doc('Data Migration Connector', 'Hub Connector')
|
||||
hub_connector.hostname = self.get_marketplace_url()
|
||||
hub_connector.username = message['email']
|
||||
hub_connector.password = message['password']
|
||||
hub_connector.save()
|
||||
if not self.registered:
|
||||
return
|
||||
|
||||
frappe.get_doc({
|
||||
'doctype': 'Data Migration Connector',
|
||||
'connector_type': 'Frappe',
|
||||
'connector_name': 'Hub Connector',
|
||||
'hostname': self.get_marketplace_url(),
|
||||
'username': message['email'],
|
||||
'password': message['password']
|
||||
}).insert()
|
||||
hub_connection = self.get_connection()
|
||||
|
||||
def reset_hub_publishing_settings(last_sync_datetime = ""):
|
||||
doc = frappe.get_doc("Marketplace Settings", "Marketplace Settings")
|
||||
doc.reset_publishing_settings(last_sync_datetime)
|
||||
doc.in_callback = 1
|
||||
doc.save()
|
||||
first_name, last_name = frappe.db.get_value('User', user_email, ['first_name', 'last_name'])
|
||||
|
||||
def reset_hub_settings(last_sync_datetime = ""):
|
||||
doc = frappe.get_doc("Marketplace Settings", "Marketplace Settings")
|
||||
doc.reset_publishing_settings(last_sync_datetime)
|
||||
doc.reset_enable()
|
||||
doc.in_callback = 1
|
||||
doc.save()
|
||||
frappe.msgprint(_("Successfully unregistered."))
|
||||
hub_user = hub_connection.post_request({
|
||||
'cmd': 'hub.hub.api.add_hub_user',
|
||||
'user_email': user_email,
|
||||
'first_name': first_name,
|
||||
'last_name': last_name,
|
||||
'hub_seller': self.hub_seller_name
|
||||
})
|
||||
|
||||
@frappe.whitelist()
|
||||
def register_seller(**kwargs):
|
||||
settings = frappe.get_doc('Marketplace Settings')
|
||||
settings.update(kwargs)
|
||||
message = settings.register()
|
||||
self.append('users', {
|
||||
'user': hub_user.get('user_email'),
|
||||
'hub_user_name': hub_user.get('hub_user_name'),
|
||||
'password': hub_user.get('password')
|
||||
})
|
||||
|
||||
return message.get('email')
|
||||
self.save()
|
||||
|
||||
def get_hub_user(self, user):
|
||||
'''Return the Hub User doc from the `users` table if password is set'''
|
||||
|
||||
filtered_users = filter(
|
||||
lambda x: x.user == user and x.password,
|
||||
self.users
|
||||
)
|
||||
|
||||
if filtered_users:
|
||||
return filtered_users[0]
|
||||
|
||||
|
||||
def get_connection(self):
|
||||
return FrappeClient(self.marketplace_url)
|
||||
|
||||
|
||||
def unregister(self):
|
||||
"""Disable the User on hubmarket.org"""
|
||||
pass
|
||||
|
@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Marketplace Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Marketplace Settings
|
||||
() => frappe.tests.make('Marketplace Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
class TestMarketplaceSettings(unittest.TestCase):
|
||||
pass
|
@ -560,6 +560,6 @@ erpnext.patches.v10_0.update_address_template_for_india
|
||||
erpnext.patches.v11_0.add_expense_claim_default_account
|
||||
execute:frappe.delete_doc("Page", "hub")
|
||||
erpnext.patches.v11_0.reset_publish_in_hub_for_all_items
|
||||
erpnext.patches.v11_0.update_hub_url # 2018-08-31
|
||||
erpnext.patches.v11_0.update_hub_url # 2018-08-31 # 2018-09-03
|
||||
erpnext.patches.v10_0.set_discount_amount
|
||||
erpnext.patches.v10_0.recalculate_gross_margin_for_project
|
||||
|
@ -2,4 +2,4 @@ import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('hub_node', 'doctype', 'Marketplace Settings')
|
||||
frappe.db.set_value('Marketplace Settings', 'Marketplace Settings', 'hub_url', 'https://hubmarket.org')
|
||||
frappe.db.set_value('Marketplace Settings', 'Marketplace Settings', 'marketplace_url', 'https://hubmarket.org')
|
||||
|
@ -20,23 +20,29 @@ import Messages from './pages/Messages.vue';
|
||||
import Profile from './pages/Profile.vue';
|
||||
import NotFound from './pages/NotFound.vue';
|
||||
|
||||
const route_map = {
|
||||
'marketplace/home': Home,
|
||||
'marketplace/search/:keyword': Search,
|
||||
'marketplace/category/:category': Category,
|
||||
'marketplace/item/:item': Item,
|
||||
'marketplace/seller/:seller': Seller,
|
||||
'marketplace/not-found': NotFound,
|
||||
function get_route_map() {
|
||||
const read_only_routes = {
|
||||
'marketplace/home': Home,
|
||||
'marketplace/search/:keyword': Search,
|
||||
'marketplace/category/:category': Category,
|
||||
'marketplace/item/:item': Item,
|
||||
'marketplace/seller/:seller': Seller,
|
||||
'marketplace/not-found': NotFound,
|
||||
}
|
||||
const registered_routes = {
|
||||
'marketplace/profile': Profile,
|
||||
'marketplace/saved-items': SavedItems,
|
||||
'marketplace/publish': Publish,
|
||||
'marketplace/published-items': PublishedItems,
|
||||
'marketplace/buying': Buying,
|
||||
'marketplace/buying/:item': Messages,
|
||||
'marketplace/selling': Selling,
|
||||
'marketplace/selling/:buyer/:item': Messages
|
||||
}
|
||||
|
||||
// Registered seller routes
|
||||
'marketplace/profile': Profile,
|
||||
'marketplace/saved-items': SavedItems,
|
||||
'marketplace/publish': Publish,
|
||||
'marketplace/published-items': PublishedItems,
|
||||
'marketplace/buying': Buying,
|
||||
'marketplace/buying/:item': Messages,
|
||||
'marketplace/selling': Selling,
|
||||
'marketplace/selling/:buyer/:item': Messages
|
||||
return hub.is_seller_registered()
|
||||
? Object.assign({}, read_only_routes, registered_routes)
|
||||
: read_only_routes;
|
||||
}
|
||||
|
||||
export default {
|
||||
@ -56,6 +62,7 @@ export default {
|
||||
this.current_page = this.get_current_page();
|
||||
},
|
||||
get_current_page() {
|
||||
const route_map = get_route_map();
|
||||
const curr_route = frappe.get_route_str();
|
||||
let route = Object.keys(route_map).filter(route => route == curr_route)[0];
|
||||
if (!route) {
|
||||
|
@ -19,7 +19,7 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
hub_registered: hub.settings.registered && frappe.session.user === hub.settings.company_email,
|
||||
hub_registered: hub.is_user_registered(),
|
||||
items: [
|
||||
{
|
||||
label: __('Browse'),
|
||||
|
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="menu_items" class="col-md-1">
|
||||
<div v-if="menu_items && menu_items.length" class="col-md-1">
|
||||
<div class="dropdown pull-right hub-item-dropdown">
|
||||
<a class="dropdown-toggle btn btn-xs btn-default" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
|
@ -56,8 +56,6 @@ export default {
|
||||
},
|
||||
|
||||
on_submit_review(values) {
|
||||
values.user = hub.settings.company_email;
|
||||
|
||||
this.review_area.reset();
|
||||
|
||||
hub.call('add_item_review', {
|
||||
|
@ -1,138 +0,0 @@
|
||||
import { get_rating_html } from './reviews';
|
||||
|
||||
function get_detail_view_html(item, allow_edit) {
|
||||
const title = item.item_name || item.name;
|
||||
const seller = item.company;
|
||||
|
||||
const who = __('Posted By {0}', [seller]);
|
||||
const when = comment_when(item.creation);
|
||||
|
||||
const city = item.city ? item.city + ', ' : '';
|
||||
const country = item.country ? item.country : '';
|
||||
const where = `${city}${country}`;
|
||||
|
||||
const dot_spacer = '<span aria-hidden="true"> · </span>';
|
||||
|
||||
const description = item.description || '';
|
||||
|
||||
let stats = __('No views yet');
|
||||
if(item.view_count) {
|
||||
const views_message = __(`${item.view_count} Views`);
|
||||
|
||||
const rating_html = get_rating_html(item.average_rating);
|
||||
const rating_count = item.no_of_ratings > 0 ? `${item.no_of_ratings} reviews` : __('No reviews yet');
|
||||
|
||||
stats = `${views_message}${dot_spacer}${rating_html} (${rating_count})`;
|
||||
}
|
||||
|
||||
let favourite_button = ''
|
||||
if (hub.settings.registered) {
|
||||
favourite_button = !item.favourited
|
||||
? `<button class="btn btn-default text-muted favourite-button" data-action="add_to_favourites">
|
||||
${__('Save')} <i class="octicon octicon-heart text-extra-muted"></i>
|
||||
</button>`
|
||||
: `<button class="btn btn-default text-muted favourite-button disabled" data-action="add_to_favourites">
|
||||
${__('Saved')}
|
||||
</button>`;
|
||||
}
|
||||
|
||||
const contact_seller_button = item.hub_seller !== hub.settings.company_email
|
||||
? `<button class="btn btn-primary" data-action="contact_seller">
|
||||
${__('Contact Seller')}
|
||||
</button>`
|
||||
: '';
|
||||
|
||||
let menu_items = '';
|
||||
|
||||
if(allow_edit) {
|
||||
menu_items = `
|
||||
<li><a data-action="edit_details">${__('Edit Details')}</a></li>
|
||||
<li><a data-action="unpublish_item">${__('Unpublish')}</a></li>`;
|
||||
} else {
|
||||
menu_items = `
|
||||
<li><a data-action="report_item">${__('Report this item')}</a></li>
|
||||
`;
|
||||
}
|
||||
|
||||
const html = `
|
||||
<div class="hub-item-container">
|
||||
<div class="row visible-xs">
|
||||
<div class="col-xs-12 margin-bottom">
|
||||
<button class="btn btn-xs btn-default" data-route="marketplace/home">${__('Back to home')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row detail-page-section margin-bottom">
|
||||
<div class="col-md-3">
|
||||
<div class="hub-item-image">
|
||||
<img src="${item.image}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8 flex flex-column">
|
||||
<div class="detail-page-header">
|
||||
<h2>${title}</h2>
|
||||
<div class="text-muted">
|
||||
<p>${where}${dot_spacer}${when}</p>
|
||||
<p>${stats}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-actions detail-page-actions">
|
||||
${favourite_button}
|
||||
${contact_seller_button}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<div class="dropdown pull-right hub-item-dropdown">
|
||||
<a class="dropdown-toggle btn btn-xs btn-default" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-right" role="menu">
|
||||
${menu_items}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row hub-item-description">
|
||||
<h6 class="col-md-12 margin-top">
|
||||
<b class="text-muted">Item Description</b>
|
||||
</h6>
|
||||
<p class="col-md-12">
|
||||
${description ? description : __('No details')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="row hub-item-seller">
|
||||
|
||||
<h6 class="col-md-12 margin-top margin-bottom">
|
||||
<b class="text-muted">Seller Information</b>
|
||||
</h6>
|
||||
<div class="col-md-1">
|
||||
<img src="https://picsum.photos/200">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="margin-bottom"><a href="#marketplace/seller/${seller}" class="bold">${seller}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- review area -->
|
||||
<div class="row hub-item-review-container">
|
||||
<div class="col-md-12 form-footer">
|
||||
<div class="form-comments">
|
||||
<div class="timeline">
|
||||
<div class="timeline-head"></div>
|
||||
<div class="timeline-items"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-right scroll-to-top">
|
||||
<a onclick="frappe.utils.scroll_to(0)"><i class="fa fa-chevron-up text-muted"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
export {
|
||||
get_detail_view_html,
|
||||
get_profile_html
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
function get_buying_item_message_card_html(item) {
|
||||
const item_name = item.item_name || item.name;
|
||||
const title = strip_html(item_name);
|
||||
|
||||
const message = item.recent_message
|
||||
const sender = message.sender === frappe.session.user ? 'You' : message.sender
|
||||
const content = strip_html(message.content)
|
||||
|
||||
// route
|
||||
item.route = `marketplace/buying/${item.name}`
|
||||
|
||||
const item_html = `
|
||||
<div class="col-md-7">
|
||||
<div class="hub-list-item" data-route="${item.route}">
|
||||
<div class="hub-list-left">
|
||||
<img class="hub-list-image" src="${item.image}">
|
||||
<div class="hub-list-body ellipsis">
|
||||
<div class="hub-list-title">${item_name}</div>
|
||||
<div class="hub-list-subtitle ellipsis">
|
||||
<span>${sender}: </span>
|
||||
<span>${content}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hub-list-right">
|
||||
<span class="text-muted">${comment_when(message.creation, true)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
return item_html;
|
||||
}
|
||||
|
||||
function get_selling_item_message_card_html(item) {
|
||||
const item_name = item.item_name || item.name;
|
||||
const title = strip_html(item_name);
|
||||
|
||||
// route
|
||||
if (!item.route) {
|
||||
item.route = `marketplace/item/${item.name}`
|
||||
}
|
||||
|
||||
let received_messages = '';
|
||||
item.received_messages.forEach(message => {
|
||||
const sender = message.sender === frappe.session.user ? 'You' : message.sender
|
||||
const content = strip_html(message.content)
|
||||
|
||||
received_messages += `
|
||||
<div class="received-message">
|
||||
<span class="text-muted">${comment_when(message.creation, true)}</span>
|
||||
<div class="ellipsis">
|
||||
<span class="bold">${sender}: </span>
|
||||
<span>${content}</span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
|
||||
const item_html = `
|
||||
<div class="selling-item-message-card">
|
||||
<div class="selling-item-detail" data-route="${item.route}">
|
||||
<img class="item-image" src="${item.image}">
|
||||
<h5 class="item-name">${item_name}</h5>
|
||||
<div class="received-message-container">
|
||||
${received_messages}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
return item_html;
|
||||
}
|
||||
|
||||
export {
|
||||
get_item_card_html,
|
||||
get_local_item_card_html,
|
||||
get_buying_item_message_card_html,
|
||||
get_selling_item_message_card_html
|
||||
}
|
@ -4,40 +4,17 @@ const ProfileDialog = (title = __('Edit Profile'), action={}) => {
|
||||
fieldtype: 'Link',
|
||||
fieldname: 'company',
|
||||
label: __('Company'),
|
||||
options: 'Company',
|
||||
onchange: () => {
|
||||
const value = dialog.get_value('company');
|
||||
|
||||
if (value) {
|
||||
frappe.db.get_doc('Company', value)
|
||||
.then(company => {
|
||||
dialog.set_values({
|
||||
country: company.country,
|
||||
currency: company.default_currency
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
options: 'Company'
|
||||
},
|
||||
{
|
||||
fieldname: 'company_email',
|
||||
label: __('Email'),
|
||||
fieldtype: 'Read Only'
|
||||
fieldtype: 'Read Only',
|
||||
fieldname: 'email',
|
||||
label: __('Email')
|
||||
},
|
||||
{
|
||||
fieldname: 'country',
|
||||
label: __('Country'),
|
||||
fieldtype: 'Read Only'
|
||||
},
|
||||
{
|
||||
fieldname: 'currency',
|
||||
label: __('Currency'),
|
||||
fieldtype: 'Read Only'
|
||||
},
|
||||
{
|
||||
fieldtype: 'Text',
|
||||
label: __('About your Company'),
|
||||
fieldname: 'company_description'
|
||||
label: __('About your company'),
|
||||
fieldname: 'company_description',
|
||||
fieldtype: 'Text'
|
||||
}
|
||||
];
|
||||
|
||||
@ -48,7 +25,11 @@ const ProfileDialog = (title = __('Edit Profile'), action={}) => {
|
||||
primary_action: () => {
|
||||
const form_values = dialog.get_values();
|
||||
let values_filled = true;
|
||||
const mandatory_fields = ['company', 'company_email', 'company_description'];
|
||||
|
||||
// TODO: Say "we notice that the company description and logo isn't set. Please set them in master."
|
||||
// Only then allow to register
|
||||
|
||||
const mandatory_fields = ['company', 'company_description'];
|
||||
mandatory_fields.forEach(field => {
|
||||
const value = form_values[field];
|
||||
if (!value) {
|
||||
@ -65,7 +46,7 @@ const ProfileDialog = (title = __('Edit Profile'), action={}) => {
|
||||
// Post create
|
||||
const default_company = frappe.defaults.get_default('company');
|
||||
dialog.set_value('company', default_company);
|
||||
dialog.set_value('company_email', frappe.session.user);
|
||||
dialog.set_value('email', frappe.session.user);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
@ -20,17 +20,18 @@ erpnext.hub.Marketplace = class Marketplace {
|
||||
this.$parent = $(parent);
|
||||
this.page = parent.page;
|
||||
|
||||
frappe.model.with_doc('Marketplace Settings').then(doc => {
|
||||
hub.settings = doc;
|
||||
const is_registered = hub.settings.registered;
|
||||
const is_registered_seller = hub.settings.company_email === frappe.session.user;
|
||||
this.update_hub_settings().then(() => {
|
||||
|
||||
this.setup_header();
|
||||
this.make_sidebar();
|
||||
this.make_body();
|
||||
this.setup_events();
|
||||
this.refresh();
|
||||
if (!is_registered && !is_registered_seller && frappe.user_roles.includes('System Manager')) {
|
||||
|
||||
if (!hub.is_seller_registered()) {
|
||||
this.page.set_primary_action('Become a Seller', this.show_register_dialog.bind(this))
|
||||
} else {
|
||||
this.page.set_secondary_action('Add Users', this.show_add_user_dialog.bind(this));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -76,10 +77,7 @@ erpnext.hub.Marketplace = class Marketplace {
|
||||
});
|
||||
|
||||
erpnext.hub.on('seller-registered', () => {
|
||||
this.page.clear_primary_action()
|
||||
frappe.model.with_doc('Marketplace Settings').then((doc)=> {
|
||||
hub.settings = doc;
|
||||
});
|
||||
this.page.clear_primary_action();
|
||||
});
|
||||
}
|
||||
|
||||
@ -88,27 +86,125 @@ erpnext.hub.Marketplace = class Marketplace {
|
||||
}
|
||||
|
||||
show_register_dialog() {
|
||||
if(frappe.session.user === 'Administrator') {
|
||||
frappe.msgprint(__('You need to be a user other than Administrator with System Manager and Item Manager roles to register on Marketplace.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_subset(['System Manager', 'Item Manager'], frappe.user_roles)) {
|
||||
frappe.msgprint(__('You need to be a user with System Manager and Item Manager roles to register on Marketplace.'));
|
||||
return;
|
||||
}
|
||||
|
||||
this.register_dialog = ProfileDialog(
|
||||
__('Become a Seller'),
|
||||
{
|
||||
label: __('Register'),
|
||||
on_submit: this.register_seller.bind(this)
|
||||
on_submit: this.register_marketplace.bind(this)
|
||||
}
|
||||
);
|
||||
|
||||
this.register_dialog.show();
|
||||
}
|
||||
|
||||
register_seller(form_values) {
|
||||
register_marketplace({company, company_description}) {
|
||||
frappe.call({
|
||||
method: 'erpnext.hub_node.doctype.marketplace_settings.marketplace_settings.register_seller',
|
||||
args: form_values
|
||||
}).then(() => {
|
||||
this.register_dialog.hide();
|
||||
frappe.set_route('marketplace', 'publish');
|
||||
method: 'erpnext.hub_node.api.register_marketplace',
|
||||
args: {
|
||||
company,
|
||||
company_description
|
||||
}
|
||||
}).then((r) => {
|
||||
if (r.message && r.message.ok) {
|
||||
this.register_dialog.hide();
|
||||
|
||||
erpnext.hub.trigger('seller-registered');
|
||||
this.update_hub_settings()
|
||||
.then(() => {
|
||||
frappe.set_route('marketplace', 'publish');
|
||||
erpnext.hub.trigger('seller-registered');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
show_add_user_dialog() {
|
||||
if (!is_subset(['System Manager', 'Item Manager'], frappe.user_roles)) {
|
||||
frappe.msgprint(__('You need to be a user with System Manager and Item Manager roles to add users to Marketplace.'));
|
||||
return;
|
||||
}
|
||||
|
||||
this.get_unregistered_users()
|
||||
.then(r => {
|
||||
const user_list = r.message;
|
||||
|
||||
const d = new frappe.ui.Dialog({
|
||||
title: __('Add Users to Marketplace'),
|
||||
fields: [
|
||||
{
|
||||
label: __('Users'),
|
||||
fieldname: 'users',
|
||||
fieldtype: 'MultiSelect',
|
||||
reqd: 1,
|
||||
get_data() {
|
||||
return user_list;
|
||||
}
|
||||
}
|
||||
],
|
||||
primary_action({ users }) {
|
||||
const selected_users = users.split(',').map(d => d.trim()).filter(Boolean);
|
||||
|
||||
if (!selected_users.every(user => user_list.includes(user))) {
|
||||
d.set_df_property('users', 'description', __('Some emails are invalid'));
|
||||
return;
|
||||
} else {
|
||||
d.set_df_property('users', 'description', '');
|
||||
}
|
||||
|
||||
frappe.call('erpnext.hub_node.api.register_users', {
|
||||
user_list: selected_users
|
||||
})
|
||||
.then(r => {
|
||||
d.hide();
|
||||
|
||||
if (r.message && r.message.length) {
|
||||
frappe.show_alert(__('Added {0} users', [r.message.length]));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
d.show();
|
||||
});
|
||||
}
|
||||
|
||||
get_unregistered_users() {
|
||||
return frappe.call('erpnext.hub_node.api.get_unregistered_users')
|
||||
}
|
||||
|
||||
update_hub_settings() {
|
||||
return frappe.db.get_doc('Marketplace Settings').then(doc => {
|
||||
hub.settings = doc;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(hub, {
|
||||
is_seller_registered() {
|
||||
return hub.settings.registered;
|
||||
},
|
||||
|
||||
is_user_registered() {
|
||||
return this.is_seller_registered() && hub.settings.users
|
||||
.filter(hub_user => hub_user.user === frappe.session.user)
|
||||
.length === 1;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns true if list_a is subset of list_b
|
||||
* @param {Array} list_a
|
||||
* @param {Array} list_b
|
||||
*/
|
||||
function is_subset(list_a, list_b) {
|
||||
return list_a.every(item => list_b.includes(item));
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
v-route="'marketplace/buying/' + item.name"
|
||||
>
|
||||
<div slot="subtitle">
|
||||
<span>{{item.recent_message.sender}}: </span>
|
||||
<span>{{item.recent_message.content | striphtml}}</span>
|
||||
<span>{{ get_sender(item.recent_message) }}: </span>
|
||||
<span>{{ item.recent_message.message | striphtml }}</span>
|
||||
</div>
|
||||
</item-list-card>
|
||||
</div>
|
||||
@ -47,6 +47,9 @@ export default {
|
||||
methods: {
|
||||
get_items_for_messages() {
|
||||
return hub.call('get_buying_items_for_messages', {}, 'action:send_message');
|
||||
},
|
||||
get_sender(message) {
|
||||
return message.sender === frappe.session.user ? __('You') : (message.sender_name || message.sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
:value="item_views_and_ratings"
|
||||
></detail-header-item>
|
||||
|
||||
<button slot="detail-header-item"
|
||||
<button v-if="primary_action" slot="detail-header-item"
|
||||
class="btn btn-primary btn-sm margin-top"
|
||||
@click="primary_action.action"
|
||||
>
|
||||
@ -56,7 +56,7 @@ export default {
|
||||
menu_items: [
|
||||
{
|
||||
label: __('Save Item'),
|
||||
condition: !this.is_own_item,
|
||||
condition: hub.is_user_registered() && !this.is_own_item,
|
||||
action: this.add_to_saved_items
|
||||
},
|
||||
{
|
||||
@ -66,12 +66,12 @@ export default {
|
||||
},
|
||||
{
|
||||
label: __('Edit Details'),
|
||||
condition: this.is_own_item,
|
||||
condition: hub.is_user_registered() && this.is_own_item,
|
||||
action: this.edit_details
|
||||
},
|
||||
{
|
||||
label: __('Unpublish Item'),
|
||||
condition: this.is_own_item,
|
||||
condition: hub.is_user_registered() && this.is_own_item,
|
||||
action: this.unpublish_item
|
||||
}
|
||||
]
|
||||
@ -81,7 +81,7 @@ export default {
|
||||
is_own_item() {
|
||||
let is_own_item = false;
|
||||
if(this.item) {
|
||||
if(this.item.hub_seller === hub.setting.company_email) {
|
||||
if(this.item.hub_seller === hub.settings.hub_seller_name) {
|
||||
is_own_item = true;
|
||||
}
|
||||
}
|
||||
@ -125,9 +125,13 @@ export default {
|
||||
},
|
||||
|
||||
primary_action() {
|
||||
return {
|
||||
label: __('Contact Seller'),
|
||||
action: this.contact_seller.bind(this)
|
||||
if (hub.is_user_registered()) {
|
||||
return {
|
||||
label: __('Contact Seller'),
|
||||
action: this.contact_seller.bind(this)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -190,9 +194,9 @@ export default {
|
||||
},
|
||||
|
||||
add_to_saved_items() {
|
||||
hub.call('add_item_to_seller_saved_items', {
|
||||
hub.call('add_item_to_user_saved_items', {
|
||||
hub_item_name: this.hub_item_name,
|
||||
hub_seller: hub.settings.company_email
|
||||
hub_user: frappe.session.user
|
||||
})
|
||||
.then(() => {
|
||||
const saved_items_link = `<b><a href="#marketplace/saved-items">${__('Saved')}</a></b>`
|
||||
@ -224,13 +228,11 @@ export default {
|
||||
if (!message) return;
|
||||
|
||||
hub.call('send_message', {
|
||||
from_seller: hub.settings.company_email,
|
||||
to_seller: this.item.hub_seller,
|
||||
hub_item: this.item.name,
|
||||
message
|
||||
})
|
||||
.then(() => {
|
||||
d.hide();
|
||||
this.contact_seller_dialog.hide();
|
||||
frappe.set_route('marketplace', 'buying', this.item.name);
|
||||
erpnext.hub.trigger('action:send_message')
|
||||
});
|
||||
|
@ -16,7 +16,7 @@
|
||||
<div class="level margin-bottom" v-for="message in messages" :key="message.name">
|
||||
<div class="level-left ellipsis" style="width: 80%;">
|
||||
<div v-html="frappe.avatar(message.sender)" />
|
||||
<div style="white-space: normal;" v-html="message.content" />
|
||||
<div style="white-space: normal;" v-html="message.message" />
|
||||
</div>
|
||||
<div class="level-right text-muted" v-html="frappe.datetime.comment_when(message.creation, true)" />
|
||||
</div>
|
||||
@ -64,13 +64,12 @@ export default {
|
||||
methods: {
|
||||
send_message(message) {
|
||||
this.messages.push({
|
||||
sender: hub.settings.company_email,
|
||||
content: message,
|
||||
sender: frappe.session.user,
|
||||
message: message,
|
||||
creation: Date.now(),
|
||||
name: frappe.utils.get_random(6)
|
||||
});
|
||||
hub.call('send_message', {
|
||||
from_seller: hub.settings.company_email,
|
||||
to_seller: this.get_against_seller(),
|
||||
hub_item: this.item_details.name,
|
||||
message
|
||||
|
@ -52,7 +52,7 @@ export default {
|
||||
get_profile() {
|
||||
hub.call(
|
||||
'get_hub_seller_profile',
|
||||
{ hub_seller: hub.settings.company_email }
|
||||
{ hub_seller: hub.settings.hub_seller_name }
|
||||
).then(profile => {
|
||||
this.init = false;
|
||||
|
||||
|
@ -5,10 +5,10 @@
|
||||
>
|
||||
<section-header>
|
||||
<div>
|
||||
<h5>{{ page_title }}</h5>
|
||||
<h5>{{ __('Published Items') }}</h5>
|
||||
<p v-if="items.length"
|
||||
class="text-muted margin-bottom">
|
||||
{{ published_items_message }}
|
||||
{{ __('You can publish upto 200 items.') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -16,17 +16,17 @@
|
||||
class="btn btn-default btn-xs publish-items"
|
||||
v-route="'marketplace/publish'"
|
||||
>
|
||||
<span>{{ publish_button_text }}</span>
|
||||
<span>{{ __('Publish More Items') }}</span>
|
||||
</button>
|
||||
|
||||
</section-header>
|
||||
|
||||
<item-cards-container
|
||||
:container_name="page_title"
|
||||
:container_name="__('Published Items')"
|
||||
:items="items"
|
||||
:item_id_fieldname="item_id_fieldname"
|
||||
:on_click="go_to_item_details_page"
|
||||
:empty_state_message="empty_state_message"
|
||||
:empty_state_message="__('You haven\'t published any items yet.')"
|
||||
:empty_state_action="publish_page_action"
|
||||
>
|
||||
</item-cards-container>
|
||||
@ -44,16 +44,9 @@ export default {
|
||||
publish_page_action: {
|
||||
label: __('Publish Your First Items'),
|
||||
on_click: () => {
|
||||
frappe.set_route(`marketplace/home`);
|
||||
frappe.set_route(`marketplace/publish`);
|
||||
}
|
||||
},
|
||||
|
||||
// Constants
|
||||
page_title: __('Published Items'),
|
||||
publish_button_text: __('Publish More Items'),
|
||||
published_items_message: __('You can publish upto 200 items.'),
|
||||
// TODO: Add empty state action
|
||||
empty_state_message: __('You haven\'t published any items yet.')
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
@ -63,7 +56,7 @@ export default {
|
||||
get_items() {
|
||||
hub.call('get_items', {
|
||||
filters: {
|
||||
hub_seller: hub.settings.company_email
|
||||
hub_seller: hub.settings.hub_seller_name
|
||||
}
|
||||
})
|
||||
.then((items) => {
|
||||
|
@ -38,7 +38,7 @@ export default {
|
||||
methods: {
|
||||
get_items() {
|
||||
hub.call(
|
||||
'get_saved_items_of_seller', {},
|
||||
'get_saved_items_of_user', {},
|
||||
'action:item_save'
|
||||
)
|
||||
.then((items) => {
|
||||
@ -83,9 +83,9 @@ export default {
|
||||
|
||||
remove_item_from_saved_items(hub_item_name) {
|
||||
erpnext.hub.trigger('action:item_save');
|
||||
hub.call('remove_item_from_seller_saved_items', {
|
||||
hub.call('remove_item_from_user_saved_items', {
|
||||
hub_item_name,
|
||||
hub_seller: hub.settings.company_email
|
||||
hub_user: frappe.session.user
|
||||
})
|
||||
.then(() => {
|
||||
this.get_items();
|
||||
|
@ -17,15 +17,15 @@
|
||||
</div>
|
||||
</item-list-card>
|
||||
<div class="hub-list-item" v-for="(message, index) in item.received_messages" :key="index"
|
||||
v-route="'marketplace/selling/' + message.buyer_email + '/' + item.name"
|
||||
v-route="'marketplace/selling/' + message.buyer + '/' + item.name"
|
||||
>
|
||||
<div class="hub-list-left">
|
||||
<div class="hub-list-body">
|
||||
<div class="hub-list-title">
|
||||
{{ message.buyer }}
|
||||
{{ message.buyer_name }}
|
||||
</div>
|
||||
<div class="hub-list-subtitle">
|
||||
{{ message.sender }}: {{ message.content }}
|
||||
{{ message.sender }}: {{ message.message | striphtml }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -62,5 +62,5 @@ Vue.directive('img-src', {
|
||||
});
|
||||
|
||||
Vue.filter('striphtml', function (text) {
|
||||
return strip_html(text);
|
||||
return strip_html(text || '');
|
||||
});
|
@ -305,6 +305,102 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sb_about",
|
||||
"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": "About the Company",
|
||||
"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": "company_logo",
|
||||
"fieldtype": "Attach Image",
|
||||
"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 Logo",
|
||||
"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": "company_description",
|
||||
"fieldtype": "Text Editor",
|
||||
"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 Description",
|
||||
"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,
|
||||
@ -741,7 +837,7 @@
|
||||
"label": "Create Chart Of Accounts Based On",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nStandard Template\nExisting Company",
|
||||
"options": "\nStandard Template\nExisting Company\n\n\n",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -775,7 +871,7 @@
|
||||
"label": "Chart Of Accounts Template",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "",
|
||||
"options": "\n\n\n",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -2630,38 +2726,6 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "company_logo",
|
||||
"fieldtype": "Attach Image",
|
||||
"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 Logo",
|
||||
"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,
|
||||
@ -2772,8 +2836,8 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2018-08-28 15:47:50.757131",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2018-09-01 16:03:30.716918",
|
||||
"modified_by": "cave@aperture.com",
|
||||
"module": "Setup",
|
||||
"name": "Company",
|
||||
"owner": "Administrator",
|
||||
@ -2918,5 +2982,6 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user