/*
         * Because of the way AJAX loading of products works, we should always
         * pass in a View instead of an EmptyResult. This ensures the CSS for
         * the modal is always loaded.
         */
        public async Task <IViewComponentResult> InvokeAsync(
            string widgetZone,
            object additionalData = null
            )
        {
            const string productListingCshtml =
                "~/Plugins/Widgets.AbcSynchronyPayments/Views/ProductListing.cshtml";
            SynchronyPaymentModel model = null;

            var productId = GetProductId(additionalData);

            if (productId == -1)
            {
                await _logger.ErrorAsync(
                    "Incorrect data model passed to ABC Warehouse " +
                    "Synchrony Payments widget.");

                return(View(productListingCshtml, model));
            }

            var productAbcDescription = await _productAbcDescriptionService.GetProductAbcDescriptionByProductIdAsync(productId);

            var abcItemNumber = productAbcDescription?.AbcItemNumber;

            // also allow getting info from generic attribute
            var productGenericAttributes = await _genericAttributeService.GetAttributesForEntityAsync(productId, "Product");

            var monthsGenericAttribute = productGenericAttributes.Where(ga => ga.Key == "SynchronyPaymentMonths")
                                         .FirstOrDefault();

            if (abcItemNumber == null && monthsGenericAttribute == null)
            {
                // No ABC Item number (or no months indicator), skip processing
                return(View(productListingCshtml, model));
            }

            var productAbcFinance =
                await _productAbcFinanceService.GetProductAbcFinanceByAbcItemNumberAsync(
                    abcItemNumber
                    );

            if (productAbcFinance == null && monthsGenericAttribute == null)
            {
                // No financing information
                return(View(productListingCshtml, model));
            }

            // generic attribute data
            var isMinimumGenericAttribute = productGenericAttributes.Where(ga => ga.Key == "SynchronyPaymentIsMinimum")
                                            .FirstOrDefault();
            var offerValidFromGenericAttribute = productGenericAttributes.Where(ga => ga.Key == "SynchronyPaymentOfferValidFrom")
                                                 .FirstOrDefault();
            var offerValidToGenericAttribute = productGenericAttributes.Where(ga => ga.Key == "SynchronyPaymentOfferValidTo")
                                               .FirstOrDefault();

            var product = await _productService.GetProductByIdAsync(productId);

            var months = productAbcFinance != null ?
                         productAbcFinance.Months :
                         int.Parse(monthsGenericAttribute.Value);
            var isMinimumPayment = productAbcFinance != null ?
                                   productAbcFinance.IsDeferredPricing :
                                   bool.Parse(isMinimumGenericAttribute.Value);
            var offerValidFrom = productAbcFinance != null ?
                                 productAbcFinance.StartDate.Value :
                                 DateTime.Parse(offerValidFromGenericAttribute.Value);
            var offerValidTo = productAbcFinance != null ?
                               productAbcFinance.EndDate.Value :
                               DateTime.Parse(offerValidToGenericAttribute.Value);

            var price = await _abcMattressListingPriceService.GetListingPriceForMattressProductAsync(productId) ?? product.Price;

            var isMattressProduct = _abcMattressProductService.IsMattressProduct(productId);

            model = new SynchronyPaymentModel
            {
                MonthCount     = months,
                MonthlyPayment = CalculatePayment(
                    price, isMinimumPayment, months
                    ),
                ProductId             = productId,
                ApplyUrl              = await GetApplyUrlAsync(),
                IsMonthlyPaymentStyle = !isMinimumPayment,
                EqualPayment          = CalculateEqualPayments(
                    price, months
                    ),
                ModalHexColor  = await HtmlHelpers.GetPavilionPrimaryColorAsync(),
                StoreName      = (await _storeContext.GetCurrentStoreAsync()).Name,
                ImageUrl       = await GetImageUrlAsync(),
                OfferValidFrom = offerValidFrom.ToShortDateString(),
                OfferValidTo   = offerValidTo.ToShortDateString()
            };

            model.FullPrice    = price;
            model.FinalPayment = model.FullPrice -
                                 (model.MonthlyPayment * (model.MonthCount - 1));
            model.IsHidden = isMattressProduct && price < 697.00M;

            if (model.MonthlyPayment == 0)
            {
                await _logger.WarningAsync(
                    $"ABC Product #{productAbcFinance.AbcItemNumber} has a " +
                    "$0 monthly fee, likely not marked with a correct " +
                    "payment type.");

                return(View(productListingCshtml, model));
            }

            switch (widgetZone)
            {
            case "productbox_addinfo_middle":
                return(View(productListingCshtml, model));

            case CustomPublicWidgetZones.ProductDetailsAfterPrice:
                return(View("~/Plugins/Widgets.AbcSynchronyPayments/Views/ProductDetail.cshtml", model));
            }

            await _logger.WarningAsync(
                "ABC Synchrony Payments: Did not match with any passed " +
                "widgets, skipping display");

            return(View(productListingCshtml, model));
        }
            /// <summary>
            /// Called asynchronously before the action, after model binding is complete.
            /// </summary>
            /// <param name="context">A context for action filters</param>
            /// <returns>A task that on completion indicates the necessary filter actions have been executed</returns>
            private async Task SaveLastVisitedPageAsync(ActionExecutingContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }

                if (context.HttpContext.Request == null)
                {
                    return;
                }

                //only in GET requests
                if (!context.HttpContext.Request.Method.Equals(WebRequestMethods.Http.Get, StringComparison.InvariantCultureIgnoreCase))
                {
                    return;
                }

                if (!await DataSettingsManager.IsDatabaseInstalledAsync())
                {
                    return;
                }

                //check whether we store last visited page URL
                if (!_customerSettings.StoreLastVisitedPage)
                {
                    return;
                }

                //get current page
                var pageUrl = _webHelper.GetThisPageUrl(true);

                if (string.IsNullOrEmpty(pageUrl))
                {
                    return;
                }

                //get previous last page
                var customer = await _workContext.GetCurrentCustomerAsync();

                var previousPageAttribute = (await _genericAttributeService
                                             .GetAttributesForEntityAsync(customer.Id, nameof(Customer)))
                                            .FirstOrDefault(attribute => attribute.Key
                                                            .Equals(NopCustomerDefaults.LastVisitedPageAttribute, StringComparison.InvariantCultureIgnoreCase));

                //save new one if don't match
                if (previousPageAttribute == null)
                {
                    //insert without event notification
                    await _genericAttributeRepository.InsertAsync(new GenericAttribute
                    {
                        EntityId = customer.Id,
                        Key      = NopCustomerDefaults.LastVisitedPageAttribute,
                        KeyGroup = nameof(Customer),
                        Value    = pageUrl,
                        CreatedOrUpdatedDateUTC = DateTime.UtcNow
                    }, false);
                }
                else if (!pageUrl.Equals(previousPageAttribute.Value, StringComparison.InvariantCultureIgnoreCase))
                {
                    //update without event notification
                    previousPageAttribute.Value = pageUrl;
                    previousPageAttribute.CreatedOrUpdatedDateUTC = DateTime.UtcNow;

                    await _genericAttributeRepository.UpdateAsync(previousPageAttribute, false);
                }
            }
