dvdl16 / woocommerce_fusion

WooCommerce connector for ERPNext v15
https://finfoot.tech
GNU General Public License v3.0
29 stars 24 forks source link

[BUG] WooCommerce Products set to Variable but without Attributes fails to sync #113

Open dvdl16 opened 3 months ago

dvdl16 commented 3 months ago

Current Behavior

WooCommerce Products set to Variable but without Attributes fails to sync

Steps To Reproduce

  1. Create a Variable product in WooCommerce
  2. Leave Attributes blank
  3. Sync in ERPNext
  4. See Error Log

image

Expected Behavior

If possible, the Item should still be created, perhaps with a placeholder attribute?

Anything else?

Error Log

  File "apps/woocommerce_fusion/woocommerce_fusion/tasks/sync_items.py", line 246, in sync_wc_product_with_erpnext_item
    self.create_item(self.woocommerce_product)
      self = <woocommerce_fusion.tasks.sync_items.SynchroniseItem object at 0x7fbeef1c2890>
  File "apps/woocommerce_fusion/woocommerce_fusion/tasks/sync_items.py", line 413, in create_item
    item.insert()
      self = <woocommerce_fusion.tasks.sync_items.SynchroniseItem object at 0x7fbeef1c2890>
      wc_product = <WooCommerceProduct: wordpress.demo.puentedigital.net~36>
      wc_server = <WooCommerceServer: wordpress.demo.puentedigital.net>
      item = <Item: 36>
      wc_attributes = []
      row = <ItemWooCommerceServer: f1ner3ajb3 parent=36>
  File "apps/frappe/frappe/model/document.py", line 291, in insert
    self.run_before_save_methods()
      self = <Item: 36>
      ignore_permissions = None
      ignore_links = None
      ignore_if_duplicate = False
      ignore_mandatory = None
      set_name = None
      set_child_names = True
  File "apps/frappe/frappe/model/document.py", line 1091, in run_before_save_methods
    self.run_method("validate")
      self = <Item: 36>
  File "apps/frappe/frappe/model/document.py", line 962, in run_method
    out = Document.hook(fn)(self, *args, **kwargs)
      self = <Item: 36>
      method = 'validate'
      args = ()
      kwargs = {}
      fn = <function Document.run_method.<locals>.fn at 0x7fbeed2cfc40>
  File "apps/frappe/frappe/model/document.py", line 1322, in composer
    return composed(self, method, *args, **kwargs)
      self = <Item: 36>
      args = ()
      kwargs = {}
      hooks = [<function apply at 0x7fbeecd9f880>, <function check_for_running_deletion_job at 0x7fbeecda94e0>]
      method = 'validate'
      doc_events = {'*': {'on_update': ['frappe.desk.notifications.clear_doctype_notifications', 'frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions', 'frappe.core.doctype.file.utils.attach_files_to_document', 'frappe.automation.doctype.assignment_rule.assignment_rule.apply', 'frappe.automation.doctype.assignment_rule.assignment_rule.update_due_date', 'frappe.core.doctype.user_type.user_type.apply_permissions_for_non_standard_user_type'], 'after_rename': ['frappe.desk.notifications.clear_doctype_notifications'], 'on_cancel': ['frappe.desk.notifications.clear_doctype_notifications', 'frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions', 'frappe.automation.doctype.assignment_rule.assignment_rule.apply'], 'on_trash': ['frappe.desk.notifications.clear_doctype_notifications', 'frappe.workflow.doctype.workflow_action.workflow_action.process_workflow_actions'], 'on_update_after_submit': ['frappe.workflow.doctype.workflow_action.workflow_action.process_w...
      handler = 'erpnext.setup.doctype.transaction_deletion_record.transaction_deletion_record.check_for_running_deletion_job'
      composed = <function Document.hook.<locals>.compose.<locals>.runner at 0x7fbeecda9440>
      compose = <function Document.hook.<locals>.compose at 0x7fbeecefac00>
      f = <function Document.run_method.<locals>.fn at 0x7fbeed2cfc40>
  File "apps/frappe/frappe/model/document.py", line 1304, in runner
    add_to_return_value(self, fn(self, *args, **kwargs))
      self = <Item: 36>
      method = 'validate'
      args = ()
      kwargs = {}
      add_to_return_value = <function Document.hook.<locals>.add_to_return_value at 0x7fbeed2cf060>
      fn = <function Document.run_method.<locals>.fn at 0x7fbeed2cfc40>
      hooks = (<function apply at 0x7fbeecd9f880>, <function check_for_running_deletion_job at 0x7fbeecda94e0>)
  File "apps/frappe/frappe/model/document.py", line 959, in fn
    return method_object(*args, **kwargs)
      self = <Item: 36>
      args = ()
      kwargs = {}
      method_object = <bound method Item.validate of <Item: 36>>
      method = 'validate'
  File "apps/erpnext/erpnext/stock/doctype/item/item.py", line 203, in validate
    self.validate_attributes()
      self = <Item: 36>
  File "apps/erpnext/erpnext/stock/doctype/item/item.py", line 917, in validate_attributes
    frappe.throw(_("Attribute table is mandatory"))
      self = <Item: 36>
      attributes = []
  File "apps/frappe/frappe/__init__.py", line 645, in throw
    msgprint(
      msg = 'Attribute table is mandatory'
      exc = <class 'frappe.exceptions.ValidationError'>
      title = None
      is_minimizable = False
      wide = False
      as_list = False
      primary_action = None
  File "apps/frappe/frappe/__init__.py", line 610, in msgprint
    _raise_exception()
      msg = 'Attribute table is mandatory'
      title = None
      raise_exception = <class 'frappe.exceptions.ValidationError'>
      as_table = False
      as_list = False
      indicator = 'red'
      alert = False
      primary_action = None
      is_minimizable = False
      wide = False
      realtime = False
      sys = <module 'sys' (built-in)>
      _raise_exception = <function msgprint.<locals>._raise_exception at 0x7fbeecefaca0>
      inspect = <module 'inspect' from '/usr/local/lib/python3.11/inspect.py'>
      out = {'message': 'Attribute table is mandatory', 'title': 'Message', 'indicator': 'red', 'raise_exception': 1, '__frappe_exc_id': 'a3ee524ba58f2f08d7a7b695a47870eb5d0a9ed599affc78a455210f'}
  File "apps/frappe/frappe/__init__.py", line 561, in _raise_exception
    raise exc
      exc = ValidationError('Attribute table is mandatory')
      inspect = <module 'inspect' from '/usr/local/lib/python3.11/inspect.py'>
      msg = 'Attribute table is mandatory'
      out = {'message': 'Attribute table is mandatory', 'title': 'Message', 'indicator': 'red', 'raise_exception': 1, '__frappe_exc_id': 'a3ee524ba58f2f08d7a7b695a47870eb5d0a9ed599affc78a455210f'}
      raise_exception = <class 'frappe.exceptions.ValidationError'>
frappe.exceptions.ValidationError: Attribute table is mandatory

Environment and Versions

Frappe CRM: v1.19.0
ERPNext: v15.33.2
Frappe Framework: v15.39.0
Frappe HR: v15.26.0
Frappe LMS: v2.1.0
Payments: v0.0.1
WooCommerce Fusion: v1.7.2

Operating System

Windows

What browsers are you seeing the problem on?

Chrome, Firefox

MartinFulgueiras commented 2 months ago

Also, when attributes are created in ERPnext, the PO sync creates the item, but overrides the attributes in ERPNext leaving the last (item) created as the only attribute in the list. For this you need to allow the option to override the attributes on settings. I believe it should add the attributes to the list and not erase the ones already in.