Webiant Logo Webiant Logo
  1. No results found.

    Try your search with a different keyword or use * as a wildcard.

IProductService.cs

using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Discounts;
using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Shipping;
using Nop.Core.Domain.Stores;

namespace Nop.Services.Catalog;

/// 
/// Product service
/// 
public partial interface IProductService
{
    #region Products

    /// 
    /// Delete a product
    /// 
    /// Product
    /// A task that represents the asynchronous operation
    Task DeleteProductAsync(Product product);

    /// 
    /// Delete products
    /// 
    /// Products
    /// A task that represents the asynchronous operation
    Task DeleteProductsAsync(IList products);

    /// 
    /// Gets all products displayed on the home page
    /// 
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the products
    /// 
    Task> GetAllProductsDisplayedOnHomepageAsync();

    /// 
    /// Gets featured products by a category identifier
    /// 
    /// Category identifier
    /// Store identifier; 0 if you want to get all records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the list of featured products
    /// 
    Task> GetCategoryFeaturedProductsAsync(int categoryId, int storeId = 0);

    /// 
    /// Gets featured products by a manufacturer identifier
    /// 
    /// Manufacturer identifier
    /// Store identifier; 0 if you want to get all records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the list of featured products
    /// 
    Task> GetManufacturerFeaturedProductsAsync(int manufacturerId, int storeId = 0);

    /// 
    /// Gets products which marked as new
    /// 
    /// Store identifier; 0 if you want to get all records
    /// Page index
    /// Page size
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the list of new products
    /// 
    Task> GetProductsMarkedAsNewAsync(int storeId = 0, int pageIndex = 0, int pageSize = int.MaxValue);

    /// 
    /// Gets product
    /// 
    /// Product identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product
    /// 
    Task GetProductByIdAsync(int productId);

    /// 
    /// Gets products by identifier
    /// 
    /// Product identifiers
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the products
    /// 
    Task> GetProductsByIdsAsync(int[] productIds);

    /// 
    /// Inserts a product
    /// 
    /// Product
    /// A task that represents the asynchronous operation
    Task InsertProductAsync(Product product);

    /// 
    /// Updates the product
    /// 
    /// Product
    /// A task that represents the asynchronous operation
    Task UpdateProductAsync(Product product);

    /// 
    /// Get number of product (published and visible) in certain category
    /// 
    /// Category identifiers
    /// Store identifier; 0 to load all records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the number of products
    /// 
    Task GetNumberOfProductsInCategoryAsync(IList categoryIds = null, int storeId = 0);

    /// 
    /// Search products
    /// 
    /// Page index
    /// Page size
    /// Category identifiers
    /// Manufacturer identifiers
    /// Store identifier; 0 to load all records
    /// Vendor identifier; 0 to load all records
    /// Warehouse identifier; 0 to load all records
    /// Product type; 0 to load all records
    /// A values indicating whether to load only products marked as "visible individually"; "false" to load all records; "true" to load "visible individually" only
    /// A value indicating whether loaded products are marked as featured (relates only to categories and manufacturers); "false" (by default) to load all records; "true" to exclude featured products from results
    /// Minimum price; null to load all records
    /// Maximum price; null to load all records
    /// Product tag identifier; 0 to load all records
    /// Keywords
    /// A value indicating whether to search by a specified "keyword" in product descriptions
    /// A value indicating whether to search by a specified "keyword" in manufacturer part number
    /// A value indicating whether to search by a specified "keyword" in product SKU
    /// A value indicating whether to search by a specified "keyword" in product tags
    /// Language identifier (search for text searching)
    /// Specification options list to filter products; null to load all records
    /// Order by
    /// A value indicating whether to show hidden records
    /// 
    /// null - process "Published" property according to "showHidden" parameter
    /// true - load only "Published" products
    /// false - load only "Unpublished" products
    /// 
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the products
    /// 
    Task> SearchProductsAsync(
        int pageIndex = 0,
        int pageSize = int.MaxValue,
        IList categoryIds = null,
        IList manufacturerIds = null,
        int storeId = 0,
        int vendorId = 0,
        int warehouseId = 0,
        ProductType? productType = null,
        bool visibleIndividuallyOnly = false,
        bool excludeFeaturedProducts = false,
        decimal? priceMin = null,
        decimal? priceMax = null,
        int productTagId = 0,
        string keywords = null,
        bool searchDescriptions = false,
        bool searchManufacturerPartNumber = true,
        bool searchSku = true,
        bool searchProductTags = false,
        int languageId = 0,
        IList filteredSpecOptions = null,
        ProductSortingEnum orderBy = ProductSortingEnum.Position,
        bool showHidden = false,
        bool? overridePublished = null);

