Skip to content

Commit

Permalink
feat: Integrate Flowkana into ERPNext (#1127)
Browse files Browse the repository at this point in the history
* feat: flowkana integration with erpnext

* feat: flowkana in erpnext

* Update erpnext/erpnext_integrations/doctype/flowkana_settings/flowkana_settings.py

Co-authored-by: sahil28297 <[email protected]>
  • Loading branch information
rvpasari and sahil28297 authored Apr 9, 2021
1 parent fb960fa commit 4ae8e29
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 3 deletions.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

frappe.ui.form.on('Flowkana Settings', {
// refresh: function(frm) {

// }
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"creation": "2021-03-19 03:53:40.417764",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"enable_flowkana_section",
"enable_flowkana",
"api_key",
"api_value",
"load_url_in_new_tab",
"url_tab"
],
"fields": [
{
"fieldname": "enable_flowkana_section",
"fieldtype": "Section Break",
"label": "Enable Flowkana"
},
{
"default": "0",
"fieldname": "enable_flowkana",
"fieldtype": "Check",
"label": "Enable Flowkana"
},
{
"depends_on": "eval: doc.enable_flowkana == 1",
"fieldname": "api_key",
"fieldtype": "Data",
"label": "API Key"
},
{
"depends_on": "eval: doc.enable_flowkana == 1",
"fieldname": "api_value",
"fieldtype": "Data",
"label": "API Value"
},
{
"default": "0",
"depends_on": "eval: doc.enable_flowkana == 1",
"fieldname": "load_url_in_new_tab",
"fieldtype": "Check",
"label": "Load URL in new tab"
},
{
"depends_on": "eval: doc.enable_flowkana == 1",
"fieldname": "url_tab",
"fieldtype": "Data",
"label": "URL Tab"
}
],
"issingle": 1,
"modified": "2021-03-19 04:07:51.319530",
"modified_by": "Administrator",
"module": "ERPNext Integrations",
"name": "Flowkana Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
import datetime
import requests
import json
from six import text_type
from frappe.model.document import Document

class FlowkanaSettings(Document):

def validate(self):
self.check_fulfillment_partner()
self.toggle_status()

def toggle_status(self):
frappe.db.set_value("Fulfillment Partner", "Flowkana", "enable_flowkana", self.enable_flowkana)

def check_fulfillment_partner(self):
"""
Create a fulfillment partner in case they don't exist.
"""
if self.enable_flowkana and not frappe.db.exists("Fulfillment Partner", "Flowkana"):
partner = frappe.get_doc({
"doctype": "Fulfillment Partner",
"partner_name": "Flowkana",
"enable": 1
}).save()

def send_delivery_request_to_flowkana(sales_order):
"""
Ping flowkana with sales order details and map response to an integration request.
Args:
sales_order_name (string): name of the sales order that needs to be sent to flowkana
"""
#create line items
item_list = []
for item in sales_order.items:
ivt_id = frappe.get_value("Item", item.item_code, "ivt_id")
line_item = {
"attributes": {
"ivt_id": ivt_id,
"test_batch_id": item.batch_no,
"external_item_code": item.item_code,
"unit_quantity": item.qty,
"unit_price": item.rate
}
}
item_list.append(line_item)

#prepare response json
request_json = {
"data": {
"attributes": {
"external_order_id": sales_order.name,
"customer_name": sales_order.customer,
"customer_license": sales_order.license,
"delivery_date": str(sales_order.delivery_date),
"note": "Test Note"
},
"relationships": {
"order_line_items": item_list
}
}
}

#create integration request
integration_request = frappe.new_doc("Integration Request")
integration_request.update({
"integration_type": "Host",
"integration_request_service": "Flowkana",
"status": "Queued",
"data": json.dumps(request_json, default=json_handler),
"reference_doctype": "Sales Order",
"reference_docname": sales_order.name
})
integration_request.save(ignore_permissions=True)

#fetch and prepare headers from flowkana settings, flag error if missing data
flowkana_settings = frappe.get_cached_doc("Flowkana Settings")
if not flowkana_settings.get("url_tab"):
frappe.throw(_("Please provide an endpoint to send data to."))
if not flowkana_settings.get("api_key", 0.0):
frappe.throw(_("Please enter API Key in flowkana settings."))
if not flowkana_settings.get("api_value", 0.0):
frappe.throw(_("Please enter API Value in flowkana settings."))

headers = {
flowkana_settings.get("api_key"): flowkana_settings.get("api_value")
}

print("request_json: ", request_json)

#ping flowkana with requisite headers and data
response = requests.post(
flowkana_settings.get("url_tab"),
headers=headers,
json=request_json)
response_data = response.json()

if response.status_code not in [200, 201, 202]:
frappe.throw("The response has the following errors: {0}".format(response_data.get("errors"),""))
return

#mark integration request status as queued, update status to queued
integration_request.output = json.dumps(response_data, default=json_handler)
integration_request.save(ignore_permissions=True)

def json_handler(obj):
if isinstance(obj, (datetime.date, datetime.timedelta, datetime.datetime)):
return text_type(obj)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals

# import frappe
import unittest

class TestFlowkanaSettings(unittest.TestCase):
pass
9 changes: 8 additions & 1 deletion erpnext/selling/doctype/sales_order/sales_order.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"company",
"transaction_date",
"delivery_date",
"fulfillment_partner",
"po_no",
"po_date",
"tax_id",
Expand Down Expand Up @@ -1257,12 +1258,18 @@
"fieldtype": "Check",
"label": "Advance Received",
"read_only": 1
},
{
"fieldname": "fulfillment_partner",
"fieldtype": "Link",
"label": "Fulfillment Partner",
"options": "Fulfillment Partner"
}
],
"icon": "fa fa-file-text",
"idx": 105,
"is_submittable": 1,
"modified": "2021-01-14 03:20:54.326989",
"modified": "2021-03-19 04:08:31.995032",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
Expand Down
10 changes: 10 additions & 0 deletions erpnext/selling/doctype/sales_order/sales_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import frappe
import json
import calendar
import requests
import frappe.utils
from frappe.utils import cstr, flt, getdate, cint, nowdate, add_days, get_link_to_form, comma_and
from frappe import _
Expand All @@ -14,10 +15,12 @@
from erpnext.stock.stock_balance import update_bin_qty, get_reserved_qty
from frappe.desk.notifications import clear_doctype_notifications
from frappe.contacts.doctype.address.address import get_company_address
from frappe.integrations.utils import create_payment_gateway, create_request_log
from erpnext.controllers.selling_controller import SellingController
from frappe.automation.doctype.auto_repeat.auto_repeat import get_next_schedule_date
from erpnext.selling.doctype.customer.customer import check_credit_limit
from erpnext.stock.doctype.item.item import get_item_defaults
from erpnext.erpnext_integrations.doctype.flowkana_settings.flowkana_settings import send_delivery_request_to_flowkana
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
from erpnext.manufacturing.doctype.production_plan.production_plan import get_items_for_material_requests
from erpnext.accounts.doctype.sales_invoice.sales_invoice import validate_inter_company_party, update_linked_doc,\
Expand Down Expand Up @@ -189,6 +192,13 @@ def on_submit(self):
from erpnext.accounts.doctype.pricing_rule.utils import update_coupon_code_count
update_coupon_code_count(self.coupon_code,'used')

