예제 #1
0
    def unregister_webhooks(self):
        deleted_webhooks = []
        for d in self.webhooks:
            with self.get_shopify_session(temp=True):
                if not Webhook.exists(d.webhook_id):
                    deleted_webhooks.append(d)
                    continue

            try:
                existing_webhooks = self.get_webhooks(d.webhook_id)
            except Exception as e:
                make_shopify_log(status="Error", exception=e, rollback=True)
                continue

            for webhook in existing_webhooks:
                try:
                    webhook.destroy()
                except Exception as e:
                    make_shopify_log(status="Error",
                                     exception=e,
                                     rollback=True)
                else:
                    deleted_webhooks.append(d)

        for d in deleted_webhooks:
            self.remove(d)
예제 #2
0
def cancel_shopify_order(shop_name: str, order: "Order", log_id: str = str()):
    """
	Cancel all sales documents if a Shopify order is cancelled.

	Args:
		shop_name (str): The name of the Shopify configuration for the store.
		order (Order): The Shopify order data.
		log_id (str, optional): The ID of an existing Shopify Log.
			Defaults to an empty string.
	"""

    frappe.set_user("Administrator")
    frappe.flags.log_id = log_id

    doctypes = ["Delivery Note", "Sales Invoice", "Sales Order"]
    for doctype in doctypes:
        doc = get_shopify_document(shop_name=shop_name,
                                   doctype=doctype,
                                   order=order)
        if not doc:
            continue

        # recursively cancel all Shopify documents
        if doc.docstatus == 1:
            try:
                # ignore document links to Shopify Payout while cancelling
                doc.flags.ignore_links = True
                doc.cancel()
            except Exception as e:
                make_shopify_log(status="Error",
                                 response_data=order.to_dict(),
                                 exception=e,
                                 rollback=True)

        # update the financial status in all linked Shopify Payouts
        payout_transactions = frappe.get_all(
            "Shopify Payout Transaction",
            filters={
                frappe.scrub(doctype):
                doc.name,
                "source_order_financial_status":
                ["!=", order.attributes.get("financial_status")]
            })

        for transaction in payout_transactions:
            frappe.db.set_value(
                "Shopify Payout Transaction", transaction.name,
                "source_order_financial_status",
                frappe.unscrub(order.attributes.get("financial_status")))
예제 #3
0
def create_shopify_delivery(shop_name: str,
                            shopify_order: "Order",
                            sales_order: "SalesOrder" = None,
                            log_id: str = str(),
                            rollback: bool = False):
    """
	Create Delivery Note documents for each Shopify delivery.

	Args:
		shop_name (str): The name of the Shopify configuration for the store.
		shopify_order (Order): The Shopify order data.
		sales_order (SalesOrder, optional): The reference Sales Order document for the
			Shopify order. Defaults to None.
		log_id (str, optional): The ID of an existing Shopify Log. Defaults to an empty string.
		rollback (bool, optional): If an error occurs while processing the order, all
			transactions will be rolled back, if this field is `True`. Defaults to False.

	Returns:
		list: The list of created Delivery Note documents, if any, otherwise an empty list.
	"""

    if not shopify_order.attributes.get("fulfillments"):
        return []
    if not sales_order:
        sales_order = get_shopify_document(shop_name=shop_name,
                                           doctype="Sales Order",
                                           order=shopify_order)
    if not sales_order or sales_order.docstatus != 1:
        return []

    frappe.flags.log_id = log_id
    try:
        delivery_notes = create_delivery_notes(shop_name, shopify_order,
                                               sales_order)
    except Exception as e:
        make_shopify_log(status="Error",
                         response_data=shopify_order.to_dict(),
                         exception=e,
                         rollback=rollback)
        return []
    else:
        make_shopify_log(status="Success",
                         response_data=shopify_order.to_dict())
        return delivery_notes
예제 #4
0
def create_shopify_invoice(shop_name: str,
                           shopify_order: "Order",
                           sales_order: "SalesOrder",
                           log_id: str = str()):
    """
	Create a Sales Invoice document for a Shopify order. If the Shopify order is refunded
	and a submitted Sales Invoice exists, make a sales return against the invoice.

	Args:
		shop_name (str): The name of the Shopify configuration for the store.
		shopify_order (Order): The Shopify order data.
		sales_order (SalesOrder, optional): The reference Sales Order document for the
			Shopify order. Defaults to None.
		log_id (str, optional): The ID of an existing Shopify Log. Defaults to an empty string.

	Returns:
		SalesInvoice: The created Sales Invoice document, if any, otherwise None.
	"""

    if not shopify_order.attributes.get("financial_status") in [
            "paid", "partially_refunded", "refunded"
    ]:
        return

    frappe.flags.log_id = log_id
    try:
        sales_invoice = create_sales_invoice(shop_name, shopify_order,
                                             sales_order)
        if sales_invoice and sales_invoice.docstatus == 1:
            create_sales_return(
                shop_name=shop_name,
                shopify_order_id=shopify_order.id,
                shopify_financial_status=shopify_order.attributes.get(
                    "financial_status"),
                sales_invoice=sales_invoice)
    except Exception as e:
        make_shopify_log(status="Error",
                         response_data=shopify_order.to_dict(),
                         exception=e)
    else:
        make_shopify_log(status="Success",
                         response_data=shopify_order.to_dict())
        return sales_invoice
