Skip to content

Commit

Permalink
fix: update order with shipstation store information (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alchez authored Oct 26, 2022
1 parent f22f120 commit 0adde63
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 16 deletions.
29 changes: 21 additions & 8 deletions shipstation_integration/customer.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
from typing import TYPE_CHECKING

import frappe
from frappe.utils import parse_addr
from frappe.utils import getdate, parse_addr

if TYPE_CHECKING:
from erpnext.selling.doctype.sales_order.sales_order import SalesOrder
from frappe.contacts.doctype.address.address import Address
from frappe.contacts.doctype.contact.contact import Contact
from shipstation.models import ShipStationAddress, ShipStationOrder
from shipstation_integration.shipstation_integration.doctype.shipstation_store.shipstation_store import (
ShipstationStore,
)


def update_customer_details(existing_so: str, order: "ShipStationOrder"):
def update_customer_details(
existing_so: str, order: "ShipStationOrder", store: "ShipstationStore"
):
existing_so_doc: "SalesOrder" = frappe.get_doc("Sales Order", existing_so)

email_id, user_name = parse_addr(existing_so_doc.amazon_customer)
if email_id:
contact = create_contact(order, email_id)
existing_so_doc.contact_person = contact.name

existing_so_doc.shipstation_order_id = order.order_id
existing_so_doc.has_pii = True
existing_so_doc.update(
{
"shipstation_order_id": order.order_id,
"shipstation_store_name": store.store_name,
"shipstation_customer_notes": getattr(order, "customer_notes", None),
"shipstation_internal_notes": getattr(order, "internal_notes", None),
"marketplace_order_id": order.order_number,
"delivery_date": getdate(order.ship_date),
"has_pii": True,
"integration_doctype": "Shipstation Settings",
"integration_doc": store.parent,
}
)

if order.bill_to and order.bill_to.street1:
if existing_so_doc.customer_address:
Expand Down Expand Up @@ -106,10 +122,7 @@ def create_customer(order: "ShipStationOrder"):
)

customer_name = (
order.customer_email
or order.customer_id
or order.ship_to.name
or customer_id
order.customer_email or order.customer_id or order.ship_to.name or customer_id
)