    /// 
    /// Gets products by product attribute
    /// 
    /// Product attribute identifier
    /// Page index
    /// Page size
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the products
    /// 
    Task> GetProductsByProductAttributeIdAsync(int productAttributeId,
        int pageIndex = 0, int pageSize = int.MaxValue);

    /// 
    /// Gets associated products
    /// 
    /// Parent product identifier (used with grouped products)
    /// Store identifier; 0 to load all records
    /// Vendor identifier; 0 to load all records
    /// A value indicating whether to show hidden records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the products
    /// 
    Task> GetAssociatedProductsAsync(int parentGroupedProductId,
        int storeId = 0, int vendorId = 0, bool showHidden = false);

    /// 
    /// Update product review totals
    /// 
    /// Product
    /// A task that represents the asynchronous operation
    Task UpdateProductReviewTotalsAsync(Product product);

    /// 
    /// Get low stock products
    /// 
    /// Vendor identifier; pass null to load all records
    /// Whether to load published products only; pass null to load all products, pass true to load only published products, pass false to load only unpublished products
    /// Page index
    /// Page size
    /// A value in indicating whether you want to load only total number of records. Set to "true" if you don't want to load data from database
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the products
    /// 
    Task> GetLowStockProductsAsync(int? vendorId = null, bool? loadPublishedOnly = true,
        int pageIndex = 0, int pageSize = int.MaxValue, bool getOnlyTotalCount = false);

    /// 
    /// Get low stock product combinations
    /// 
    /// Vendor identifier; pass null to load all records
    /// Whether to load combinations of published products only; pass null to load all products, pass true to load only published products, pass false to load only unpublished products
    /// Page index
    /// Page size
    /// A value in indicating whether you want to load only total number of records. Set to "true" if you don't want to load data from database
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product combinations
    /// 
    Task> GetLowStockProductCombinationsAsync(int? vendorId = null, bool? loadPublishedOnly = true,
        int pageIndex = 0, int pageSize = int.MaxValue, bool getOnlyTotalCount = false);

    /// 
    /// Gets a product by SKU
    /// 
    /// SKU
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product
    /// 
    Task GetProductBySkuAsync(string sku);

    /// 
    /// Gets a products by SKU array
    /// 
    /// SKU array
    /// Vendor ID; 0 to load all records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the products
    /// 
    Task> GetProductsBySkuAsync(string[] skuArray, int vendorId = 0);

    /// 
    /// Update HasTierPrices property (used for performance optimization)
    /// 
    /// Product
    /// A task that represents the asynchronous operation
    Task UpdateHasTierPricesPropertyAsync(Product product);

    /// 
    /// Update HasDiscountsApplied property (used for performance optimization)
    /// 
    /// Product
    /// A task that represents the asynchronous operation
    Task UpdateHasDiscountsAppliedAsync(Product product);

    /// 
    /// Gets number of products by vendor identifier
    /// 
    /// Vendor identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the number of products
    /// 
    Task GetNumberOfProductsByVendorIdAsync(int vendorId);

    /// 
    /// Parse "required product Ids" property
    /// 
    /// Product
    /// A list of required product IDs
    int[] ParseRequiredProductIds(Product product);

    /// 
    /// Get a value indicating whether a product is available now (availability dates)
    /// 
    /// Product
    /// Datetime to check; pass null to use current date
    /// Result
    bool ProductIsAvailable(Product product, DateTime? dateTime = null);

