--upgrade scripts from nopCommerce 3.70 to 3.80 --new locale resources declare @resources xml --a resource will be deleted if its value is empty set @resources=' Indicates whether a customer should be notified by email about new private messages. Check to allow customers to edit items already placed in the cart or wishlist. It could be useful when your products have attributes or any other fields entered by a customer. Update Choose a picture associated to this attribute value. This picture will replace the main product image when this product attribute value is clicked (selected) Square picture Upload a picture to be used with the image squares attribute control Added a new topic (''{0}'') Edited a topic (''{0}'') Deleted a topic (''{0}'') Deleted an order (ID = {0}) Edited an order (ID = {0}). See order notes for details Restricted products [and quantity range] Restricted products [and quantity range] Page size Set the page size for history of reward points on ''My account'' page. You need to save the language before you can make or change resources for this language. String resources Reviews per store Check to display reviews written in the current store only (on a product details page). Page Size options should have unique items. Page Size options should have unique items. Page Size options should not have duplicate items. Store A store name in which this review was written. Store Search by a specific store. Sort options Display order Is active Name reCAPTCHA version Select version of the reCAPTCHA. The reCAPTCHA response is invalid or malformed. Please try again. Version 1.0 Version 2.0 Product Search by a specific product. Products have been imported successfully. The flag image file name. The image should be saved into \images\flags\ directory. Planned date of sending The specific send date and time. Send immediately Send message immediately. Planned date of sending Enter a specific date and time to send the campaign. Leave empty to send it immediately. Planned date of sending The specific send date and time. Send immediately Send message immediately. Imported categories are distinguished by ID. If the ID already exists, then its corresponding category will be updated. For new categories ID do not need to specify Imported manufacturers are distinguished by ID. If the ID already exists, then its corresponding manufacturer will be updated. For new manufacturers ID do not need to specify Categories have been imported successfully. Manufacturers have been imported successfully. Name Search by a specific setting name. Value Search by a specific setting value. Resource name Search by a specific resource. Value Search by a specific resource value. Delay send The delay before sending message. Send immediately Send message immediately. Days Hours Allow search by vendor Check to allow customers to search by vendor on advanced search page. Vendor Published Determines whether this topic is published (visible) in your store. Store Search by a specific store. Store Search by a specific store. Import requires a lot of memory resources. That''s why it''s not recommended to import more than 500 - 1,000 records at once. If you have more records, it''s better to split them to multiple Excel files and import separately. Order statuses Search by a specific order statuses e.g. Complete. Payment statuses Search by a specific payment statuses e.g. Paid. Shipping statuses Search by a specific shipping statuses e.g. Not yet shipped. Condition Attribute Choose an attribute. Enable condition Check to specify a condition (depending on other attribute) when this attribute should be enabled (visible). No attribute exists that could be used as condition. You need to save the checkout attribute before you can edit conditional attributes. The backup created Backup file "{0}" deleted Backup now Database backups Database is restored Delete Download File Name File Size Restore Processing database backup... Flag image IP address Search by IP address. RGB color Choose color to be used instead of an option text name (it''ll be displayed as "color square"). Specify color Check to choose color to be used instead of an option text name (it''ll be displayed as "color square"). Confirm email Email is required. The email and confirmation email do not match. Force entering email twice Force entering email twice during registration This attribute is already added to this product Maximum number of products Sets a maximum number of products per vendor The maximum allowed number of products has been exceeded ({0}) Start date The start date for the search. End date The end date for the search. Not returnable Check if this product is not returnable. In this case a customer won''t be allowed to submit return request. Started customer impersonation (Email: {0}, ID = {1}) Finished customer impersonation (Email: {0}, ID = {1}) Impersonated by store owner (Email: {0}, ID = {1}) Impersonation by store owner was finished (Email: {0}, ID = {1}) Manage this page IP address The IP address for the search. Allow users to vote for posts Set if you want to allow users to vote for posts. Maximum votes per day Maximum number of votes for user per day. Votes You already voted for this post You need to log in to vote for post A maximum of {0} votes can be cast per user per day You cannot vote for your own post Import product images using hash Check to use fast HASHBYTES (hash sum) database function to compare pictures when importing products. Please note that this functionality is not supported by some database. Coordinated Universal Time (UTC) Coordinated Universal Time (UTC). Current user time Current user time (based on specified datetime and timezone settings). Each spent will earn reward points 1 reward point = Do not to forget to update order totals after adding this product. Search sub categories Export Print PDF invoices Print PDF invoices (all found) Print PDF invoices (selected) Print packaging slips Print packaging slips (all found) Print packaging slips (selected) Australia Post API Key Specify Australia Post API Key. Import Search Add (reduce) points Enter points to add. Negative values are also supported (reduce points). Add (reduce) reward points General settings Admin area. Manage External Authentication External authentication back to extenal authentication method list All plugins and themes Shipping methods used by offline shipping rate compuration methods (e.g. "Fixed Rate Shipping" or "Shipping by weight"). Email accounts Message queue Newsletter subscribers Product attributes Checkout attributes Specification attributes Content management Number of products in mini-shopping cart Orders Registered customers Pending return requests Low stock products More info Incomplete orders Orders Month Week Year New customers Month Week Year Latest Orders View All Orders Common statistics Require registration for downloadable products Require account creation to purchase downloadable products. My product reviews Approved Pending Product review for Show product reviews tab on ''My account'' page Check to show product reviews tab on '' My account'' page. Product reviews page size Set the page size for product reviews e.g. ''10'' reviews per page. My product reviews Return request number mask Return request number mask. For example, RMA-{ID}-{YYYY}-{MM}-{DD}. {ID} - Return request identifier {YYYY} - year of return request creation date {YY} - last two digits of year of return request creation date {MM} - month of return request creation date {DD} - day of return request creation date ID Return request identifier. Categories Choose categories. You can manage product categories by selecting Catalog > Categories. No categories available. Allow guests to leave comments Check to allow guests to leave comments. Allow guests to leave comments Check to allow guests to leave comments. External authentication. Auto register enabled Check to enable auto registration when using external authentication (e.g. using Facebokk or Twitter). Reloading plugin list... Default page title Allow vendors to edit info Check to allow vendors to edit information about themselves (in public store). Please note that localizable properties (name, description) are not supported in case if you have multiple languages (only standard values can be edited in this case). Vendor info Vendor info Name Email Description Picture Remove picture You can add only picture file Notify about vendor information changes Check to notify a store owner about vendor information changes. Vendor name is required. Email is required. Picture Description You can add only picture file or Manufacturers Choose the manufacturer. You can manage manufacturers by selecting Catalog > Manufacturers. Customer roles Additional shipping charge Admin comment Allow back in stock subscriptions Allow customer reviews Allowed quantities Allow only existing attribute combinations Available end date Available for pre-order Available start date Backorders General information Advanced product types Price Shipping Access control list Inventory Mappings Linked products Settings Call for price Created on Cross-sells products Customer enters price Delivery date Dimensions Disable buy button Disable wishlist button Discounts Display order Display availability Display stock qty Downloadable product Free shipping GTIN (global trade item number) ID Is gift card Is rental Low stock activity Manufacturer part number Mark as new Mark as new. End date Mark as new. Start date Maximum cart qty Minimum cart qty Minimum stock qty Check fields you want to see on the product details page in the "basic" mode. Settings Notify for qty below Not returnable PAngV (base price) enabled Product cost Product tags Product template Product type Published Recurring product Related products Require other products Ship separately Show on home page Special price Special price end date Special price start date Stores Telecommunications, broadcasting and electronic services Tier prices Vendor Visible individually Updated on Use multiple warehouses Warehouses Weight Prices General information Inventory Shipping Mappings Access control list Require other products No categories available. No manufacturers available. Discounts Select discounts to apply to this product. You can manage discounts by selecting Discounts from the Promotions menu. No discounts available. Create at least one discount before mapping. Limited to stores Customer roles Choose one or several customer roles i.e. administrators, vendors, guests, who will be able to see this product in catalog. If you don''t need this option just leave this field empty. In order to use this functionality you have to disable the following setting: Catalog settings > Ignore ACL rules (sitewide). Gift card Downloadable product Recurring product Rental Stock qty Multiple warehouses Display availability Minimum stock qty Notify for qty below Minimum cart qty Maximum cart qty Inventory method Old price No stores available. Tabs and display options SEO Purchased with orders Require other products Product type can be simple or grouped. In most cases your product will have the Simple product type. You need to use Grouped product type when a new product consists of one or more existing products that will be displayed on one single product details page. Check it if you want the product to be on catalog or search results. You can uncheck this box to hide associated products from catalog and make them accessible only from grouped product details page. Short description is the text that is displayed in product list i.e. сategory / manufacturer pages. Full description is the text that is displayed in product page. This comment is for internal use only, not visible for customers. Product tags are the keywords for product identification. The more products associated with a particular tag, the larger it will show on the tag cloud. Check to mark the product as new. Use this option for promoting new products. Check if it is a gift card. After adding gift card products to the shopping cart and completing the purchases, you can then search and view the list of all the purchased gift cards by selecting Gift Cards from the Sales menu. There are two gift card types: virtual and physical. WARNING: not recommended to change the gift card type from one to another in a "live" store. Check if the product is downloadable. When customers purchase a downloadable product, they can download it direct from your store. The link will be visible after checkout. You can download file using URL or uploading from the computer. If you want to download file using URL check the box Use download URL. Select this checkbox if the customer has a user agreement (a customer must agree with this user agreement when trying to download the product). You can download file using URL or uploading from the computer. If you want to download file using URL check the box Use download URL. Check if it is a recurring product. For any product, you can define a recurring cycle to enable the system to automatically create orders that repeat when a customer purchases such products. Specify the cycle length. It is a time period recurring order can be repeated. Specify the cycle period. It defines units time period can be measured in. Total cycles are number of times customer will receive the recurring product. The price of the product. You can manage currency by selecting Configuration > Location > Currencies. Product cost is a prime product cost. This field is only for internal use, not visible for customers. Set a special price of the product. The new price will be valid between the start and end dates. Select discouts. You can manage discounts by selecting Discounts from the Promotions menu. The tax classification for the product. You can manage tax categories by selecting Configuration > Tax > Tax Categories. Tier pricing is a promotional tool that allows a store owner to price items differently for higher quantities. Select inventory method. There are three methods: Don’t track inventory, Track inventory and Track inventory by attributes. You should use Track inventory by attributes when the product has different combinations of these attributes and then manage inventory for this combinations. Choose the warehouse which will be used when calculating shipping rates. You can manage warehouses by selecting Configuration > Shipping > Warehouses. Check if the product can be shipped. You can manage shipping settings by selecting Configuration > Shipping. The product weight. The product length. The product width. Check if the product should be shipped separately from other products (in single box). Notice that if the order includes several items of this product, all of them will be shipped separately. Choose the vendor. You can manage vendors by selecting Customers > Vendors. Check if the product requires adding other products to the cart. The Related Products option provides the opportunity to advertise products that are not part of the selected category, to your visitors. These products are displayed on the product details pages. The Cross-sell products option provides the opportunity to buy additional products that generally go with the selected product. They are displayed at the bottom of the checkout page. Product attributes are quantifiable or descriptive aspects of a product (such as, color). For example, if you were to create an attribute for color, with the values of blue, green, yellow, and so on, you may want to apply this attribute to shirts, which you sell in various colors (you can adjust a price or weight for any of existing attribute values). You can add attribute for your product using existing list of attributes, or if you need to create a new one go to Catalog > Attributes > Product attributes. Please notice that if you want to manage inventory by product attributes (e.g. 5 green shirts and 3 blue ones), then ensure that Inventory method is set to Track inventory by product attributes. Specification attributes are product features i.e, screen size, number of USB-ports, visible on product details page. Specification attributes can be used for filtering products on the category details page. Unlike product attributes, specification attributes are used for information purposes only. Choose a delivery date which will be displayed in the public store. You can manage delivery dates by selecting Configuration > Shipping > Delivery dates. The product height. Also note that some attribute control types that support custom user input (e.g. file upload, textboxes, date picker) are useless with attribute combinations Limited to customer role Choose a customer role which subscribers will get this email. Store Search by a specific store. Cumulative with other discounts If checked, this discount can be used with other ones simultaneously. Please note that this feature works only for discounts with the same discount type. Right now discounts with distinct types are already cumulative. Ship to the same address Check to display "ship to the same address" option during checkout ("billing address" step). In this case case "shipping address" with appropriate options (e.g. pick up in store) will be skipped. Also note that all billing countries should support shipping ("Allow shipping" checkbox ticked). Ship to the same address API key Specify Canada Post API key. Customer number Specify customer number. Use Sandbox Check to enable Sandbox (testing environment). Standard Manage shipping methods Shipping method restrictions Shipping providers Shipping rate computation methods (providers) Sitemap enabled Check to enable sitemap. Sitemap includes categories Check if you want to include categories in sitemap. Sitemap includes manufacturers Check if you want to include manufacturers in sitemap. Sitemap includes products Check if you want to include products in sitemap. tag]]> tag(s) here. For example, some custom tag. Or leave empty if ignore this setting.]]> You can''t deactivate the last administrator. At least one administrator account should exists. You can''t remove the Administrator role. At least one administrator account should exists. You can''t delete the last administrator. At least one administrator account should exists. Edited activity log types Deleted activity log Quantity has been changed while you were editing the product. Changes haven''t been saved. Please ensure that everything is correct and click "Save" button one more time. Additional info In order to use this functionality you have to disable the following setting: Configuration > Catalog settings > Ignore "limit per store" rules (sitewide). In order to use this functionality you have to disable the following setting: Configuration > Catalog settings > Ignore ACL rules (sitewide). Import requires a lot of memory resources. That''s why it''s not recommended to import more than 500 - 1,000 records at once. If you have more records, it''s better to split them to multiple Excel files and import separately. Note that some attribute control types that support custom user input (e.g. file upload, textboxes, date picker) are useless with attribute combinations Logo Upload your store logo. If not uploaded, then the default one will be used. You''re not allowed to change passwords of administrators. Only administrators can do it. You''re not allowed to delete administrators. Only administrators can do it. Choose customer roles of this user No customer roles available. Create at least one customer role before mapping. Specification attributes are product features i.e, screen size, number of USB-ports, visible on product details page. Specification attributes can be used for filtering products on the category details page. Unlike product attributes, specification attributes are used for information purposes only. You can add attributes to existing product on a product details page. Product attributes are quantifiable or descriptive aspects of a product (such as, color). For example, if you were to create an attribute for color, with the values of blue, green, yellow, and so on, you may want to apply this attribute to shirts, which you sell in various colors (you can adjust a price or weight for any of existing attribute values). You can add attributes to existing product on a product details page. Checkout attributes are displayed on the shopping cart page and provide the opportunity to offer more services to customers, i.e. gift wrapping, before placing the order. A value indicating whether "Pick Up in Store" option is enabled during checkout. Please ensure that you have at least one active pickup point provider. Display pickup points on the map Check to display pickup points on the map. Google maps API key Specify Google maps API key. Pickup point providers back to pickup point provider list Configure Display order Friendly name Is active Logo System name Pickup points Pickup point address Pickup point address info. View address on Google Maps Pickup Pick up your items at the store Pickup at {0} Pickup points could not be loaded Select pickup point Pickup point address Pickup point address Pickup point: Are you sure you want to perform this action? Logout Measures Dimensions The primary dimension can''t be deleted. NOTE: if you change your primary dimension, then do not forget to update the appropriate ratios of the units Display order Is primary dimension Mark as primary dimension Name Please provide a name. Ratio to primary dimension System keyword Please provide a system keyword. Weights The primary weight can''t be deleted. NOTE: if you change your primary weight, then do not forget to update the appropriate ratios of the units Display order Is primary weight Mark as primary weight Name Please provide a name. Ratio to primary weight System keyword Please provide a system keyword. Customer info Activity log Place order (impersonate) Product info Category info Manufacturer info Discounts Select discounts to apply to this category. You can manage discounts by selecting Discounts from the Promotions menu. No discounts available. Create at least one discount before mapping. Discounts Select discounts to apply to this manufacturer. You can manage discounts by selecting Discounts from the Promotions menu. No discounts available. Create at least one discount before mapping. Limited to customer roles Select customer roles for which the category will be shown. Leave empty if you want this category to be visible to all users. Limited to customer roles Select customer roles for which the manufacturer will be shown. Leave empty if you want this manufacturer to be visible to all users. Select customer roles for which the topic will be shown. Leave empty if you want this topic to be visible to all users. Option to limit this product to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. In order to use this functionality you have to disable the following setting: Catalog settings > Ignore "limit per store" rules. Option to limit this blog post to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this category to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this manufacturer to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this country to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this currency to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this language to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this template to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this news item to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this topic to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this attribute to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Option to limit this plugin to a certain store. If you have multiple stores, choose one or several from the list. If you don''t use this option just leave this field empty. Default tax address (used for tax calculation) Shipping origin Order subtotal The subtotal of this order. excl tax incl tax Order shipping The total shipping cost for this order. excl tax incl tax Order subtotal discount The subtotal discount of this order. excl tax incl tax Payment method additional fee The payment method additional fee for this order. excl tax incl tax In order to use this functionality you have to disable the following setting: Catalog settings > Ignore "limit per store" rules. In order to use this functionality you have to disable the following setting: Catalog settings > Ignore ACL rules (sitewide). The Return Request feature (RMA) enables customers to send products back to you. Here you can find all submitted return requests. Recurring payments are used for automatic renewal of consumable merchandise or subscription services. Access control list is a list of permissions attached to customer roles. This list specifies the access rights of users to objects. Affiliate is an Internet-based marketing practice in which a business rewards one or more affiliates for each visitor or customer. It is a web-based pay-for-performance program designed to compensate affiliate partner for driving qualified leads or sales to a merchant web site. One column product page One column product page Auto update order totals Check to automatically update order totals on editing an order in admin area. IMPORANT: currently this functionality is in BETA testing status. Export/Import products with attributes Check if products should be exported/imported with product attributes Product attributes Specification attributes The tax classification for this attribute (used to calculate tax). You can manage tax categories by selecting Configuration : Tax : Tax Categories. Payment method additional fee tax category Select tax category used for payment method additional fee tax calculation. Shipping tax category Select tax category used for shipping tax calculation. Basic Advanced Manufacturers ' CREATE TABLE #LocaleStringResourceTmp ( [ResourceName] [nvarchar](200) NOT NULL, [ResourceValue] [nvarchar](max) NOT NULL ) INSERT INTO #LocaleStringResourceTmp (ResourceName, ResourceValue) SELECT nref.value('@Name', 'nvarchar(200)'), nref.value('Value[1]', 'nvarchar(MAX)') FROM @resources.nodes('//Language/LocaleResource') AS R(nref) --do it for each existing language DECLARE @ExistingLanguageID int DECLARE cur_existinglanguage CURSOR FOR SELECT [ID] FROM [Language] OPEN cur_existinglanguage FETCH NEXT FROM cur_existinglanguage INTO @ExistingLanguageID WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @ResourceName nvarchar(200) DECLARE @ResourceValue nvarchar(MAX) DECLARE cur_localeresource CURSOR FOR SELECT ResourceName, ResourceValue FROM #LocaleStringResourceTmp OPEN cur_localeresource FETCH NEXT FROM cur_localeresource INTO @ResourceName, @ResourceValue WHILE @@FETCH_STATUS = 0 BEGIN IF (EXISTS (SELECT 1 FROM [LocaleStringResource] WHERE LanguageID=@ExistingLanguageID AND ResourceName=@ResourceName)) BEGIN UPDATE [LocaleStringResource] SET [ResourceValue]=@ResourceValue WHERE LanguageID=@ExistingLanguageID AND ResourceName=@ResourceName END ELSE BEGIN INSERT INTO [LocaleStringResource] ( [LanguageId], [ResourceName], [ResourceValue] ) VALUES ( @ExistingLanguageID, @ResourceName, @ResourceValue ) END IF (@ResourceValue is null or @ResourceValue = '') BEGIN DELETE [LocaleStringResource] WHERE LanguageID=@ExistingLanguageID AND ResourceName=@ResourceName END FETCH NEXT FROM cur_localeresource INTO @ResourceName, @ResourceValue END CLOSE cur_localeresource DEALLOCATE cur_localeresource --fetch next language identifier FETCH NEXT FROM cur_existinglanguage INTO @ExistingLanguageID END CLOSE cur_existinglanguage DEALLOCATE cur_existinglanguage DROP TABLE #LocaleStringResourceTmp GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[ProductAttributeValue]') and NAME='ImageSquaresPictureId') BEGIN ALTER TABLE [ProductAttributeValue] ADD [ImageSquaresPictureId] int NULL END GO UPDATE [ProductAttributeValue] SET [ImageSquaresPictureId] = 0 WHERE [ImageSquaresPictureId] IS NULL GO ALTER TABLE [ProductAttributeValue] ALTER COLUMN [ImageSquaresPictureId] int NOT NULL GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[ProductReview]') and NAME='StoreId') BEGIN ALTER TABLE [dbo].[ProductReview] ADD [StoreId] int NULL END GO DECLARE @DefaultStoreId INT SET @DefaultStoreId = (SELECT TOP (1) Id FROM [dbo].[Store]); UPDATE [dbo].[ProductReview] SET StoreId = @DefaultStoreId WHERE StoreId IS NULL GO ALTER TABLE [dbo].[ProductReview] ALTER COLUMN [StoreId] INT NOT NULL GO IF EXISTS (SELECT 1 FROM sys.objects WHERE name = 'ProductReview_Store' AND parent_object_id = Object_id('ProductReview') AND Objectproperty(object_id,N'IsForeignKey') = 1) ALTER TABLE dbo.ProductReview DROP CONSTRAINT ProductReview_Store GO ALTER TABLE [dbo].[ProductReview] WITH CHECK ADD CONSTRAINT [ProductReview_Store] FOREIGN KEY([StoreId]) REFERENCES [dbo].[Store] ([Id]) ON DELETE CASCADE GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'catalogsettings.showproductreviewsperstore') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'catalogsettings.showproductreviewsperstore', N'False', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'mediasettings.imagesquarepicturesize') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'mediasettings.imagesquarepicturesize', N'32', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'mediasettings.importproductimagesusinghash') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'mediasettings.importproductimagesusinghash', N'true', 0) END GO --new activity types IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'AddNewTopic') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'AddNewTopic', N'Add a new topic', N'true') END GO IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'DeleteTopic') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'DeleteTopic', N'Delete a topic', N'true') END GO IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'EditTopic') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'EditTopic', N'Edit a topic', N'true') END GO IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'DeleteOrder') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'DeleteOrder', N'Delete an order', N'true') END GO IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'EditOrder') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'EditOrder', N'Edit an order', N'true') END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'rewardpointssettings.pagesize') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'rewardpointssettings.pagesize', N'10', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'catalogsettings.productsortingenumdisabled') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'catalogsettings.productsortingenumdisabled',N'',0); END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'catalogsettings.productsortingenumdisplayorder') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'catalogsettings.productsortingenumdisplayorder',N'',0); END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'captchasettings.recaptchaversion') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'captchasettings.recaptchaversion',N'1',0); END GO --new or update setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'captchasettings.recaptchatheme') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'captchasettings.recaptchatheme',N'',0); END ELSE BEGIN UPDATE [Setting] SET [Value] = N'' WHERE [Name] = N'captchasettings.recaptchatheme' END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'captchasettings.recaptchalanguage') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'captchasettings.recaptchalanguage',N'',0); END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'vendorsettings.maximumproductnumber') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'vendorsettings.maximumproductnumber',N'3000',0); END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[QueuedEmail]') and NAME='DontSendBeforeDateUtc') BEGIN ALTER TABLE [QueuedEmail] ADD [DontSendBeforeDateUtc] DATETIME NULL END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[Campaign]') and NAME='DontSendBeforeDateUtc') BEGIN ALTER TABLE [Campaign] ADD [DontSendBeforeDateUtc] DATETIME NULL END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[MessageTemplate]') and NAME='DelayBeforeSend') BEGIN ALTER TABLE [MessageTemplate] ADD [DelayBeforeSend] INT NULL END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[MessageTemplate]') and NAME='DelayPeriodId') BEGIN ALTER TABLE [MessageTemplate] ADD [DelayPeriodId] INT NULL END GO UPDATE [MessageTemplate] SET [DelayPeriodId] = 0 WHERE [DelayPeriodId] IS NULL GO ALTER TABLE [MessageTemplate] ALTER COLUMN [DelayPeriodId] int NOT NULL GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'vendorsettings.allowsearchbyvendor') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'vendorsettings.allowsearchbyvendor',N'False',0); END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[Topic]') and NAME='Published') BEGIN ALTER TABLE [Topic] ADD [Published] bit NULL END GO UPDATE [Topic] SET [Published] = 1 WHERE [Published] IS NULL GO ALTER TABLE [Topic] ALTER COLUMN [Published] bit NOT NULL GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[CheckoutAttribute]') and NAME='ConditionAttributeXml') BEGIN ALTER TABLE [CheckoutAttribute] ADD [ConditionAttributeXml] nvarchar(MAX) NULL END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'commonsettings.deleteguesttaskolderthanminutes') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'commonsettings.deleteguesttaskolderthanminutes',N'1440',0); END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[SpecificationAttributeOption]') and NAME='ColorSquaresRgb') BEGIN ALTER TABLE [SpecificationAttributeOption] ADD [ColorSquaresRgb] nvarchar(100) NULL END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'customersettings.enteringemailtwice') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'customersettings.enteringemailtwice',N'False',0); END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'pdfsettings.fontfilename') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'pdfsettings.fontfilename', N'FreeSerif.ttf', 0) END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[ActivityLog]') and NAME='IpAddress') BEGIN ALTER TABLE [ActivityLog] ADD [IpAddress] nvarchar(200) NULL END GO --a stored procedure update IF EXISTS ( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ProductLoadAllPaged]') AND OBJECTPROPERTY(object_id,N'IsProcedure') = 1) DROP PROCEDURE [ProductLoadAllPaged] GO CREATE PROCEDURE [dbo].[ProductLoadAllPaged] ( @CategoryIds nvarchar(MAX) = null, --a list of category IDs (comma-separated list). e.g. 1,2,3 @ManufacturerId int = 0, @StoreId int = 0, @VendorId int = 0, @WarehouseId int = 0, @ProductTypeId int = null, --product type identifier, null - load all products @VisibleIndividuallyOnly bit = 0, --0 - load all products , 1 - "visible indivially" only @MarkedAsNewOnly bit = 0, --0 - load all products , 1 - "marked as new" only @ProductTagId int = 0, @FeaturedProducts bit = null, --0 featured only , 1 not featured only, null - load all products @PriceMin decimal(18, 4) = null, @PriceMax decimal(18, 4) = null, @Keywords nvarchar(4000) = null, @SearchDescriptions bit = 0, --a value indicating whether to search by a specified "keyword" in product descriptions @SearchSku bit = 0, --a value indicating whether to search by a specified "keyword" in product SKU @SearchProductTags bit = 0, --a value indicating whether to search by a specified "keyword" in product tags @UseFullTextSearch bit = 0, @FullTextMode int = 0, --0 - using CONTAINS with , 5 - using CONTAINS and OR with , 10 - using CONTAINS and AND with @FilteredSpecs nvarchar(MAX) = null, --filter by specification attribute options (comma-separated list of IDs). e.g. 14,15,16 @LanguageId int = 0, @OrderBy int = 0, --0 - position, 5 - Name: A to Z, 6 - Name: Z to A, 10 - Price: Low to High, 11 - Price: High to Low, 15 - creation date @AllowedCustomerRoleIds nvarchar(MAX) = null, --a list of customer role IDs (comma-separated list) for which a product should be shown (if a subjet to ACL) @PageIndex int = 0, @PageSize int = 2147483644, @ShowHidden bit = 0, @OverridePublished bit = null, --null - process "Published" property according to "showHidden" parameter, true - load only "Published" products, false - load only "Unpublished" products @LoadFilterableSpecificationAttributeOptionIds bit = 0, --a value indicating whether we should load the specification attribute option identifiers applied to loaded products (all pages) @FilterableSpecificationAttributeOptionIds nvarchar(MAX) = null OUTPUT, --the specification attribute option identifiers applied to loaded products (all pages). returned as a comma separated list of identifiers @TotalRecords int = null OUTPUT ) AS BEGIN /* Products that filtered by keywords */ CREATE TABLE #KeywordProducts ( [ProductId] int NOT NULL ) DECLARE @SearchKeywords bit, @OriginalKeywords nvarchar(4000), @sql nvarchar(max), @sql_orderby nvarchar(max) SET NOCOUNT ON --filter by keywords SET @Keywords = isnull(@Keywords, '') SET @Keywords = rtrim(ltrim(@Keywords)) SET @OriginalKeywords = @Keywords IF ISNULL(@Keywords, '') != '' BEGIN SET @SearchKeywords = 1 IF @UseFullTextSearch = 1 BEGIN --remove wrong chars (' ") SET @Keywords = REPLACE(@Keywords, '''', '') SET @Keywords = REPLACE(@Keywords, '"', '') --full-text search IF @FullTextMode = 0 BEGIN --0 - using CONTAINS with SET @Keywords = ' "' + @Keywords + '*" ' END ELSE BEGIN --5 - using CONTAINS and OR with --10 - using CONTAINS and AND with --clean multiple spaces WHILE CHARINDEX(' ', @Keywords) > 0 SET @Keywords = REPLACE(@Keywords, ' ', ' ') DECLARE @concat_term nvarchar(100) IF @FullTextMode = 5 --5 - using CONTAINS and OR with BEGIN SET @concat_term = 'OR' END IF @FullTextMode = 10 --10 - using CONTAINS and AND with BEGIN SET @concat_term = 'AND' END --now let's build search string declare @fulltext_keywords nvarchar(4000) set @fulltext_keywords = N'' declare @index int set @index = CHARINDEX(' ', @Keywords, 0) -- if index = 0, then only one field was passed IF(@index = 0) set @fulltext_keywords = ' "' + @Keywords + '*" ' ELSE BEGIN DECLARE @first BIT SET @first = 1 WHILE @index > 0 BEGIN IF (@first = 0) SET @fulltext_keywords = @fulltext_keywords + ' ' + @concat_term + ' ' ELSE SET @first = 0 SET @fulltext_keywords = @fulltext_keywords + '"' + SUBSTRING(@Keywords, 1, @index - 1) + '*"' SET @Keywords = SUBSTRING(@Keywords, @index + 1, LEN(@Keywords) - @index) SET @index = CHARINDEX(' ', @Keywords, 0) end -- add the last field IF LEN(@fulltext_keywords) > 0 SET @fulltext_keywords = @fulltext_keywords + ' ' + @concat_term + ' ' + '"' + SUBSTRING(@Keywords, 1, LEN(@Keywords)) + '*"' END SET @Keywords = @fulltext_keywords END END ELSE BEGIN --usual search by PATINDEX SET @Keywords = '%' + @Keywords + '%' END --PRINT @Keywords --product name SET @sql = ' INSERT INTO #KeywordProducts ([ProductId]) SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[Name], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[Name]) > 0 ' --localized product name SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''Name''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' IF @SearchDescriptions = 1 BEGIN --product short description SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[ShortDescription], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[ShortDescription]) > 0 ' --product full description SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[FullDescription], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[FullDescription]) > 0 ' --localized product short description SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''ShortDescription''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' --localized product full description SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''FullDescription''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' END --SKU (exact match) IF @SearchSku = 1 BEGIN SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE p.[Sku] = @OriginalKeywords ' END IF @SearchProductTags = 1 BEGIN --product tags (exact match) SET @sql = @sql + ' UNION SELECT pptm.Product_Id FROM Product_ProductTag_Mapping pptm with(NOLOCK) INNER JOIN ProductTag pt with(NOLOCK) ON pt.Id = pptm.ProductTag_Id WHERE pt.[Name] = @OriginalKeywords ' --localized product tags SET @sql = @sql + ' UNION SELECT pptm.Product_Id FROM LocalizedProperty lp with (NOLOCK) INNER JOIN Product_ProductTag_Mapping pptm with(NOLOCK) ON lp.EntityId = pptm.ProductTag_Id WHERE lp.LocaleKeyGroup = N''ProductTag'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''Name'' AND lp.[LocaleValue] = @OriginalKeywords ' END --PRINT (@sql) EXEC sp_executesql @sql, N'@Keywords nvarchar(4000), @OriginalKeywords nvarchar(4000)', @Keywords, @OriginalKeywords END ELSE BEGIN SET @SearchKeywords = 0 END --filter by category IDs SET @CategoryIds = isnull(@CategoryIds, '') CREATE TABLE #FilteredCategoryIds ( CategoryId int not null ) INSERT INTO #FilteredCategoryIds (CategoryId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@CategoryIds, ',') DECLARE @CategoryIdsCount int SET @CategoryIdsCount = (SELECT COUNT(1) FROM #FilteredCategoryIds) --filter by customer role IDs (access control list) SET @AllowedCustomerRoleIds = isnull(@AllowedCustomerRoleIds, '') CREATE TABLE #FilteredCustomerRoleIds ( CustomerRoleId int not null ) INSERT INTO #FilteredCustomerRoleIds (CustomerRoleId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@AllowedCustomerRoleIds, ',') --paging DECLARE @PageLowerBound int DECLARE @PageUpperBound int DECLARE @RowsToReturn int SET @RowsToReturn = @PageSize * (@PageIndex + 1) SET @PageLowerBound = @PageSize * @PageIndex SET @PageUpperBound = @PageLowerBound + @PageSize + 1 CREATE TABLE #DisplayOrderTmp ( [Id] int IDENTITY (1, 1) NOT NULL, [ProductId] int NOT NULL ) SET @sql = ' INSERT INTO #DisplayOrderTmp ([ProductId]) SELECT p.Id FROM Product p with (NOLOCK)' IF @CategoryIdsCount > 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_Category_Mapping pcm with (NOLOCK) ON p.Id = pcm.ProductId' END IF @ManufacturerId > 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_Manufacturer_Mapping pmm with (NOLOCK) ON p.Id = pmm.ProductId' END IF ISNULL(@ProductTagId, 0) != 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_ProductTag_Mapping pptm with (NOLOCK) ON p.Id = pptm.Product_Id' END --searching by keywords IF @SearchKeywords = 1 BEGIN SET @sql = @sql + ' JOIN #KeywordProducts kp ON p.Id = kp.ProductId' END SET @sql = @sql + ' WHERE p.Deleted = 0' --filter by category IF @CategoryIdsCount > 0 BEGIN SET @sql = @sql + ' AND pcm.CategoryId IN (SELECT CategoryId FROM #FilteredCategoryIds)' IF @FeaturedProducts IS NOT NULL BEGIN SET @sql = @sql + ' AND pcm.IsFeaturedProduct = ' + CAST(@FeaturedProducts AS nvarchar(max)) END END --filter by manufacturer IF @ManufacturerId > 0 BEGIN SET @sql = @sql + ' AND pmm.ManufacturerId = ' + CAST(@ManufacturerId AS nvarchar(max)) IF @FeaturedProducts IS NOT NULL BEGIN SET @sql = @sql + ' AND pmm.IsFeaturedProduct = ' + CAST(@FeaturedProducts AS nvarchar(max)) END END --filter by vendor IF @VendorId > 0 BEGIN SET @sql = @sql + ' AND p.VendorId = ' + CAST(@VendorId AS nvarchar(max)) END --filter by warehouse IF @WarehouseId > 0 BEGIN --we should also ensure that 'ManageInventoryMethodId' is set to 'ManageStock' (1) --but we skip it in order to prevent hard-coded values (e.g. 1) and for better performance SET @sql = @sql + ' AND ( (p.UseMultipleWarehouses = 0 AND p.WarehouseId = ' + CAST(@WarehouseId AS nvarchar(max)) + ') OR (p.UseMultipleWarehouses > 0 AND EXISTS (SELECT 1 FROM ProductWarehouseInventory [pwi] WHERE [pwi].WarehouseId = ' + CAST(@WarehouseId AS nvarchar(max)) + ' AND [pwi].ProductId = p.Id)) )' END --filter by product type IF @ProductTypeId is not null BEGIN SET @sql = @sql + ' AND p.ProductTypeId = ' + CAST(@ProductTypeId AS nvarchar(max)) END --filter by "visible individually" IF @VisibleIndividuallyOnly = 1 BEGIN SET @sql = @sql + ' AND p.VisibleIndividually = 1' END --filter by "marked as new" IF @MarkedAsNewOnly = 1 BEGIN SET @sql = @sql + ' AND p.MarkAsNew = 1 AND (getutcdate() BETWEEN ISNULL(p.MarkAsNewStartDateTimeUtc, ''1/1/1900'') and ISNULL(p.MarkAsNewEndDateTimeUtc, ''1/1/2999''))' END --filter by product tag IF ISNULL(@ProductTagId, 0) != 0 BEGIN SET @sql = @sql + ' AND pptm.ProductTag_Id = ' + CAST(@ProductTagId AS nvarchar(max)) END --"Published" property IF (@OverridePublished is null) BEGIN --process according to "showHidden" IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND p.Published = 1' END END ELSE IF (@OverridePublished = 1) BEGIN --published only SET @sql = @sql + ' AND p.Published = 1' END ELSE IF (@OverridePublished = 0) BEGIN --unpublished only SET @sql = @sql + ' AND p.Published = 0' END --show hidden IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND p.Deleted = 0 AND (getutcdate() BETWEEN ISNULL(p.AvailableStartDateTimeUtc, ''1/1/1900'') and ISNULL(p.AvailableEndDateTimeUtc, ''1/1/2999''))' END --min price IF @PriceMin is not null BEGIN SET @sql = @sql + ' AND ( ( --special price (specified price and valid date range) (p.SpecialPrice IS NOT NULL AND (getutcdate() BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.SpecialPrice >= ' + CAST(@PriceMin AS nvarchar(max)) + ') ) OR ( --regular price (price isnt specified or date range isnt valid) (p.SpecialPrice IS NULL OR (getutcdate() NOT BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.Price >= ' + CAST(@PriceMin AS nvarchar(max)) + ') ) )' END --max price IF @PriceMax is not null BEGIN SET @sql = @sql + ' AND ( ( --special price (specified price and valid date range) (p.SpecialPrice IS NOT NULL AND (getutcdate() BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.SpecialPrice <= ' + CAST(@PriceMax AS nvarchar(max)) + ') ) OR ( --regular price (price isnt specified or date range isnt valid) (p.SpecialPrice IS NULL OR (getutcdate() NOT BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.Price <= ' + CAST(@PriceMax AS nvarchar(max)) + ') ) )' END --show hidden and ACL IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND (p.SubjectToAcl = 0 OR EXISTS ( SELECT 1 FROM #FilteredCustomerRoleIds [fcr] WHERE [fcr].CustomerRoleId IN ( SELECT [acl].CustomerRoleId FROM [AclRecord] acl with (NOLOCK) WHERE [acl].EntityId = p.Id AND [acl].EntityName = ''Product'' ) ))' END --show hidden and filter by store IF @StoreId > 0 BEGIN SET @sql = @sql + ' AND (p.LimitedToStores = 0 OR EXISTS ( SELECT 1 FROM [StoreMapping] sm with (NOLOCK) WHERE [sm].EntityId = p.Id AND [sm].EntityName = ''Product'' and [sm].StoreId=' + CAST(@StoreId AS nvarchar(max)) + ' ))' END --filter by specification attribution options SET @FilteredSpecs = isnull(@FilteredSpecs, '') CREATE TABLE #FilteredSpecs ( SpecificationAttributeOptionId int not null ) INSERT INTO #FilteredSpecs (SpecificationAttributeOptionId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@FilteredSpecs, ',') DECLARE @SpecAttributesCount int SET @SpecAttributesCount = (SELECT COUNT(1) FROM #FilteredSpecs) IF @SpecAttributesCount > 0 BEGIN --do it for each specified specification option DECLARE @SpecificationAttributeOptionId int DECLARE cur_SpecificationAttributeOption CURSOR FOR SELECT [SpecificationAttributeOptionId] FROM [#FilteredSpecs] OPEN cur_SpecificationAttributeOption FETCH NEXT FROM cur_SpecificationAttributeOption INTO @SpecificationAttributeOptionId WHILE @@FETCH_STATUS = 0 BEGIN SET @sql = @sql + ' AND p.Id in (select psam.ProductId from [Product_SpecificationAttribute_Mapping] psam with (NOLOCK) where psam.AllowFiltering = 1 and psam.SpecificationAttributeOptionId = ' + CAST(@SpecificationAttributeOptionId AS nvarchar(max)) + ')' --fetch next identifier FETCH NEXT FROM cur_SpecificationAttributeOption INTO @SpecificationAttributeOptionId END CLOSE cur_SpecificationAttributeOption DEALLOCATE cur_SpecificationAttributeOption END --sorting SET @sql_orderby = '' IF @OrderBy = 5 /* Name: A to Z */ SET @sql_orderby = ' p.[Name] ASC' ELSE IF @OrderBy = 6 /* Name: Z to A */ SET @sql_orderby = ' p.[Name] DESC' ELSE IF @OrderBy = 10 /* Price: Low to High */ SET @sql_orderby = ' p.[Price] ASC' ELSE IF @OrderBy = 11 /* Price: High to Low */ SET @sql_orderby = ' p.[Price] DESC' ELSE IF @OrderBy = 15 /* creation date */ SET @sql_orderby = ' p.[CreatedOnUtc] DESC' ELSE /* default sorting, 0 (position) */ BEGIN --category position (display order) IF @CategoryIdsCount > 0 SET @sql_orderby = ' pcm.DisplayOrder ASC' --manufacturer position (display order) IF @ManufacturerId > 0 BEGIN IF LEN(@sql_orderby) > 0 SET @sql_orderby = @sql_orderby + ', ' SET @sql_orderby = @sql_orderby + ' pmm.DisplayOrder ASC' END --name IF LEN(@sql_orderby) > 0 SET @sql_orderby = @sql_orderby + ', ' SET @sql_orderby = @sql_orderby + ' p.[Name] ASC' END SET @sql = @sql + ' ORDER BY' + @sql_orderby --PRINT (@sql) EXEC sp_executesql @sql DROP TABLE #FilteredCategoryIds DROP TABLE #FilteredSpecs DROP TABLE #FilteredCustomerRoleIds DROP TABLE #KeywordProducts CREATE TABLE #PageIndex ( [IndexId] int IDENTITY (1, 1) NOT NULL, [ProductId] int NOT NULL ) INSERT INTO #PageIndex ([ProductId]) SELECT ProductId FROM #DisplayOrderTmp GROUP BY ProductId ORDER BY min([Id]) --total records SET @TotalRecords = @@rowcount DROP TABLE #DisplayOrderTmp --prepare filterable specification attribute option identifier (if requested) IF @LoadFilterableSpecificationAttributeOptionIds = 1 BEGIN CREATE TABLE #FilterableSpecs ( [SpecificationAttributeOptionId] int NOT NULL ) INSERT INTO #FilterableSpecs ([SpecificationAttributeOptionId]) SELECT DISTINCT [psam].SpecificationAttributeOptionId FROM [Product_SpecificationAttribute_Mapping] [psam] with (NOLOCK) WHERE [psam].[AllowFiltering] = 1 AND [psam].[ProductId] IN (SELECT [pi].ProductId FROM #PageIndex [pi]) --build comma separated list of filterable identifiers SELECT @FilterableSpecificationAttributeOptionIds = COALESCE(@FilterableSpecificationAttributeOptionIds + ',' , '') + CAST(SpecificationAttributeOptionId as nvarchar(4000)) FROM #FilterableSpecs DROP TABLE #FilterableSpecs END --return products SELECT TOP (@RowsToReturn) p.* FROM #PageIndex [pi] INNER JOIN Product p with (NOLOCK) on p.Id = [pi].[ProductId] WHERE [pi].IndexId > @PageLowerBound AND [pi].IndexId < @PageUpperBound ORDER BY [pi].IndexId DROP TABLE #PageIndex END GO IF EXISTS ( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[FullText_Enable]') AND OBJECTPROPERTY(object_id,N'IsProcedure') = 1) DROP PROCEDURE [FullText_Enable] GO CREATE PROCEDURE [FullText_Enable] AS BEGIN --create catalog EXEC(' IF NOT EXISTS (SELECT 1 FROM sys.fulltext_catalogs WHERE [name] = ''nopCommerceFullTextCatalog'') CREATE FULLTEXT CATALOG [nopCommerceFullTextCatalog] AS DEFAULT') --create indexes DECLARE @create_index_text nvarchar(4000) SET @create_index_text = ' IF NOT EXISTS (SELECT 1 FROM sys.fulltext_indexes WHERE object_id = object_id(''[Product]'')) CREATE FULLTEXT INDEX ON [Product]([Name], [ShortDescription], [FullDescription]) KEY INDEX [' + dbo.[nop_getprimarykey_indexname] ('Product') + '] ON [nopCommerceFullTextCatalog] WITH CHANGE_TRACKING AUTO' EXEC(@create_index_text) SET @create_index_text = ' IF NOT EXISTS (SELECT 1 FROM sys.fulltext_indexes WHERE object_id = object_id(''[LocalizedProperty]'')) CREATE FULLTEXT INDEX ON [LocalizedProperty]([LocaleValue]) KEY INDEX [' + dbo.[nop_getprimarykey_indexname] ('LocalizedProperty') + '] ON [nopCommerceFullTextCatalog] WITH CHANGE_TRACKING AUTO' EXEC(@create_index_text) SET @create_index_text = ' IF NOT EXISTS (SELECT 1 FROM sys.fulltext_indexes WHERE object_id = object_id(''[ProductTag]'')) CREATE FULLTEXT INDEX ON [ProductTag]([Name]) KEY INDEX [' + dbo.[nop_getprimarykey_indexname] ('ProductTag') + '] ON [nopCommerceFullTextCatalog] WITH CHANGE_TRACKING AUTO' EXEC(@create_index_text) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'taxsettings.logerrors') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'taxsettings.logerrors', N'True', 0) END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[Product]') and NAME='NotReturnable') BEGIN ALTER TABLE [Product] ADD [NotReturnable] bit NULL END GO UPDATE [Product] SET [NotReturnable] = 0 WHERE [NotReturnable] IS NULL GO ALTER TABLE [Product] ALTER COLUMN [NotReturnable] bit NOT NULL GO --new activity types IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'Impersonation.Started') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'Impersonation.Started', N'Customer impersonation session. Started', N'true') END GO IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'Impersonation.Finished') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'Impersonation.Finished', N'Customer impersonation session. Finished', N'true') END GO --new table IF NOT EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Forums_PostVote]') and OBJECTPROPERTY(object_id, N'IsUserTable') = 1) BEGIN CREATE TABLE [dbo].[Forums_PostVote]( [Id] [int] IDENTITY(1,1) NOT NULL, [ForumPostId] [int] NOT NULL, [CustomerId] [int] NOT NULL, [IsUp] [bit] NOT NULL, [CreatedOnUtc] [datetime] NOT NULL PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ) END GO IF EXISTS (SELECT 1 FROM sys.objects WHERE name = 'Forums_PostVote_Forums_Post' AND parent_object_id = Object_id('Forums_PostVote') AND Objectproperty(object_id, N'IsForeignKey') = 1) BEGIN ALTER TABLE dbo.Forums_PostVote DROP CONSTRAINT Forums_PostVote_Forums_Post END GO ALTER TABLE [dbo].[Forums_PostVote] WITH CHECK ADD CONSTRAINT [Forums_PostVote_Forums_Post] FOREIGN KEY([ForumPostId]) REFERENCES [dbo].[Forums_Post] ([Id]) ON DELETE CASCADE GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[Forums_Post]') and NAME='VoteCount') BEGIN ALTER TABLE [Forums_Post] ADD [VoteCount] int NULL END GO UPDATE [Forums_Post] SET [VoteCount] = 0 WHERE [VoteCount] IS NULL GO ALTER TABLE [Forums_Post] ALTER COLUMN [VoteCount] int NOT NULL GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'forumsettings.allowpostvoting') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'forumsettings.allowpostvoting', N'True', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'forumsettings.maxvotesperday') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'forumsettings.maxvotesperday', N'30', 0) END GO IF EXISTS ( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ProductLoadAllPaged]') AND OBJECTPROPERTY(object_id,N'IsProcedure') = 1) DROP PROCEDURE [ProductLoadAllPaged] GO CREATE PROCEDURE [dbo].[ProductLoadAllPaged] ( @CategoryIds nvarchar(MAX) = null, --a list of category IDs (comma-separated list). e.g. 1,2,3 @ManufacturerId int = 0, @StoreId int = 0, @VendorId int = 0, @WarehouseId int = 0, @ProductTypeId int = null, --product type identifier, null - load all products @VisibleIndividuallyOnly bit = 0, --0 - load all products , 1 - "visible indivially" only @MarkedAsNewOnly bit = 0, --0 - load all products , 1 - "marked as new" only @ProductTagId int = 0, @FeaturedProducts bit = null, --0 featured only , 1 not featured only, null - load all products @PriceMin decimal(18, 4) = null, @PriceMax decimal(18, 4) = null, @Keywords nvarchar(4000) = null, @SearchDescriptions bit = 0, --a value indicating whether to search by a specified "keyword" in product descriptions @SearchManufacturerPartNumber bit = 0, -- a value indicating whether to search by a specified "keyword" in manufacturer part number @SearchSku bit = 0, --a value indicating whether to search by a specified "keyword" in product SKU @SearchProductTags bit = 0, --a value indicating whether to search by a specified "keyword" in product tags @UseFullTextSearch bit = 0, @FullTextMode int = 0, --0 - using CONTAINS with , 5 - using CONTAINS and OR with , 10 - using CONTAINS and AND with @FilteredSpecs nvarchar(MAX) = null, --filter by specification attribute options (comma-separated list of IDs). e.g. 14,15,16 @LanguageId int = 0, @OrderBy int = 0, --0 - position, 5 - Name: A to Z, 6 - Name: Z to A, 10 - Price: Low to High, 11 - Price: High to Low, 15 - creation date @AllowedCustomerRoleIds nvarchar(MAX) = null, --a list of customer role IDs (comma-separated list) for which a product should be shown (if a subjet to ACL) @PageIndex int = 0, @PageSize int = 2147483644, @ShowHidden bit = 0, @OverridePublished bit = null, --null - process "Published" property according to "showHidden" parameter, true - load only "Published" products, false - load only "Unpublished" products @LoadFilterableSpecificationAttributeOptionIds bit = 0, --a value indicating whether we should load the specification attribute option identifiers applied to loaded products (all pages) @FilterableSpecificationAttributeOptionIds nvarchar(MAX) = null OUTPUT, --the specification attribute option identifiers applied to loaded products (all pages). returned as a comma separated list of identifiers @TotalRecords int = null OUTPUT ) AS BEGIN /* Products that filtered by keywords */ CREATE TABLE #KeywordProducts ( [ProductId] int NOT NULL ) DECLARE @SearchKeywords bit, @OriginalKeywords nvarchar(4000), @sql nvarchar(max), @sql_orderby nvarchar(max) SET NOCOUNT ON --filter by keywords SET @Keywords = isnull(@Keywords, '') SET @Keywords = rtrim(ltrim(@Keywords)) SET @OriginalKeywords = @Keywords IF ISNULL(@Keywords, '') != '' BEGIN SET @SearchKeywords = 1 IF @UseFullTextSearch = 1 BEGIN --remove wrong chars (' ") SET @Keywords = REPLACE(@Keywords, '''', '') SET @Keywords = REPLACE(@Keywords, '"', '') --full-text search IF @FullTextMode = 0 BEGIN --0 - using CONTAINS with SET @Keywords = ' "' + @Keywords + '*" ' END ELSE BEGIN --5 - using CONTAINS and OR with --10 - using CONTAINS and AND with --clean multiple spaces WHILE CHARINDEX(' ', @Keywords) > 0 SET @Keywords = REPLACE(@Keywords, ' ', ' ') DECLARE @concat_term nvarchar(100) IF @FullTextMode = 5 --5 - using CONTAINS and OR with BEGIN SET @concat_term = 'OR' END IF @FullTextMode = 10 --10 - using CONTAINS and AND with BEGIN SET @concat_term = 'AND' END --now let's build search string declare @fulltext_keywords nvarchar(4000) set @fulltext_keywords = N'' declare @index int set @index = CHARINDEX(' ', @Keywords, 0) -- if index = 0, then only one field was passed IF(@index = 0) set @fulltext_keywords = ' "' + @Keywords + '*" ' ELSE BEGIN DECLARE @first BIT SET @first = 1 WHILE @index > 0 BEGIN IF (@first = 0) SET @fulltext_keywords = @fulltext_keywords + ' ' + @concat_term + ' ' ELSE SET @first = 0 SET @fulltext_keywords = @fulltext_keywords + '"' + SUBSTRING(@Keywords, 1, @index - 1) + '*"' SET @Keywords = SUBSTRING(@Keywords, @index + 1, LEN(@Keywords) - @index) SET @index = CHARINDEX(' ', @Keywords, 0) end -- add the last field IF LEN(@fulltext_keywords) > 0 SET @fulltext_keywords = @fulltext_keywords + ' ' + @concat_term + ' ' + '"' + SUBSTRING(@Keywords, 1, LEN(@Keywords)) + '*"' END SET @Keywords = @fulltext_keywords END END ELSE BEGIN --usual search by PATINDEX SET @Keywords = '%' + @Keywords + '%' END --PRINT @Keywords --product name SET @sql = ' INSERT INTO #KeywordProducts ([ProductId]) SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[Name], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[Name]) > 0 ' --localized product name SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''Name''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' IF @SearchDescriptions = 1 BEGIN --product short description SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[ShortDescription], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[ShortDescription]) > 0 ' --product full description SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[FullDescription], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[FullDescription]) > 0 ' --localized product short description SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''ShortDescription''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' --localized product full description SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''FullDescription''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' END --manufacturer part number (exact match) IF @SearchManufacturerPartNumber = 1 BEGIN SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE p.[ManufacturerPartNumber] = @OriginalKeywords ' END --SKU (exact match) IF @SearchSku = 1 BEGIN SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE p.[Sku] = @OriginalKeywords ' END IF @SearchProductTags = 1 BEGIN --product tags (exact match) SET @sql = @sql + ' UNION SELECT pptm.Product_Id FROM Product_ProductTag_Mapping pptm with(NOLOCK) INNER JOIN ProductTag pt with(NOLOCK) ON pt.Id = pptm.ProductTag_Id WHERE pt.[Name] = @OriginalKeywords ' --localized product tags SET @sql = @sql + ' UNION SELECT pptm.Product_Id FROM LocalizedProperty lp with (NOLOCK) INNER JOIN Product_ProductTag_Mapping pptm with(NOLOCK) ON lp.EntityId = pptm.ProductTag_Id WHERE lp.LocaleKeyGroup = N''ProductTag'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''Name'' AND lp.[LocaleValue] = @OriginalKeywords ' END --PRINT (@sql) EXEC sp_executesql @sql, N'@Keywords nvarchar(4000), @OriginalKeywords nvarchar(4000)', @Keywords, @OriginalKeywords END ELSE BEGIN SET @SearchKeywords = 0 END --filter by category IDs SET @CategoryIds = isnull(@CategoryIds, '') CREATE TABLE #FilteredCategoryIds ( CategoryId int not null ) INSERT INTO #FilteredCategoryIds (CategoryId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@CategoryIds, ',') DECLARE @CategoryIdsCount int SET @CategoryIdsCount = (SELECT COUNT(1) FROM #FilteredCategoryIds) --filter by customer role IDs (access control list) SET @AllowedCustomerRoleIds = isnull(@AllowedCustomerRoleIds, '') CREATE TABLE #FilteredCustomerRoleIds ( CustomerRoleId int not null ) INSERT INTO #FilteredCustomerRoleIds (CustomerRoleId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@AllowedCustomerRoleIds, ',') --paging DECLARE @PageLowerBound int DECLARE @PageUpperBound int DECLARE @RowsToReturn int SET @RowsToReturn = @PageSize * (@PageIndex + 1) SET @PageLowerBound = @PageSize * @PageIndex SET @PageUpperBound = @PageLowerBound + @PageSize + 1 CREATE TABLE #DisplayOrderTmp ( [Id] int IDENTITY (1, 1) NOT NULL, [ProductId] int NOT NULL ) SET @sql = ' INSERT INTO #DisplayOrderTmp ([ProductId]) SELECT p.Id FROM Product p with (NOLOCK)' IF @CategoryIdsCount > 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_Category_Mapping pcm with (NOLOCK) ON p.Id = pcm.ProductId' END IF @ManufacturerId > 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_Manufacturer_Mapping pmm with (NOLOCK) ON p.Id = pmm.ProductId' END IF ISNULL(@ProductTagId, 0) != 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_ProductTag_Mapping pptm with (NOLOCK) ON p.Id = pptm.Product_Id' END --searching by keywords IF @SearchKeywords = 1 BEGIN SET @sql = @sql + ' JOIN #KeywordProducts kp ON p.Id = kp.ProductId' END SET @sql = @sql + ' WHERE p.Deleted = 0' --filter by category IF @CategoryIdsCount > 0 BEGIN SET @sql = @sql + ' AND pcm.CategoryId IN (SELECT CategoryId FROM #FilteredCategoryIds)' IF @FeaturedProducts IS NOT NULL BEGIN SET @sql = @sql + ' AND pcm.IsFeaturedProduct = ' + CAST(@FeaturedProducts AS nvarchar(max)) END END --filter by manufacturer IF @ManufacturerId > 0 BEGIN SET @sql = @sql + ' AND pmm.ManufacturerId = ' + CAST(@ManufacturerId AS nvarchar(max)) IF @FeaturedProducts IS NOT NULL BEGIN SET @sql = @sql + ' AND pmm.IsFeaturedProduct = ' + CAST(@FeaturedProducts AS nvarchar(max)) END END --filter by vendor IF @VendorId > 0 BEGIN SET @sql = @sql + ' AND p.VendorId = ' + CAST(@VendorId AS nvarchar(max)) END --filter by warehouse IF @WarehouseId > 0 BEGIN --we should also ensure that 'ManageInventoryMethodId' is set to 'ManageStock' (1) --but we skip it in order to prevent hard-coded values (e.g. 1) and for better performance SET @sql = @sql + ' AND ( (p.UseMultipleWarehouses = 0 AND p.WarehouseId = ' + CAST(@WarehouseId AS nvarchar(max)) + ') OR (p.UseMultipleWarehouses > 0 AND EXISTS (SELECT 1 FROM ProductWarehouseInventory [pwi] WHERE [pwi].WarehouseId = ' + CAST(@WarehouseId AS nvarchar(max)) + ' AND [pwi].ProductId = p.Id)) )' END --filter by product type IF @ProductTypeId is not null BEGIN SET @sql = @sql + ' AND p.ProductTypeId = ' + CAST(@ProductTypeId AS nvarchar(max)) END --filter by "visible individually" IF @VisibleIndividuallyOnly = 1 BEGIN SET @sql = @sql + ' AND p.VisibleIndividually = 1' END --filter by "marked as new" IF @MarkedAsNewOnly = 1 BEGIN SET @sql = @sql + ' AND p.MarkAsNew = 1 AND (getutcdate() BETWEEN ISNULL(p.MarkAsNewStartDateTimeUtc, ''1/1/1900'') and ISNULL(p.MarkAsNewEndDateTimeUtc, ''1/1/2999''))' END --filter by product tag IF ISNULL(@ProductTagId, 0) != 0 BEGIN SET @sql = @sql + ' AND pptm.ProductTag_Id = ' + CAST(@ProductTagId AS nvarchar(max)) END --"Published" property IF (@OverridePublished is null) BEGIN --process according to "showHidden" IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND p.Published = 1' END END ELSE IF (@OverridePublished = 1) BEGIN --published only SET @sql = @sql + ' AND p.Published = 1' END ELSE IF (@OverridePublished = 0) BEGIN --unpublished only SET @sql = @sql + ' AND p.Published = 0' END --show hidden IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND p.Deleted = 0 AND (getutcdate() BETWEEN ISNULL(p.AvailableStartDateTimeUtc, ''1/1/1900'') and ISNULL(p.AvailableEndDateTimeUtc, ''1/1/2999''))' END --min price IF @PriceMin is not null BEGIN SET @sql = @sql + ' AND ( ( --special price (specified price and valid date range) (p.SpecialPrice IS NOT NULL AND (getutcdate() BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.SpecialPrice >= ' + CAST(@PriceMin AS nvarchar(max)) + ') ) OR ( --regular price (price isnt specified or date range isnt valid) (p.SpecialPrice IS NULL OR (getutcdate() NOT BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.Price >= ' + CAST(@PriceMin AS nvarchar(max)) + ') ) )' END --max price IF @PriceMax is not null BEGIN SET @sql = @sql + ' AND ( ( --special price (specified price and valid date range) (p.SpecialPrice IS NOT NULL AND (getutcdate() BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.SpecialPrice <= ' + CAST(@PriceMax AS nvarchar(max)) + ') ) OR ( --regular price (price isnt specified or date range isnt valid) (p.SpecialPrice IS NULL OR (getutcdate() NOT BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.Price <= ' + CAST(@PriceMax AS nvarchar(max)) + ') ) )' END --show hidden and ACL IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND (p.SubjectToAcl = 0 OR EXISTS ( SELECT 1 FROM #FilteredCustomerRoleIds [fcr] WHERE [fcr].CustomerRoleId IN ( SELECT [acl].CustomerRoleId FROM [AclRecord] acl with (NOLOCK) WHERE [acl].EntityId = p.Id AND [acl].EntityName = ''Product'' ) ))' END --show hidden and filter by store IF @StoreId > 0 BEGIN SET @sql = @sql + ' AND (p.LimitedToStores = 0 OR EXISTS ( SELECT 1 FROM [StoreMapping] sm with (NOLOCK) WHERE [sm].EntityId = p.Id AND [sm].EntityName = ''Product'' and [sm].StoreId=' + CAST(@StoreId AS nvarchar(max)) + ' ))' END --filter by specification attribution options SET @FilteredSpecs = isnull(@FilteredSpecs, '') CREATE TABLE #FilteredSpecs ( SpecificationAttributeOptionId int not null ) INSERT INTO #FilteredSpecs (SpecificationAttributeOptionId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@FilteredSpecs, ',') DECLARE @SpecAttributesCount int SET @SpecAttributesCount = (SELECT COUNT(1) FROM #FilteredSpecs) IF @SpecAttributesCount > 0 BEGIN --do it for each specified specification option DECLARE @SpecificationAttributeOptionId int DECLARE cur_SpecificationAttributeOption CURSOR FOR SELECT [SpecificationAttributeOptionId] FROM [#FilteredSpecs] OPEN cur_SpecificationAttributeOption FETCH NEXT FROM cur_SpecificationAttributeOption INTO @SpecificationAttributeOptionId WHILE @@FETCH_STATUS = 0 BEGIN SET @sql = @sql + ' AND p.Id in (select psam.ProductId from [Product_SpecificationAttribute_Mapping] psam with (NOLOCK) where psam.AllowFiltering = 1 and psam.SpecificationAttributeOptionId = ' + CAST(@SpecificationAttributeOptionId AS nvarchar(max)) + ')' --fetch next identifier FETCH NEXT FROM cur_SpecificationAttributeOption INTO @SpecificationAttributeOptionId END CLOSE cur_SpecificationAttributeOption DEALLOCATE cur_SpecificationAttributeOption END --sorting SET @sql_orderby = '' IF @OrderBy = 5 /* Name: A to Z */ SET @sql_orderby = ' p.[Name] ASC' ELSE IF @OrderBy = 6 /* Name: Z to A */ SET @sql_orderby = ' p.[Name] DESC' ELSE IF @OrderBy = 10 /* Price: Low to High */ SET @sql_orderby = ' p.[Price] ASC' ELSE IF @OrderBy = 11 /* Price: High to Low */ SET @sql_orderby = ' p.[Price] DESC' ELSE IF @OrderBy = 15 /* creation date */ SET @sql_orderby = ' p.[CreatedOnUtc] DESC' ELSE /* default sorting, 0 (position) */ BEGIN --category position (display order) IF @CategoryIdsCount > 0 SET @sql_orderby = ' pcm.DisplayOrder ASC' --manufacturer position (display order) IF @ManufacturerId > 0 BEGIN IF LEN(@sql_orderby) > 0 SET @sql_orderby = @sql_orderby + ', ' SET @sql_orderby = @sql_orderby + ' pmm.DisplayOrder ASC' END --name IF LEN(@sql_orderby) > 0 SET @sql_orderby = @sql_orderby + ', ' SET @sql_orderby = @sql_orderby + ' p.[Name] ASC' END SET @sql = @sql + ' ORDER BY' + @sql_orderby --PRINT (@sql) EXEC sp_executesql @sql DROP TABLE #FilteredCategoryIds DROP TABLE #FilteredSpecs DROP TABLE #FilteredCustomerRoleIds DROP TABLE #KeywordProducts CREATE TABLE #PageIndex ( [IndexId] int IDENTITY (1, 1) NOT NULL, [ProductId] int NOT NULL ) INSERT INTO #PageIndex ([ProductId]) SELECT ProductId FROM #DisplayOrderTmp GROUP BY ProductId ORDER BY min([Id]) --total records SET @TotalRecords = @@rowcount DROP TABLE #DisplayOrderTmp --prepare filterable specification attribute option identifier (if requested) IF @LoadFilterableSpecificationAttributeOptionIds = 1 BEGIN CREATE TABLE #FilterableSpecs ( [SpecificationAttributeOptionId] int NOT NULL ) INSERT INTO #FilterableSpecs ([SpecificationAttributeOptionId]) SELECT DISTINCT [psam].SpecificationAttributeOptionId FROM [Product_SpecificationAttribute_Mapping] [psam] with (NOLOCK) WHERE [psam].[AllowFiltering] = 1 AND [psam].[ProductId] IN (SELECT [pi].ProductId FROM #PageIndex [pi]) --build comma separated list of filterable identifiers SELECT @FilterableSpecificationAttributeOptionIds = COALESCE(@FilterableSpecificationAttributeOptionIds + ',' , '') + CAST(SpecificationAttributeOptionId as nvarchar(4000)) FROM #FilterableSpecs DROP TABLE #FilterableSpecs END --return products SELECT TOP (@RowsToReturn) p.* FROM #PageIndex [pi] INNER JOIN Product p with (NOLOCK) on p.Id = [pi].[ProductId] WHERE [pi].IndexId > @PageLowerBound AND [pi].IndexId < @PageUpperBound ORDER BY [pi].IndexId DROP TABLE #PageIndex END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'adminareasettings.popupgridpagesize') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'adminareasettings.popupgridpagesize', N'10', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'customersettings.requireregistrationfordownloadableproducts') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'customersettings.requireregistrationfordownloadableproducts', N'False', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'catalogsettings.showproductreviewstabonaccountpage') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'catalogsettings.showproductreviewstabonaccountpage', N'True', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'catalogsettings.productreviewspagesizeonaccountpage') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'catalogsettings.productreviewspagesizeonaccountpage', N'10', 0) END GO --delete some settings DELETE FROM [Setting] WHERE [name] = N'catalogsettings.IgnoreDiscounts' and [StoreId] > 0 GO DELETE FROM [Setting] WHERE [name] = N'catalogsettings.IgnoreFeaturedProducts' and [StoreId] > 0 GO DELETE FROM [Setting] WHERE [name] = N'catalogsettings.IgnoreAcl' and [StoreId] > 0 GO DELETE FROM [Setting] WHERE [name] = N'catalogsettings.IgnoreStoreLimitations' and [StoreId] > 0 GO DELETE FROM [Setting] WHERE [name] = N'catalogsettings.CacheProductPrices' and [StoreId] > 0 GO --a stored procedure update IF EXISTS ( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[ProductLoadAllPaged]') AND OBJECTPROPERTY(object_id,N'IsProcedure') = 1) DROP PROCEDURE [ProductLoadAllPaged] GO CREATE PROCEDURE [dbo].[ProductLoadAllPaged] ( @CategoryIds nvarchar(MAX) = null, --a list of category IDs (comma-separated list). e.g. 1,2,3 @ManufacturerId int = 0, @StoreId int = 0, @VendorId int = 0, @WarehouseId int = 0, @ProductTypeId int = null, --product type identifier, null - load all products @VisibleIndividuallyOnly bit = 0, --0 - load all products , 1 - "visible indivially" only @MarkedAsNewOnly bit = 0, --0 - load all products , 1 - "marked as new" only @ProductTagId int = 0, @FeaturedProducts bit = null, --0 featured only , 1 not featured only, null - load all products @PriceMin decimal(18, 4) = null, @PriceMax decimal(18, 4) = null, @Keywords nvarchar(4000) = null, @SearchDescriptions bit = 0, --a value indicating whether to search by a specified "keyword" in product descriptions @SearchManufacturerPartNumber bit = 0, -- a value indicating whether to search by a specified "keyword" in manufacturer part number @SearchSku bit = 0, --a value indicating whether to search by a specified "keyword" in product SKU @SearchProductTags bit = 0, --a value indicating whether to search by a specified "keyword" in product tags @UseFullTextSearch bit = 0, @FullTextMode int = 0, --0 - using CONTAINS with , 5 - using CONTAINS and OR with , 10 - using CONTAINS and AND with @FilteredSpecs nvarchar(MAX) = null, --filter by specification attribute options (comma-separated list of IDs). e.g. 14,15,16 @LanguageId int = 0, @OrderBy int = 0, --0 - position, 5 - Name: A to Z, 6 - Name: Z to A, 10 - Price: Low to High, 11 - Price: High to Low, 15 - creation date @AllowedCustomerRoleIds nvarchar(MAX) = null, --a list of customer role IDs (comma-separated list) for which a product should be shown (if a subjet to ACL) @PageIndex int = 0, @PageSize int = 2147483644, @ShowHidden bit = 0, @OverridePublished bit = null, --null - process "Published" property according to "showHidden" parameter, true - load only "Published" products, false - load only "Unpublished" products @LoadFilterableSpecificationAttributeOptionIds bit = 0, --a value indicating whether we should load the specification attribute option identifiers applied to loaded products (all pages) @FilterableSpecificationAttributeOptionIds nvarchar(MAX) = null OUTPUT, --the specification attribute option identifiers applied to loaded products (all pages). returned as a comma separated list of identifiers @TotalRecords int = null OUTPUT ) AS BEGIN /* Products that filtered by keywords */ CREATE TABLE #KeywordProducts ( [ProductId] int NOT NULL ) DECLARE @SearchKeywords bit, @OriginalKeywords nvarchar(4000), @sql nvarchar(max), @sql_orderby nvarchar(max) SET NOCOUNT ON --filter by keywords SET @Keywords = isnull(@Keywords, '') SET @Keywords = rtrim(ltrim(@Keywords)) SET @OriginalKeywords = @Keywords IF ISNULL(@Keywords, '') != '' BEGIN SET @SearchKeywords = 1 IF @UseFullTextSearch = 1 BEGIN --remove wrong chars (' ") SET @Keywords = REPLACE(@Keywords, '''', '') SET @Keywords = REPLACE(@Keywords, '"', '') --full-text search IF @FullTextMode = 0 BEGIN --0 - using CONTAINS with SET @Keywords = ' "' + @Keywords + '*" ' END ELSE BEGIN --5 - using CONTAINS and OR with --10 - using CONTAINS and AND with --clean multiple spaces WHILE CHARINDEX(' ', @Keywords) > 0 SET @Keywords = REPLACE(@Keywords, ' ', ' ') DECLARE @concat_term nvarchar(100) IF @FullTextMode = 5 --5 - using CONTAINS and OR with BEGIN SET @concat_term = 'OR' END IF @FullTextMode = 10 --10 - using CONTAINS and AND with BEGIN SET @concat_term = 'AND' END --now let's build search string declare @fulltext_keywords nvarchar(4000) set @fulltext_keywords = N'' declare @index int set @index = CHARINDEX(' ', @Keywords, 0) -- if index = 0, then only one field was passed IF(@index = 0) set @fulltext_keywords = ' "' + @Keywords + '*" ' ELSE BEGIN DECLARE @first BIT SET @first = 1 WHILE @index > 0 BEGIN IF (@first = 0) SET @fulltext_keywords = @fulltext_keywords + ' ' + @concat_term + ' ' ELSE SET @first = 0 SET @fulltext_keywords = @fulltext_keywords + '"' + SUBSTRING(@Keywords, 1, @index - 1) + '*"' SET @Keywords = SUBSTRING(@Keywords, @index + 1, LEN(@Keywords) - @index) SET @index = CHARINDEX(' ', @Keywords, 0) end -- add the last field IF LEN(@fulltext_keywords) > 0 SET @fulltext_keywords = @fulltext_keywords + ' ' + @concat_term + ' ' + '"' + SUBSTRING(@Keywords, 1, LEN(@Keywords)) + '*"' END SET @Keywords = @fulltext_keywords END END ELSE BEGIN --usual search by PATINDEX SET @Keywords = '%' + @Keywords + '%' END --PRINT @Keywords --product name SET @sql = ' INSERT INTO #KeywordProducts ([ProductId]) SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[Name], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[Name]) > 0 ' --localized product name SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''Name''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' IF @SearchDescriptions = 1 BEGIN --product short description SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[ShortDescription], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[ShortDescription]) > 0 ' --product full description SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE ' IF @UseFullTextSearch = 1 SET @sql = @sql + 'CONTAINS(p.[FullDescription], @Keywords) ' ELSE SET @sql = @sql + 'PATINDEX(@Keywords, p.[FullDescription]) > 0 ' --localized product short description SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''ShortDescription''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' --localized product full description SET @sql = @sql + ' UNION SELECT lp.EntityId FROM LocalizedProperty lp with (NOLOCK) WHERE lp.LocaleKeyGroup = N''Product'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''FullDescription''' IF @UseFullTextSearch = 1 SET @sql = @sql + ' AND CONTAINS(lp.[LocaleValue], @Keywords) ' ELSE SET @sql = @sql + ' AND PATINDEX(@Keywords, lp.[LocaleValue]) > 0 ' END --manufacturer part number (exact match) IF @SearchManufacturerPartNumber = 1 BEGIN SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE p.[ManufacturerPartNumber] = @OriginalKeywords ' END --SKU (exact match) IF @SearchSku = 1 BEGIN SET @sql = @sql + ' UNION SELECT p.Id FROM Product p with (NOLOCK) WHERE p.[Sku] = @OriginalKeywords ' END IF @SearchProductTags = 1 BEGIN --product tags (exact match) SET @sql = @sql + ' UNION SELECT pptm.Product_Id FROM Product_ProductTag_Mapping pptm with(NOLOCK) INNER JOIN ProductTag pt with(NOLOCK) ON pt.Id = pptm.ProductTag_Id WHERE pt.[Name] = @OriginalKeywords ' --localized product tags SET @sql = @sql + ' UNION SELECT pptm.Product_Id FROM LocalizedProperty lp with (NOLOCK) INNER JOIN Product_ProductTag_Mapping pptm with(NOLOCK) ON lp.EntityId = pptm.ProductTag_Id WHERE lp.LocaleKeyGroup = N''ProductTag'' AND lp.LanguageId = ' + ISNULL(CAST(@LanguageId AS nvarchar(max)), '0') + ' AND lp.LocaleKey = N''Name'' AND lp.[LocaleValue] = @OriginalKeywords ' END --PRINT (@sql) EXEC sp_executesql @sql, N'@Keywords nvarchar(4000), @OriginalKeywords nvarchar(4000)', @Keywords, @OriginalKeywords END ELSE BEGIN SET @SearchKeywords = 0 END --filter by category IDs SET @CategoryIds = isnull(@CategoryIds, '') CREATE TABLE #FilteredCategoryIds ( CategoryId int not null ) INSERT INTO #FilteredCategoryIds (CategoryId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@CategoryIds, ',') DECLARE @CategoryIdsCount int SET @CategoryIdsCount = (SELECT COUNT(1) FROM #FilteredCategoryIds) --filter by customer role IDs (access control list) SET @AllowedCustomerRoleIds = isnull(@AllowedCustomerRoleIds, '') CREATE TABLE #FilteredCustomerRoleIds ( CustomerRoleId int not null ) INSERT INTO #FilteredCustomerRoleIds (CustomerRoleId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@AllowedCustomerRoleIds, ',') DECLARE @FilteredCustomerRoleIdsCount int SET @FilteredCustomerRoleIdsCount = (SELECT COUNT(1) FROM #FilteredCustomerRoleIds) --paging DECLARE @PageLowerBound int DECLARE @PageUpperBound int DECLARE @RowsToReturn int SET @RowsToReturn = @PageSize * (@PageIndex + 1) SET @PageLowerBound = @PageSize * @PageIndex SET @PageUpperBound = @PageLowerBound + @PageSize + 1 CREATE TABLE #DisplayOrderTmp ( [Id] int IDENTITY (1, 1) NOT NULL, [ProductId] int NOT NULL ) SET @sql = ' SELECT p.Id FROM Product p with (NOLOCK)' IF @CategoryIdsCount > 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_Category_Mapping pcm with (NOLOCK) ON p.Id = pcm.ProductId' END IF @ManufacturerId > 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_Manufacturer_Mapping pmm with (NOLOCK) ON p.Id = pmm.ProductId' END IF ISNULL(@ProductTagId, 0) != 0 BEGIN SET @sql = @sql + ' LEFT JOIN Product_ProductTag_Mapping pptm with (NOLOCK) ON p.Id = pptm.Product_Id' END --searching by keywords IF @SearchKeywords = 1 BEGIN SET @sql = @sql + ' JOIN #KeywordProducts kp ON p.Id = kp.ProductId' END SET @sql = @sql + ' WHERE p.Deleted = 0' --filter by category IF @CategoryIdsCount > 0 BEGIN SET @sql = @sql + ' AND pcm.CategoryId IN (SELECT CategoryId FROM #FilteredCategoryIds)' IF @FeaturedProducts IS NOT NULL BEGIN SET @sql = @sql + ' AND pcm.IsFeaturedProduct = ' + CAST(@FeaturedProducts AS nvarchar(max)) END END --filter by manufacturer IF @ManufacturerId > 0 BEGIN SET @sql = @sql + ' AND pmm.ManufacturerId = ' + CAST(@ManufacturerId AS nvarchar(max)) IF @FeaturedProducts IS NOT NULL BEGIN SET @sql = @sql + ' AND pmm.IsFeaturedProduct = ' + CAST(@FeaturedProducts AS nvarchar(max)) END END --filter by vendor IF @VendorId > 0 BEGIN SET @sql = @sql + ' AND p.VendorId = ' + CAST(@VendorId AS nvarchar(max)) END --filter by warehouse IF @WarehouseId > 0 BEGIN --we should also ensure that 'ManageInventoryMethodId' is set to 'ManageStock' (1) --but we skip it in order to prevent hard-coded values (e.g. 1) and for better performance SET @sql = @sql + ' AND ( (p.UseMultipleWarehouses = 0 AND p.WarehouseId = ' + CAST(@WarehouseId AS nvarchar(max)) + ') OR (p.UseMultipleWarehouses > 0 AND EXISTS (SELECT 1 FROM ProductWarehouseInventory [pwi] WHERE [pwi].WarehouseId = ' + CAST(@WarehouseId AS nvarchar(max)) + ' AND [pwi].ProductId = p.Id)) )' END --filter by product type IF @ProductTypeId is not null BEGIN SET @sql = @sql + ' AND p.ProductTypeId = ' + CAST(@ProductTypeId AS nvarchar(max)) END --filter by "visible individually" IF @VisibleIndividuallyOnly = 1 BEGIN SET @sql = @sql + ' AND p.VisibleIndividually = 1' END --filter by "marked as new" IF @MarkedAsNewOnly = 1 BEGIN SET @sql = @sql + ' AND p.MarkAsNew = 1 AND (getutcdate() BETWEEN ISNULL(p.MarkAsNewStartDateTimeUtc, ''1/1/1900'') and ISNULL(p.MarkAsNewEndDateTimeUtc, ''1/1/2999''))' END --filter by product tag IF ISNULL(@ProductTagId, 0) != 0 BEGIN SET @sql = @sql + ' AND pptm.ProductTag_Id = ' + CAST(@ProductTagId AS nvarchar(max)) END --"Published" property IF (@OverridePublished is null) BEGIN --process according to "showHidden" IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND p.Published = 1' END END ELSE IF (@OverridePublished = 1) BEGIN --published only SET @sql = @sql + ' AND p.Published = 1' END ELSE IF (@OverridePublished = 0) BEGIN --unpublished only SET @sql = @sql + ' AND p.Published = 0' END --show hidden IF @ShowHidden = 0 BEGIN SET @sql = @sql + ' AND p.Deleted = 0 AND (getutcdate() BETWEEN ISNULL(p.AvailableStartDateTimeUtc, ''1/1/1900'') and ISNULL(p.AvailableEndDateTimeUtc, ''1/1/2999''))' END --min price IF @PriceMin is not null BEGIN SET @sql = @sql + ' AND ( ( --special price (specified price and valid date range) (p.SpecialPrice IS NOT NULL AND (getutcdate() BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.SpecialPrice >= ' + CAST(@PriceMin AS nvarchar(max)) + ') ) OR ( --regular price (price isnt specified or date range isnt valid) (p.SpecialPrice IS NULL OR (getutcdate() NOT BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.Price >= ' + CAST(@PriceMin AS nvarchar(max)) + ') ) )' END --max price IF @PriceMax is not null BEGIN SET @sql = @sql + ' AND ( ( --special price (specified price and valid date range) (p.SpecialPrice IS NOT NULL AND (getutcdate() BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.SpecialPrice <= ' + CAST(@PriceMax AS nvarchar(max)) + ') ) OR ( --regular price (price isnt specified or date range isnt valid) (p.SpecialPrice IS NULL OR (getutcdate() NOT BETWEEN isnull(p.SpecialPriceStartDateTimeUtc, ''1/1/1900'') AND isnull(p.SpecialPriceEndDateTimeUtc, ''1/1/2999''))) AND (p.Price <= ' + CAST(@PriceMax AS nvarchar(max)) + ') ) )' END --show hidden and ACL IF @ShowHidden = 0 and @FilteredCustomerRoleIdsCount > 0 BEGIN SET @sql = @sql + ' AND (p.SubjectToAcl = 0 OR EXISTS ( SELECT 1 FROM #FilteredCustomerRoleIds [fcr] WHERE [fcr].CustomerRoleId IN ( SELECT [acl].CustomerRoleId FROM [AclRecord] acl with (NOLOCK) WHERE [acl].EntityId = p.Id AND [acl].EntityName = ''Product'' ) ))' END --filter by store IF @StoreId > 0 BEGIN SET @sql = @sql + ' AND (p.LimitedToStores = 0 OR EXISTS ( SELECT 1 FROM [StoreMapping] sm with (NOLOCK) WHERE [sm].EntityId = p.Id AND [sm].EntityName = ''Product'' and [sm].StoreId=' + CAST(@StoreId AS nvarchar(max)) + ' ))' END --prepare filterable specification attribute option identifier (if requested) IF @LoadFilterableSpecificationAttributeOptionIds = 1 BEGIN CREATE TABLE #FilterableSpecs ( [SpecificationAttributeOptionId] int NOT NULL ) DECLARE @sql_filterableSpecs nvarchar(max) SET @sql_filterableSpecs = ' INSERT INTO #FilterableSpecs ([SpecificationAttributeOptionId]) SELECT DISTINCT [psam].SpecificationAttributeOptionId FROM [Product_SpecificationAttribute_Mapping] [psam] WITH (NOLOCK) WHERE [psam].[AllowFiltering] = 1 AND [psam].[ProductId] IN (' + @sql + ')' EXEC sp_executesql @sql_filterableSpecs --build comma separated list of filterable identifiers SELECT @FilterableSpecificationAttributeOptionIds = COALESCE(@FilterableSpecificationAttributeOptionIds + ',' , '') + CAST(SpecificationAttributeOptionId as nvarchar(4000)) FROM #FilterableSpecs DROP TABLE #FilterableSpecs END --filter by specification attribution options SET @FilteredSpecs = isnull(@FilteredSpecs, '') CREATE TABLE #FilteredSpecs ( SpecificationAttributeOptionId int not null ) INSERT INTO #FilteredSpecs (SpecificationAttributeOptionId) SELECT CAST(data as int) FROM [nop_splitstring_to_table](@FilteredSpecs, ',') CREATE TABLE #FilteredSpecsWithAttributes ( SpecificationAttributeId int not null, SpecificationAttributeOptionId int not null ) INSERT INTO #FilteredSpecsWithAttributes (SpecificationAttributeId, SpecificationAttributeOptionId) SELECT sao.SpecificationAttributeId, fs.SpecificationAttributeOptionId FROM #FilteredSpecs fs INNER JOIN SpecificationAttributeOption sao ON sao.Id = fs.SpecificationAttributeOptionId ORDER BY sao.SpecificationAttributeId DECLARE @SpecAttributesCount int SET @SpecAttributesCount = (SELECT COUNT(1) FROM #FilteredSpecsWithAttributes) IF @SpecAttributesCount > 0 BEGIN --do it for each specified specification option DECLARE @SpecificationAttributeOptionId int DECLARE @SpecificationAttributeId int DECLARE @LastSpecificationAttributeId int SET @LastSpecificationAttributeId = 0 DECLARE cur_SpecificationAttributeOption CURSOR FOR SELECT SpecificationAttributeId, SpecificationAttributeOptionId FROM #FilteredSpecsWithAttributes OPEN cur_SpecificationAttributeOption FOREACH: FETCH NEXT FROM cur_SpecificationAttributeOption INTO @SpecificationAttributeId, @SpecificationAttributeOptionId IF (@LastSpecificationAttributeId <> 0 AND @SpecificationAttributeId <> @LastSpecificationAttributeId OR @@FETCH_STATUS <> 0) SET @sql = @sql + ' AND p.Id in (select psam.ProductId from [Product_SpecificationAttribute_Mapping] psam with (NOLOCK) where psam.AllowFiltering = 1 and psam.SpecificationAttributeOptionId IN (SELECT SpecificationAttributeOptionId FROM #FilteredSpecsWithAttributes WHERE SpecificationAttributeId = ' + CAST(@LastSpecificationAttributeId AS nvarchar(max)) + '))' SET @LastSpecificationAttributeId = @SpecificationAttributeId IF @@FETCH_STATUS = 0 GOTO FOREACH CLOSE cur_SpecificationAttributeOption DEALLOCATE cur_SpecificationAttributeOption END --sorting SET @sql_orderby = '' IF @OrderBy = 5 /* Name: A to Z */ SET @sql_orderby = ' p.[Name] ASC' ELSE IF @OrderBy = 6 /* Name: Z to A */ SET @sql_orderby = ' p.[Name] DESC' ELSE IF @OrderBy = 10 /* Price: Low to High */ SET @sql_orderby = ' p.[Price] ASC' ELSE IF @OrderBy = 11 /* Price: High to Low */ SET @sql_orderby = ' p.[Price] DESC' ELSE IF @OrderBy = 15 /* creation date */ SET @sql_orderby = ' p.[CreatedOnUtc] DESC' ELSE /* default sorting, 0 (position) */ BEGIN --category position (display order) IF @CategoryIdsCount > 0 SET @sql_orderby = ' pcm.DisplayOrder ASC' --manufacturer position (display order) IF @ManufacturerId > 0 BEGIN IF LEN(@sql_orderby) > 0 SET @sql_orderby = @sql_orderby + ', ' SET @sql_orderby = @sql_orderby + ' pmm.DisplayOrder ASC' END --name IF LEN(@sql_orderby) > 0 SET @sql_orderby = @sql_orderby + ', ' SET @sql_orderby = @sql_orderby + ' p.[Name] ASC' END SET @sql = @sql + ' ORDER BY' + @sql_orderby SET @sql = ' INSERT INTO #DisplayOrderTmp ([ProductId])' + @sql --PRINT (@sql) EXEC sp_executesql @sql DROP TABLE #FilteredCategoryIds DROP TABLE #FilteredSpecs DROP TABLE #FilteredSpecsWithAttributes DROP TABLE #FilteredCustomerRoleIds DROP TABLE #KeywordProducts CREATE TABLE #PageIndex ( [IndexId] int IDENTITY (1, 1) NOT NULL, [ProductId] int NOT NULL ) INSERT INTO #PageIndex ([ProductId]) SELECT ProductId FROM #DisplayOrderTmp GROUP BY ProductId ORDER BY min([Id]) --total records SET @TotalRecords = @@rowcount DROP TABLE #DisplayOrderTmp --return products SELECT TOP (@RowsToReturn) p.* FROM #PageIndex [pi] INNER JOIN Product p with (NOLOCK) on p.Id = [pi].[ProductId] WHERE [pi].IndexId > @PageLowerBound AND [pi].IndexId < @PageUpperBound ORDER BY [pi].IndexId DROP TABLE #PageIndex END GO --update message templates UPDATE [MessageTemplate] SET [Body] = REPLACE([Body], 'ReturnRequest.ID', 'ReturnRequest.CustomNumber') GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'ordersettings.returnrequestnumbermask') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'ordersettings.returnrequestnumbermask', N'{ID}', 0) END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[ReturnRequest]') and NAME='CustomNumber') BEGIN ALTER TABLE [ReturnRequest] ADD [CustomNumber] NVARCHAR(MAX) NULL END GO UPDATE [ReturnRequest] SET [CustomNumber] = CAST([Id] AS NVARCHAR(200)) WHERE [CustomNumber] IS NULL OR [CustomNumber] = N'' GO ALTER TABLE [ReturnRequest] ALTER COLUMN [CustomNumber] NVARCHAR(MAX) NOT NULL GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'vendorsettings.allowvendorstoeditinfo') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'vendorsettings.allowvendorstoeditinfo', N'False', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'vendorsettings.notifystoreowneraboutvendorinformationchange') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'vendorsettings.notifystoreowneraboutvendorinformationchange', N'True', 0) END GO -- new message template IF NOT EXISTS (SELECT 1 FROM [dbo].[MessageTemplate] WHERE [Name] = N'VendorInformationChange.StoreOwnerNotification') BEGIN INSERT [dbo].[MessageTemplate] ([Name], [BccEmailAddresses], [Subject], [Body], [IsActive], [AttachedDownloadId], [EmailAccountId], [LimitedToStores], [DelayPeriodId]) VALUES (N'VendorInformationChange.StoreOwnerNotification', NULL, N'%Store.Name%. Vendor information change.', N'

