refactor!: drop shopify integration from ERPNext (#26700)
BREAKING CHANGE: remove Shopify integration. The integration is moved to a separate app with additional enhancements. The app is still FOSS and licensed under the same license as ERPNext. Any data migration required is taken care of after installing the app and enabling it. New app: https://github.com/frappe/ecommerce_integrations
This commit is contained in:
parent
78762850ee
commit
efb037b566
@ -1,353 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
import json
|
||||
from frappe.utils import cstr, cint, nowdate, getdate, flt, get_request_session, get_datetime
|
||||
from erpnext.erpnext_integrations.utils import validate_webhooks_request
|
||||
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice
|
||||
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_product import sync_item_from_shopify
|
||||
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_customer import create_customer
|
||||
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log, dump_request_data
|
||||
from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import get_shopify_url, get_header
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@validate_webhooks_request("Shopify Settings", 'X-Shopify-Hmac-Sha256', secret_key='shared_secret')
|
||||
def store_request_data(order=None, event=None):
|
||||
if frappe.request:
|
||||
order = json.loads(frappe.request.data)
|
||||
event = frappe.request.headers.get('X-Shopify-Topic')
|
||||
|
||||
dump_request_data(order, event)
|
||||
|
||||
def sync_sales_order(order, request_id=None, old_order_sync=False):
|
||||
frappe.set_user('Administrator')
|
||||
shopify_settings = frappe.get_doc("Shopify Settings")
|
||||
frappe.flags.request_id = request_id
|
||||
|
||||
if not frappe.db.get_value("Sales Order", filters={"shopify_order_id": cstr(order['id'])}):
|
||||
try:
|
||||
validate_customer(order, shopify_settings)
|
||||
validate_item(order, shopify_settings)
|
||||
create_order(order, shopify_settings, old_order_sync=old_order_sync)
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Error", exception=e)
|
||||
|
||||
else:
|
||||
make_shopify_log(status="Success")
|
||||
|
||||
def prepare_sales_invoice(order, request_id=None):
|
||||
frappe.set_user('Administrator')
|
||||
shopify_settings = frappe.get_doc("Shopify Settings")
|
||||
frappe.flags.request_id = request_id
|
||||
|
||||
try:
|
||||
sales_order = get_sales_order(cstr(order['id']))
|
||||
if sales_order:
|
||||
create_sales_invoice(order, shopify_settings, sales_order)
|
||||
make_shopify_log(status="Success")
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Error", exception=e, rollback=True)
|
||||
|
||||
def prepare_delivery_note(order, request_id=None):
|
||||
frappe.set_user('Administrator')
|
||||
shopify_settings = frappe.get_doc("Shopify Settings")
|
||||
frappe.flags.request_id = request_id
|
||||
|
||||
try:
|
||||
sales_order = get_sales_order(cstr(order['id']))
|
||||
if sales_order:
|
||||
create_delivery_note(order, shopify_settings, sales_order)
|
||||
make_shopify_log(status="Success")
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Error", exception=e, rollback=True)
|
||||
|
||||
def get_sales_order(shopify_order_id):
|
||||
sales_order = frappe.db.get_value("Sales Order", filters={"shopify_order_id": shopify_order_id})
|
||||
if sales_order:
|
||||
so = frappe.get_doc("Sales Order", sales_order)
|
||||
return so
|
||||
|
||||
def validate_customer(order, shopify_settings):
|
||||
customer_id = order.get("customer", {}).get("id")
|
||||
if customer_id:
|
||||
if not frappe.db.get_value("Customer", {"shopify_customer_id": customer_id}, "name"):
|
||||
create_customer(order.get("customer"), shopify_settings)
|
||||
|
||||
def validate_item(order, shopify_settings):
|
||||
for item in order.get("line_items"):
|
||||
if item.get("product_id") and not frappe.db.get_value("Item", {"shopify_product_id": item.get("product_id")}, "name"):
|
||||
sync_item_from_shopify(shopify_settings, item)
|
||||
|
||||
def create_order(order, shopify_settings, old_order_sync=False, company=None):
|
||||
so = create_sales_order(order, shopify_settings, company)
|
||||
if so:
|
||||
if order.get("financial_status") == "paid":
|
||||
create_sales_invoice(order, shopify_settings, so, old_order_sync=old_order_sync)
|
||||
|
||||
if order.get("fulfillments") and not old_order_sync:
|
||||
create_delivery_note(order, shopify_settings, so)
|
||||
|
||||
def create_sales_order(shopify_order, shopify_settings, company=None):
|
||||
product_not_exists = []
|
||||
customer = frappe.db.get_value("Customer", {"shopify_customer_id": shopify_order.get("customer", {}).get("id")}, "name")
|
||||
so = frappe.db.get_value("Sales Order", {"shopify_order_id": shopify_order.get("id")}, "name")
|
||||
|
||||
if not so:
|
||||
items = get_order_items(shopify_order.get("line_items"), shopify_settings, getdate(shopify_order.get('created_at')))
|
||||
|
||||
if not items:
|
||||
message = 'Following items exists in the shopify order but relevant records were not found in the shopify Product master'
|
||||
message += "\n" + ", ".join(product_not_exists)
|
||||
|
||||
make_shopify_log(status="Error", exception=message, rollback=True)
|
||||
|
||||
return ''
|
||||
|
||||
so = frappe.get_doc({
|
||||
"doctype": "Sales Order",
|
||||
"naming_series": shopify_settings.sales_order_series or "SO-Shopify-",
|
||||
"shopify_order_id": shopify_order.get("id"),
|
||||
"shopify_order_number": shopify_order.get("name"),
|
||||
"customer": customer or shopify_settings.default_customer,
|
||||
"transaction_date": getdate(shopify_order.get("created_at")) or nowdate(),
|
||||
"delivery_date": getdate(shopify_order.get("created_at")) or nowdate(),
|
||||
"company": shopify_settings.company,
|
||||
"selling_price_list": shopify_settings.price_list,
|
||||
"ignore_pricing_rule": 1,
|
||||
"items": items,
|
||||
"taxes": get_order_taxes(shopify_order, shopify_settings),
|
||||
"apply_discount_on": "Grand Total",
|
||||
"discount_amount": get_discounted_amount(shopify_order),
|
||||
})
|
||||
|
||||
if company:
|
||||
so.update({
|
||||
"company": company,
|
||||
"status": "Draft"
|
||||
})
|
||||
so.flags.ignore_mandatory = True
|
||||
so.save(ignore_permissions=True)
|
||||
so.submit()
|
||||
|
||||
else:
|
||||
so = frappe.get_doc("Sales Order", so)
|
||||
|
||||
frappe.db.commit()
|
||||
return so
|
||||
|
||||
def create_sales_invoice(shopify_order, shopify_settings, so, old_order_sync=False):
|
||||
if not frappe.db.get_value("Sales Invoice", {"shopify_order_id": shopify_order.get("id")}, "name")\
|
||||
and so.docstatus==1 and not so.per_billed and cint(shopify_settings.sync_sales_invoice):
|
||||
|
||||
if old_order_sync:
|
||||
posting_date = getdate(shopify_order.get('created_at'))
|
||||
else:
|
||||
posting_date = nowdate()
|
||||
|
||||
si = make_sales_invoice(so.name, ignore_permissions=True)
|
||||
si.shopify_order_id = shopify_order.get("id")
|
||||
si.shopify_order_number = shopify_order.get("name")
|
||||
si.set_posting_time = 1
|
||||
si.posting_date = posting_date
|
||||
si.due_date = posting_date
|
||||
si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-"
|
||||
si.flags.ignore_mandatory = True
|
||||
set_cost_center(si.items, shopify_settings.cost_center)
|
||||
si.insert(ignore_mandatory=True)
|
||||
si.submit()
|
||||
make_payament_entry_against_sales_invoice(si, shopify_settings, posting_date)
|
||||
frappe.db.commit()
|
||||
|
||||
def set_cost_center(items, cost_center):
|
||||
for item in items:
|
||||
item.cost_center = cost_center
|
||||
|
||||
def make_payament_entry_against_sales_invoice(doc, shopify_settings, posting_date=None):
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||
payment_entry = get_payment_entry(doc.doctype, doc.name, bank_account=shopify_settings.cash_bank_account)
|
||||
payment_entry.flags.ignore_mandatory = True
|
||||
payment_entry.reference_no = doc.name
|
||||
payment_entry.posting_date = posting_date or nowdate()
|
||||
payment_entry.reference_date = posting_date or nowdate()
|
||||
payment_entry.insert(ignore_permissions=True)
|
||||
payment_entry.submit()
|
||||
|
||||
def create_delivery_note(shopify_order, shopify_settings, so):
|
||||
if not cint(shopify_settings.sync_delivery_note):
|
||||
return
|
||||
|
||||
for fulfillment in shopify_order.get("fulfillments"):
|
||||
if not frappe.db.get_value("Delivery Note", {"shopify_fulfillment_id": fulfillment.get("id")}, "name")\
|
||||
and so.docstatus==1:
|
||||
|
||||
dn = make_delivery_note(so.name)
|
||||
dn.shopify_order_id = fulfillment.get("order_id")
|
||||
dn.shopify_order_number = shopify_order.get("name")
|
||||
dn.set_posting_time = 1
|
||||
dn.posting_date = getdate(fulfillment.get("created_at"))
|
||||
dn.shopify_fulfillment_id = fulfillment.get("id")
|
||||
dn.naming_series = shopify_settings.delivery_note_series or "DN-Shopify-"
|
||||
dn.items = get_fulfillment_items(dn.items, fulfillment.get("line_items"), shopify_settings)
|
||||
dn.flags.ignore_mandatory = True
|
||||
dn.save()
|
||||
dn.submit()
|
||||
frappe.db.commit()
|
||||
|
||||
def get_fulfillment_items(dn_items, fulfillment_items, shopify_settings):
|
||||
return [dn_item.update({"qty": item.get("quantity")}) for item in fulfillment_items for dn_item in dn_items\
|
||||
if get_item_code(item) == dn_item.item_code]
|
||||
|
||||
def get_discounted_amount(order):
|
||||
discounted_amount = 0.0
|
||||
for discount in order.get("discount_codes"):
|
||||
discounted_amount += flt(discount.get("amount"))
|
||||
return discounted_amount
|
||||
|
||||
def get_order_items(order_items, shopify_settings, delivery_date):
|
||||
items = []
|
||||
all_product_exists = True
|
||||
product_not_exists = []
|
||||
|
||||
for shopify_item in order_items:
|
||||
if not shopify_item.get('product_exists'):
|
||||
all_product_exists = False
|
||||
product_not_exists.append({'title':shopify_item.get('title'),
|
||||
'shopify_order_id': shopify_item.get('id')})
|
||||
continue
|
||||
|
||||
if all_product_exists:
|
||||
item_code = get_item_code(shopify_item)
|
||||
items.append({
|
||||
"item_code": item_code,
|
||||
"item_name": shopify_item.get("name"),
|
||||
"rate": shopify_item.get("price"),
|
||||
"delivery_date": delivery_date,
|
||||
"qty": shopify_item.get("quantity"),
|
||||
"stock_uom": shopify_item.get("uom") or _("Nos"),
|
||||
"warehouse": shopify_settings.warehouse
|
||||
})
|
||||
else:
|
||||
items = []
|
||||
|
||||
return items
|
||||
|
||||
def get_item_code(shopify_item):
|
||||
item_code = frappe.db.get_value("Item", {"shopify_variant_id": shopify_item.get("variant_id")}, "item_code")
|
||||
if not item_code:
|
||||
item_code = frappe.db.get_value("Item", {"shopify_product_id": shopify_item.get("product_id")}, "item_code")
|
||||
if not item_code:
|
||||
item_code = frappe.db.get_value("Item", {"item_name": shopify_item.get("title")}, "item_code")
|
||||
|
||||
return item_code
|
||||
|
||||
def get_order_taxes(shopify_order, shopify_settings):
|
||||
taxes = []
|
||||
for tax in shopify_order.get("tax_lines"):
|
||||
taxes.append({
|
||||
"charge_type": _("On Net Total"),
|
||||
"account_head": get_tax_account_head(tax),
|
||||
"description": "{0} - {1}%".format(tax.get("title"), tax.get("rate") * 100.0),
|
||||
"rate": tax.get("rate") * 100.00,
|
||||
"included_in_print_rate": 1 if shopify_order.get("taxes_included") else 0,
|
||||
"cost_center": shopify_settings.cost_center
|
||||
})
|
||||
|
||||
taxes = update_taxes_with_shipping_lines(taxes, shopify_order.get("shipping_lines"), shopify_settings)
|
||||
|
||||
return taxes
|
||||
|
||||
def update_taxes_with_shipping_lines(taxes, shipping_lines, shopify_settings):
|
||||
"""Shipping lines represents the shipping details,
|
||||
each such shipping detail consists of a list of tax_lines"""
|
||||
for shipping_charge in shipping_lines:
|
||||
if shipping_charge.get("price"):
|
||||
taxes.append({
|
||||
"charge_type": _("Actual"),
|
||||
"account_head": get_tax_account_head(shipping_charge),
|
||||
"description": shipping_charge["title"],
|
||||
"tax_amount": shipping_charge["price"],
|
||||
"cost_center": shopify_settings.cost_center
|
||||
})
|
||||
|
||||
for tax in shipping_charge.get("tax_lines"):
|
||||
taxes.append({
|
||||
"charge_type": _("Actual"),
|
||||
"account_head": get_tax_account_head(tax),
|
||||
"description": tax["title"],
|
||||
"tax_amount": tax["price"],
|
||||
"cost_center": shopify_settings.cost_center
|
||||
})
|
||||
|
||||
return taxes
|
||||
|
||||
def get_tax_account_head(tax):
|
||||
tax_title = tax.get("title").encode("utf-8")
|
||||
|
||||
tax_account = frappe.db.get_value("Shopify Tax Account", \
|
||||
{"parent": "Shopify Settings", "shopify_tax": tax_title}, "tax_account")
|
||||
|
||||
if not tax_account:
|
||||
frappe.throw(_("Tax Account not specified for Shopify Tax {0}").format(tax.get("title")))
|
||||
|
||||
return tax_account
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def sync_old_orders():
|
||||
frappe.set_user('Administrator')
|
||||
shopify_settings = frappe.get_doc('Shopify Settings')
|
||||
|
||||
if not shopify_settings.sync_missing_orders:
|
||||
return
|
||||
|
||||
url = get_url(shopify_settings)
|
||||
session = get_request_session()
|
||||
|
||||
try:
|
||||
res = session.get(url, headers=get_header(shopify_settings))
|
||||
res.raise_for_status()
|
||||
orders = res.json()["orders"]
|
||||
|
||||
for order in orders:
|
||||
if is_sync_complete(shopify_settings, order):
|
||||
stop_sync(shopify_settings)
|
||||
return
|
||||
|
||||
sync_sales_order(order=order, old_order_sync=True)
|
||||
last_order_id = order.get('id')
|
||||
|
||||
if last_order_id:
|
||||
shopify_settings.load_from_db()
|
||||
shopify_settings.last_order_id = last_order_id
|
||||
shopify_settings.save()
|
||||
frappe.db.commit()
|
||||
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
def stop_sync(shopify_settings):
|
||||
shopify_settings.sync_missing_orders = 0
|
||||
shopify_settings.last_order_id = ''
|
||||
shopify_settings.save()
|
||||
frappe.db.commit()
|
||||
|
||||
def get_url(shopify_settings):
|
||||
last_order_id = shopify_settings.last_order_id
|
||||
|
||||
if not last_order_id:
|
||||
if shopify_settings.sync_based_on == 'Date':
|
||||
url = get_shopify_url("admin/api/2021-04/orders.json?limit=250&created_at_min={0}&since_id=0".format(
|
||||
get_datetime(shopify_settings.from_date)), shopify_settings)
|
||||
else:
|
||||
url = get_shopify_url("admin/api/2021-04/orders.json?limit=250&since_id={0}".format(
|
||||
shopify_settings.from_order_id), shopify_settings)
|
||||
else:
|
||||
url = get_shopify_url("admin/api/2021-04/orders.json?limit=250&since_id={0}".format(last_order_id), shopify_settings)
|
||||
|
||||
return url
|
||||
|
||||
def is_sync_complete(shopify_settings, order):
|
||||
if shopify_settings.sync_based_on == 'Date':
|
||||
return getdate(shopify_settings.to_date) < getdate(order.get('created_at'))
|
||||
else:
|
||||
return cstr(order.get('id')) == cstr(shopify_settings.to_order_id)
|
||||
|
@ -1,22 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Shopify Log', {
|
||||
refresh: function(frm) {
|
||||
if (frm.doc.request_data && frm.doc.status=='Error'){
|
||||
frm.add_custom_button('Resync', function() {
|
||||
frappe.call({
|
||||
method:"erpnext.erpnext_integrations.doctype.shopify_log.shopify_log.resync",
|
||||
args:{
|
||||
method:frm.doc.method,
|
||||
name: frm.doc.name,
|
||||
request_data: frm.doc.request_data
|
||||
},
|
||||
callback: function(r){
|
||||
frappe.msgprint(__("Order rescheduled for sync"))
|
||||
}
|
||||
})
|
||||
}).addClass('btn-primary');
|
||||
}
|
||||
}
|
||||
});
|
@ -1,268 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-03-14 10:02:06.227184",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "System",
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"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": "Title",
|
||||
"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,
|
||||
"default": "Queued",
|
||||
"fieldname": "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,
|
||||
"options": "",
|
||||
"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": "method",
|
||||
"fieldtype": "Small Text",
|
||||
"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": "Method",
|
||||
"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": "message",
|
||||
"fieldtype": "Code",
|
||||
"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": "Message",
|
||||
"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": "traceback",
|
||||
"fieldtype": "Code",
|
||||
"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": "Traceback",
|
||||
"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": "request_data",
|
||||
"fieldtype": "Code",
|
||||
"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": "Request Data",
|
||||
"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": 1,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-04-20 16:23:36.862381",
|
||||
"modified_by": "Administrator",
|
||||
"module": "ERPNext Integrations",
|
||||
"name": "Shopify Log",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Administrator",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import json
|
||||
from frappe.model.document import Document
|
||||
from erpnext.erpnext_integrations.utils import get_webhook_address
|
||||
|
||||
class ShopifyLog(Document):
|
||||
pass
|
||||
|
||||
|
||||
def make_shopify_log(status="Queued", exception=None, rollback=False):
|
||||
# if name not provided by log calling method then fetch existing queued state log
|
||||
make_new = False
|
||||
|
||||
if not frappe.flags.request_id:
|
||||
make_new = True
|
||||
|
||||
if rollback:
|
||||
frappe.db.rollback()
|
||||
|
||||
if make_new:
|
||||
log = frappe.get_doc({"doctype":"Shopify Log"}).insert(ignore_permissions=True)
|
||||
else:
|
||||
log = log = frappe.get_doc("Shopify Log", frappe.flags.request_id)
|
||||
|
||||
log.message = get_message(exception)
|
||||
log.traceback = frappe.get_traceback()
|
||||
log.status = status
|
||||
log.save(ignore_permissions=True)
|
||||
frappe.db.commit()
|
||||
|
||||
def get_message(exception):
|
||||
message = None
|
||||
|
||||
if hasattr(exception, 'message'):
|
||||
message = exception.message
|
||||
elif hasattr(exception, '__str__'):
|
||||
message = exception.__str__()
|
||||
else:
|
||||
message = "Something went wrong while syncing"
|
||||
return message
|
||||
|
||||
def dump_request_data(data, event="create/order"):
|
||||
event_mapper = {
|
||||
"orders/create": get_webhook_address(connector_name='shopify_connection', method="sync_sales_order", exclude_uri=True),
|
||||
"orders/paid" : get_webhook_address(connector_name='shopify_connection', method="prepare_sales_invoice", exclude_uri=True),
|
||||
"orders/fulfilled": get_webhook_address(connector_name='shopify_connection', method="prepare_delivery_note", exclude_uri=True)
|
||||
}
|
||||
|
||||
log = frappe.get_doc({
|
||||
"doctype": "Shopify Log",
|
||||
"request_data": json.dumps(data, indent=1),
|
||||
"method": event_mapper[event]
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
frappe.db.commit()
|
||||
frappe.enqueue(method=event_mapper[event], queue='short', timeout=300, is_async=True,
|
||||
**{"order": data, "request_id": log.name})
|
||||
|
||||
@frappe.whitelist()
|
||||
def resync(method, name, request_data):
|
||||
frappe.db.set_value("Shopify Log", name, "status", "Queued", update_modified=False)
|
||||
frappe.enqueue(method=method, queue='short', timeout=300, is_async=True,
|
||||
**{"order": json.loads(request_data), "request_id": name})
|
@ -1,12 +0,0 @@
|
||||
frappe.listview_settings['Shopify Log'] = {
|
||||
add_fields: ["status"],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.status==="Success"){
|
||||
return [__("Success"), "green", "status,=,Success"];
|
||||
} else if(doc.status ==="Error"){
|
||||
return [__("Error"), "red", "status,=,Error"];
|
||||
} else if(doc.status ==="Queued"){
|
||||
return [__("Queued"), "orange", "status,=,Queued"];
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Shopify Log", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Shopify Log
|
||||
() => frappe.tests.make('Shopify Log', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
@ -1,12 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Shopify Log')
|
||||
|
||||
class TestShopifyLog(unittest.TestCase):
|
||||
pass
|
@ -1,90 +0,0 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.provide("erpnext_integrations.shopify_settings");
|
||||
|
||||
frappe.ui.form.on("Shopify Settings", "onload", function(frm){
|
||||
frappe.call({
|
||||
method:"erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings.get_series",
|
||||
callback:function(r){
|
||||
$.each(r.message, function(key, value){
|
||||
set_field_options(key, value);
|
||||
});
|
||||
}
|
||||
});
|
||||
erpnext_integrations.shopify_settings.setup_queries(frm);
|
||||
})
|
||||
|
||||
frappe.ui.form.on("Shopify Settings", "app_type", function(frm) {
|
||||
frm.toggle_reqd("api_key", (frm.doc.app_type == "Private"));
|
||||
frm.toggle_reqd("password", (frm.doc.app_type == "Private"));
|
||||
})
|
||||
|
||||
frappe.ui.form.on("Shopify Settings", "refresh", function(frm){
|
||||
if(!frm.doc.__islocal && frm.doc.enable_shopify === 1){
|
||||
frm.toggle_reqd("price_list", true);
|
||||
frm.toggle_reqd("warehouse", true);
|
||||
frm.toggle_reqd("taxes", true);
|
||||
frm.toggle_reqd("company", true);
|
||||
frm.toggle_reqd("cost_center", true);
|
||||
frm.toggle_reqd("cash_bank_account", true);
|
||||
frm.toggle_reqd("sales_order_series", true);
|
||||
frm.toggle_reqd("customer_group", true);
|
||||
frm.toggle_reqd("shared_secret", true);
|
||||
|
||||
frm.toggle_reqd("sales_invoice_series", frm.doc.sync_sales_invoice);
|
||||
frm.toggle_reqd("delivery_note_series", frm.doc.sync_delivery_note);
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
$.extend(erpnext_integrations.shopify_settings, {
|
||||
setup_queries: function(frm) {
|
||||
frm.fields_dict["warehouse"].get_query = function(doc) {
|
||||
return {
|
||||
filters:{
|
||||
"company": doc.company,
|
||||
"is_group": "No"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict["taxes"].grid.get_field("tax_account").get_query = function(doc){
|
||||
return {
|
||||
"query": "erpnext.controllers.queries.tax_account_query",
|
||||
"filters": {
|
||||
"account_type": ["Tax", "Chargeable", "Expense Account"],
|
||||
"company": doc.company
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict["cash_bank_account"].get_query = function(doc) {
|
||||
return {
|
||||
filters: [
|
||||
["Account", "account_type", "in", ["Cash", "Bank"]],
|
||||
["Account", "root_type", "=", "Asset"],
|
||||
["Account", "is_group", "=",0],
|
||||
["Account", "company", "=", doc.company]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict["cost_center"].get_query = function(doc) {
|
||||
return {
|
||||
filters:{
|
||||
"company": doc.company,
|
||||
"is_group": "No"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict["price_list"].get_query = function() {
|
||||
return {
|
||||
filters:{
|
||||
"selling": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
@ -1,353 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2015-05-18 05:21:07.270859",
|
||||
"doctype": "DocType",
|
||||
"document_type": "System",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"status_html",
|
||||
"enable_shopify",
|
||||
"app_type",
|
||||
"column_break_4",
|
||||
"last_sync_datetime",
|
||||
"section_break_2",
|
||||
"shopify_url",
|
||||
"api_key",
|
||||
"column_break_3",
|
||||
"password",
|
||||
"shared_secret",
|
||||
"access_token",
|
||||
"section_break_38",
|
||||
"webhooks",
|
||||
"section_break_15",
|
||||
"default_customer",
|
||||
"column_break_19",
|
||||
"customer_group",
|
||||
"company_dependent_settings",
|
||||
"company",
|
||||
"cash_bank_account",
|
||||
"column_break_20",
|
||||
"cost_center",
|
||||
"erp_settings",
|
||||
"price_list",
|
||||
"update_price_in_erpnext_price_list",
|
||||
"column_break_26",
|
||||
"warehouse",
|
||||
"section_break_25",
|
||||
"sales_order_series",
|
||||
"column_break_27",
|
||||
"sync_delivery_note",
|
||||
"delivery_note_series",
|
||||
"sync_sales_invoice",
|
||||
"sales_invoice_series",
|
||||
"section_break_22",
|
||||
"html_16",
|
||||
"taxes",
|
||||
"syncing_details_section",
|
||||
"sync_missing_orders",
|
||||
"sync_based_on",
|
||||
"column_break_41",
|
||||
"from_date",
|
||||
"to_date",
|
||||
"from_order_id",
|
||||
"to_order_id",
|
||||
"last_order_id"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "status_html",
|
||||
"fieldtype": "HTML",
|
||||
"label": "status html",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "enable_shopify",
|
||||
"fieldtype": "Check",
|
||||
"label": "Enable Shopify"
|
||||
},
|
||||
{
|
||||
"default": "Private",
|
||||
"fieldname": "app_type",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "App Type",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "last_sync_datetime",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Last Sync Datetime",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"description": "eg: frappe.myshopify.com",
|
||||
"fieldname": "shopify_url",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Shop URL",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.app_type==\"Private\"",
|
||||
"fieldname": "api_key",
|
||||
"fieldtype": "Data",
|
||||
"label": "API Key"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.app_type==\"Private\"",
|
||||
"fieldname": "password",
|
||||
"fieldtype": "Password",
|
||||
"label": "Password"
|
||||
},
|
||||
{
|
||||
"fieldname": "shared_secret",
|
||||
"fieldtype": "Data",
|
||||
"label": "Shared secret"
|
||||
},
|
||||
{
|
||||
"fieldname": "access_token",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Access Token",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "section_break_38",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Webhooks Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "webhooks",
|
||||
"fieldtype": "Table",
|
||||
"label": "Webhooks",
|
||||
"options": "Shopify Webhook Detail",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_15",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Customer Settings"
|
||||
},
|
||||
{
|
||||
"description": "If Shopify does not have a customer in the order, then while syncing the orders, the system will consider the default customer for the order",
|
||||
"fieldname": "default_customer",
|
||||
"fieldtype": "Link",
|
||||
"label": "Default Customer",
|
||||
"options": "Customer"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_19",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"description": "Customer Group will set to selected group while syncing customers from Shopify",
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer Group",
|
||||
"options": "Customer Group"
|
||||
},
|
||||
{
|
||||
"fieldname": "company_dependent_settings",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "For Company",
|
||||
"options": "Company"
|
||||
},
|
||||
{
|
||||
"description": "Cash Account will used for Sales Invoice creation",
|
||||
"fieldname": "cash_bank_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cash/Bank Account",
|
||||
"options": "Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_20",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"options": "Cost Center"
|
||||
},
|
||||
{
|
||||
"fieldname": "erp_settings",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "price_list",
|
||||
"fieldtype": "Link",
|
||||
"label": "Price List",
|
||||
"options": "Price List"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "update_price_in_erpnext_price_list",
|
||||
"fieldtype": "Check",
|
||||
"label": "Update Price from Shopify To ERPNext Price List"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_26",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"description": "Default Warehouse to to create Sales Order and Delivery Note",
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_25",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "sales_order_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Sales Order Series"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_27",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "sync_delivery_note",
|
||||
"fieldtype": "Check",
|
||||
"label": "Import Delivery Notes from Shopify on Shipment"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_delivery_note==1",
|
||||
"fieldname": "delivery_note_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Delivery Note Series"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "sync_sales_invoice",
|
||||
"fieldtype": "Check",
|
||||
"label": "Import Sales Invoice from Shopify if Payment is marked"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_sales_invoice==1",
|
||||
"fieldname": "sales_invoice_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Sales Invoice Series"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_22",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "html_16",
|
||||
"fieldtype": "HTML",
|
||||
"options": "Map Shopify Taxes / Shipping Charges to ERPNext Account"
|
||||
},
|
||||
{
|
||||
"fieldname": "taxes",
|
||||
"fieldtype": "Table",
|
||||
"label": "Shopify Tax Account",
|
||||
"options": "Shopify Tax Account"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "syncing_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Syncing Missing Orders"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_missing_orders",
|
||||
"fieldname": "last_order_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Last Order Id",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_41",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "On checking this Order from the ",
|
||||
"fieldname": "sync_missing_orders",
|
||||
"fieldtype": "Check",
|
||||
"label": "Sync Missing Old Shopify Orders"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_missing_orders",
|
||||
"fieldname": "sync_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Sync Based On",
|
||||
"mandatory_depends_on": "eval:doc.sync_missing_orders",
|
||||
"options": "\nDate\nShopify Order Id"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders",
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Date",
|
||||
"mandatory_depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date",
|
||||
"mandatory_depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders",
|
||||
"fieldname": "from_order_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "From Order Id",
|
||||
"mandatory_depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders",
|
||||
"fieldname": "to_order_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "To Order Id",
|
||||
"mandatory_depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders"
|
||||
}
|
||||
],
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-02 17:35:41.953317",
|
||||
"modified_by": "Administrator",
|
||||
"module": "ERPNext Integrations",
|
||||
"name": "Shopify Settings",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import json
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_request_session
|
||||
from requests.exceptions import HTTPError
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
|
||||
from erpnext.erpnext_integrations.utils import get_webhook_address
|
||||
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log
|
||||
|
||||
class ShopifySettings(Document):
|
||||
def validate(self):
|
||||
if self.enable_shopify == 1:
|
||||
setup_custom_fields()
|
||||
self.validate_access_credentials()
|
||||
self.register_webhooks()
|
||||
else:
|
||||
self.unregister_webhooks()
|
||||
|
||||
def validate_access_credentials(self):
|
||||
if not (self.get_password(raise_exception=False) and self.api_key and self.shopify_url):
|
||||
frappe.msgprint(_("Missing value for Password, API Key or Shopify URL"), raise_exception=frappe.ValidationError)
|
||||
|
||||
def register_webhooks(self):
|
||||
webhooks = ["orders/create", "orders/paid", "orders/fulfilled"]
|
||||
# url = get_shopify_url('admin/webhooks.json', self)
|
||||
created_webhooks = [d.method for d in self.webhooks]
|
||||
url = get_shopify_url('admin/api/2021-04/webhooks.json', self)
|
||||
for method in webhooks:
|
||||
session = get_request_session()
|
||||
try:
|
||||
res = session.post(url, data=json.dumps({
|
||||
"webhook": {
|
||||
"topic": method,
|
||||
"address": get_webhook_address(connector_name='shopify_connection', method='store_request_data', force_https=True),
|
||||
"format": "json"
|
||||
}
|
||||
}), headers=get_header(self))
|
||||
res.raise_for_status()
|
||||
self.update_webhook_table(method, res.json())
|
||||
|
||||
except HTTPError as e:
|
||||
error_message = res.json().get('errors', e)
|
||||
make_shopify_log(status="Warning", exception=error_message, rollback=True)
|
||||
|
||||
except Exception as e:
|
||||
make_shopify_log(status="Warning", exception=e, rollback=True)
|
||||
|
||||
def unregister_webhooks(self):
|
||||
session = get_request_session()
|
||||
deleted_webhooks = []
|
||||
|
||||
for d in self.webhooks:
|
||||
url = get_shopify_url('admin/api/2021-04/webhooks/{0}.json'.format(d.webhook_id), self)
|
||||
try:
|
||||
res = session.delete(url, headers=get_header(self))
|
||||
res.raise_for_status()
|
||||
deleted_webhooks.append(d)
|
||||
|
||||
except HTTPError as e:
|
||||
error_message = res.json().get('errors', e)
|
||||
make_shopify_log(status="Warning", exception=error_message, rollback=True)
|
||||
|
||||
except Exception as e:
|
||||
frappe.log_error(message=e, title='Shopify Webhooks Issue')
|
||||
|
||||
for d in deleted_webhooks:
|
||||
self.remove(d)
|
||||
|
||||
def update_webhook_table(self, method, res):
|
||||
self.append("webhooks", {
|
||||
"webhook_id": res['webhook']['id'],
|
||||
"method": method
|
||||
})
|
||||
|
||||
def get_shopify_url(path, settings):
|
||||
if settings.app_type == "Private":
|
||||
return 'https://{}:{}@{}/{}'.format(settings.api_key, settings.get_password('password'), settings.shopify_url, path)
|
||||
else:
|
||||
return 'https://{}/{}'.format(settings.shopify_url, path)
|
||||
|
||||
def get_header(settings):
|
||||
header = {'Content-Type': 'application/json'}
|
||||
|
||||
return header
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_series():
|
||||
return {
|
||||
"sales_order_series" : frappe.get_meta("Sales Order").get_options("naming_series") or "SO-Shopify-",
|
||||
"sales_invoice_series" : frappe.get_meta("Sales Invoice").get_options("naming_series") or "SI-Shopify-",
|
||||
"delivery_note_series" : frappe.get_meta("Delivery Note").get_options("naming_series") or "DN-Shopify-"
|
||||
}
|
||||
|
||||
def setup_custom_fields():
|
||||
custom_fields = {
|
||||
"Customer": [
|
||||
dict(fieldname='shopify_customer_id', label='Shopify Customer Id',
|
||||
fieldtype='Data', insert_after='series', read_only=1, print_hide=1)
|
||||
],
|
||||
"Supplier": [
|
||||
dict(fieldname='shopify_supplier_id', label='Shopify Supplier Id',
|
||||
fieldtype='Data', insert_after='supplier_name', read_only=1, print_hide=1)
|
||||
],
|
||||
"Address": [
|
||||
dict(fieldname='shopify_address_id', label='Shopify Address Id',
|
||||
fieldtype='Data', insert_after='fax', read_only=1, print_hide=1)
|
||||
],
|
||||
"Item": [
|
||||
dict(fieldname='shopify_variant_id', label='Shopify Variant Id',
|
||||
fieldtype='Data', insert_after='item_code', read_only=1, print_hide=1),
|
||||
dict(fieldname='shopify_product_id', label='Shopify Product Id',
|
||||
fieldtype='Data', insert_after='item_code', read_only=1, print_hide=1),
|
||||
dict(fieldname='shopify_description', label='Shopify Description',
|
||||
fieldtype='Text Editor', insert_after='description', read_only=1, print_hide=1)
|
||||
],
|
||||
"Sales Order": [
|
||||
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1),
|
||||
dict(fieldname='shopify_order_number', label='Shopify Order Number',
|
||||
fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1)
|
||||
],
|
||||
"Delivery Note":[
|
||||
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1),
|
||||
dict(fieldname='shopify_order_number', label='Shopify Order Number',
|
||||
fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1),
|
||||
dict(fieldname='shopify_fulfillment_id', label='Shopify Fulfillment Id',
|
||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1)
|
||||
],
|
||||
"Sales Invoice": [
|
||||
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1),
|
||||
dict(fieldname='shopify_order_number', label='Shopify Order Number',
|
||||
fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1)
|
||||
]
|
||||
}
|
||||
|
||||
create_custom_fields(custom_fields)
|
@ -1,71 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
def create_customer(shopify_customer, shopify_settings):
|
||||
import frappe.utils.nestedset
|
||||
|
||||
cust_name = (shopify_customer.get("first_name") + " " + (shopify_customer.get("last_name") \
|
||||
and shopify_customer.get("last_name") or "")) if shopify_customer.get("first_name")\
|
||||
else shopify_customer.get("email")
|
||||
|
||||
try:
|
||||
customer = frappe.get_doc({
|
||||
"doctype": "Customer",
|
||||
"name": shopify_customer.get("id"),
|
||||
"customer_name" : cust_name,
|
||||
"shopify_customer_id": shopify_customer.get("id"),
|
||||
"sync_with_shopify": 1,
|
||||
"customer_group": shopify_settings.customer_group,
|
||||
"territory": frappe.utils.nestedset.get_root_of("Territory"),
|
||||
"customer_type": _("Individual")
|
||||
})
|
||||
customer.flags.ignore_mandatory = True
|
||||
customer.insert(ignore_permissions=True)
|
||||
|
||||
if customer:
|
||||
create_customer_address(customer, shopify_customer)
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
def create_customer_address(customer, shopify_customer):
|
||||
addresses = shopify_customer.get("addresses", [])
|
||||
|
||||
if not addresses and "default_address" in shopify_customer:
|
||||
addresses.append(shopify_customer["default_address"])
|
||||
|
||||
for i, address in enumerate(addresses):
|
||||
address_title, address_type = get_address_title_and_type(customer.customer_name, i)
|
||||
try :
|
||||
frappe.get_doc({
|
||||
"doctype": "Address",
|
||||
"shopify_address_id": address.get("id"),
|
||||
"address_title": address_title,
|
||||
"address_type": address_type,
|
||||
"address_line1": address.get("address1") or "Address 1",
|
||||
"address_line2": address.get("address2"),
|
||||
"city": address.get("city") or "City",
|
||||
"state": address.get("province"),
|
||||
"pincode": address.get("zip"),
|
||||
"country": address.get("country"),
|
||||
"phone": address.get("phone"),
|
||||
"email_id": shopify_customer.get("email"),
|
||||
"links": [{
|
||||
"link_doctype": "Customer",
|
||||
"link_name": customer.name
|
||||
}]
|
||||
}).insert(ignore_mandatory=True)
|
||||
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
def get_address_title_and_type(customer_name, index):
|
||||
address_type = _("Billing")
|
||||
address_title = customer_name
|
||||
if frappe.db.get_value("Address", "{0}-{1}".format(customer_name.strip(), address_type)):
|
||||
address_title = "{0}-{1}".format(customer_name.strip(), index)
|
||||
|
||||
return address_title, address_type
|
@ -1,309 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from erpnext import get_default_company
|
||||
from frappe.utils import cstr, cint, get_request_session
|
||||
from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import get_shopify_url, get_header
|
||||
|
||||
shopify_variants_attr_list = ["option1", "option2", "option3"]
|
||||
|
||||
def sync_item_from_shopify(shopify_settings, item):
|
||||
url = get_shopify_url("admin/api/2021-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
|
||||
session = get_request_session()
|
||||
|
||||
try:
|
||||
res = session.get(url, headers=get_header(shopify_settings))
|
||||
res.raise_for_status()
|
||||
|
||||
shopify_item = res.json()["product"]
|
||||
make_item(shopify_settings.warehouse, shopify_item)
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
def make_item(warehouse, shopify_item):
|
||||
add_item_weight(shopify_item)
|
||||
|
||||
if has_variants(shopify_item):
|
||||
attributes = create_attribute(shopify_item)
|
||||
create_item(shopify_item, warehouse, 1, attributes)
|
||||
create_item_variants(shopify_item, warehouse, attributes, shopify_variants_attr_list)
|
||||
|
||||
else:
|
||||
shopify_item["variant_id"] = shopify_item['variants'][0]["id"]
|
||||
create_item(shopify_item, warehouse)
|
||||
|
||||
def add_item_weight(shopify_item):
|
||||
shopify_item["weight"] = shopify_item['variants'][0]["weight"]
|
||||
shopify_item["weight_unit"] = shopify_item['variants'][0]["weight_unit"]
|
||||
|
||||
def has_variants(shopify_item):
|
||||
if len(shopify_item.get("options")) >= 1 and "Default Title" not in shopify_item.get("options")[0]["values"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def create_attribute(shopify_item):
|
||||
attribute = []
|
||||
# shopify item dict
|
||||
for attr in shopify_item.get('options'):
|
||||
if not frappe.db.get_value("Item Attribute", attr.get("name"), "name"):
|
||||
frappe.get_doc({
|
||||
"doctype": "Item Attribute",
|
||||
"attribute_name": attr.get("name"),
|
||||
"item_attribute_values": [
|
||||
{
|
||||
"attribute_value": attr_value,
|
||||
"abbr":attr_value
|
||||
}
|
||||
for attr_value in attr.get("values")
|
||||
]
|
||||
}).insert()
|
||||
attribute.append({"attribute": attr.get("name")})
|
||||
|
||||
else:
|
||||
# check for attribute values
|
||||
item_attr = frappe.get_doc("Item Attribute", attr.get("name"))
|
||||
if not item_attr.numeric_values:
|
||||
set_new_attribute_values(item_attr, attr.get("values"))
|
||||
item_attr.save()
|
||||
attribute.append({"attribute": attr.get("name")})
|
||||
|
||||
else:
|
||||
attribute.append({
|
||||
"attribute": attr.get("name"),
|
||||
"from_range": item_attr.get("from_range"),
|
||||
"to_range": item_attr.get("to_range"),
|
||||
"increment": item_attr.get("increment"),
|
||||
"numeric_values": item_attr.get("numeric_values")
|
||||
})
|
||||
|
||||
return attribute
|
||||
|
||||
def set_new_attribute_values(item_attr, values):
|
||||
for attr_value in values:
|
||||
if not any((d.abbr.lower() == attr_value.lower() or d.attribute_value.lower() == attr_value.lower())\
|
||||
for d in item_attr.item_attribute_values):
|
||||
item_attr.append("item_attribute_values", {
|
||||
"attribute_value": attr_value,
|
||||
"abbr": attr_value
|
||||
})
|
||||
|
||||
def create_item(shopify_item, warehouse, has_variant=0, attributes=None,variant_of=None):
|
||||
item_dict = {
|
||||
"doctype": "Item",
|
||||
"shopify_product_id": shopify_item.get("id"),
|
||||
"shopify_variant_id": shopify_item.get("variant_id"),
|
||||
"variant_of": variant_of,
|
||||
"sync_with_shopify": 1,
|
||||
"is_stock_item": 1,
|
||||
"item_code": cstr(shopify_item.get("item_code")) or cstr(shopify_item.get("id")),
|
||||
"item_name": shopify_item.get("title", '').strip(),
|
||||
"description": shopify_item.get("body_html") or shopify_item.get("title"),
|
||||
"shopify_description": shopify_item.get("body_html") or shopify_item.get("title"),
|
||||
"item_group": get_item_group(shopify_item.get("product_type")),
|
||||
"has_variants": has_variant,
|
||||
"attributes":attributes or [],
|
||||
"stock_uom": shopify_item.get("uom") or _("Nos"),
|
||||
"stock_keeping_unit": shopify_item.get("sku") or get_sku(shopify_item),
|
||||
"default_warehouse": warehouse,
|
||||
"image": get_item_image(shopify_item),
|
||||
"weight_uom": shopify_item.get("weight_unit"),
|
||||
"weight_per_unit": shopify_item.get("weight"),
|
||||
"default_supplier": get_supplier(shopify_item),
|
||||
"item_defaults": [
|
||||
{
|
||||
"company": get_default_company()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
if not is_item_exists(item_dict, attributes, variant_of=variant_of):
|
||||
item_details = get_item_details(shopify_item)
|
||||
name = ''
|
||||
|
||||
if not item_details:
|
||||
new_item = frappe.get_doc(item_dict)
|
||||
new_item.insert(ignore_permissions=True, ignore_mandatory=True)
|
||||
name = new_item.name
|
||||
|
||||
if not name:
|
||||
name = item_details.name
|
||||
|
||||
if not has_variant:
|
||||
add_to_price_list(shopify_item, name)
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
def create_item_variants(shopify_item, warehouse, attributes, shopify_variants_attr_list):
|
||||
template_item = frappe.db.get_value("Item", filters={"shopify_product_id": shopify_item.get("id")},
|
||||
fieldname=["name", "stock_uom"], as_dict=True)
|
||||
|
||||
if template_item:
|
||||
for variant in shopify_item.get("variants"):
|
||||
shopify_item_variant = {
|
||||
"id" : variant.get("id"),
|
||||
"item_code": variant.get("id"),
|
||||
"title": variant.get("title"),
|
||||
"product_type": shopify_item.get("product_type"),
|
||||
"sku": variant.get("sku"),
|
||||
"uom": template_item.stock_uom or _("Nos"),
|
||||
"item_price": variant.get("price"),
|
||||
"variant_id": variant.get("id"),
|
||||
"weight_unit": variant.get("weight_unit"),
|
||||
"weight": variant.get("weight")
|
||||
}
|
||||
|
||||
for i, variant_attr in enumerate(shopify_variants_attr_list):
|
||||
if variant.get(variant_attr):
|
||||
attributes[i].update({"attribute_value": get_attribute_value(variant.get(variant_attr), attributes[i])})
|
||||
create_item(shopify_item_variant, warehouse, 0, attributes, template_item.name)
|
||||
|
||||
def get_attribute_value(variant_attr_val, attribute):
|
||||
attribute_value = frappe.db.sql("""select attribute_value from `tabItem Attribute Value`
|
||||
where parent = %s and (abbr = %s or attribute_value = %s)""", (attribute["attribute"], variant_attr_val,
|
||||
variant_attr_val), as_list=1)
|
||||
return attribute_value[0][0] if len(attribute_value)>0 else cint(variant_attr_val)
|
||||
|
||||
def get_item_group(product_type=None):
|
||||
import frappe.utils.nestedset
|
||||
parent_item_group = frappe.utils.nestedset.get_root_of("Item Group")
|
||||
|
||||
if product_type:
|
||||
if not frappe.db.get_value("Item Group", product_type, "name"):
|
||||
item_group = frappe.get_doc({
|
||||
"doctype": "Item Group",
|
||||
"item_group_name": product_type,
|
||||
"parent_item_group": parent_item_group,
|
||||
"is_group": "No"
|
||||
}).insert()
|
||||
return item_group.name
|
||||
else:
|
||||
return product_type
|
||||
else:
|
||||
return parent_item_group
|
||||
|
||||
|
||||
def get_sku(item):
|
||||
if item.get("variants"):
|
||||
return item.get("variants")[0].get("sku")
|
||||
return ""
|
||||
|
||||
def add_to_price_list(item, name):
|
||||
shopify_settings = frappe.db.get_value("Shopify Settings", None, ["price_list", "update_price_in_erpnext_price_list"], as_dict=1)
|
||||
if not shopify_settings.update_price_in_erpnext_price_list:
|
||||
return
|
||||
|
||||
item_price_name = frappe.db.get_value("Item Price",
|
||||
{"item_code": name, "price_list": shopify_settings.price_list}, "name")
|
||||
|
||||
if not item_price_name:
|
||||
frappe.get_doc({
|
||||
"doctype": "Item Price",
|
||||
"price_list": shopify_settings.price_list,
|
||||
"item_code": name,
|
||||
"price_list_rate": item.get("item_price") or item.get("variants")[0].get("price")
|
||||
}).insert()
|
||||
else:
|
||||
item_rate = frappe.get_doc("Item Price", item_price_name)
|
||||
item_rate.price_list_rate = item.get("item_price") or item.get("variants")[0].get("price")
|
||||
item_rate.save()
|
||||
|
||||
def get_item_image(shopify_item):
|
||||
if shopify_item.get("image"):
|
||||
return shopify_item.get("image").get("src")
|
||||
return None
|
||||
|
||||
def get_supplier(shopify_item):
|
||||
if shopify_item.get("vendor"):
|
||||
supplier = frappe.db.sql("""select name from tabSupplier
|
||||
where name = %s or shopify_supplier_id = %s """, (shopify_item.get("vendor"),
|
||||
shopify_item.get("vendor").lower()), as_list=1)
|
||||
|
||||
if not supplier:
|
||||
supplier = frappe.get_doc({
|
||||
"doctype": "Supplier",
|
||||
"supplier_name": shopify_item.get("vendor"),
|
||||
"shopify_supplier_id": shopify_item.get("vendor").lower(),
|
||||
"supplier_group": get_supplier_group()
|
||||
}).insert()
|
||||
return supplier.name
|
||||
else:
|
||||
return shopify_item.get("vendor")
|
||||
else:
|
||||
return ""
|
||||
|
||||
def get_supplier_group():
|
||||
supplier_group = frappe.db.get_value("Supplier Group", _("Shopify Supplier"))
|
||||
if not supplier_group:
|
||||
supplier_group = frappe.get_doc({
|
||||
"doctype": "Supplier Group",
|
||||
"supplier_group_name": _("Shopify Supplier")
|
||||
}).insert()
|
||||
return supplier_group.name
|
||||
return supplier_group
|
||||
|
||||
def get_item_details(shopify_item):
|
||||
item_details = {}
|
||||
|
||||
item_details = frappe.db.get_value("Item", {"shopify_product_id": shopify_item.get("id")},
|
||||
["name", "stock_uom", "item_name"], as_dict=1)
|
||||
|
||||
if item_details:
|
||||
return item_details
|
||||
|
||||
else:
|
||||
item_details = frappe.db.get_value("Item", {"shopify_variant_id": shopify_item.get("id")},
|
||||
["name", "stock_uom", "item_name"], as_dict=1)
|
||||
return item_details
|
||||
|
||||
def is_item_exists(shopify_item, attributes=None, variant_of=None):
|
||||
if variant_of:
|
||||
name = variant_of
|
||||
else:
|
||||
name = frappe.db.get_value("Item", {"item_name": shopify_item.get("item_name")})
|
||||
|
||||
if name:
|
||||
item = frappe.get_doc("Item", name)
|
||||
item.flags.ignore_mandatory=True
|
||||
|
||||
if not variant_of and not item.shopify_product_id:
|
||||
item.shopify_product_id = shopify_item.get("shopify_product_id")
|
||||
item.shopify_variant_id = shopify_item.get("shopify_variant_id")
|
||||
item.save()
|
||||
return True
|
||||
|
||||
if item.shopify_product_id and attributes and attributes[0].get("attribute_value"):
|
||||
if not variant_of:
|
||||
variant_of = frappe.db.get_value("Item",
|
||||
{"shopify_product_id": item.shopify_product_id}, "variant_of")
|
||||
|
||||
# create conditions for all item attributes,
|
||||
# as we are putting condition basis on OR it will fetch all items matching either of conditions
|
||||
# thus comparing matching conditions with len(attributes)
|
||||
# which will give exact matching variant item.
|
||||
|
||||
conditions = ["(iv.attribute='{0}' and iv.attribute_value = '{1}')"\
|
||||
.format(attr.get("attribute"), attr.get("attribute_value")) for attr in attributes]
|
||||
|
||||
conditions = "( {0} ) and iv.parent = it.name ) = {1}".format(" or ".join(conditions), len(attributes))
|
||||
|
||||
parent = frappe.db.sql(""" select * from tabItem it where
|
||||
( select count(*) from `tabItem Variant Attribute` iv
|
||||
where {conditions} and it.variant_of = %s """.format(conditions=conditions) ,
|
||||
variant_of, as_list=1)
|
||||
|
||||
if parent:
|
||||
variant = frappe.get_doc("Item", parent[0][0])
|
||||
variant.flags.ignore_mandatory = True
|
||||
|
||||
variant.shopify_product_id = shopify_item.get("shopify_product_id")
|
||||
variant.shopify_variant_id = shopify_item.get("shopify_variant_id")
|
||||
variant.save()
|
||||
return False
|
||||
|
||||
if item.shopify_product_id and item.shopify_product_id != shopify_item.get("shopify_product_id"):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
else:
|
||||
return False
|
@ -1,527 +0,0 @@
|
||||
[
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Print Settings",
|
||||
"fieldname": "compact_item_print",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "with_letterhead",
|
||||
"label": "Compact Item Print",
|
||||
"modified": "2016-06-06 15:18:17.025602",
|
||||
"name": "Print Settings-compact_item_print",
|
||||
"no_copy": 0,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Customer",
|
||||
"fieldname": "shopify_customer_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "naming_series",
|
||||
"label": "Shopify Customer Id",
|
||||
"modified": "2016-01-15 17:25:28.991818",
|
||||
"name": "Customer-shopify_customer_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Address",
|
||||
"fieldname": "shopify_address_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "fax",
|
||||
"label": "Shopify Address Id",
|
||||
"modified": "2016-01-15 17:50:52.213743",
|
||||
"name": "Address-shopify_address_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Sales Order",
|
||||
"fieldname": "shopify_order_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "title",
|
||||
"label": "Shopify Order Id",
|
||||
"modified": "2016-01-18 09:55:50.764524",
|
||||
"name": "Sales Order-shopify_order_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Item",
|
||||
"fieldname": "shopify_product_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "item_code",
|
||||
"label": "Shopify Product Id",
|
||||
"modified": "2016-01-19 15:44:16.132952",
|
||||
"name": "Item-shopify_product_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Sales Invoice",
|
||||
"fieldname": "shopify_order_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "naming_series",
|
||||
"label": "Shopify Order Id",
|
||||
"modified": "2016-01-19 16:30:12.261797",
|
||||
"name": "Sales Invoice-shopify_order_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Delivery Note",
|
||||
"fieldname": "shopify_order_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "title",
|
||||
"label": "Shopify Order Id",
|
||||
"modified": "2016-01-19 16:30:31.201198",
|
||||
"name": "Delivery Note-shopify_order_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Item",
|
||||
"fieldname": "stock_keeping_unit",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "stock_uom",
|
||||
"label": "Stock Keeping Unit",
|
||||
"modified": "2015-11-10 09:29:10.854943",
|
||||
"name": "Item-stock_keeping_unit",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": "0",
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Item",
|
||||
"fieldname": "sync_with_shopify",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "is_stock_item",
|
||||
"label": "Sync With Shopify",
|
||||
"modified": "2015-10-12 15:54:31.997714",
|
||||
"name": "Item-sync_with_shopify",
|
||||
"no_copy": 0,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Customer",
|
||||
"fieldname": "sync_with_shopify",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "is_frozen",
|
||||
"label": "Sync With Shopify",
|
||||
"modified": "2015-10-01 17:31:55.758826",
|
||||
"name": "Customer-sync_with_shopify",
|
||||
"no_copy": 0,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Item",
|
||||
"fieldname": "shopify_variant_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "item_code",
|
||||
"label": "Variant Id",
|
||||
"modified": "2015-11-09 18:26:50.825858",
|
||||
"name": "Item-shopify_variant_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Item",
|
||||
"fieldname": "sync_qty_with_shopify",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "item_code",
|
||||
"label": "Sync Quantity With Shopify",
|
||||
"modified": "2015-12-29 08:37:46.183295",
|
||||
"name": "Item-sync_qty_with_shopify",
|
||||
"no_copy": 0,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Delivery Note",
|
||||
"fieldname": "shopify_fulfillment_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "title",
|
||||
"label": "Shopify Fulfillment Id",
|
||||
"modified": "2016-01-20 23:50:35.609543",
|
||||
"name": "Delivery Note-shopify_fulfillment_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Supplier",
|
||||
"fieldname": "shopify_supplier_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "supplier_name",
|
||||
"label": "Shopify Supplier Id",
|
||||
"modified": "2016-02-01 15:41:25.818306",
|
||||
"name": "Supplier-shopify_supplier_id",
|
||||
"no_copy": 1,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Item",
|
||||
"fieldname": "shopify_description",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"insert_after": "section_break_11",
|
||||
"label": "shopify_description",
|
||||
"modified": "2016-06-15 12:15:36.325581",
|
||||
"name": "Item-shopify_description",
|
||||
"no_copy": 0,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
}
|
||||
]
|
@ -1,59 +0,0 @@
|
||||
{
|
||||
"customer": {
|
||||
"id": 2324518599,
|
||||
"email": "andrew@wyatt.co.in",
|
||||
"accepts_marketing": false,
|
||||
"created_at": "2016-01-20T17:18:35+05:30",
|
||||
"updated_at": "2016-01-20T17:22:23+05:30",
|
||||
"first_name": "Andrew",
|
||||
"last_name": "Wyatt",
|
||||
"orders_count": 0,
|
||||
"state": "disabled",
|
||||
"total_spent": "0.00",
|
||||
"last_order_id": null,
|
||||
"note": "",
|
||||
"verified_email": true,
|
||||
"multipass_identifier": null,
|
||||
"tax_exempt": false,
|
||||
"tags": "",
|
||||
"last_order_name": null,
|
||||
"default_address": {
|
||||
"id": 2476804295,
|
||||
"first_name": "Andrew",
|
||||
"last_name": "Wyatt",
|
||||
"company": "Wyatt Inc.",
|
||||
"address1": "B-11, Betahouse",
|
||||
"address2": "Street 11, Sector 52",
|
||||
"city": "Manhattan",
|
||||
"province": "New York",
|
||||
"country": "United States",
|
||||
"zip": "10027",
|
||||
"phone": "145-112211",
|
||||
"name": "Andrew Wyatt",
|
||||
"province_code": "NY",
|
||||
"country_code": "US",
|
||||
"country_name": "United States",
|
||||
"default": true
|
||||
},
|
||||
"addresses": [
|
||||
{
|
||||
"id": 2476804295,
|
||||
"first_name": "Andrew",
|
||||
"last_name": "Wyatt",
|
||||
"company": "Wyatt Inc.",
|
||||
"address1": "B-11, Betahouse",
|
||||
"address2": "Street 11, Sector 52",
|
||||
"city": "Manhattan",
|
||||
"province": "New York",
|
||||
"country": "United States",
|
||||
"zip": "10027",
|
||||
"phone": "145-112211",
|
||||
"name": "Andrew Wyatt",
|
||||
"province_code": "NY",
|
||||
"country_code": "US",
|
||||
"country_name": "United States",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
{
|
||||
"product": {
|
||||
"id": 4059739520,
|
||||
"title": "Shopify Test Item",
|
||||
"body_html": "<div>Hold back Spin Medallion-Set of 2</div>\n<div></div>\n<div>Finish: Plated/ Powder Coated</div>\n<div>Material: Iron</div>\n<div>Color Finish: Satin Silver, Brown Oil Rubbed, Roman Bronze</div>\n<div>Qty: 1 Set</div>",
|
||||
"vendor": "Boa casa",
|
||||
"product_type": "Curtain Accessories",
|
||||
"created_at": "2016-01-18T17:16:37+05:30",
|
||||
"handle": "1001624-01",
|
||||
"updated_at": "2016-01-20T17:26:44+05:30",
|
||||
"published_at": "2016-01-18T17:16:37+05:30",
|
||||
"template_suffix": null,
|
||||
"published_scope": "global",
|
||||
"tags": "Category_Curtain Accessories, Type_Holdback",
|
||||
"variants": [{
|
||||
"id": 13917612359,
|
||||
"product_id": 4059739520,
|
||||
"title": "Test BALCK Item",
|
||||
"price": "499.00",
|
||||
"sku": "",
|
||||
"position": 1,
|
||||
"grams": 0,
|
||||
"inventory_policy": "continue",
|
||||
"compare_at_price": null,
|
||||
"fulfillment_service": "manual",
|
||||
"inventory_management": "shopify",
|
||||
"option1": "BLACK",
|
||||
"option2": null,
|
||||
"option3": null,
|
||||
"created_at": "2016-01-18T17:16:37+05:30",
|
||||
"updated_at": "2016-01-20T17:26:44+05:30",
|
||||
"requires_shipping": true,
|
||||
"taxable": true,
|
||||
"barcode": "",
|
||||
"inventory_quantity": -1,
|
||||
"old_inventory_quantity": -1,
|
||||
"image_id": 8539321735,
|
||||
"weight": 0,
|
||||
"weight_unit": "kg"
|
||||
}, {
|
||||
"id": 13917612423,
|
||||
"product_id": 4059739520,
|
||||
"title": "Test BLUE Item",
|
||||
"price": "499.00",
|
||||
"sku": "",
|
||||
"position": 2,
|
||||
"grams": 0,
|
||||
"inventory_policy": "continue",
|
||||
"compare_at_price": null,
|
||||
"fulfillment_service": "manual",
|
||||
"inventory_management": "shopify",
|
||||
"option1": "BLUE",
|
||||
"option2": null,
|
||||
"option3": null,
|
||||
"created_at": "2016-01-18T17:16:37+05:30",
|
||||
"updated_at": "2016-01-20T17:26:44+05:30",
|
||||
"requires_shipping": true,
|
||||
"taxable": true,
|
||||
"barcode": "",
|
||||
"inventory_quantity": -1,
|
||||
"old_inventory_quantity": -1,
|
||||
"image_id": null,
|
||||
"weight": 0,
|
||||
"weight_unit": "kg"
|
||||
}, {
|
||||
"id": 13917612487,
|
||||
"product_id": 4059739520,
|
||||
"title": "Test White Item",
|
||||
"price": "499.00",
|
||||
"sku": "",
|
||||
"position": 3,
|
||||
"grams": 0,
|
||||
"inventory_policy": "continue",
|
||||
"compare_at_price": null,
|
||||
"fulfillment_service": "manual",
|
||||
"inventory_management": "shopify",
|
||||
"option1": "White",
|
||||
"option2": null,
|
||||
"option3": null,
|
||||
"created_at": "2016-01-18T17:16:37+05:30",
|
||||
"updated_at": "2016-01-18T17:16:37+05:30",
|
||||
"requires_shipping": true,
|
||||
"taxable": true,
|
||||
"barcode": "",
|
||||
"inventory_quantity": 0,
|
||||
"old_inventory_quantity": 0,
|
||||
"image_id": null,
|
||||
"weight": 0,
|
||||
"weight_unit": "kg"
|
||||
}],
|
||||
"options": [{
|
||||
"id": 4985027399,
|
||||
"product_id": 4059739520,
|
||||
"name": "Colour",
|
||||
"position": 1,
|
||||
"values": [
|
||||
"BLACK",
|
||||
"BLUE",
|
||||
"White"
|
||||
]
|
||||
}],
|
||||
"images": [{
|
||||
"id": 8539321735,
|
||||
"product_id": 4059739520,
|
||||
"position": 1,
|
||||
"created_at": "2016-01-18T17:16:37+05:30",
|
||||
"updated_at": "2016-01-18T17:16:37+05:30",
|
||||
"src": "https://cdn.shopify.com/s/files/1/1123/0654/products/2015-12-17_6.png?v=1453117597",
|
||||
"variant_ids": [
|
||||
13917612359
|
||||
]
|
||||
}],
|
||||
"image": {
|
||||
"id": 8539321735,
|
||||
"product_id": 4059739520,
|
||||
"position": 1,
|
||||
"created_at": "2016-01-18T17:16:37+05:30",
|
||||
"updated_at": "2016-01-18T17:16:37+05:30",
|
||||
"src": "https://cdn.shopify.com/s/files/1/1123/0654/products/2015-12-17_6.png?v=1453117597",
|
||||
"variant_ids": [
|
||||
13917612359
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,270 +0,0 @@
|
||||
{
|
||||
"order": {
|
||||
"id": 2414345735,
|
||||
"email": "andrew@wyatt.co.in",
|
||||
"closed_at": null,
|
||||
"created_at": "2016-01-20T17:26:39+05:30",
|
||||
"updated_at": "2016-01-20T17:27:15+05:30",
|
||||
"number": 5,
|
||||
"note": "",
|
||||
"token": "660fed25987517b733644a8c9ec7c8e0",
|
||||
"gateway": "manual",
|
||||
"test": false,
|
||||
"total_price": "1018.00",
|
||||
"subtotal_price": "998.00",
|
||||
"total_weight": 0,
|
||||
"total_tax": "0.00",
|
||||
"taxes_included": false,
|
||||
"currency": "INR",
|
||||
"financial_status": "paid",
|
||||
"confirmed": true,
|
||||
"total_discounts": "0.00",
|
||||
"total_line_items_price": "998.00",
|
||||
"cart_token": null,
|
||||
"buyer_accepts_marketing": false,
|
||||
"name": "#1005",
|
||||
"referring_site": null,
|
||||
"landing_site": null,
|
||||
"cancelled_at": null,
|
||||
"cancel_reason": null,
|
||||
"total_price_usd": "15.02",
|
||||
"checkout_token": null,
|
||||
"reference": null,
|
||||
"user_id": 55391175,
|
||||
"location_id": null,
|
||||
"source_identifier": null,
|
||||
"source_url": null,
|
||||
"processed_at": "2016-01-20T17:26:39+05:30",
|
||||
"device_id": null,
|
||||
"browser_ip": null,
|
||||
"landing_site_ref": null,
|
||||
"order_number": 1005,
|
||||
"discount_codes": [],
|
||||
"note_attributes": [],
|
||||
"payment_gateway_names": [
|
||||
"manual"
|
||||
],
|
||||
"processing_method": "manual",
|
||||
"checkout_id": null,
|
||||
"source_name": "shopify_draft_order",
|
||||
"fulfillment_status": "fulfilled",
|
||||
"tax_lines": [],
|
||||
"tags": "",
|
||||
"contact_email": "andrew@wyatt.co.in",
|
||||
"line_items": [
|
||||
{
|
||||
"id": 4125768135,
|
||||
"variant_id": 13917612359,
|
||||
"title": "Shopify Test Item",
|
||||
"quantity": 1,
|
||||
"price": "499.00",
|
||||
"grams": 0,
|
||||
"sku": "",
|
||||
"variant_title": "Roman BALCK 1",
|
||||
"vendor": "Boa casa",
|
||||
"fulfillment_service": "manual",
|
||||
"product_id": 4059739527,
|
||||
"requires_shipping": true,
|
||||
"taxable": true,
|
||||
"gift_card": false,
|
||||
"name": "Roman BALCK 1",
|
||||
"variant_inventory_management": "shopify",
|
||||
"properties": [],
|
||||
"product_exists": true,
|
||||
"fulfillable_quantity": 0,
|
||||
"total_discount": "0.00",
|
||||
"fulfillment_status": "fulfilled",
|
||||
"tax_lines": []
|
||||
},
|
||||
{
|
||||
"id": 4125768199,
|
||||
"variant_id": 13917612423,
|
||||
"title": "Shopify Test Item",
|
||||
"quantity": 1,
|
||||
"price": "499.00",
|
||||
"grams": 0,
|
||||
"sku": "",
|
||||
"variant_title": "Satin BLUE 1",
|
||||
"vendor": "Boa casa",
|
||||
"fulfillment_service": "manual",
|
||||
"product_id": 4059739527,
|
||||
"requires_shipping": true,
|
||||
"taxable": true,
|
||||
"gift_card": false,
|
||||
"name": "Satin BLUE 1",
|
||||
"variant_inventory_management": "shopify",
|
||||
"properties": [],
|
||||
"product_exists": true,
|
||||
"fulfillable_quantity": 0,
|
||||
"total_discount": "0.00",
|
||||
"fulfillment_status": "fulfilled",
|
||||
"tax_lines": []
|
||||
}
|
||||
],
|
||||
"shipping_lines": [
|
||||
{
|
||||
"id": 2108906247,
|
||||
"title": "International Shipping",
|
||||
"price": "20.00",
|
||||
"code": "International Shipping",
|
||||
"source": "shopify",
|
||||
"phone": null,
|
||||
"tax_lines": []
|
||||
}
|
||||
],
|
||||
"billing_address": {
|
||||
"first_name": "Andrew",
|
||||
"address1": "B-11, Betahouse",
|
||||
"phone": "145-112211",
|
||||
"city": "Manhattan",
|
||||
"zip": "10027",
|
||||
"province": "New York",
|
||||
"country": "United States",
|
||||
"last_name": "Wyatt",
|
||||
"address2": "Street 11, Sector 52",
|
||||
"company": "Wyatt Inc.",
|
||||
"latitude": 40.8138912,
|
||||
"longitude": -73.96243270000001,
|
||||
"name": "Andrew Wyatt",
|
||||
"country_code": "US",
|
||||
"province_code": "NY"
|
||||
},
|
||||
"shipping_address": {
|
||||
"first_name": "Andrew",
|
||||
"address1": "B-11, Betahouse",
|
||||
"phone": "145-112211",
|
||||
"city": "Manhattan",
|
||||
"zip": "10027",
|
||||
"province": "New York",
|
||||
"country": "United States",
|
||||
"last_name": "Wyatt",
|
||||
"address2": "Street 11, Sector 52",
|
||||
"company": "Wyatt Inc.",
|
||||
"latitude": 40.8138912,
|
||||
"longitude": -73.96243270000001,
|
||||
"name": "Andrew Wyatt",
|
||||
"country_code": "US",
|
||||
"province_code": "NY"
|
||||
},
|
||||
"fulfillments": [
|
||||
{
|
||||
"id": 1849629255,
|
||||
"order_id": 2414345735,
|
||||
"status": "success",
|
||||
"created_at": "2016-01-20T17:27:15+05:30",
|
||||
"service": "manual",
|
||||
"updated_at": "2016-01-20T17:27:15+05:30",
|
||||
"tracking_company": null,
|
||||
"tracking_number": null,
|
||||
"tracking_numbers": [],
|
||||
"tracking_url": null,
|
||||
"tracking_urls": [],
|
||||
"receipt": {},
|
||||
"line_items": [
|
||||
{
|
||||
"id": 4125768199,
|
||||
"variant_id": 13917612423,
|
||||
"title": "1001624/01",
|
||||
"quantity": 1,
|
||||
"price": "499.00",
|
||||
"grams": 0,
|
||||
"sku": "",
|
||||
"variant_title": "Satin Silver",
|
||||
"vendor": "Boa casa",
|
||||
"fulfillment_service": "manual",
|
||||
"product_id": 4059739527,
|
||||
"requires_shipping": true,
|
||||
"taxable": true,
|
||||
"gift_card": false,
|
||||
"name": "1001624/01 - Satin Silver",
|
||||
"variant_inventory_management": "shopify",
|
||||
"properties": [],
|
||||
"product_exists": true,
|
||||
"fulfillable_quantity": 0,
|
||||
"total_discount": "0.00",
|
||||
"fulfillment_status": "fulfilled",
|
||||
"tax_lines": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 1849628167,
|
||||
"order_id": 2414345735,
|
||||
"status": "success",
|
||||
"created_at": "2016-01-20T17:26:58+05:30",
|
||||
"service": "manual",
|
||||
"updated_at": "2016-01-20T17:26:58+05:30",
|
||||
"tracking_company": null,
|
||||
"tracking_number": null,
|
||||
"tracking_numbers": [],
|
||||
"tracking_url": null,
|
||||
"tracking_urls": [],
|
||||
"receipt": {},
|
||||
"line_items": [
|
||||
{
|
||||
"id": 4125768135,
|
||||
"variant_id": 13917612359,
|
||||
"title": "1001624/01",
|
||||
"quantity": 1,
|
||||
"price": "499.00",
|
||||
"grams": 0,
|
||||
"sku": "",
|
||||
"variant_title": "Roman Bronze",
|
||||
"vendor": "Boa casa",
|
||||
"fulfillment_service": "manual",
|
||||
"product_id": 4059739527,
|
||||
"requires_shipping": true,
|
||||
"taxable": true,
|
||||
"gift_card": false,
|
||||
"name": "1001624/01 - Roman Bronze",
|
||||
"variant_inventory_management": "shopify",
|
||||
"properties": [],
|
||||
"product_exists": true,
|
||||
"fulfillable_quantity": 0,
|
||||
"total_discount": "0.00",
|
||||
"fulfillment_status": "fulfilled",
|
||||
"tax_lines": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"refunds": [],
|
||||
"customer": {
|
||||
"id": 2324518599,
|
||||
"email": "andrew@wyatt.co.in",
|
||||
"accepts_marketing": false,
|
||||
"created_at": "2016-01-20T17:18:35+05:30",
|
||||
"updated_at": "2016-01-20T17:26:39+05:30",
|
||||
"first_name": "Andrew",
|
||||
"last_name": "Wyatt",
|
||||
"orders_count": 1,
|
||||
"state": "disabled",
|
||||
"total_spent": "1018.00",
|
||||
"last_order_id": 2414345735,
|
||||
"note": "",
|
||||
"verified_email": true,
|
||||
"multipass_identifier": null,
|
||||
"tax_exempt": false,
|
||||
"tags": "",
|
||||
"last_order_name": "#1005",
|
||||
"default_address": {
|
||||
"id": 2476804295,
|
||||
"first_name": "Andrew",
|
||||
"last_name": "Wyatt",
|
||||
"company": "Wyatt Inc.",
|
||||
"address1": "B-11, Betahouse",
|
||||
"address2": "Street 11, Sector 52",
|
||||
"city": "Manhattan",
|
||||
"province": "New York",
|
||||
"country": "United States",
|
||||
"zip": "10027",
|
||||
"phone": "145-112211",
|
||||
"name": "Andrew Wyatt",
|
||||
"province_code": "NY",
|
||||
"country_code": "US",
|
||||
"country_name": "United States",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Shopify Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Shopify Settings
|
||||
() => frappe.tests.make('Shopify Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
@ -1,107 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
import unittest, os, json
|
||||
from frappe.utils import cstr, cint
|
||||
from erpnext.erpnext_integrations.connectors.shopify_connection import create_order
|
||||
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_product import make_item
|
||||
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_customer import create_customer
|
||||
from frappe.core.doctype.data_import.data_import import import_doc
|
||||
|
||||
|
||||
class ShopifySettings(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
frappe.set_user("Administrator")
|
||||
|
||||
cls.allow_negative_stock = cint(frappe.db.get_value('Stock Settings', None, 'allow_negative_stock'))
|
||||
if not cls.allow_negative_stock:
|
||||
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 1)
|
||||
|
||||
# use the fixture data
|
||||
import_doc(path=frappe.get_app_path("erpnext", "erpnext_integrations/doctype/shopify_settings/test_data/custom_field.json"))
|
||||
|
||||
frappe.reload_doctype("Customer")
|
||||
frappe.reload_doctype("Sales Order")
|
||||
frappe.reload_doctype("Delivery Note")
|
||||
frappe.reload_doctype("Sales Invoice")
|
||||
|
||||
cls.setup_shopify()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
if not cls.allow_negative_stock:
|
||||
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0)
|
||||
|
||||
@classmethod
|
||||
def setup_shopify(cls):
|
||||
shopify_settings = frappe.get_doc("Shopify Settings")
|
||||
shopify_settings.taxes = []
|
||||
|
||||
shopify_settings.update({
|
||||
"app_type": "Private",
|
||||
"shopify_url": "test.myshopify.com",
|
||||
"api_key": "17702c7c4452b9c5d235240b6e7a39da",
|
||||
"password": "17702c7c4452b9c5d235240b6e7a39da",
|
||||
"shared_secret": "17702c7c4452b9c5d235240b6e7a39da",
|
||||
"price_list": "_Test Price List",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"cash_bank_account": "Cash - _TC",
|
||||
"account": "Cash - _TC",
|
||||
"customer_group": "_Test Customer Group",
|
||||
"cost_center": "Main - _TC",
|
||||
"taxes": [
|
||||
{
|
||||
"shopify_tax": "International Shipping",
|
||||
"tax_account":"Legal Expenses - _TC"
|
||||
}
|
||||
],
|
||||
"enable_shopify": 0,
|
||||
"sales_order_series": "SO-",
|
||||
"sync_sales_invoice": 1,
|
||||
"sales_invoice_series": "SINV-",
|
||||
"sync_delivery_note": 1,
|
||||
"delivery_note_series": "DN-"
|
||||
}).save(ignore_permissions=True)
|
||||
|
||||
cls.shopify_settings = shopify_settings
|
||||
|
||||
def test_order(self):
|
||||
# Create Customer
|
||||
with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_customer.json")) as shopify_customer:
|
||||
shopify_customer = json.load(shopify_customer)
|
||||
create_customer(shopify_customer.get("customer"), self.shopify_settings)
|
||||
|
||||
# Create Item
|
||||
with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_item.json")) as shopify_item:
|
||||
shopify_item = json.load(shopify_item)
|
||||
make_item("_Test Warehouse - _TC", shopify_item.get("product"))
|
||||
|
||||
# Create Order
|
||||
with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_order.json")) as shopify_order:
|
||||
shopify_order = json.load(shopify_order)
|
||||
|
||||
create_order(shopify_order.get("order"), self.shopify_settings, False, company="_Test Company")
|
||||
|
||||
sales_order = frappe.get_doc("Sales Order", {"shopify_order_id": cstr(shopify_order.get("order").get("id"))})
|
||||
|
||||
self.assertEqual(cstr(shopify_order.get("order").get("id")), sales_order.shopify_order_id)
|
||||
|
||||
# Check for customer
|
||||
shopify_order_customer_id = cstr(shopify_order.get("order").get("customer").get("id"))
|
||||
sales_order_customer_id = frappe.get_value("Customer", sales_order.customer, "shopify_customer_id")
|
||||
|
||||
self.assertEqual(shopify_order_customer_id, sales_order_customer_id)
|
||||
|
||||
# Check sales invoice
|
||||
sales_invoice = frappe.get_doc("Sales Invoice", {"shopify_order_id": sales_order.shopify_order_id})
|
||||
self.assertEqual(sales_invoice.rounded_total, sales_order.rounded_total)
|
||||
|
||||
# Check delivery note
|
||||
delivery_note_count = frappe.db.sql("""select count(*) from `tabDelivery Note`
|
||||
where shopify_order_id = %s""", sales_order.shopify_order_id)[0][0]
|
||||
|
||||
self.assertEqual(delivery_note_count, len(shopify_order.get("order").get("fulfillments")))
|
@ -1,133 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2015-10-05 16:55:20.455371",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "shopify_tax",
|
||||
"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": "Shopify Tax/Shipping Title",
|
||||
"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": 1,
|
||||
"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_2",
|
||||
"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,
|
||||
"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,
|
||||
"fieldname": "tax_account",
|
||||
"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": "ERPNext Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Account",
|
||||
"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": 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-04-09 11:36:49.272815",
|
||||
"modified_by": "Administrator",
|
||||
"module": "ERPNext Integrations",
|
||||
"name": "Shopify Tax Account",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, 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 ShopifyTaxAccount(Document):
|
||||
pass
|
@ -1,103 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-04-10 17:06:22.697427",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 0,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "webhook_id",
|
||||
"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": "Webhook ID",
|
||||
"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": "method",
|
||||
"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": "Method",
|
||||
"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-04-11 12:43:09.456449",
|
||||
"modified_by": "Administrator",
|
||||
"module": "ERPNext Integrations",
|
||||
"name": "Shopify Webhook Detail",
|
||||
"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
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# -*- 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 ShopifyWebhookDetail(Document):
|
||||
pass
|
@ -40,16 +40,6 @@
|
||||
"onboard": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"dependencies": "",
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"label": "Shopify Settings",
|
||||
"link_to": "Shopify Settings",
|
||||
"link_type": "DocType",
|
||||
"onboard": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
@ -113,4 +103,4 @@
|
||||
"pin_to_bottom": 0,
|
||||
"pin_to_top": 0,
|
||||
"shortcuts": []
|
||||
}
|
||||
}
|
||||
|
@ -30,16 +30,6 @@
|
||||
"onboard": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"dependencies": "",
|
||||
"hidden": 0,
|
||||
"is_query_report": 0,
|
||||
"label": "Shopify Settings",
|
||||
"link_to": "Shopify Settings",
|
||||
"link_type": "DocType",
|
||||
"onboard": 0,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"dependencies": "",
|
||||
"hidden": 0,
|
||||
@ -79,4 +69,4 @@
|
||||
"pin_to_bottom": 0,
|
||||
"pin_to_top": 0,
|
||||
"shortcuts": []
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,6 @@ scheduler_events = {
|
||||
"erpnext.projects.doctype.project.project.hourly_reminder",
|
||||
"erpnext.projects.doctype.project.project.collect_project_status",
|
||||
"erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts",
|
||||
"erpnext.erpnext_integrations.connectors.shopify_connection.sync_old_orders",
|
||||
"erpnext.support.doctype.service_level_agreement.service_level_agreement.set_service_level_agreement_variance"
|
||||
],
|
||||
"hourly_long": [
|
||||
|
@ -45,7 +45,6 @@ erpnext.patches.v11_0.make_location_from_warehouse
|
||||
erpnext.patches.v11_0.make_asset_finance_book_against_old_entries
|
||||
erpnext.patches.v11_0.check_buying_selling_in_currency_exchange
|
||||
erpnext.patches.v11_0.move_item_defaults_to_child_table_for_multicompany #02-07-2018 #19-06-2019
|
||||
erpnext.patches.v11_0.refactor_erpnext_shopify #2018-09-07
|
||||
erpnext.patches.v11_0.rename_overproduction_percent_field
|
||||
erpnext.patches.v11_0.update_backflush_subcontract_rm_based_on_bom
|
||||
erpnext.patches.v11_0.inter_state_field_for_gst
|
||||
@ -143,7 +142,6 @@ erpnext.patches.v12_0.add_variant_of_in_item_attribute_table
|
||||
erpnext.patches.v12_0.rename_bank_account_field_in_journal_entry_account
|
||||
erpnext.patches.v12_0.create_default_energy_point_rules
|
||||
erpnext.patches.v12_0.set_produced_qty_field_in_sales_order_for_work_order
|
||||
erpnext.patches.v12_0.set_default_shopify_app_type
|
||||
erpnext.patches.v12_0.set_cwip_and_delete_asset_settings
|
||||
erpnext.patches.v12_0.set_expense_account_in_landed_cost_voucher_taxes
|
||||
erpnext.patches.v12_0.replace_accounting_with_accounts_in_home_settings
|
||||
@ -244,7 +242,6 @@ erpnext.patches.v13_0.updates_for_multi_currency_payroll
|
||||
erpnext.patches.v13_0.update_reason_for_resignation_in_employee
|
||||
execute:frappe.delete_doc("Report", "Quoted Item Comparison")
|
||||
erpnext.patches.v13_0.update_member_email_address
|
||||
erpnext.patches.v13_0.update_custom_fields_for_shopify
|
||||
erpnext.patches.v13_0.updates_for_multi_currency_payroll
|
||||
erpnext.patches.v13_0.create_leave_policy_assignment_based_on_employee_current_leave_policy
|
||||
erpnext.patches.v13_0.update_pos_closing_entry_in_merge_log
|
||||
@ -299,3 +296,4 @@ erpnext.patches.v13_0.update_subscription_status_in_memberships
|
||||
erpnext.patches.v13_0.update_amt_in_work_order_required_items
|
||||
erpnext.patches.v13_0.update_export_type_for_gst
|
||||
erpnext.patches.v13_0.update_tds_check_field #3
|
||||
erpnext.patches.v13_0.shopify_deprecation_warning
|
@ -1,43 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.installer import remove_from_installed_apps
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_settings')
|
||||
frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_tax_account')
|
||||
frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_log')
|
||||
frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_webhook_detail')
|
||||
|
||||
if 'erpnext_shopify' in frappe.get_installed_apps():
|
||||
remove_from_installed_apps('erpnext_shopify')
|
||||
|
||||
frappe.delete_doc("Module Def", 'erpnext_shopify')
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
frappe.db.sql("truncate `tabShopify Log`")
|
||||
|
||||
setup_app_type()
|
||||
else:
|
||||
disable_shopify()
|
||||
|
||||
def setup_app_type():
|
||||
try:
|
||||
shopify_settings = frappe.get_doc("Shopify Settings")
|
||||
shopify_settings.app_type = 'Private'
|
||||
shopify_settings.update_price_in_erpnext_price_list = 0 if getattr(shopify_settings, 'push_prices_to_shopify', None) else 1
|
||||
shopify_settings.flags.ignore_mandatory = True
|
||||
shopify_settings.ignore_permissions = True
|
||||
shopify_settings.save()
|
||||
except Exception:
|
||||
frappe.db.set_value("Shopify Settings", None, "enable_shopify", 0)
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
|
||||
def disable_shopify():
|
||||
# due to frappe.db.set_value wrongly written and enable_shopify being default 1
|
||||
# Shopify Settings isn't properly configured and leads to error
|
||||
shopify = frappe.get_doc('Shopify Settings')
|
||||
|
||||
if shopify.app_type == "Public" or shopify.app_type == None or \
|
||||
(shopify.enable_shopify and not (shopify.shopify_url or shopify.api_key)):
|
||||
frappe.db.set_value("Shopify Settings", None, "enable_shopify", 0)
|
@ -1,6 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('erpnext_integrations', 'doctype', 'shopify_settings')
|
||||
frappe.db.set_value('Shopify Settings', None, 'app_type', 'Private')
|
10
erpnext/patches/v13_0/shopify_deprecation_warning.py
Normal file
10
erpnext/patches/v13_0/shopify_deprecation_warning.py
Normal file
@ -0,0 +1,10 @@
|
||||
import click
|
||||
|
||||
|
||||
def execute():
|
||||
|
||||
click.secho(
|
||||
"Shopify Integration is moved to a separate app and will be removed from ERPNext in version-14.\n"
|
||||
"Please install the app to continue using the integration: https://github.com/frappe/ecommerce_integrations",
|
||||
fg="yellow",
|
||||
)
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import setup_custom_fields
|
||||
|
||||
def execute():
|
||||
if frappe.db.get_single_value('Shopify Settings', 'enable_shopify'):
|
||||
setup_custom_fields()
|
Loading…
Reference in New Issue
Block a user