    /// 
    /// Get a list of allowed quantities (parse 'AllowedQuantities' property)
    /// 
    /// Product
    /// Result
    int[] ParseAllowedQuantities(Product product);

    /// 
    /// Get total quantity
    /// 
    /// Product
    /// 
    /// A value indicating whether we should consider "Reserved Quantity" property 
    /// when "multiple warehouses" are used
    /// 
    /// 
    /// Warehouse identifier. Used to limit result to certain warehouse.
    /// Used only with "multiple warehouses" enabled.
    /// 
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    Task GetTotalStockQuantityAsync(Product product, bool useReservedQuantity = true, int warehouseId = 0);

    /// 
    /// Get number of rental periods (price ratio)
    /// 
    /// Product
    /// Start date
    /// End date
    /// Number of rental periods
    int GetRentalPeriods(Product product, DateTime startDate, DateTime endDate);

    /// 
    /// Formats the stock availability/quantity message
    /// 
    /// Product
    /// Selected product attributes in XML format (if specified)
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the stock message
    /// 
    Task FormatStockMessageAsync(Product product, string attributesXml);

    /// 
    /// Formats SKU
    /// 
    /// Product
    /// Attributes in XML format
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the sKU
    /// 
    Task FormatSkuAsync(Product product, string attributesXml = null);

    /// 
    /// Formats manufacturer part number
    /// 
    /// Product
    /// Attributes in XML format
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the manufacturer part number
    /// 
    Task FormatMpnAsync(Product product, string attributesXml = null);

    /// 
    /// Formats GTIN
    /// 
    /// Product
    /// Attributes in XML format
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the gTIN
    /// 
    Task FormatGtinAsync(Product product, string attributesXml = null);

    /// 
    /// Formats start/end date for rental product
    /// 
    /// Product
    /// Date
    /// Formatted date
    string FormatRentalDate(Product product, DateTime date);

    /// 
    /// Update product store mappings
    /// 
    /// Product
    /// A list of store ids for mapping
    /// A task that represents the asynchronous operation
    Task UpdateProductStoreMappingsAsync(Product product, IList limitedToStoresIds);

    /// 
    /// Gets the value whether the sequence contains downloadable products
    /// 
    /// Product identifiers
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    Task HasAnyDownloadableProductAsync(int[] productIds);

    /// 
    /// Gets the value whether the sequence contains gift card products
    /// 
    /// Product identifiers
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    Task HasAnyGiftCardProductAsync(int[] productIds);

    /// 
    /// Gets the value whether the sequence contains recurring products
    /// 
    /// Product identifiers
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    Task HasAnyRecurringProductAsync(int[] productIds);

    /// 
    /// Returns a list of sku of not existing products
    /// 
    /// The sku of the products to check
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the list of sku not existing products
    /// 
    Task GetNotExistingProductsAsync(string[] productSku);

    #endregion

    #region Inventory management methods

    /// 
    /// Adjust inventory
    /// 
    /// Product
    /// Quantity to increase or decrease
    /// Attributes in XML format
    /// Message for the stock quantity history
    /// A task that represents the asynchronous operation
    Task AdjustInventoryAsync(Product product, int quantityToChange, string attributesXml = "", string message = "");

    /// 
    /// Book the reserved quantity
    /// 
    /// Product
    /// Warehouse identifier
    /// Quantity, must be negative
    /// Message for the stock quantity history
    /// A task that represents the asynchronous operation
    Task BookReservedInventoryAsync(Product product, int warehouseId, int quantity, string message = "");

    /// 
    /// Reverse booked inventory (if acceptable)
    /// 
    /// product
    /// Shipment item
    /// Quantity reversed
    /// Message for the stock quantity history
    /// A task that represents the asynchronous operation
    Task ReverseBookedInventoryAsync(Product product, ShipmentItem shipmentItem, string message = "");

    #endregion

    #region Related products

    /// 
    /// Deletes a related product
    /// 
    /// Related product
    /// A task that represents the asynchronous operation
    Task DeleteRelatedProductAsync(RelatedProduct relatedProduct);