%Store.Name%

Vendor %Vendor.Name% (%Vendor.Email%) has just changed information about itself.

', 1, 0, 0, 0, 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'ordersettings.GeneratePdfInvoiceInCustomerLanguage') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'ordersettings.GeneratePdfInvoiceInCustomerLanguage', N'true', 0) END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[Campaign]') and NAME='CustomerRoleId') BEGIN ALTER TABLE [Campaign] ADD [CustomerRoleId] INT NULL END GO UPDATE [Campaign] SET [CustomerRoleId] = 0 WHERE [CustomerRoleId] IS NULL GO ALTER TABLE [Campaign] ALTER COLUMN [CustomerRoleId] INT NOT NULL GO GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[Discount]') and NAME='IsCumulative') BEGIN ALTER TABLE [Discount] ADD [IsCumulative] bit NULL END GO UPDATE [Discount] SET [IsCumulative] = 0 WHERE [IsCumulative] IS NULL GO ALTER TABLE [Discount] ALTER COLUMN [IsCumulative] bit NOT NULL GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'shippingsettings.shiptosameaddress') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'shippingsettings.shiptosameaddress', N'False', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'seosettings.customheadtags') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'seosettings.customheadtags', N'', 0) END GO --new activity types IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'EditActivityLogTypes') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'EditActivityLogTypes', N'Edit activity log types', N'true') END GO --new activity types IF NOT EXISTS (SELECT 1 FROM [ActivityLogType] WHERE [SystemKeyword] = N'DeleteActivityLog') BEGIN INSERT [ActivityLogType] ([SystemKeyword], [Name], [Enabled]) VALUES (N'DeleteActivityLog', N'Delete activity log', N'true') END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'storeinformationsettings.logopictureid') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'storeinformationsettings.logopictureid', N'0', 0) END GO --delete setting DELETE FROM [Setting] WHERE [name] = N'shippingsettings.pickupinstorefee' GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'shippingsettings.displaypickuppointsonmap') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'shippingsettings.displaypickuppointsonmap', N'false', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'shippingsettings.googlemapsapikey') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'shippingsettings.googlemapsapikey', N'', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'shippingsettings.activepickuppointprovidersystemnames') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'shippingsettings.activepickuppointprovidersystemnames', N'', 0) END GO --new column IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id=object_id('[Order]') and NAME='PickupAddressId') BEGIN ALTER TABLE [Order] ADD [PickupAddressId] int NULL END GO IF EXISTS (SELECT 1 FROM sys.objects WHERE name = 'Order_PickupAddress' AND parent_object_id = Object_id('Order') AND Objectproperty(object_id, N'IsForeignKey') = 1) BEGIN ALTER TABLE [dbo].[Order] DROP CONSTRAINT [Order_PickupAddress] END GO ALTER TABLE [dbo].[Order] WITH CHECK ADD CONSTRAINT [Order_PickupAddress] FOREIGN KEY([PickupAddressId]) REFERENCES [dbo].[Address] ([Id]) GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'adminareasettings.hideadvertisementsonadminarea') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'adminareasettings.hideadvertisementsonadminarea', N'false', 0) END GO --delete setting DELETE FROM [Setting] WHERE [name] = N'commonsettings.hideadvertisementsonadminarea' GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'customersettings.deleteguesttaskolderthanminutes') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'customersettings.deleteguesttaskolderthanminutes', N'1440', 0) END GO --delete setting DELETE FROM [Setting] WHERE [name] = N'commonsettings.deleteguesttaskolderthanminutes' GO --delete permission DELETE FROM [PermissionRecord] WHERE [SystemName] = N'ManageMeasures' GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'ordersettings.autoupdateordertotalsoneditingorder') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'ordersettings.autoupdateordertotalsoneditingorder', N'false', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'producteditorsettings.weight') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'producteditorsettings.weight', N'true', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'producteditorsettings.dimensions') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'producteditorsettings.dimensions', N'true', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'catalogsettings.exportimportproductattributes') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'catalogsettings.exportimportproductattributes', N'True', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'producteditorsettings.productattributes') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'producteditorsettings.productattributes', N'true', 0) END GO --new setting IF NOT EXISTS (SELECT 1 FROM [Setting] WHERE [name] = N'producteditorsettings.specificationattributes') BEGIN INSERT [Setting] ([Name], [Value], [StoreId]) VALUES (N'producteditorsettings.specificationattributes', N'true', 0) END GO