flowkana_settings = frappe.get_cached_doc("Flowkana Settings")

#send delivery request to flowkana if enabled by user
if flowkana_settings.enable_flowkana and self.fulfillment_partner == "Flowkana":
send_delivery_request_to_flowkana(self)


def on_cancel(self):
super(SalesOrder, self).on_cancel()

Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt

frappe.ui.form.on('Fulfillment Partner', {
// refresh: function(frm) {

// }
});
48 changes: 48 additions & 0 deletions erpnext/stock/doctype/fulfillment_partner/fulfillment_partner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"autoname": "field:partner_name",
"creation": "2021-03-19 04:02:49.718866",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"partner_name",
"enable"
],
"fields": [
{
"default": "0",
"fieldname": "enable",
"fieldtype": "Check",
"label": "Enable"
},
{
"fieldname": "partner_name",
"fieldtype": "Data",
"label": "Partner Name",
"unique": 1
}
],
"modified": "2021-03-19 04:05:27.925753",
"modified_by": "Administrator",
"module": "Stock",
"name": "Fulfillment Partner",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
10 changes: 10 additions & 0 deletions erpnext/stock/doctype/fulfillment_partner/fulfillment_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, 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 FulfillmentPartner(Document):
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals

# import frappe
import unittest

class TestFulfillmentPartner(unittest.TestCase):
pass
16 changes: 14 additions & 2 deletions erpnext/stock/doctype/item/item.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@
"publish_in_hub",
"hub_category_to_publish",
"hub_warehouse",
"synced_with_hub"
"synced_with_hub",
"flowkana_details_section",
"ivt_id"
],
"fields": [
{
Expand Down Expand Up @@ -1115,14 +1117,24 @@
"fieldtype": "Table",
"label": "Shipping Information",
"options": "Shipping Information"
},
{
"fieldname": "flowkana_details_section",
"fieldtype": "Section Break",
"label": "Flowkana Details"
},
{
"fieldname": "ivt_id",
"fieldtype": "Data",
"label": "Inventory ID"
}
],
"has_web_view": 1,
"icon": "fa fa-tag",
"idx": 2,
"image_field": "image",
"max_attachments": 1,
"modified": "2021-02-02 00:19:02.360290",
"modified": "2021-03-30 00:55:05.858803",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",
Expand Down

0 comments on commit 4ae8e29

Please sign in to comment.