    /// 
    /// Gets related products by product identifier
    /// 
    /// The first product identifier
    /// A value indicating whether to show hidden records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the related products
    /// 
    Task> GetRelatedProductsByProductId1Async(int productId1, bool showHidden = false);

    /// 
    /// Gets a related product
    /// 
    /// Related product identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the related product
    /// 
    Task GetRelatedProductByIdAsync(int relatedProductId);

    /// 
    /// Inserts a related product
    /// 
    /// Related product
    /// A task that represents the asynchronous operation
    Task InsertRelatedProductAsync(RelatedProduct relatedProduct);

    /// 
    /// Updates a related product
    /// 
    /// Related product
    /// A task that represents the asynchronous operation
    Task UpdateRelatedProductAsync(RelatedProduct relatedProduct);

    /// 
    /// Finds a related product item by specified identifiers
    /// 
    /// Source
    /// The first product identifier
    /// The second product identifier
    /// Related product
    RelatedProduct FindRelatedProduct(IList source, int productId1, int productId2);

    #endregion

    #region Cross-sell products

    /// 
    /// Deletes a cross-sell product
    /// 
    /// Cross-sell
    /// A task that represents the asynchronous operation
    Task DeleteCrossSellProductAsync(CrossSellProduct crossSellProduct);

    /// 
    /// Gets cross-sell products by product identifier
    /// 
    /// The first product identifier
    /// A value indicating whether to show hidden records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the cross-sell products
    /// 
    Task> GetCrossSellProductsByProductId1Async(int productId1, bool showHidden = false);

    /// 
    /// Gets a cross-sell product
    /// 
    /// Cross-sell product identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the cross-sell product
    /// 
    Task GetCrossSellProductByIdAsync(int crossSellProductId);

    /// 
    /// Inserts a cross-sell product
    /// 
    /// Cross-sell product
    /// A task that represents the asynchronous operation
    Task InsertCrossSellProductAsync(CrossSellProduct crossSellProduct);

    /// 
    /// Gets a cross-sells
    /// 
    /// Shopping cart
    /// Number of products to return
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the cross-sells
    /// 
    Task> GetCrossSellProductsByShoppingCartAsync(IList cart, int numberOfProducts);

    /// 
    /// Finds a cross-sell product item by specified identifiers
    /// 
    /// Source
    /// The first product identifier
    /// The second product identifier
    /// Cross-sell product
    CrossSellProduct FindCrossSellProduct(IList source, int productId1, int productId2);

    #endregion

    #region Tier prices

    /// 
    /// Gets a product tier prices for customer
    /// 
    /// Product
    /// Customer
    /// Store
    /// A task that represents the asynchronous operation
    Task> GetTierPricesAsync(Product product, Customer customer, Store store);

    /// 
    /// Gets a tier prices by product identifier
    /// 
    /// Product identifier
    /// A task that represents the asynchronous operation
    Task> GetTierPricesByProductAsync(int productId);

    /// 
    /// Deletes a tier price
    /// 
    /// Tier price
    /// A task that represents the asynchronous operation
    Task DeleteTierPriceAsync(TierPrice tierPrice);

    /// 
    /// Gets a tier price
    /// 
    /// Tier price identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the ier price
    /// 
    Task GetTierPriceByIdAsync(int tierPriceId);

    /// 
    /// Inserts a tier price
    /// 
    /// Tier price
    /// A task that represents the asynchronous operation
    Task InsertTierPriceAsync(TierPrice tierPrice);

    /// 
    /// Updates the tier price
    /// 
    /// Tier price
    /// A task that represents the asynchronous operation
    Task UpdateTierPriceAsync(TierPrice tierPrice);

    /// 
    /// Gets a preferred tier price
    /// 
    /// Product
    /// Customer
    /// Store
    /// Quantity
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the ier price
    /// 
    Task GetPreferredTierPriceAsync(Product product, Customer customer, Store store, int quantity);

    #endregion

    #region Product pictures

    /// 
    /// Deletes a product picture
    /// 
    /// Product picture
    /// A task that represents the asynchronous operation
    Task DeleteProductPictureAsync(ProductPicture productPicture);

