def update_item_qty_handler(doc, site_doc, api_map, headers, silent=False): logs = [] success = False qty = get_item_qty(doc) # Cannot find product id -> cannot sync if (not doc.get(OC_PROD_ID)): sync_info(logs, 'Product ID for Opencart is missing', stop=True, silent=silent, error=True) data = [{ "product_id": doc.get(OC_PROD_ID), "quantity": str(cint(qty)) }] # Push qty to opencart res = oc_requests(site_doc.get('server_base_url'), headers, api_map, 'Product Quantity', stop=False, data=data) if res: # Not successful if (not res.get('success')): sync_info(logs, 'Quantity for product %s not updated on Opencart. Error: %s' %(doc.get('name'), res.get('error')), stop=False, silent=silent, error=True) else: success = True sync_info(logs, 'Quantity for product %s successfully updated on Opencart'%doc.get('name'), stop=False, silent=silent) return { 'success': success, 'logs': logs }
def sync_all_items(server_base_url, api_map, header_key, header_value, silent=False): # Header headers = {} headers[header_key] = header_value # Query for items that has synced time < modified time items = frappe.db.sql("""select name, oc_product_id, item_code, item_name, description, \ oc_meta_keyword, oc_meta_description, oc_price, oc_enable, item_group, modified, last_sync_oc from `tabItem` where last_sync_oc<modified and oc_product_id is not null""") # Init results results = [] logs = [] success = False if (len(items)==0): sync_info(logs, 'All items are up to date', stop=True, silent=silent) else: data = [] names = [] for item in items: names.append("'"+item[0]+"'") data.append ({ "product_id": item[1], "model": item[2], "sku": item[2], "price": item[7] or 0, "status": item[8], "product_store": ["0"], "product_category": [item[9]], "product_description": { "1":{ "name": item[3], "meta_keyword" : item[5] or '', "meta_description" : item[6] or '', "description" : item[4] or '' } }, # Irrelevant "sort_order": "1", "tax_class_id": "1", "manufacturer_id": "1" }) results.append([item[2], item[3], item[1], item[10], item[11]]) # Bulk Update to server res = oc_requests(server_base_url, headers, api_map, 'Bulk Product Edit', data=data, stop=False, logs=logs, silent=silent) if res: # Success ? if (not res.get('success')): sync_info(logs, 'Some product not updated on Opencart. Error: %s' %(res.get('error')), stop=False, silent=silent) else: frappe.db.sql("""update `tabItem` set last_sync_oc = Now() where name in (%s)""" %(','.join(names))) sync_info(logs, '%d Product(s) successfully updated to Opencart site' %len(items), stop=False, silent=silent) success = True return { 'results': results, 'success': success, 'logs': logs }
def sync_all_items(server_base_url, api_map, header_key, header_value, silent=False): # Header headers = {} headers[header_key] = header_value # Query for items that has synced time < modified time items = frappe.db.sql( """select name, oc_product_id, item_code, item_name, description, \ oc_meta_keyword, oc_meta_description, oc_price, oc_enable, item_group, modified, last_sync_oc from `tabItem` where last_sync_oc<modified and oc_product_id is not null""" ) # Init results results = [] logs = [] success = False if (len(items) == 0): sync_info(logs, 'All items are up to date', stop=True, silent=silent) else: data = [] names = [] for item in items: names.append("'" + item[0] + "'") data.append({ "product_id": item[1], "model": item[2], "sku": item[2], "price": item[7] or 0, "status": item[8], "product_store": ["0"], "product_category": [item[9]], "product_description": { "1": { "name": item[3], "meta_keyword": item[5] or '', "meta_description": item[6] or '', "description": item[4] or '' } }, # Irrelevant "sort_order": "1", "tax_class_id": "1", "manufacturer_id": "1" }) results.append([item[2], item[3], item[1], item[10], item[11]]) # Bulk Update to server res = oc_requests(server_base_url, headers, api_map, 'Bulk Product Edit', data=data, stop=False, logs=logs, silent=silent) if res: # Success ? if (not res.get('success')): sync_info(logs, 'Some product not updated on Opencart. Error: %s' % (res.get('error')), stop=False, silent=silent) else: frappe.db.sql( """update `tabItem` set last_sync_oc = Now() where name in (%s)""" % (','.join(names))) sync_info( logs, '%d Product(s) successfully updated to Opencart site' % len(items), stop=False, silent=silent) success = True return {'results': results, 'success': success, 'logs': logs}
def pull_products_from_oc(site_name, silent=False): results = {} results_list = [] check_count = 0 update_count = 0 add_count = 0 skip_count = 0 success = True site_doc = frappe.get_doc('Opencart Site', site_name) opencart_api = oc_api.get(site_name) items_default_warehouse = site_doc.get('items_default_warehouse') if not items_default_warehouse: sync_info([], 'Please specify a Default Warehouse and proceed.', stop=True, silent=silent) for oc_category in opencart_api.get_all_categories(): doc_item_group = item_groups.get_item_group(site_name, oc_category.id) for oc_product in opencart_api.get_products_by_category(oc_category.id): check_count += 1 item_code = oc_product.get('model', '').upper() doc_item = get_item_by_item_code(item_code) # skip product if it is disabled on Opencart site if not int(oc_product.get('status') or 0): skip_count += 1 extras = (1, 'skipped', 'Skipped: item with Item No. "%s" is disabled on Opencart site' % item_code) results_list.append((oc_product.get('name'), '', oc_product.get('product_id'), '', '') + extras) continue if doc_item_group: if doc_item: try: update_item(site_name, doc_item, oc_product, item_group=doc_item_group.get('name')) except Exception as ex: skip_count += 1 extras = (1, 'skipped', 'Skipped: due to exception: %s' % str(ex)) results_list.append((oc_product.get('name'), '', oc_product.get('product_id'), '', '') + extras) continue update_count += 1 extras = (1, 'updated', 'Updated') results_list.append((doc_item.get('name'), doc_item_group.get('name'), oc_product.get('product_id'), doc_item.get_formatted('oc_last_sync_from'), doc_item.get('modified')) + extras) else: skip_count += 1 extras = (1, 'skipped', 'Skipped: cannot found item with Item No. "%s"' % item_code) results_list.append((oc_product.get('name'), '', oc_product.get('product_id'), '', '') + extras) continue params = { 'doctype': 'Item', 'item_code': oc_product.get('model'), 'item_group': doc_item_group.get('name'), 'is_group': 'No', 'default_warehouse': items_default_warehouse, 'item_name': oc_product.get('name'), 'description': oc_product.get('description'), 'show_in_website': 1, 'image': oc_product.get('image'), 'min_order_qty': oc_product.get('minimum'), 'oc_is_updating': 1, 'oc_site': site_name, 'oc_product_id': oc_product.get('product_id'), 'oc_manufacturer_id': oc_product.get('manufacturer_id'), 'oc_tax_class_id': oc_product.get('tax_class_id'), 'oc_stock_status': oc_product.get('stock_status'), 'oc_model': oc_product.get('model'), 'oc_sku': oc_product.get('sku'), 'oc_quantity': oc_product.get('quantity'), 'oc_status': int(oc_product.get('status') or 0), 'oc_meta_title': oc_product.get('meta_title'), 'oc_meta_keyword': oc_product.get('meta_keyword'), 'oc_meta_description': oc_product.get('meta_description'), 'price': oc_product.get('price'), 'oc_sync_from': True, 'oc_last_sync_from': datetime.now(), 'oc_sync_to': True, 'oc_last_sync_to': datetime.now() } doc_item = frappe.get_doc(params) doc_item.insert(ignore_permissions=True) # discounts for oc_discount in oc_product.get('discounts'): customer_group = customer_groups.get(site_name, oc_discount.get('customer_group_id')) if not customer_group: continue doc_item.append('oc_discounts', { 'item_name': doc_item.get('name'), 'customer_group': customer_group.get('name'), 'quantity': oc_discount.get('quantity'), 'priority': oc_discount.get('priority'), 'price': oc_discount.get('price'), 'date_start': oc_discount.get('date_start'), 'date_end': oc_discount.get('date_end'), }) # cpesials for oc_special in oc_product.get('special'): customer_group = customer_groups.get(site_name, oc_special.get('customer_group_id')) if not customer_group: continue doc_item.append('oc_specials', { 'item_name': doc_item.get('name'), 'customer_group': customer_group.get('name'), 'priority': oc_special.get('priority'), 'price': oc_special.get('price'), 'date_start': oc_special.get('date_start'), 'date_end': oc_special.get('date_end'), }) doc_item.update({'oc_is_updating': 1}) doc_item.save() add_count += 1 extras = (1, 'added', 'Added') results_list.append((doc_item.get('name'), doc_item_group.get('name'), oc_product.get('product_id'), doc_item.get_formatted('oc_last_sync_from'), doc_item.get('modified')) + extras) else: skip_count += 1 extras = (1, 'skipped', 'Skipped: missed parent category') results_list.append((oc_product.get('name'), '', oc_product.get('product_id'), '', '') + extras) results = { 'check_count': check_count, 'add_count': add_count, 'update_count': update_count, 'skip_count': skip_count, 'results': results_list, 'success': success, } return results
def pull_from_inventory_spreadsheet(site_name, silent=False): results = {} results_list = [] check_count = 0 update_count = 0 add_count = 0 skip_count = 0 success = True try: rows = read_csv_content_from_attached_file(frappe.get_doc("Opencart Site", site_name)) except: frappe.throw(_("Please select a valid csv file with data")) # detect item_code, quantity, description is_header_detected = False item_code_idx = 0 quantity_idx = 0 description_idx = 0 for row in rows: if not is_header_detected: try: robust_row = ['' if field is None else field.lower().strip() for field in row] item_code_idx = map(lambda a: a.startswith('item no') or a.startswith('item code'), robust_row).index(True) quantity_idx = map(lambda a: a.startswith('quantity'), robust_row).index(True) description_idx = map(lambda a: a.startswith('description'), robust_row).index(True) except ValueError: continue else: is_header_detected = True continue item_code = row[item_code_idx] quantity = row[quantity_idx] description = row[description_idx] if item_code is None or quantity is None or description is None: continue item_code = item_code.strip().upper() check_count += 1 site_doc = frappe.get_doc('Opencart Site', site_name) items_default_warehouse = site_doc.get('items_default_warehouse') root_item_group = site_doc.get('root_item_group') if not items_default_warehouse: sync_info([], 'Please specify a Default Warehouse and proceed.', stop=True, silent=silent) doc_item = get_item_by_item_code(item_code) if doc_item: # update_item(doc_item, oc_product) update_count += 1 extras = (1, 'updated', 'Updated') results_list.append((doc_item.get('name'), doc_item.get('item_group'), doc_item.get('oc_product_id'), doc_item.get_formatted('oc_last_sync_from'), doc_item.get('modified')) + extras) else: # creating new Item params = { 'doctype': 'Item', 'item_group': root_item_group, 'item_code': item_code, 'is_group': 'No', 'default_warehouse': items_default_warehouse, 'item_name': description, 'description': '', 'show_in_website': 0, 'oc_is_updating': 1, 'oc_site': site_name, 'oc_product_id': '', 'oc_manufacturer_id': '', 'oc_tax_class_id': '', 'oc_stock_status': '', 'oc_model': item_code, 'oc_sku': item_code, # 'oc_quantity': quantity, 'oc_status': 0, 'oc_meta_title': '', 'oc_meta_keyword': '', 'oc_meta_description': '', 'price': '', 'oc_sync_from': False, 'oc_last_sync_from': datetime.now(), 'oc_sync_to': False, 'oc_last_sync_to': datetime.now(), } doc_item = frappe.get_doc(params) doc_item.insert(ignore_permissions=True) add_count += 1 extras = (1, 'added', 'Added') results_list.append((doc_item.get('name'), root_item_group, doc_item.get('oc_product_id'), doc_item.get_formatted('oc_last_sync_from'), doc_item.get('modified')) + extras) results = { 'check_count': check_count, 'add_count': add_count, 'update_count': update_count, 'skip_count': skip_count, 'results': results_list, 'success': success, } return results
def sync_child_groups(item_group_name, site_name, server_base_url, api_map, header_key, header_value, silent=False): # item_group = frappe.get_doc("Item Group", item_group_name) logs = [] # Check if any is not updated count = frappe.db.sql("""select count(*) from \ (select if(opencart_last_sync + INTERVAL %(buffer)s SECOND > modified, 1, 0) as updated \ from `tabItem Group` where lft>%(lft)s and rgt<=%(rgt)s) as cat_tbl where cat_tbl.updated=0""", {"lft": item_group.lft, "rgt": item_group.rgt, "buffer": OC_CAT_SYNC_BUFFER}) # Init for result results = {} results_list = [] update_count = 0 add_count = 0 success = True # Skip if everything is up to date if (count[0][0]==0): sync_info(logs, 'All items groups are up to date', stop=True, silent=silent) else: # site_doc = frappe.get_doc("Opencart Site", site_name) groups = frappe.db.sql("""select name, if(opencart_last_sync + INTERVAL %(buffer)s SECOND > modified, 1, 0) as updated \ from `tabItem Group` where lft>%(lft)s and rgt<=%(rgt)s order by lft asc""", {"lft": item_group.lft, "rgt": item_group.rgt, "buffer": OC_CAT_SYNC_BUFFER}) # Header headers = {} headers[header_key] = header_value # Loop through group and update for group in groups: group_name, group_updated = group group_doc = frappe.get_doc("Item Group", group_name) # Check if it synced already 2 sec buffer. # Because we save using code the modified get updated after last_sync time if (group_updated): extras = (1, 'updated', 'Updated') else: extras = (0, 'not-updated', 'Not Updated') # Parent category parent_id = "0" if group_doc.get('parent_item_group')!=item_group_name: parent_doc = frappe.get_doc("Item Group", group_doc.get('parent_item_group')) parent_id = parent_doc.get('opencart_category_id') # Sync with oc is_updating = group_doc.get(OC_CAT_ID) and group_doc.get(OC_CAT_ID) > 0 data = { "sort_order": "1", "parent_id": parent_id, "status": group_doc.get('enable_on_opencart'), "category_store": ["0"], "category_description": { "1":{ "name": group_doc.get('name'), "description" : group_doc.get('opencart_description') or "", "meta_keyword" : group_doc.get('opencart_meta_keyword') or "", "meta_description" : group_doc.get('opencart_meta_description') or "", } }, "keyword": ','.join(["category", group_doc.get('name')]), # Prevent error from "column": "1" } # Get API obj api_name = 'Category Edit' if is_updating else 'Category Add' api_params = {'id': group_doc.get(OC_CAT_ID)} if is_updating else None # Push change to server res = oc_requests(server_base_url, headers, api_map, api_name, url_params=api_params, data=data, logs=logs, silent=silent, stop=False) if res is None or res.get('success')==False: success = False sync_info(logs, "Failed to update/add item group: %s. Error: %s"%(group_name, \ res.get('error') if hasattr(res, 'error') else 'Unknown error'), error=True, silent=silent) # Handle response else: updating_props = { "sell_on_opencart": True, "opencart_site": site_name, "opencart_last_sync": datetime.now() } if not group_doc.opencart_category_id: updating_props.update({"opencart_category_id": res.get('category_id')}) group_doc.update(updating_props) group_doc.ignore_validate=True group_doc.save() # Add count if (is_updating): update_count+=1 extras = (group_updated, 'just-updated', 'Just Updated') sync_info(logs, "Successfully updated item group: %s."%(group_name), error=False, silent=True) else: add_count+=1 extras = (group_updated, 'just-added', 'Just Added') sync_info(logs, "Successfully added item group: %s."%(group_name), error=False, silent=True) # Update images as well, optional sync_group_image_handle (group_doc, site_doc, api_map, headers) # Append results results_list.append((group_doc.get('name'), group_doc.get('parent_item_group'), \ group_doc.get('opencart_category_id'), group_doc.get_formatted('opencart_last_sync'), \ group_doc.get('modified'))+extras) results = { 'add_count': add_count, 'update_count': update_count, 'results': results_list, 'success': success, 'logs': logs } return results
def sync_child_groups(item_group_name, site_name, server_base_url, api_map, header_key, header_value, silent=False): # item_group = frappe.get_doc("Item Group", item_group_name) logs = [] # Check if any is not updated count = frappe.db.sql( """select count(*) from \ (select if(opencart_last_sync + INTERVAL %(buffer)s SECOND > modified, 1, 0) as updated \ from `tabItem Group` where lft>%(lft)s and rgt<=%(rgt)s) as cat_tbl where cat_tbl.updated=0""", { "lft": item_group.lft, "rgt": item_group.rgt, "buffer": OC_CAT_SYNC_BUFFER }) # Init for result results = {} results_list = [] update_count = 0 add_count = 0 success = True # Skip if everything is up to date if (count[0][0] == 0): sync_info(logs, 'All items groups are up to date', stop=True, silent=silent) else: # site_doc = frappe.get_doc("Opencart Site", site_name) groups = frappe.db.sql( """select name, if(opencart_last_sync + INTERVAL %(buffer)s SECOND > modified, 1, 0) as updated \ from `tabItem Group` where lft>%(lft)s and rgt<=%(rgt)s order by lft asc""", { "lft": item_group.lft, "rgt": item_group.rgt, "buffer": OC_CAT_SYNC_BUFFER }) # Header headers = {} headers[header_key] = header_value # Loop through group and update for group in groups: group_name, group_updated = group group_doc = frappe.get_doc("Item Group", group_name) # Check if it synced already 2 sec buffer. # Because we save using code the modified get updated after last_sync time if (group_updated): extras = (1, 'updated', 'Updated') else: extras = (0, 'not-updated', 'Not Updated') # Parent category parent_id = "0" if group_doc.get('parent_item_group') != item_group_name: parent_doc = frappe.get_doc( "Item Group", group_doc.get('parent_item_group')) parent_id = parent_doc.get('opencart_category_id') # Sync with oc is_updating = group_doc.get( OC_CAT_ID) and group_doc.get(OC_CAT_ID) > 0 data = { "sort_order": "1", "parent_id": parent_id, "status": group_doc.get('enable_on_opencart'), "category_store": ["0"], "category_description": { "1": { "name": group_doc.get('name'), "description": group_doc.get('opencart_description') or "", "meta_keyword": group_doc.get('opencart_meta_keyword') or "", "meta_description": group_doc.get('opencart_meta_description') or "", } }, "keyword": ','.join(["category", group_doc.get('name')]), # Prevent error from "column": "1" } # Get API obj api_name = 'Category Edit' if is_updating else 'Category Add' api_params = { 'id': group_doc.get(OC_CAT_ID) } if is_updating else None # Push change to server res = oc_requests(server_base_url, headers, api_map, api_name, url_params=api_params, data=data, logs=logs, silent=silent, stop=False) if res is None or res.get('success') == False: success = False sync_info(logs, "Failed to update/add item group: %s. Error: %s"%(group_name, \ res.get('error') if hasattr(res, 'error') else 'Unknown error'), error=True, silent=silent) # Handle response else: updating_props = { "sell_on_opencart": True, "opencart_site": site_name, "opencart_last_sync": datetime.now() } if not group_doc.opencart_category_id: updating_props.update( {"opencart_category_id": res.get('category_id')}) group_doc.update(updating_props) group_doc.ignore_validate = True group_doc.save() # Add count if (is_updating): update_count += 1 extras = (group_updated, 'just-updated', 'Just Updated') sync_info(logs, "Successfully updated item group: %s." % (group_name), error=False, silent=True) else: add_count += 1 extras = (group_updated, 'just-added', 'Just Added') sync_info(logs, "Successfully added item group: %s." % (group_name), error=False, silent=True) # Update images as well, optional sync_group_image_handle(group_doc, site_doc, api_map, headers) # Append results results_list.append((group_doc.get('name'), group_doc.get('parent_item_group'), \ group_doc.get('opencart_category_id'), group_doc.get_formatted('opencart_last_sync'), \ group_doc.get('modified'))+extras) results = { 'add_count': add_count, 'update_count': update_count, 'results': results_list, 'success': success, 'logs': logs } return results