예제 #5
0
    def register_webhooks(self):
        from shopify_integration.webhooks import get_webhook_url, SHOPIFY_WEBHOOK_TOPIC_MAPPER

        for topic in SHOPIFY_WEBHOOK_TOPIC_MAPPER:
            with self.get_shopify_session(temp=True):
                webhook = Webhook.create({
                    "topic": topic,
                    "address": get_webhook_url(),
                    "format": "json"
                })

            if webhook.is_valid():
                self.append("webhooks", {
                    "webhook_id": webhook.id,
                    "method": webhook.topic
                })
            else:
                make_shopify_log(status="Error",
                                 response_data=webhook.to_dict(),
                                 exception=webhook.errors.full_messages(),
                                 rollback=True)
예제 #6
0
def sync_items_from_shopify(shop_name: str):
	"""
	For a given Shopify store, sync all active products and create Item
	documents for missing products.

	Args:
		shop_name (str): The name of the Shopify configuration for the store.
	"""

	frappe.set_user("Administrator")
	shopify_settings: "ShopifySettings" = frappe.get_doc("Shopify Settings", shop_name)

	try:
		shopify_items = shopify_settings.get_products(status="active")
	except Exception as e:
		make_shopify_log(status="Error", exception=e, rollback=True)
		return

	for shopify_item in shopify_items:
		shopify_item: Product
		make_item(shopify_settings, shopify_item)
예제 #7
0
def create_shopify_order(shop_name: str,
                         shopify_order: "Order",
                         log_id: str = str()):
    """
	Create a Sales Order document for a Shopify order.

	Args:
		shop_name (str): The name of the Shopify configuration for the store.
		shopify_order (Order): The Shopify order data.
		log_id (str, optional): The ID of an existing Shopify Log. Defaults
			to an empty string.

	Returns:
		SalesOrder: The created Sales Order document, if any, otherwise None.
	"""

    from shopify_integration.customers import validate_customer
    from shopify_integration.products import validate_item

    frappe.flags.log_id = log_id

    existing_so = get_shopify_document(shop_name=shop_name,
                                       doctype="Sales Order",
                                       order=shopify_order)
    if existing_so:
        existing_so: "SalesOrder"
        make_shopify_log(status="Skipped",
                         response_data=shopify_order.to_dict())
        return existing_so

    try:
        validate_customer(shop_name, shopify_order)
        validate_item(shop_name, shopify_order)
        sales_order = create_sales_order(shop_name, shopify_order)
    except Exception as e:
        make_shopify_log(status="Error",
                         response_data=shopify_order.to_dict(),
                         exception=e)
    else:
        make_shopify_log(status="Success",
                         response_data=shopify_order.to_dict())
        return sales_order
예제 #8
0
def prepare_sales_invoice(shop_name: str, order: "Order", log_id: str = str()):
    """
	Webhook endpoint to process invoices for Shopify orders.

	Args:
		shop_name (str): The name of the Shopify configuration for the store.
		order (Order): The Shopify order data.
		log_id (str, optional): The ID of an existing Shopify Log.
			Defaults to an empty string.
	"""

    from shopify_integration.orders import create_shopify_documents

    frappe.set_user("Administrator")
    frappe.flags.log_id = log_id

    try:
        sales_order = get_shopify_document(shop_name=shop_name,
                                           doctype="Sales Order",
                                           order=order)
        if not sales_order:
            create_shopify_documents(shop_name, order, log_id)
            sales_order = get_shopify_document(shop_name=shop_name,
                                               doctype="Sales Order",
                                               order=order)

        if sales_order:
            sales_order: "SalesOrder"
            create_sales_invoice(shop_name, order, sales_order)
            make_shopify_log(status="Success", response_data=order.to_dict())
        else:
            make_shopify_log(status="Skipped", response_data=order.to_dict())
    except Exception as e:
        make_shopify_log(status="Error",
                         response_data=order.to_dict(),
                         exception=e,
                         rollback=True)