예제 #3
0
        public async Task <IActionResult> UpdateCustomer(
            [ModelBinder(typeof(JsonModelBinder <CustomerDto>))]
            Delta <CustomerDto> customerDelta)
        {
            // Here we display the errors if the validation has failed at some point.
            if (!ModelState.IsValid)
            {
                return(Error());
            }

            // Updateting the customer
            var currentCustomer = await _customerApiService.GetCustomerEntityByIdAsync(customerDelta.Dto.Id);

            if (currentCustomer == null)
            {
                return(Error(HttpStatusCode.NotFound, "customer", "not found"));
            }

            customerDelta.Merge(currentCustomer);

            if (customerDelta.Dto.RoleIds.Count > 0)
            {
                await AddValidRolesAsync(customerDelta, currentCustomer);
            }

            if (customerDelta.Dto.Addresses.Count > 0)
            {
                var currentCustomerAddresses = (await CustomerService.GetAddressesByCustomerIdAsync(currentCustomer.Id)).ToDictionary(address => address.Id, address => address);

                foreach (var passedAddress in customerDelta.Dto.Addresses)
                {
                    var addressEntity = passedAddress.ToEntity();

                    if (currentCustomerAddresses.ContainsKey(passedAddress.Id))
                    {
                        _mappingHelper.Merge(passedAddress, currentCustomerAddresses[passedAddress.Id]);
                    }
                    else
                    {
                        await CustomerService.InsertCustomerAddressAsync(currentCustomer, addressEntity);
                    }
                }
            }

            await CustomerService.UpdateCustomerAsync(currentCustomer);

            await InsertFirstAndLastNameGenericAttributesAsync(customerDelta.Dto.FirstName, customerDelta.Dto.LastName, currentCustomer);


            if (!string.IsNullOrEmpty(customerDelta.Dto.LanguageId) && int.TryParse(customerDelta.Dto.LanguageId, out var languageId) &&
                await _languageService.GetLanguageByIdAsync(languageId) != null)
            {
                await _genericAttributeService.SaveAttributeAsync(currentCustomer, NopCustomerDefaults.LanguageIdAttribute, languageId);
            }

            //password
            if (!string.IsNullOrWhiteSpace(customerDelta.Dto.Password))
            {
                await AddPasswordAsync(customerDelta.Dto.Password, currentCustomer);
            }

            // TODO: Localization

            // Preparing the result dto of the new customer
            // We do not prepare the shopping cart items because we have a separate endpoint for them.
            var updatedCustomer = currentCustomer.ToDto();

            // This is needed because the entity framework won't populate the navigation properties automatically
            // and the country name will be left empty because the mapping depends on the navigation property
            // so we do it by hand here.
            await PopulateAddressCountryNamesAsync(updatedCustomer);

            var attributes = await _genericAttributeService.GetAttributesForEntityAsync(currentCustomer.Id, typeof(Customer).Name);

            // Set the fist and last name separately because they are not part of the customer entity, but are saved in the generic attributes.
            var firstNameGenericAttribute = attributes.FirstOrDefault(x => x.Key == "FirstName");

            if (firstNameGenericAttribute != null)
            {
                updatedCustomer.FirstName = firstNameGenericAttribute.Value;
            }

            var lastNameGenericAttribute = attributes.FirstOrDefault(x => x.Key == "LastName");

            if (lastNameGenericAttribute != null)
            {
                updatedCustomer.LastName = lastNameGenericAttribute.Value;
            }

            var languageIdGenericAttribute = attributes.FirstOrDefault(x => x.Key == "LanguageId");

            if (languageIdGenericAttribute != null)
            {
                updatedCustomer.LanguageId = languageIdGenericAttribute.Value;
            }

            //activity log
            await CustomerActivityService.InsertActivityAsync("UpdateCustomer", await LocalizationService.GetResourceAsync("ActivityLog.UpdateCustomer"), currentCustomer);

            var customersRootObject = new CustomersRootObject();

            customersRootObject.Customers.Add(updatedCustomer);

            var json = JsonFieldsSerializer.Serialize(customersRootObject, string.Empty);

            return(new RawJsonActionResult(json));
        }