    /// 
    /// Gets a product pictures by product identifier
    /// 
    /// The product identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product pictures
    /// 
    Task> GetProductPicturesByProductIdAsync(int productId);

    /// 
    /// Gets a product picture
    /// 
    /// Product picture identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product picture
    /// 
    Task GetProductPictureByIdAsync(int productPictureId);

    /// 
    /// Inserts a product picture
    /// 
    /// Product picture
    /// A task that represents the asynchronous operation
    Task InsertProductPictureAsync(ProductPicture productPicture);

    /// 
    /// Updates a product picture
    /// 
    /// Product picture
    /// A task that represents the asynchronous operation
    Task UpdateProductPictureAsync(ProductPicture productPicture);

    /// 
    /// Get the IDs of all product images 
    /// 
    /// Products IDs
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the all picture identifiers grouped by product ID
    /// 
    Task> GetProductsImagesIdsAsync(int[] productsIds);

    /// 
    /// Get products to which a discount is applied
    /// 
    /// Discount identifier; pass null to load all records
    /// A value indicating whether to load deleted products
    /// Page index
    /// Page size
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the list of products
    /// 
    Task> GetProductsWithAppliedDiscountAsync(int? discountId = null,
        bool showHidden = false, int pageIndex = 0, int pageSize = int.MaxValue);

    #endregion

    #region Product videos

    /// 
    /// Deletes a product video
    /// 
    /// Product video
    /// A task that represents the asynchronous operation
    Task DeleteProductVideoAsync(ProductVideo productVideo);

    /// 
    /// Gets a product videos by product identifier
    /// 
    /// The product identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product videos
    /// 
    Task> GetProductVideosByProductIdAsync(int productId);

    /// 
    /// Gets a product video
    /// 
    /// Product video identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product video
    /// 
    Task GetProductVideoByIdAsync(int productVideoId);

    /// 
    /// Inserts a product video
    /// 
    /// Product picture
    /// A task that represents the asynchronous operation
    Task InsertProductVideoAsync(ProductVideo productVideo);

    /// 
    /// Updates a product video
    /// 
    /// Product video
    /// A task that represents the asynchronous operation
    Task UpdateProductVideoAsync(ProductVideo productVideo);

    #endregion

    #region Product reviews

    /// 
    /// Gets all product reviews
    /// 
    /// Customer identifier (who wrote a review); 0 to load all records
    /// A value indicating whether to content is approved; null to load all records 
    /// Item creation from; null to load all records
    /// Item creation to; null to load all records
    /// Search title or review text; null to load all records
    /// The store identifier; pass 0 to load all records
    /// The product identifier; pass 0 to load all records
    /// The vendor identifier (limit to products of this vendor); pass 0 to load all records
    /// A value indicating whether to show hidden records
    /// Page index
    /// Page size
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the reviews
    /// 
    Task> GetAllProductReviewsAsync(int customerId = 0, bool? approved = null,
        DateTime? fromUtc = null, DateTime? toUtc = null,
        string message = null, int storeId = 0, int productId = 0, int vendorId = 0, bool showHidden = false,
        int pageIndex = 0, int pageSize = int.MaxValue);

    /// 
    /// Gets product review
    /// 
    /// Product review identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product review
    /// 
    Task GetProductReviewByIdAsync(int productReviewId);

    /// 
    /// Get product reviews by identifiers
    /// 
    /// Product review identifiers
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the product reviews
    /// 
    Task> GetProductReviewsByIdsAsync(int[] productReviewIds);

    /// 
    /// Inserts a product review
    /// 
    /// Product review
    /// A task that represents the asynchronous operation
    Task InsertProductReviewAsync(ProductReview productReview);

    /// 
    /// Deletes a product review
    /// 
    /// Product review
    /// A task that represents the asynchronous operation
    Task DeleteProductReviewAsync(ProductReview productReview);

    /// 
    /// Deletes product reviews
    /// 
    /// Product reviews
    /// A task that represents the asynchronous operation
    Task DeleteProductReviewsAsync(IList productReviews);