if frappe.db.exists("Customer", customer_name):
Expand Down
19 changes: 19 additions & 0 deletions shipstation_integration/public/js/delivery_note.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
frappe.ui.form.on("Delivery Note", {
refresh: frm => {
shipping.shipstation(frm);

if (frm.doc.docstatus === 1 && frm.doc.shipstation_order_id) {
frm.add_custom_button(__('Fetch Shipment'), () => {
frappe.call({
method: "shipstation_integration.shipping.fetch_shipment",
args: {
"delivery_note": frm.doc.name
},
freeze: true,
callback: function(r) {
if (r.message) {
frappe.msgprint(`A shipment was fetched from Shipstation and created at ${r.message}`)
} else {
frappe.msgprint(`No new shipment(s) were found against Shipstation ID: ${frm.doc.shipstation_order_id.bold()}`)
}
}
});
}).removeClass("btn-default").addClass("btn-primary");
}
}
})
7 changes: 5 additions & 2 deletions shipstation_integration/shipments.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,11 @@ def create_erpnext_shipment(shipment: "ShipStationOrder", store: "ShipstationSto
if store.create_delivery_note:
delivery_note = create_delivery_note(shipment, sales_invoice)

shipment_doc = None
if store.create_shipment:
shipment = create_shipment(shipment, store, delivery_note)
shipment_doc = create_shipment(shipment, store, delivery_note)

return shipment_doc


def cancel_voided_shipments(shipment: "ShipStationOrder"):
Expand Down Expand Up @@ -281,4 +284,4 @@ def create_shipment(
shipment_doc.submit()
frappe.db.commit()

return shipment
return shipment_doc
91 changes: 85 additions & 6 deletions shipstation_integration/shipping.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@
import frappe
from frappe import _
from frappe.contacts.doctype.address.address import Address
from frappe.utils.data import get_datetime, today
from frappe.utils import get_datetime, get_link_to_form, today
from frappe.utils.file_manager import save_file

from shipstation_integration.shipments import (
cancel_voided_shipments,
create_erpnext_shipment,
)

if TYPE_CHECKING:
from frappe.core.doctype.file.file import File
from shipstation_integration.shipstation_integration.doctype.shipstation_settings.shipstation_settings import (
ShipstationSettings
ShipstationSettings,
)
from shipstation_integration.shipstation_integration.doctype.shipstation_store.shipstation_store import (
ShipstationStore,
)


Expand Down Expand Up @@ -105,7 +113,7 @@ def _create_shipping_label(doc: str, values: str, user: str = str()):
if isinstance(shipment, dict) and shipment.get("ExceptionMessage"):
process_error(
shipment,
message="There was an error generating the label. Please contact your administrator."
message="There was an error generating the label. Please contact your administrator.",
)

pdf = BytesIO(base64.b64decode(shipment.label_data))
Expand All @@ -125,7 +133,7 @@ def attach_shipping_label(pdf: BytesIO, doctype: str, name: str):
if not isinstance(pdf, BytesIO):
process_error(
pdf,
message="There was an error attaching the label. Please contact your administrator."
message="There was an error attaching the label. Please contact your administrator.",
)

file: "File" = save_file(
Expand All @@ -134,7 +142,7 @@ def attach_shipping_label(pdf: BytesIO, doctype: str, name: str):
dt=doctype,
dn=name,
folder="Home/Shipstation Labels",
is_private=True
is_private=True,
)

return file
Expand Down Expand Up @@ -179,7 +187,7 @@ def get_shipstation_address(address: Address, person_name: str = str()):
state=address.state,
postal_code=address.pincode,
phone=address.phone,
country=country_code
country=country_code,
)


Expand Down Expand Up @@ -229,3 +237,74 @@ def get_shipstation_settings(doc: str) -> Optional[str]:
def push_attachment_update(attachment: "File", user: str):
js = f"if (cur_frm.doc.name =='{attachment.attached_to_name}') {{cur_frm.refresh();}}"
frappe.publish_realtime("eval_js", js, user=user or frappe.session.user)


@frappe.whitelist()
def fetch_shipment(delivery_note: str):
delivery_note = frappe.get_doc("Delivery Note", delivery_note)

if (
delivery_note.integration_doctype == "Shipstation Settings"
and delivery_note.integration_doc
):
settings = [delivery_note.integration_doc]
else:
settings = frappe.get_all("Shipstation Settings", pluck="name")

for setting in settings:
sss_doc = frappe.get_doc("Shipstation Settings", setting)
client = sss_doc.client()
client.timeout = 60

parameters = {
"order_id": delivery_note.shipstation_order_id,
"include_shipment_items": True,
}

try:
shipments: List["ShipStationOrder"] = client.list_shipments(
parameters=parameters
)
except Exception as e:
frappe.log_error(
title="Error while fetching Shipstation shipment", message=e
)
return

created_shipments = []
for shipment in shipments:
# sometimes Shipstation will return `None` in the response
if not shipment:
continue

existing_shipments = frappe.get_all(
"Shipment", filters={"shipment_id": shipment.shipment_id}
)

if existing_shipments:
continue

if shipment.voided:
cancel_voided_shipments(shipment)
else:
store_id = shipment.advanced_options.store_id
store: "ShipstationStore" = next(
(
store
for store in sss_doc.shipstation_stores
if store.store_id == store_id
),
None,
)

delivery_note.db_set("shipstation_shipment_id", shipment.shipment_id)
shipment = create_erpnext_shipment(shipment, store)
if shipment:
created_shipments.append(
get_link_to_form(shipment.doctype, shipment.name)
)

if created_shipments:
frappe.msgprint(
_("Created Shipment(s): {0}").format(", ".join(created_shipments))
)

0 comments on commit 0adde63

Please sign in to comment.