예제 #4
0
        public async Task <IActionResult> UpdateUser([ModelBinder(typeof(JsonModelBinder <UserDto>))] Delta <UserDto> userDelta)
        {
            if (!ModelState.IsValid)
            {
                return(await Error());
            }

            var currentUser = _userApiService.GetUserEntityById(userDelta.Dto.Id);

            if (currentUser == null)
            {
                return(await Error(HttpStatusCode.NotFound, "user", "not found"));
            }

            userDelta.Merge(currentUser);

            //password
            if (!string.IsNullOrWhiteSpace(userDelta.Dto.Password))
            {
                await AddPassword(userDelta.Dto.Password, currentUser);
            }

            //roles
            if (userDelta.Dto.RoleIds.Count > 0)
            {
                AddValidRoles(userDelta, currentUser);
            }

            //stores
            if (userDelta.Dto.StoreIds.Count > 0)
            {
                await AddValidStores(userDelta, currentUser);
            }

            await UserService.UpdateUserAsync(currentUser);

            await InsertFirstAndLastNameGenericAttributes(userDelta.Dto.FirstName, userDelta.Dto.LastName, currentUser);

            // Preparing the result dto of the new user
            var updatedUser = currentUser.ToDto();

            var firstNameGenericAttribute =
                (await _genericAttributeService.GetAttributesForEntityAsync(currentUser.Id, typeof(User).Name))
                .FirstOrDefault(x => x.Key == "FirstName");

            if (firstNameGenericAttribute != null)
            {
                updatedUser.FirstName = firstNameGenericAttribute.Value;
            }

            var lastNameGenericAttribute =
                (await _genericAttributeService.GetAttributesForEntityAsync(currentUser.Id, typeof(User).Name))
                .FirstOrDefault(x => x.Key == "LastName");

            if (lastNameGenericAttribute != null)
            {
                updatedUser.LastName = lastNameGenericAttribute.Value;
            }

            updatedUser.UserPassword = _userApiService.GetUserPassword(updatedUser.Id);

            //activity log
            await UserActivityService.InsertActivityAsync("EditUser", $"Edited a user (ID = {currentUser.Id})", currentUser);

            var usersRootObject = new UsersRootObject();

            usersRootObject.Users.Add(updatedUser);

            var json = JsonFieldsSerializer.Serialize(usersRootObject, String.Empty);

            return(new RawJsonActionResult(json));
        }
