def test_invalid_product_import_using_invalid_file(self): valid_test_file = os.path.join(os.getcwd(), "tests", "data", "create_cisco_test_data.json") product_file = ImportProductsExcelFile(valid_test_file) with self.assertRaises(InvalidExcelFileFormat): product_file.verify_file()
def test_invalid_product_import_using_excel_file_with_invalid_table_name(self): valid_test_file = os.path.join(os.getcwd(), "tests", "data", "excel_import_products_test-invalid_table_name.xlsx") product_file = ImportProductsExcelFile(valid_test_file) with self.assertRaises(InvalidImportFormatException): product_file.verify_file()
def clean(self): # validation of the import products excel file uploaded_file = self.cleaned_data.get("excel_file") if uploaded_file is None: raise forms.ValidationError("invalid upload, file has no content.") if len(uploaded_file.name.split('.')) == 1: raise forms.ValidationError("file type is not supported.") if uploaded_file.name.split('.')[-1] not in self.FILE_EXT_WHITELIST: raise forms.ValidationError("only .xlsx files is allowed") # verify that content can be read try: tmp = tempfile.NamedTemporaryFile(suffix="." + uploaded_file.name.split(".")[-1]) tmp.write(uploaded_file.read()) import_product = ImportProductsExcelFile(tmp.name) import_product.verify_file() # with this implementation, only 20000 items can be imported using a single excel file if import_product.amount_of_products > 20000: raise forms.ValidationError("Excel files with more than 20000 " "entries are currently not supported " "(found %s entries), please upload " "multiple smaller files" % import_product.amount_of_products) tmp.close() except InvalidImportFormatException as ex: msg = "Invalid structure in Excel file (%s)" % ex logger.info(msg) raise forms.ValidationError(msg) except InvalidExcelFileFormat: logger.debug("Invalid excel file format") raise forms.ValidationError("Invalid excel file format") except forms.ValidationError: raise except Exception as ex: logger.warn("Unexpected error while uploading file", ex) raise forms.ValidationError("Unexpected error occurred during upload (%s)" % ex)
def import_products(request): """view for the import of products using Excel :param request: :return: """ context = {} if request.method == "POST": form = ImportProductsFileUploadForm(request.POST, request.FILES) if form.is_valid(): # file is valid, execute the import uploaded_file = request.FILES['excel_file'] tmp = tempfile.NamedTemporaryFile(suffix="." + uploaded_file.name.split(".")[-1]) uploaded_file.open() tmp.write(uploaded_file.read()) try: import_products_excel = ImportProductsExcelFile(tmp.name) import_products_excel.verify_file() import_products_excel.import_products_to_database() context['import_valid_imported_products'] = import_products_excel.valid_imported_products context['import_invalid_products'] = import_products_excel.invalid_products context['import_messages'] = import_products_excel.import_result_messages context['import_result'] = "success" except Exception as ex: msg = "unexpected error occurred during import (%s)" % ex logger.error(msg, ex) context['import_messages'] = msg context['import_result'] = "error" finally: tmp.close() else: form = ImportProductsFileUploadForm() context['form'] = form return render_to_response("productdb/settings/import_products.html", context=context, context_instance=RequestContext(request))
def clean(self): # validation of the import products excel file uploaded_file = self.cleaned_data.get("excel_file") if uploaded_file is None: raise forms.ValidationError("invalid upload, file has no content.") if len(uploaded_file.name.split('.')) == 1: raise forms.ValidationError("file type is not supported.") if uploaded_file.name.split('.')[-1] not in self.FILE_EXT_WHITELIST: raise forms.ValidationError("only .xlsx files is allowed") # verify that content can be read try: tmp = tempfile.NamedTemporaryFile( suffix="." + uploaded_file.name.split(".")[-1]) tmp.write(uploaded_file.read()) import_product = ImportProductsExcelFile(tmp.name) import_product.verify_file() tmp.close() except InvalidImportFormatException as ex: msg = "Invalid structure in Excel file (%s)" % ex logger.info(msg) raise forms.ValidationError(msg) except InvalidExcelFileFormat: logger.debug("Invalid excel file format") raise forms.ValidationError("Invalid excel file format") except forms.ValidationError: raise except Exception as ex: logger.warn("Unexpected error while uploading file", ex) raise forms.ValidationError( "Unexpected error occurred during upload (%s)" % ex)
def clean(self): # validation of the import products excel file uploaded_file = self.cleaned_data.get("excel_file") if uploaded_file is None: raise forms.ValidationError("invalid upload, file has no content.") if len(uploaded_file.name.split('.')) == 1: raise forms.ValidationError("file type is not supported.") if uploaded_file.name.split('.')[-1] not in self.FILE_EXT_WHITELIST: raise forms.ValidationError("only .xlsx files is allowed") # verify that content can be read try: tmp = tempfile.NamedTemporaryFile(suffix="." + uploaded_file.name.split(".")[-1]) tmp.write(uploaded_file.read()) import_product = ImportProductsExcelFile(tmp.name) import_product.verify_file() tmp.close() except InvalidImportFormatException as ex: msg = "Invalid structure in Excel file (%s)" % ex logger.info(msg) raise forms.ValidationError(msg) except InvalidExcelFileFormat: logger.debug("Invalid excel file format") raise forms.ValidationError("Invalid excel file format") except forms.ValidationError: raise except Exception as ex: logger.warn("Unexpected error while uploading file", ex) raise forms.ValidationError("Unexpected error occurred during upload (%s)" % ex)
def prepare_import_products_excel_file(filename, verify_file=True, start_import=True): """ helping method, that creates a new ImportProductsExcelFile instance based on a "filename" in the test data directory """ valid_test_file = os.path.join(os.getcwd(), "tests", "data", filename) product_file = ImportProductsExcelFile(valid_test_file) if verify_file: product_file.verify_file() if start_import: product_file.import_products_to_database() return product_file
def test_valid_product_import_using_excel_with_currency_column(self): """ test a valid product import using the standard Excel template with separate list price and currency columns """ test_product_ids = [ 'WS-C2960S-48FPD-L', 'WS-C2960S-48LPD-L', 'WS-C2960S-24PD-L', 'WS-C2960S-48TD-L', 'WS-C2960S-24TD-L', 'WS-C2960S-48FPS-L', 'WS-C2960S-48LPS-L', 'WS-C2960S-24PS-L', 'CAB-STK-E-0.5M', 'CAB-STK-E-1M=', 'CAB-STK-E-1M', 'CAB-STK-E-3M=', 'CAB-CONSOLE-RJ45=', 'CAB-CONSOLE-USB=', 'EX4200-24F', 'EX4200-24F-DC', 'WS-C2960S-48TS-L', 'WS-C2960S-24TS-L', 'WS-C2960S-48TS-S', 'WS-C2960S-24TS-S', 'C2960S-STACK', 'C2960S-STACK=', 'CAB-STK-E-0.5M=', 'EX4200-24F-S', 'EX4200-24PX', ] products = [ { 'product id': 'WS-C2960S-48FPD-L', 'description': 'Catalyst 2960S 48 GigE PoE 740W, 2 x 10G SFP+ LAN Base', 'list price': 8795, 'currency': 'USD', 'vendor': 'Cisco Systems', }, { 'product id': 'CAB-STK-E-1M', 'description': 'Cisco FlexStack 1m stacking cable', 'list price': 100, 'currency': 'USD', 'vendor': 'unassigned', }, { 'product id': 'CAB-STK-E-1M=', 'description': 'Cisco Bladeswitch 1M stack cable', 'list price': None, 'currency': 'USD', 'vendor': 'Cisco Systems', }, ] valid_test_file = os.path.join(os.getcwd(), "tests", "data", "excel_import_products_test.xlsx") product_file = ImportProductsExcelFile(valid_test_file) product_file.verify_file() self.assertTrue(product_file.valid_file, "given excel file has no valid format") product_file.import_products_to_database() self.assertEqual(product_file.valid_imported_products, 25) self.assertEqual(product_file.invalid_products, 0) self.assertEqual(product_file.amount_of_products, 25) self.assertIsNotNone(product_file.import_result_messages) # verify that the expected products are created in the database for pid in test_product_ids: Product.objects.get(product_id=pid) # look at the imported values from the for product in products: p = Product.objects.get(product_id=product['product id']) self.assertEqual(p.description, product['description']) self.assertEqual(p.list_price, product['list price'], p.product_id) self.assertEqual(p.currency, product['currency']) self.assertEqual(p.vendor.name, product['vendor'])
def import_price_list(self, job_file_id, create_notification_on_server=True, user_for_revision=None): """ import products from the given price list """ def update_task_state(status_message): """Update the status message of the task, which is displayed in the watch view""" self.update_state(state=TaskState.PROCESSING, meta={ "status_message": status_message }) update_task_state("Try to import uploaded file...") try: import_excel_file = JobFile.objects.get(id=job_file_id) except: msg = "Cannot find file that was uploaded." logger.error(msg, exc_info=True) result = { "error_message": msg } return result # verify that file exists try: import_products_excel = ImportProductsExcelFile( path_to_excel_file=import_excel_file.file, user_for_revision=User.objects.get(username=user_for_revision) ) import_products_excel.verify_file() update_task_state("File valid, start updating the database...") import_products_excel.import_products_to_database(status_callback=update_task_state) update_task_state("Database import finished, processing results...") summary_msg = "User <strong>%s</strong> imported a Product list, %s Products " \ "changed." % (user_for_revision, import_products_excel.valid_imported_products) detail_msg = "<div style=\"text-align:left;\">%s " \ "Products successful updated. " % import_products_excel.valid_imported_products if import_products_excel.invalid_products != 0: detail_msg += "%s entries are invalid. Please check the following messages for " \ "more details." % import_products_excel.invalid_products if len(import_products_excel.import_result_messages) != 0: detail_msg += "<ul>" for e in import_products_excel.import_result_messages: detail_msg += "<li>%s</li>" % e detail_msg += "</ul></div>" # if the task was executed eager, set state to SUCCESS (required for testing) if self.request.is_eager: self.update_state(state=TaskState.SUCCESS, meta={ "status_message": detail_msg }) if create_notification_on_server: NotificationMessage.objects.create( title="Import product list", type=NotificationMessage.MESSAGE_INFO, summary_message=summary_msg, detailed_message=detail_msg ) # drop the file import_excel_file.delete() result = { "status_message": detail_msg } except InvalidImportFormatException as ex: msg = "import failed, invalid file format (%s)" % ex logger.error(msg, ex) result = { "error_message": msg } except Exception as ex: msg = "Unexpected exception occurred while importing product list (%s)" % ex logger.error(msg, ex) result = { "error_message": msg } return result
def import_price_list(self, job_file_id, create_notification_on_server=True, user_for_revision=None): """ import products from the given price list """ def update_task_state(status_message): """Update the status message of the task, which is displayed in the watch view""" self.update_state(state=TaskState.PROCESSING, meta={"status_message": status_message}) update_task_state("Try to import uploaded file...") try: import_excel_file = JobFile.objects.get(id=job_file_id) except: msg = "Cannot find file that was uploaded." logger.error(msg, exc_info=True) result = {"error_message": msg} return result # verify that file exists try: import_products_excel = ImportProductsExcelFile( path_to_excel_file=import_excel_file.file, user_for_revision=User.objects.get(username=user_for_revision)) import_products_excel.verify_file() update_task_state("File valid, start updating the database...") import_products_excel.import_products_to_database( status_callback=update_task_state) update_task_state("Database import finished, processing results...") summary_msg = "User <strong>%s</strong> imported a Product list, %s Products " \ "changed." % (user_for_revision, import_products_excel.valid_imported_products) detail_msg = "<div style=\"text-align:left;\">%s " \ "Products successful updated. " % import_products_excel.valid_imported_products if import_products_excel.invalid_products != 0: detail_msg += "%s entries are invalid. Please check the following messages for " \ "more details." % import_products_excel.invalid_products if len(import_products_excel.import_result_messages) != 0: detail_msg += "<ul>" for e in import_products_excel.import_result_messages: detail_msg += "<li>%s</li>" % e detail_msg += "</ul></div>" # if the task was executed eager, set state to SUCCESS (required for testing) if self.request.is_eager: self.update_state(state=TaskState.SUCCESS, meta={"status_message": detail_msg}) if create_notification_on_server: NotificationMessage.objects.create( title="Import product list", type=NotificationMessage.MESSAGE_INFO, summary_message=summary_msg, detailed_message=detail_msg) # drop the file import_excel_file.delete() result = {"status_message": detail_msg} except InvalidImportFormatException as ex: msg = "import failed, invalid file format (%s)" % ex logger.error(msg, ex) result = {"error_message": msg} except Exception as ex: msg = "Unexpected exception occurred while importing product list (%s)" % ex logger.error(msg, ex) result = {"error_message": msg} return result