    /// 
    /// Sets or create a product review helpfulness record
    /// 
    /// Product reviews
    /// Value indicating whether a review a helpful
    /// A task that represents the asynchronous operation
    Task SetProductReviewHelpfulnessAsync(ProductReview productReview, bool helpfulness);

    /// 
    /// Updates a totals helpfulness count for product review
    /// 
    /// Product review
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    Task UpdateProductReviewHelpfulnessTotalsAsync(ProductReview productReview);

    /// 
    /// Updates a product review
    /// 
    /// Product review
    /// A task that represents the asynchronous operation
    Task UpdateProductReviewAsync(ProductReview productReview);

    /// 
    /// Check possibility added review for current customer
    /// 
    /// Current product
    /// The store identifier; pass 0 to load all records
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the 
    /// 
    Task CanAddReviewAsync(int productId, int storeId = 0);

    #endregion

    #region Product warehouses

    /// 
    /// Get a product warehouse-inventory records by product identifier
    /// 
    /// Product identifier
    /// A task that represents the asynchronous operation
    Task> GetAllProductWarehouseInventoryRecordsAsync(int productId);

    /// 
    /// Deletes a ProductWarehouseInventory
    /// 
    /// ProductWarehouseInventory
    /// A task that represents the asynchronous operation
    Task DeleteProductWarehouseInventoryAsync(ProductWarehouseInventory pwi);

    /// 
    /// Inserts a ProductWarehouseInventory
    /// 
    /// ProductWarehouseInventory
    /// A task that represents the asynchronous operation
    Task InsertProductWarehouseInventoryAsync(ProductWarehouseInventory pwi);

    /// 
    /// Updates a record to manage product inventory per warehouse
    /// 
    /// Record to manage product inventory per warehouse
    /// A task that represents the asynchronous operation
    Task UpdateProductWarehouseInventoryAsync(ProductWarehouseInventory pwi);

    #endregion

    #region Stock quantity history

    /// 
    /// Add stock quantity change entry
    /// 
    /// Product
    /// Quantity adjustment
    /// Current stock quantity
    /// Warehouse identifier
    /// Message
    /// Product attribute combination identifier
    /// A task that represents the asynchronous operation
    Task AddStockQuantityHistoryEntryAsync(Product product, int quantityAdjustment, int stockQuantity,
        int warehouseId = 0, string message = "", int? combinationId = null);

    /// 
    /// Get the history of the product stock quantity changes
    /// 
    /// Product
    /// Warehouse identifier; pass 0 to load all entries
    /// Product attribute combination identifier; pass 0 to load all entries
    /// Page index
    /// Page size
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the list of stock quantity change entries
    /// 
    Task> GetStockQuantityHistoryAsync(Product product, int warehouseId = 0, int combinationId = 0,
        int pageIndex = 0, int pageSize = int.MaxValue);

    #endregion

    #region Product discounts

    /// 
    /// Clean up product references for a specified discount
    /// 
    /// Discount
    /// A task that represents the asynchronous operation
    Task ClearDiscountProductMappingAsync(Discount discount);

    /// 
    /// Get a discount-product mapping records by product identifier
    /// 
    /// Product identifier
    /// A task that represents the asynchronous operation
    Task> GetAllDiscountsAppliedToProductAsync(int productId);

    /// 
    /// Get a discount-product mapping record
    /// 
    /// Product identifier
    /// Discount identifier
    /// 
    /// A task that represents the asynchronous operation
    /// The task result contains the result
    /// 
    Task GetDiscountAppliedToProductAsync(int productId, int discountId);

    /// 
    /// Inserts a discount-product mapping record
    /// 
    /// Discount-product mapping
    /// A task that represents the asynchronous operation
    Task InsertDiscountProductMappingAsync(DiscountProductMapping discountProductMapping);

    /// 
    /// Deletes a discount-product mapping record
    /// 
    /// Discount-product mapping
    /// A task that represents the asynchronous operation
    Task DeleteDiscountProductMappingAsync(DiscountProductMapping discountProductMapping);

    #endregion
}