Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: item variant sync #212

Merged
merged 12 commits into from
Nov 11, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
"erpnext_to_shopify_sync_section",
"upload_erpnext_items",
"update_shopify_item_on_update",
"column_break_34",
"sync_new_item_as_draft",
"upload_variants_as_items",
"inventory_sync_section",
"warehouse",
"update_erpnext_stock_levels_to_shopify",
Expand Down Expand Up @@ -327,12 +330,29 @@
"hidden": 1,
"label": "Last Inventory Sync",
"read_only": 1
},
{
"fieldname": "column_break_34",
"fieldtype": "Column Break"
},
{
"default": "0",
"description": "Caution: Only 3 attributes will be accepted by Shopify",
"fieldname": "upload_variants_as_items",
"fieldtype": "Check",
"label": "Upload ERPNext Variants as Shopify Items"
},
{
"default": "1",
"fieldname": "sync_new_item_as_draft",
rtdany10 marked this conversation as resolved.
Show resolved Hide resolved
"fieldtype": "Check",
"label": "Sync New Items as Draft"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2022-02-16 11:34:11.966616",
"modified": "2022-10-29 11:29:09.606865",
"modified_by": "Administrator",
"module": "shopify",
"name": "Shopify Setting",
Expand Down
116 changes: 95 additions & 21 deletions ecommerce_integrations/shopify/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def upload_erpnext_item(doc, method=None):
New items are pushed to shopify and changes to existing items are
updated depending on what is configured in "Shopify Setting" doctype.
"""
item = doc # alias for readability
template_item = item = doc # alias for readability
# a new item recieved from ecommerce_integrations is being inserted
if item.flags.from_integration:
return
Expand All @@ -342,51 +342,125 @@ def upload_erpnext_item(doc, method=None):
if frappe.flags.in_import:
return

if doc.has_variants or doc.variant_of:
msgprint(_("Item with variants or template items can not be uploaded to Shopify."))
if item.has_variants:
# msgprint(_("Template items can not be uploaded to Shopify."))
rtdany10 marked this conversation as resolved.
Show resolved Hide resolved
return

if doc.variant_of and not setting.upload_variants_as_items:
msgprint(_("Enable variant sync in setting to upload item to Shopify."))
return

if item.variant_of:
template_item = frappe.get_doc("Item", item.variant_of)

product_id = frappe.db.get_value(
"Ecommerce Item",
{"erpnext_item_code": item.name, "integration": MODULE_NAME},
{"erpnext_item_code": template_item.name, "integration": MODULE_NAME},
"integration_item_code",
)
is_new_product = not bool(product_id)

if is_new_product:

product = Product()
product.published = False
product.status = "draft"
product.status = "draft" if setting.sync_new_item_as_draft else "active"

map_erpnext_item_to_shopify(shopify_product=product, erpnext_item=item)
map_erpnext_item_to_shopify(shopify_product=product, erpnext_item=template_item)
is_successful = product.save()

if is_successful:
update_default_variant_properties(
product, sku=item.item_code, price=item.standard_rate, is_stock_item=item.is_stock_item,
product,
sku=template_item.item_code,
price=template_item.standard_rate,
is_stock_item=template_item.is_stock_item,
)
if item.variant_of:
product.options = []
product.variants = []
variant_attributes = {"title": template_item.item_name}
max_index_range = min(3, len(template_item.attributes))
for i in range(0, max_index_range):
attr = template_item.attributes[i]
product.options.append(
{
"name": attr.attribute,
"values": frappe.db.get_all(
"Item Attribute Value", {"parent": attr.attribute}, pluck="attribute_value"
),
}
)
try:
variant_attributes[f"option{i+1}"] = item.attributes[i].attribute_value
except IndexError:
frappe.throw(_("Shopify Error: Missing value for attribute {}").format(attr.attribute))
product.variants.append(Variant(variant_attributes))

product.save() # push variant

ecom_item = frappe.get_doc(
{
"doctype": "Ecommerce Item",
"erpnext_item_code": item.name,
"integration": MODULE_NAME,
"integration_item_code": str(product.id),
"variant_id": str(product.variants[0].id),
"sku": str(product.variants[0].sku),
}
)
ecom_item.insert()
ecom_items = list(set([item, template_item]))
for d in ecom_items:
ecom_item = frappe.get_doc(
{
"doctype": "Ecommerce Item",
"erpnext_item_code": d.name,
"integration": MODULE_NAME,
"integration_item_code": str(product.id),
"variant_id": "" if d.has_variants else str(product.variants[0].id),
rtdany10 marked this conversation as resolved.
Show resolved Hide resolved
"sku": "" if d.has_variants else str(product.variants[0].sku),
"has_variants": d.has_variants,
"variant_of": d.variant_of,
}
)
ecom_item.insert()

write_upload_log(status=is_successful, product=product, item=item)
elif setting.update_shopify_item_on_update:
product = Product.find(product_id)
if product:
map_erpnext_item_to_shopify(shopify_product=product, erpnext_item=item)
update_default_variant_properties(product, is_stock_item=item.is_stock_item)
map_erpnext_item_to_shopify(shopify_product=product, erpnext_item=template_item)
update_default_variant_properties(product, is_stock_item=template_item.is_stock_item)

if item.variant_of:
product.options = []
variant_attributes = {}
max_index_range = min(3, len(template_item.attributes))
for i in range(0, max_index_range):
attr = template_item.attributes[i]
product.options.append(
{
"name": attr.attribute,
"values": frappe.db.get_all(
"Item Attribute Value", {"parent": attr.attribute}, pluck="attribute_value"
),
}
)
try:
variant_attributes[f"option{i+1}"] = item.attributes[i].attribute_value
except IndexError:
frappe.throw(_("Shopify Error: Missing value for attribute {}").format(attr.attribute))
product.variants.append(Variant(variant_attributes))

is_successful = product.save()
if is_successful and item.variant_of:
variant_product_id = frappe.db.get_value(
"Ecommerce Item",
{"erpnext_item_code": item.name, "integration": MODULE_NAME},
"integration_item_code",
)
if not variant_product_id:
frappe.get_doc(
{
"doctype": "Ecommerce Item",
"erpnext_item_code": item.name,
"integration": MODULE_NAME,
"integration_item_code": str(product.id),
"variant_id": str(product.variants[-1].id),
"sku": str(product.variants[-1].sku),
"variant_of": item.variant_of,
}
).insert()

write_upload_log(status=is_successful, product=product, item=item, action="Updated")


Expand Down