예제 #5
0
        public async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            #region Store

            var geocode = new GoogleGeocoder {
                ApiKey = _configuration["APIKey"]
            };

            var stores = new List <Store>();

            using (var conn = new SqlConnection(SqlHelper.ConnectionString))
            {
                var commandText = @"SELECT TOP 10 [outlet_no], [outlet_name], [price_level], [area_code], 
                                [address1], [address2], [address3], [postcode], [city], [state], [country] 
                                FROM [dbo].[btb_HHT_Outlet] WHERE [status] = 1";

                var reader = await SqlHelper.ExecuteReader(conn, CommandType.Text, commandText, null);

                while (reader.Read())
                {
                    var existingStore = await _storeRepository.GetByIdAsync(Convert.ToInt32(reader["outlet_no"]));

                    if (existingStore != null && (existingStore.Status == Convert.ToByte(true) || existingStore.UserStores.Any()))
                    {
                        continue;
                    }

                    var store = new Store
                    {
                        P_BranchNo = Convert.ToInt32(reader["outlet_no"]),
                        P_Name     = reader["outlet_name"].ToString(),
                        P_AreaCode = reader["area_code"].ToString(),
                        P_Addr1    = reader["address1"].ToString(),
                        P_Addr2    = reader["address2"].ToString(),
                        P_Addr3    = reader["address3"].ToString(),
                        P_Postcode = Convert.ToInt32(reader["postcode"].ToString()),
                        P_City     = reader["city"].ToString(),
                        P_State    = reader["state"].ToString(),
                        P_Country  = reader["country"].ToString()
                    };

                    if (!string.IsNullOrEmpty(store.P_Addr1) && store.P_Postcode != 0 &&
                        !string.IsNullOrEmpty(store.P_State) && !string.IsNullOrEmpty(store.P_Country))
                    {
                        var getCoordinates = await geocode.GeocodeAsync(
                            $"{store.P_Addr1}{store.P_Addr2}{store.P_Addr3}{store.P_Postcode}{store.P_City}{store.P_State}{store.P_Country}");

                        var addresses = getCoordinates as IList <GoogleAddress> ?? getCoordinates.ToList();
                        if (addresses.Any())
                        {
                            store.Latitude  = addresses.First().Coordinates.Latitude;
                            store.Longitude = addresses.First().Coordinates.Longitude;
                        }
                    }

                    stores.Add(store);
                }
            }

            try
            {
                var clearStores =
                    from s in _storeRepository.Table
                    where s.Status != Convert.ToByte(true)
                    select s;
                if (clearStores.Any(s => s.UserStores.Count.Equals(0)))
                {
                    var deletedStores = clearStores.Count();

                    await _storeRepository.DeleteAsync(clearStores);

                    await _userActivityService.InsertActivityAsync("ClearStore", $"Deleted old master data from [Store] (Total deleted stores = {deletedStores})", new Store());
                }

                await _storeRepository.InsertAsync(stores);

                await _userActivityService.InsertActivityAsync("DownloadStore", $"Downloaded master data to [Store] (Total added stores = {stores.Count})", new Store());
            }
            catch (Exception exception)
            {
                _logger.Error("An error occurred while downloading data to table [Store]", exception);
            }

            #endregion

            #region Role

            var roles = new List <Role>();

            using (var conn = new SqlConnection(SqlHelper.ConnectionString))
            {
                var commandText = @"SELECT DISTINCT(CASE WHEN [role] = '' OR[role] IS NULL THEN 'Outlet' ELSE[role] END) AS Role 
                                    FROM [dbo].[btb_HHT_Staff]";

                var reader = await SqlHelper.ExecuteReader(conn, CommandType.Text, commandText, null);

                while (reader.Read())
                {
                    var existingRole = _roleRepository.Table.FirstOrDefault(x => x.Name.Equals(reader["Role"].ToString(), StringComparison.InvariantCultureIgnoreCase));
                    if (existingRole != null && existingRole.Active)
                    {
                        continue;
                    }

                    if (!reader["Role"].ToString().Contains("Admin", StringComparison.InvariantCultureIgnoreCase) &&
                        !reader["Role"].ToString().Contains("Registered", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var role = new Role
                        {
                            Name       = reader["Role"].ToString(),
                            SystemName = reader["Role"].ToString(),
                        };

                        roles.Add(role);
                    }
                }
            }

            try
            {
                var clearRoles =
                    from r in _roleRepository.Table
                    where !r.IsSystemRole && !r.Active
                    select r;
                if (clearRoles.Any())
                {
                    var deletedRoles = clearRoles.Count();

                    await _roleRepository.DeleteAsync(clearRoles);

                    await _userActivityService.InsertActivityAsync("ClearRole", $"Deleted old master data from [Role] (Total deleted roles = {deletedRoles})", new Role());
                }

                await _roleRepository.InsertAsync(roles);

                await _userActivityService.InsertActivityAsync("DownloadRole", $"Downloaded master data to [Role] (Total added roles = {roles.Count})", new Role());
            }
            catch (Exception exception)
            {
                _logger.Error("An error occurred while downloading data to table [Role]", exception);
            }

            #endregion

            #region User

            try
            {
                var clearUsers =
                    from u in _userRepository.Table
                    where !u.IsSystemAccount && !u.Active
                    select u;
                if (clearUsers.Any(u => u.UserStores.Count.Equals(0) && u.UserRoles.Count.Equals(0)))
                {
                    //remove from generic attribute
                    foreach (var user in clearUsers.ToList())
                    {
                        var genericAttributes = await _genericAttributeService.GetAttributesForEntityAsync(user.Id, typeof(User).Name);

                        await _genericAttributeService.DeleteAttributes(genericAttributes.ToList());
                    }

                    var deletedUsers = clearUsers.Count();

                    await _userRepository.DeleteAsync(clearUsers);

                    await _userActivityService.InsertActivityAsync("ClearUser", $"Deleted old master data from [User] (Total deleted users = {deletedUsers})", new User());
                }

                var registeredRole = _userService.GetRoleBySystemName(UserDefaults.RegisteredRoleName);

                using (var conn = new SqlConnection(SqlHelper.ConnectionString))
                {
                    var commandText = @"SELECT TOP 10 [staff_no], [staff_barcode], [staff_name], [department_code], [role], [email] 
                                        FROM [dbo].[btb_HHT_Staff]";

                    var reader = await SqlHelper.ExecuteReader(conn, CommandType.Text, commandText, null);

                    while (reader.Read())
                    {
                        var existingUser = await _userService.GetUserByUsernameAsync(reader["staff_no"].ToString());

                        if (existingUser != null && (existingUser.Active || existingUser.UserStores.Any() || existingUser.UserRoles.Any()))
                        {
                            continue;
                        }

                        var systemName = string.IsNullOrEmpty(reader["role"].ToString()) ? "Outlet" : reader["role"].ToString() == "Admin" ? "Administrators" : reader["role"].ToString();

                        if (!string.IsNullOrWhiteSpace(reader["email"].ToString()))
                        {
                            var user = new User
                            {
                                UserGuid      = Guid.NewGuid(),
                                Email         = reader["email"].ToString().Trim(),
                                Username      = reader["staff_no"].ToString(),
                                CreatedOnUtc  = DateTime.UtcNow,
                                ModifiedOnUtc = DateTime.UtcNow,
                            };

                            var role = _userService.GetRoleBySystemName(systemName);
                            user.AddUserRole(new UserRole {
                                Role = role
                            });
                            user.AddUserRole(new UserRole {
                                Role = registeredRole
                            });

                            await _userService.InsertUserAsync(user);

                            await _genericAttributeService.SaveAttributeAsync(user, UserDefaults.FirstNameAttribute,
                                                                              reader["staff_name"].ToString());

                            _userPasswordRepository.Insert(new UserPassword
                            {
                                User           = user,
                                Password       = "******",
                                PasswordFormat = PasswordFormat.Clear,
                                PasswordSalt   = string.Empty,
                                CreatedOnUtc   = DateTime.UtcNow
                            });
                        }
                    }
                }

                await _userActivityService.InsertActivityAsync("DownloadUser", $"Downloaded master data to [User] (Total added users = {_userRepository.Table.Count()})", new User());
            }
            catch (Exception exception)
            {
                _logger.Error("An error occurred while downloading data to table [User]", exception);
            }

            #endregion

            #region Item

            var items = new List <Item>();

            using (var conn = new SqlConnection(SqlHelper.ConnectionString))
            {
                var commandText = @"SELECT TOP 10 [P_StockCode], [P_Desc], [P_SubCategoryID], [P_SPrice1], [P_SPrice2], 
                                    [P_SPrice3], [P_SPrice4], [P_SPrice5], [P_SPrice6], [P_SPrice7], [P_SPrice8],
                                    [P_SPrice9], [P_SPrice10], [P_SPrice11], [P_SPrice12], [P_SPrice13], [P_SPrice14],
                                    [P_SPrice15], [P_ModifyDT], [P_OrderStatus], [P_DisplayShelfLife] 
                                    FROM [dbo].[ItemMaster]";

                var reader = await SqlHelper.ExecuteReader(conn, CommandType.Text, commandText, null);

                while (reader.Read())
                {
                    var existingItem = _itemRepository.Table.FirstOrDefault(x => x.P_StockCode.Equals(reader["P_StockCode"].ToString(), StringComparison.InvariantCultureIgnoreCase));
                    if (existingItem != null)
                    {
                        continue;
                    }

                    var item = new Item
                    {
                        P_StockCode        = reader["P_StockCode"].ToString(),
                        P_Desc             = reader["P_Desc"].ToString(),
                        P_SubCategoryID    = Convert.ToInt32(reader["P_SubCategoryID"]),
                        P_SPrice1          = Convert.ToDouble(reader["P_SPrice1"].ToString()),
                        P_SPrice2          = Convert.ToDouble(reader["P_SPrice2"].ToString()),
                        P_SPrice3          = Convert.ToDouble(reader["P_SPrice3"].ToString()),
                        P_SPrice4          = Convert.ToDouble(reader["P_SPrice4"].ToString()),
                        P_SPrice5          = Convert.ToDouble(reader["P_SPrice5"].ToString()),
                        P_SPrice6          = Convert.ToDouble(reader["P_SPrice6"].ToString()),
                        P_SPrice7          = Convert.ToDouble(reader["P_SPrice7"].ToString()),
                        P_SPrice8          = Convert.ToDouble(reader["P_SPrice8"].ToString()),
                        P_SPrice9          = Convert.ToDouble(reader["P_SPrice9"].ToString()),
                        P_SPrice10         = Convert.ToDouble(reader["P_SPrice10"].ToString()),
                        P_SPrice11         = Convert.ToDouble(reader["P_SPrice11"].ToString()),
                        P_SPrice12         = Convert.ToDouble(reader["P_SPrice12"].ToString()),
                        P_SPrice13         = Convert.ToDouble(reader["P_SPrice13"].ToString()),
                        P_SPrice14         = Convert.ToDouble(reader["P_SPrice14"].ToString()),
                        P_SPrice15         = Convert.ToDouble(reader["P_SPrice15"].ToString()),
                        P_ModifyDT         = Convert.ToDateTime(reader["P_ModifyDT"].ToString()),
                        P_OrderStatus      = Convert.ToInt32(reader["P_OrderStatus"].ToString()),
                        P_DisplayShelfLife = Convert.ToInt32(reader["P_DisplayShelfLife"].ToString())
                    };

                    items.Add(item);
                }
            }

            try
            {
                var clearItems =
                    from i in _itemRepository.Table
                    where string.IsNullOrEmpty(i.P_StockCode) && string.IsNullOrEmpty(i.P_Desc)
                    select i;
                if (clearItems.Any())
                {
                    var deletedItems = clearItems.Count();

                    await _itemRepository.DeleteAsync(clearItems);

                    await _userActivityService.InsertActivityAsync("ClearItem", $"Deleted old master data from [Item] (Total deleted items = {deletedItems})", new Item());
                }

                await _itemRepository.InsertAsync(items);

                await _userActivityService.InsertActivityAsync("DownloadItem", $"Downloaded master data to [Item] (Total added items = {items.Count})", new Item());
            }
            catch (Exception exception)
            {
                _logger.Error("An error occurred while downloading data to table [Item]", exception);
            }

            #endregion
        }