mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 07:54:46 +00:00
Woocommerce Integration (#13217)
* WIP for WooCommerce Integration * WIP for WooComm Integration * WIP WooComm * Added Woocommerce Settings * Woocommerce Settings Enable Sync Makes fields mandatory * Woocommerce whitelisted endpoints * [Clean Up] Woocommerce Settings * Verify Webhook Data * Fix Verify Webhook * WIP WooComm * WIP and working few modules * Customer creating partially * Customer creation successful * Refactored Customer code * WIP Address * Fixed address and customer bug. Now working fine * WIP for products. Creation of items successful * Handling json for product * Products creating and updating properly * Custom checkbox for required doctypes * Product feature fully completed * WIP orders * Sales order working properly * Orders mapping successfully * New version Customer Working Properly * Items creation properly * Working on sales order * Orders comming successfully * Bug fixes * Fixed date format for delivery date * Code Cleanup * Woo setting page modified * Fixed minor bug * Fixes * Minimum Viable Product * Cleanup * Removed duplicate file from erpnext config * Added more default changes to woo settings * Fixes as per required * Fixes * Bug fix * few changes and fix * Fixing * Fixes with test * Added Test for Woocommerce - Emulates request * Fix woocommerce test * fix woocommerce test * verify_request: py3 ready * Codacy fixes * WooCommerce Integration Docs * Codacy changes * Codacy fixes * User set tax account * Fixes for account * Fix for warehouse issue * Docs updated * Codacy fix * Updated Docs * Minor changes * Tested added for repeat order and cleanup * Minor change * docs and gifs renamed according to convention * Doc updated
This commit is contained in:
committed by
Rushabh Mehta
parent
b60a52b194
commit
df83148d7c
@@ -0,0 +1,206 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, base64, hashlib, hmac, json
|
||||
import datetime
|
||||
from frappe import _
|
||||
|
||||
|
||||
def verify_request():
|
||||
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
||||
sig = base64.b64encode(
|
||||
hmac.new(
|
||||
woocommerce_settings.secret.encode('utf8'),
|
||||
frappe.request.data,
|
||||
hashlib.sha256
|
||||
).digest()
|
||||
)
|
||||
|
||||
if frappe.request.data and \
|
||||
frappe.get_request_header("X-Wc-Webhook-Signature") and \
|
||||
not sig == bytes(frappe.get_request_header("X-Wc-Webhook-Signature").encode()):
|
||||
frappe.throw(_("Unverified Webhook Data"))
|
||||
frappe.set_user(woocommerce_settings.modified_by)
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def order():
|
||||
|
||||
verify_request()
|
||||
|
||||
if frappe.request.data:
|
||||
fd = json.loads(frappe.request.data)
|
||||
else:
|
||||
return "success"
|
||||
|
||||
event = frappe.get_request_header("X-Wc-Webhook-Event")
|
||||
|
||||
if event == "created":
|
||||
|
||||
raw_billing_data = fd.get("billing")
|
||||
customer_woo_com_email = raw_billing_data.get("email")
|
||||
|
||||
if frappe.get_value("Customer",{"woocommerce_email": customer_woo_com_email}):
|
||||
# Edit
|
||||
link_customer_and_address(raw_billing_data,1)
|
||||
else:
|
||||
# Create
|
||||
link_customer_and_address(raw_billing_data,0)
|
||||
|
||||
|
||||
items_list = fd.get("line_items")
|
||||
for item in items_list:
|
||||
|
||||
item_woo_com_id = item.get("product_id")
|
||||
|
||||
if frappe.get_value("Item",{"woocommerce_id": item_woo_com_id}):
|
||||
#Edit
|
||||
link_item(item,1)
|
||||
else:
|
||||
link_item(item,0)
|
||||
|
||||
|
||||
customer_name = raw_billing_data.get("first_name") + " " + raw_billing_data.get("last_name")
|
||||
|
||||
new_sales_order = frappe.new_doc("Sales Order")
|
||||
new_sales_order.customer = customer_name
|
||||
|
||||
created_date = fd.get("date_created").split("T")
|
||||
new_sales_order.transaction_date = created_date[0]
|
||||
|
||||
new_sales_order.po_no = fd.get("id")
|
||||
new_sales_order.woocommerce_id = fd.get("id")
|
||||
new_sales_order.naming_series = "SO-"
|
||||
|
||||
placed_order_date = created_date[0]
|
||||
raw_date = datetime.datetime.strptime(placed_order_date, "%Y-%m-%d")
|
||||
raw_delivery_date = frappe.utils.add_to_date(raw_date,days = 7)
|
||||
order_delivery_date_str = raw_delivery_date.strftime('%Y-%m-%d')
|
||||
order_delivery_date = str(order_delivery_date_str)
|
||||
|
||||
new_sales_order.delivery_date = order_delivery_date
|
||||
|
||||
for item in items_list:
|
||||
woocomm_item_id = item.get("product_id")
|
||||
found_item = frappe.get_doc("Item",{"woocommerce_id": woocomm_item_id})
|
||||
|
||||
ordered_items_tax = item.get("total_tax")
|
||||
|
||||
default_set_company = frappe.get_doc("Global Defaults")
|
||||
company = default_set_company.default_company
|
||||
found_company = frappe.get_doc("Company",{"name":company})
|
||||
company_abbr = found_company.abbr
|
||||
|
||||
new_sales_order.append("items",{
|
||||
"item_code": found_item.item_code,
|
||||
"item_name": found_item.item_name,
|
||||
"description": found_item.item_name,
|
||||
"delivery_date":order_delivery_date,
|
||||
"uom": "Nos",
|
||||
"qty": item.get("quantity"),
|
||||
"rate": item.get("price"),
|
||||
"warehouse": "Stores" + " - " + company_abbr
|
||||
})
|
||||
|
||||
add_tax_details(new_sales_order,ordered_items_tax,"Ordered Item tax",0)
|
||||
|
||||
# shipping_details = fd.get("shipping_lines") # used for detailed order
|
||||
shipping_total = fd.get("shipping_total")
|
||||
shipping_tax = fd.get("shipping_tax")
|
||||
|
||||
add_tax_details(new_sales_order,shipping_tax,"Shipping Tax",1)
|
||||
add_tax_details(new_sales_order,shipping_total,"Shipping Total",1)
|
||||
|
||||
new_sales_order.submit()
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
def link_customer_and_address(raw_billing_data,customer_status):
|
||||
|
||||
if customer_status == 0:
|
||||
# create
|
||||
customer = frappe.new_doc("Customer")
|
||||
address = frappe.new_doc("Address")
|
||||
|
||||
if customer_status == 1:
|
||||
# Edit
|
||||
customer_woo_com_email = raw_billing_data.get("email")
|
||||
customer = frappe.get_doc("Customer",{"woocommerce_email": customer_woo_com_email})
|
||||
old_name = customer.customer_name
|
||||
|
||||
full_name = str(raw_billing_data.get("first_name"))+ " "+str(raw_billing_data.get("last_name"))
|
||||
customer.customer_name = full_name
|
||||
customer.woocommerce_email = str(raw_billing_data.get("email"))
|
||||
customer.save()
|
||||
frappe.db.commit()
|
||||
|
||||
if customer_status == 1:
|
||||
frappe.rename_doc("Customer", old_name, full_name)
|
||||
address = frappe.get_doc("Address",{"woocommerce_email":customer_woo_com_email})
|
||||
customer = frappe.get_doc("Customer",{"woocommerce_email": customer_woo_com_email})
|
||||
|
||||
address.address_line1 = raw_billing_data.get("address_1", "Not Provided")
|
||||
address.address_line2 = raw_billing_data.get("address_2", "Not Provided")
|
||||
address.city = raw_billing_data.get("city", "Not Provided")
|
||||
address.woocommerce_email = str(raw_billing_data.get("email"))
|
||||
address.address_type = "Shipping"
|
||||
address.country = frappe.get_value("Country", filters={"code":raw_billing_data.get("country", "IN").lower()})
|
||||
address.state = raw_billing_data.get("state")
|
||||
address.pincode = str(raw_billing_data.get("postcode"))
|
||||
address.phone = str(raw_billing_data.get("phone"))
|
||||
address.email_id = str(raw_billing_data.get("email"))
|
||||
|
||||
address.append("links", {
|
||||
"link_doctype": "Customer",
|
||||
"link_name": customer.customer_name
|
||||
})
|
||||
|
||||
address.save()
|
||||
frappe.db.commit()
|
||||
|
||||
if customer_status == 1:
|
||||
|
||||
address = frappe.get_doc("Address",{"woocommerce_email":customer_woo_com_email})
|
||||
old_address_title = address.name
|
||||
new_address_title = customer.customer_name+"-billing"
|
||||
address.address_title = customer.customer_name
|
||||
address.save()
|
||||
|
||||
frappe.rename_doc("Address",old_address_title,new_address_title)
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
def link_item(item_data,item_status):
|
||||
|
||||
if item_status == 0:
|
||||
#Create Item
|
||||
item = frappe.new_doc("Item")
|
||||
|
||||
if item_status == 1:
|
||||
#Edit Item
|
||||
item_woo_com_id = item_data.get("product_id")
|
||||
item = frappe.get_doc("Item",{"woocommerce_id": item_woo_com_id})
|
||||
|
||||
item.item_name = str(item_data.get("name"))
|
||||
item.item_code = "woocommerce - " + str(item_data.get("product_id"))
|
||||
item.woocommerce_id = str(item_data.get("product_id"))
|
||||
item.item_group = "WooCommerce Products"
|
||||
item.save()
|
||||
frappe.db.commit()
|
||||
|
||||
def add_tax_details(sales_order,price,desc,status):
|
||||
|
||||
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
||||
|
||||
if status == 0:
|
||||
# Product taxes
|
||||
account_head_type = woocommerce_settings.tax_account
|
||||
|
||||
if status == 1:
|
||||
# Shipping taxes
|
||||
account_head_type = woocommerce_settings.f_n_f_account
|
||||
|
||||
sales_order.append("taxes",{
|
||||
"charge_type":"Actual",
|
||||
"account_head": account_head_type,
|
||||
"tax_amount": price,
|
||||
"description": desc
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Woocommerce Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Woocommerce Settings
|
||||
() => frappe.tests.make('Woocommerce Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
class TestWoocommerceSettings(unittest.TestCase):
|
||||
pass
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Woocommerce Settings', {
|
||||
refresh (frm) {
|
||||
frm.trigger("add_button_generate_secret");
|
||||
frm.trigger("check_enabled");
|
||||
frm.set_query("tax_account", ()=>{
|
||||
return {
|
||||
"filters": {
|
||||
"company": frappe.defaults.get_default("company"),
|
||||
"is_group": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
enable_sync (frm) {
|
||||
frm.trigger("check_enabled");
|
||||
},
|
||||
|
||||
add_button_generate_secret(frm) {
|
||||
frm.add_custom_button(__('Generate Secret'), () => {
|
||||
frappe.confirm(
|
||||
__("Apps using current key won't be able to access, are you sure?"),
|
||||
() => {
|
||||
frappe.call({
|
||||
type:"POST",
|
||||
method:"erpnext.erpnext_integrations.doctype.woocommerce_settings.woocommerce_settings.generate_secret",
|
||||
}).done(() => {
|
||||
frm.reload_doc();
|
||||
}).fail(() => {
|
||||
frappe.msgprint(__("Could not generate Secret"));
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
check_enabled (frm) {
|
||||
frm.set_df_property("woocommerce_server_url", "reqd", frm.doc.enable_sync);
|
||||
frm.set_df_property("api_consumer_key", "reqd", frm.doc.enable_sync);
|
||||
frm.set_df_property("api_consumer_secret", "reqd", frm.doc.enable_sync);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,465 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-02-12 15:10:05.495713",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "enable_sync",
|
||||
"fieldtype": "Check",
|
||||
"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": "Enable Sync",
|
||||
"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": "sb_00",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"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": "woocommerce_server_url",
|
||||
"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": "Woocommerce Server URL",
|
||||
"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": "secret",
|
||||
"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": "Secret",
|
||||
"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": "cb_00",
|
||||
"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": "api_consumer_key",
|
||||
"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": "API consumer key",
|
||||
"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": "api_consumer_secret",
|
||||
"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": "API consumer secret",
|
||||
"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": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "sb_accounting_details",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Accounting Details",
|
||||
"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": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Tax 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
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_10",
|
||||
"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": "f_n_f_account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Freight and Forwarding 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
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "endpoints",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Endpoints",
|
||||
"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": "endpoint",
|
||||
"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": "Endpoint",
|
||||
"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": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-03-23 16:57:20.880513",
|
||||
"modified_by": "Administrator",
|
||||
"module": "ERPNext Integrations",
|
||||
"name": "Woocommerce Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
# -*- 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 import _
|
||||
from frappe.model.document import Document
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
class WoocommerceSettings(Document):
|
||||
def validate(self):
|
||||
self.validate_settings()
|
||||
self.create_delete_custom_fields()
|
||||
self.create_webhook_url()
|
||||
|
||||
def create_delete_custom_fields(self):
|
||||
if self.enable_sync:
|
||||
# create
|
||||
create_custom_field_id_and_check_status = False
|
||||
create_custom_field_email_check = False
|
||||
names = ["Customer-woocommerce_id","Sales Order-woocommerce_id","Item-woocommerce_id","Address-woocommerce_id"]
|
||||
names_check_box = ["Customer-woocommerce_check","Sales Order-woocommerce_check","Item-woocommerce_check","Address-woocommerce_check"]
|
||||
email_names = ["Customer-woocommerce_email","Address-woocommerce_email"]
|
||||
|
||||
for i in zip(names,names_check_box):
|
||||
|
||||
if not frappe.get_value("Custom Field",{"name":i[0]}) or not frappe.get_value("Custom Field",{"name":i[1]}):
|
||||
create_custom_field_id_and_check_status = True
|
||||
break;
|
||||
|
||||
|
||||
if create_custom_field_id_and_check_status:
|
||||
names = ["Customer","Sales Order","Item","Address"]
|
||||
for name in names:
|
||||
custom = frappe.new_doc("Custom Field")
|
||||
custom.dt = name
|
||||
custom.label = "woocommerce_id"
|
||||
custom.read_only = 1
|
||||
custom.save()
|
||||
|
||||
custom = frappe.new_doc("Custom Field")
|
||||
custom.dt = name
|
||||
custom.label = "woocommerce_check"
|
||||
custom.fieldtype = "Check"
|
||||
custom.read_only = 1
|
||||
custom.save()
|
||||
|
||||
for i in email_names:
|
||||
|
||||
if not frappe.get_value("Custom Field",{"name":i}):
|
||||
create_custom_field_email_check = True
|
||||
break;
|
||||
|
||||
if create_custom_field_email_check:
|
||||
names = ["Customer","Address"]
|
||||
for name in names:
|
||||
custom = frappe.new_doc("Custom Field")
|
||||
custom.dt = name
|
||||
custom.label = "woocommerce_email"
|
||||
custom.read_only = 1
|
||||
custom.save()
|
||||
|
||||
if not frappe.get_value("Item Group",{"name": "WooCommerce Products"}):
|
||||
item_group = frappe.new_doc("Item Group")
|
||||
item_group.item_group_name = "WooCommerce Products"
|
||||
item_group.parent_item_group = "All Item Groups"
|
||||
item_group.save()
|
||||
|
||||
|
||||
elif not self.enable_sync:
|
||||
# delete
|
||||
names = ["Customer-woocommerce_id","Sales Order-woocommerce_id","Item-woocommerce_id","Address-woocommerce_id"]
|
||||
names_check_box = ["Customer-woocommerce_check","Sales Order-woocommerce_check","Item-woocommerce_check","Address-woocommerce_check"]
|
||||
email_names = ["Customer-woocommerce_email","Address-woocommerce_email"]
|
||||
for name in names:
|
||||
frappe.delete_doc("Custom Field",name)
|
||||
|
||||
for name in names_check_box:
|
||||
frappe.delete_doc("Custom Field",name)
|
||||
|
||||
for name in email_names:
|
||||
frappe.delete_doc("Custom Field",name)
|
||||
|
||||
frappe.delete_doc("Item Group","WooCommerce Products")
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
def validate_settings(self):
|
||||
if self.enable_sync:
|
||||
if not self.secret:
|
||||
self.set("secret", frappe.generate_hash())
|
||||
|
||||
if not self.woocommerce_server_url:
|
||||
frappe.throw(_("Please enter Woocommerce Server URL"))
|
||||
|
||||
if not self.api_consumer_key:
|
||||
frappe.throw(_("Please enter API Consumer Key"))
|
||||
|
||||
if not self.api_consumer_secret:
|
||||
frappe.throw(_("Please enter API Consumer Secret"))
|
||||
|
||||
def create_webhook_url(self):
|
||||
endpoint = "/api/method/erpnext.erpnext_integrations.connectors.woocommerce_connection.order"
|
||||
|
||||
try:
|
||||
url = frappe.request.url
|
||||
except RuntimeError:
|
||||
# for CI Test to work
|
||||
url = "http://localhost:8000"
|
||||
|
||||
server_url = '{uri.scheme}://{uri.netloc}'.format(
|
||||
uri=urlparse(url)
|
||||
)
|
||||
|
||||
delivery_url = server_url + endpoint
|
||||
self.endpoint = delivery_url
|
||||
|
||||
@frappe.whitelist()
|
||||
def generate_secret():
|
||||
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
|
||||
woocommerce_settings.secret = frappe.generate_hash()
|
||||
woocommerce_settings.save()
|
||||
Reference in New Issue
Block a user