enobis/module-sales-quantity-limit v1.2.2

Sales Quantity Limitation Extension for Magento2.x

Sales Quantity Limit - Feature Overview

Fair, automatic purchase limits per product and time period - enforced in the cart and checkout.


What Is It

Sales Quantity Limit lets you cap how much of a product a customer may buy per day, week, month, quarter, year or over their lifetime. Limits are set directly on the product, checked against the customer's real order history and enforced the moment a quantity is added or changed in the cart.


Key Features

🎯 Per-Product Limits

  • Set a time period and a maximum quantity on each product
  • Limits can differ per website
  • Products without a limit are not affected

🗓️ Flexible Time Periods

  • Day, week, month, quarter, year or lifetime
  • Counts all orders in the current period; canceled orders are not counted

👥 Choose Who the Limit Applies To

  • Per customer
  • Per account relation or per company (when the matching Enobis / Proline modules are installed)
  • Combined scopes such as company and customer

🛒 Enforced in the Cart

  • Quantity changes are checked immediately
  • Clear messages tell the customer the maximum available quantity and the period limit
  • Works for simple and virtual products and for bundle components
  • Quantities of the same product spread over several cart lines are added up

👀 Transparent for Customers

  • Optional display of the remaining quantity on the product page
  • Messages translated into German, English, French, Italian, Spanish, Polish and Russian

⚙️ Simple to Operate

  • One switch to enable, one setting for the scope
  • Own ACL resource to restrict who may change the settings

Who Is It For

Target group Benefit
B2B shops with contingents Limit annual or monthly quantities per customer or company
Shops with scarce or regulated goods Prevent hoarding and bulk buying
Promotions and special offers Cap quantity per customer and period
Shop operators No manual order checking

How It Works

Product: limit value + period
        |
Customer changes cart quantity
        |
Module sums non-canceled orders in the current period (per scope)
        |
Requested qty > remaining qty?
   |-- yes --> cart error message with the maximum quantity
   '-- no  --> order can proceed

Integrations & Requirements

  • Magento 2 (Framework 102.0.7+ / 103.0.3+), PHP 8.1 - 8.3
  • Optional: Enobis Account Relation Switcher, Ecoplan Proline (extra scopes)

Use Cases

(inferred from the functionality - please review)

  • A supplier allows each customer 100 units of a product per quarter
  • A promotional item may be bought once per customer (lifetime)
  • A company shares one monthly quota across all its users

Sales Quantity Limit - by Enobis

Sales Quantity Limit - Documentation

Table of Contents

  1. Requirements
  2. Installation
  3. Configuration
  4. Product attributes
  5. Features and behavior
  6. Scopes
  7. Data model
  8. Routes, events and extension points
  9. Security and permissions
  10. Localization
  11. Troubleshooting

1. Requirements

Requirement Version
PHP ~8.1.0 | ~8.2.0 | ~8.3.0
magento/framework ^102.0.7 | ^103.0.3
magento/module-backend >= 102.0
magento/module-catalog >= 102.0
Enobis_AccountRelationSwitcher optional, needed for scopes relation*
Ecoplan_Proline optional, needed for scopes company*

The module is loaded after Magento_Catalog and Magento_Backend.

2. Installation

composer require enobis/module-sales-quantity-limit
bin/magento module:enable Enobis_SalesQuantityLimit
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

setup:upgrade creates the two product attributes (section 4).

3. Configuration

Path: Stores > Configuration > Enobis > Sales Quantity Limit. Visible in Default and Website scope.

About

Field Description
Module Version Read-only information field
Composer Version Read-only information field

General

Field Config path Type Default Scope Description
Enabled sales_quantity_limit/general/enabled Yes/No No Default, Website Master switch. When off, no limit is evaluated and no error is added
Scope sales_quantity_limit/general/scope Select Customer Default, Website Whose orders are counted (section 6). Only shown when Enabled = Yes
Show Available Period Qty sales_quantity_limit/general/show_available_period_qty Yes/No No Default, Website Shows the remaining quantity on the product page. Only shown when Enabled = Yes

4. Product attributes

Both attributes are created in the attribute group "General" with website scope, are not required and are available in product listings.

Code Label Type Input Position
sales_qty_limit_period Sales Qty Limit Period varchar Select 120
sales_qty_limit_value Sales Qty Limit Value decimal Text 130

Options for the period: NONE (empty), Day, Week, Month, Quarter, Year, Lifetime (stored values day, week, month, quarter, year, lifetime).

A product is limited only when the period is set and the module is enabled. Both attributes are included in the quote-item attribute group so they are available on cart items.

5. Features and behavior

Limit check in the cart

The check runs on the event sales_quote_item_qty_set_after whenever the quantity of a quote item is set.

  • It is skipped when the module is disabled, for items without a product, and when the quote is in super mode (is_super_mode, e.g. admin order creation).
  • The ordered quantity of the product in the current period is the sum of qty_ordered over sales_order_item of all orders whose status is not canceled, filtered by the scope (section 6).
  • Remaining quantity = limit value - ordered quantity (minimum 0).
  • If the requested row quantity, or the total quantity of the same product across several cart lines, exceeds the remaining quantity, an error is set on the cart item and the quote. The message names the maximum available quantity, the product name, the limit and the period.
  • For bundle products, each selected option product that has a limit is checked with option quantity multiplied by cart quantity.
  • A custom registry flag sales_quantity_limitation_skip_apply disables the check for the current request.

Time periods

Orders are grouped by their creation date: day (Y-m-d), week, month (Y-m), quarter (Y-Qn), year (Y), lifetime (all orders). The current period is determined from the current date.

Display on product pages

When "Show Available Period Qty" is enabled, products of type simple, virtual and bundle show:

  • "Available Period Qty: n / Period" - remaining quantity in the period
  • "Available Total Qty: n" - shown only when the limitation data contains extended quantity information (qty_extend)

The data is loaded by a POST AJAX request to salesquantitylimit/product/ajaxlimitation. The request does not trigger a customer-section reload.

6. Scopes

The scope decides which orders are counted. Every scope adds a filter on a column of sales_order.

Scope value Label Filter column Requires
customer Customer customer_id (guests: 0) -
relation Relation active_relation Enobis_AccountRelationSwitcher
relation/customer Relation/Customer active_relation and customer_id Enobis_AccountRelationSwitcher
company Company proline_company_id Ecoplan_Proline
company/customer Company/Customer proline_company_id and customer_id Ecoplan_Proline

Scopes starting with relation or company appear in the dropdown only when the respective module is enabled. The columns active_relation and proline_company_id must exist on sales_order (provided by those modules).

7. Data model

The module adds no tables or columns. It adds two product EAV attributes (section 4) and reads sales_order and sales_order_item.

8. Routes, events and extension points

Type Identifier Description
Frontend route salesquantitylimit frontName
Controller salesquantitylimit/product/ajaxlimitation POST, XHR only, JSON body {"productId": n}. Returns error, productId, productSku, productStatus, productAvailable and limitation (time_period, qty, value, scope, qty_base, qty_ordered, qty_available, qty_left). HTTP 400 for invalid requests
Observed event sales_quote_item_qty_set_after Observer salesQuantityLimit
Dispatched event sales_quantity_limit_controller_product_ajax_limitation Data: product, limitation, transport, request. Observers may change transport->response
DI Enobis\SalesQuantityLimit\Model\Limitation\Scope Argument scopes lists the available scopes; additional scopes can be added via di.xml
Catalog attributes group quote_item sales_qty_limit_period, sales_qty_limit_value
JS Magento_Customer/js/section-config mixin Excludes the AJAX URL from section invalidation
Layout catalog_product_view_type_simple, _virtual, _bundle Adds the available-quantity block to the product page

9. Security and permissions

  • ACL resource Enobis_SalesQuantityLimit::config_sales_quantity_limit ("Sales Quantity Limit Section") controls access to the configuration section (under Stores > Settings > Configuration).
  • The AJAX controller accepts only POST requests with XHR header and returns only the limit data of the requested product for the current customer/scope.
  • The module is disabled by default.

10. Localization

Translations are included for de_DE, en_US, es_ES, fr_FR, it_IT, pl_PL and ru_RU.

11. Troubleshooting

Symptom Check
No limit is enforced Module enabled for the website? Period set on the product (value not NONE) in the right website scope? Value set?
Relation/Company scopes missing in dropdown The respective optional module must be enabled
Remaining quantity not shown on product page "Show Available Period Qty" enabled; product has a limit; product type is simple, virtual or bundle; theme renders the product.info.*.extra container
Limits not applied in admin order creation Quotes in super mode are not checked
Counts seem wrong Canceled orders are not counted; all other statuses are. Check the selected scope
Settings not visible Admin role needs the ACL resource for the Sales Quantity Limit section

Changelog

1.2.2 (2026-10-13)

  • 2026-10-13 Support configurable products, add README config field (f47aa1a)

    Show the remaining period quantity for configurable products. The block now indexes limited child products by their super attribute values, and the JS requests limitation data for the selected variant (with response caching and ignoring outdated responses). A new layout file adds the block to configurable product pages, and the template passes the child index and period labels to the JS.

    Also add an admin config field that renders the module README.md as HTML, add README, DOCUMENTATION, MARKETING and FINDINGS docs (FINDINGS is export-ignored), and bump the version to 1.2.2.

1.2.1 (2026-04-09)

  • 2026-04-09 Logging removed from the module (4d95f0f)

  • 2026-04-09 Version: 1.2.1 (68e8754)

    • Logging removed from the module

1.2.0 (2026-03-20)

  • 2026-03-20 Tweak code (ddb40c5)

    Allow PHP 8.3 Drop PHP 7.4 support

  • 2026-03-20 Version 1.2.0 (d322a45)

    Allow PHP 8.3

    #14375

1.1.11 (2025-06-04)

  • 2025-06-03 - First use up the sales limit before it goes to the quota (3794966)

  • 2025-06-04 Version: 1.1.11 (33a66cb)

    Fix:

    • First use up the sales limit before it goes to the quota

1.1.10 (2025-05-26)

  • 2025-05-26 - Calculation logic adapted (dc5b907)

  • 2025-05-26 Version: 1.1.10 (357d6db)

    Fix:

    • Calculation logic adapted

1.1.9 (2025-05-23)

  • 2025-05-23 - Added the scope for queries (e9313dd)

  • 2025-05-23 - Workaround so that the message section is not always reloaded for Ajax calls (1a8c280)

  • 2025-05-23 Tweak code (fc4eed3)

  • 2025-05-23 Version: 1.1.9 (28da0bf)

    Bugfix:

    • Added the scope for queries

    Optimisation:

    • Workaround so that the message section is not always reloaded for Ajax calls

1.1.8 (2025-01-23)

  • 2025-01-23 Tweak code (7a3c90a)

  • 2025-01-23 Introduce .gitattributes to exclude development files (1697694)

  • 2025-01-23 PHP 8.2 support added (975967e)

  • 2025-01-23 Version: 1.1.8 (9209e29)

    Optimization:

    • PHP 8.2 support added

1.1.7 (2023-07-12)

  • 2023-07-12 add new period type "lifetime" (1d1279e)

  • 2023-07-12 version 1.1.7 (2f11655)

    add new period type "lifetime"

1.1.6 (2023-03-09)

  • 2023-03-09 Version: 1.1.6 - Added Translation (3c6c4e2)

    Signed-off-by: karlbuedding-enobis karl.buedding@enobis.de

1.1.5 (2022-12-05)

1.1.4 (2022-03-09)

1.1.3 (2021-08-11)

  • 2021-08-11 Version 1.1.3 (c8d31a1)

    Optimisation;

    • show available period qty on bundle product

1.1.2 (2020-12-18)

  • 2020-12-18 Version 1.1.2 (f0dd535)

    improvements show available period qty

1.1.1 (2020-12-17)

  • 2020-12-17 Version 1.1.1 (ca48f1d)

    improvements show available period qty

1.1.0 (2020-12-16)

  • 2020-12-16 Version 1.1.0 (7423942)

    show available period qty

1.0.2 (2020-12-16)

  • 2020-05-29 current spec (aebe9be)

  • 2020-06-08 improve limitation validation process in cart to check composite products (bundle, etc.) too (7641a65)

  • 2020-06-08 Merge branch 'composite-product-in-cart' (01f95e7)

  • 2020-06-08 add about system configuration (28deb76)

  • 2020-06-08 Version 1.0.0 (72c64fc)

    improve limitation validation process in cart to check composite products (bundle, etc.) too add about system configuration

  • 2020-12-16 re-add processing composite product in cart (grouped, bundle etc.) (ce5d1e6)

  • 2020-12-16 Version 1.0.2 (29fd4c4)

    improve limitation validation process in cart to check composite products (bundle, etc.) too

1.0.1 (2020-12-07)

  • 2020-12-07 Version 0.1.6 (fa532cd)

    fix: sql unknown column error

  • 2020-12-07 Version 1.0.1 (b4a4ca7)

    fix: sql unknown column error

1.0.0 (2020-06-08)

  • 2020-05-29 current spec (aebe9be)

  • 2020-06-08 improve limitation validation process in cart to check composite products (bundle, etc.) too (7641a65)

  • 2020-06-08 Merge branch 'composite-product-in-cart' (01f95e7)

  • 2020-06-08 add about system configuration (28deb76)

  • 2020-06-08 Version 1.0.0 (72c64fc)

    improve limitation validation process in cart to check composite products (bundle, etc.) too add about system configuration

0.1.5 (2020-05-19)

  • 2020-05-19 Version 0.1.5 (a3ac2a3)

    fix: display wrong limitation qty for time period in error message

0.1.4 (2020-05-19)

  • 2020-05-18 fix: canceled orders not handled as expected (c5643b3)

  • 2020-05-18 add product sku to limitation error messages (01690ab)

  • 2020-05-19 Merge branch 'dev' (c2d10c0)

  • 2020-05-19 Version 0.1.4 (a08a8cd)

    add product sku to limitation error messages fix: canceled orders not handled as expected

0.1.3 (2020-05-08)

  • 2020-05-08 Version 0.1.3 (e02ebf3)

    fix: fatal error on customer login

0.1.2 (2020-05-08)

  • 2020-05-08 add day time period (99936f7)

  • 2020-05-08 fix: limitation not working when flat catalog enabled (3f21d9e)

  • 2020-05-08 Version 0.1.2 (c96fe83)

    add day time period fix: limitation not working when flat catalog enabled

0.1.1 (2020-05-07)

  • 2020-05-07 fix: missing relation id when using limitation scope "relation" / "relation/customer" (67a4518)

  • 2020-05-07 Version 0.1.1 (f880048)

    fix: missing relation id when using limitation scope "relation" / "relation/customer"

0.1.0 (2020-05-06)

  • 2020-05-06 Version 0.1.0 (2f9008b)

    first implementation

0.0.1 (2020-05-06)

  • 2020-05-06 base files (04f2c57)

README.md

Enobis Sales Quantity Limit

Limits how many units of a product a customer can order within a time period (day, week, month, quarter, year or lifetime) and shows the remaining quantity on the product page.

Facts

Module name Enobis_SalesQuantityLimit
Composer package enobis/module-sales-quantity-limit
Package type magento2-module
License proprietary
Vendor / support Enobis
Admin configuration Stores > Configuration > Enobis > Sales Quantity Limit

Requirements

  • PHP 8.1, 8.2 or 8.3
  • Magento Framework ^102.0.7 | ^103.0.3
  • magento/module-backend >= 102.0
  • magento/module-catalog >= 102.0
  • Optional: Enobis_AccountRelationSwitcher (scopes "Relation"), Ecoplan_Proline (scopes "Company")

Installation

composer require enobis/module-sales-quantity-limit
bin/magento module:enable Enobis_SalesQuantityLimit
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

Quick start

  1. Enable the module under Stores > Configuration > Enobis > Sales Quantity Limit > General.
  2. Choose the scope (who the limit applies to).
  3. Open a product, group "General": set Sales Qty Limit Period and Sales Qty Limit Value.
  4. Optionally enable "Show Available Period Qty" to display the remaining quantity on the product page.

Documentation

Documentation for all Enobis modules and themes is available at https://docs.enobis.de

  • DOCUMENTATION.md - configuration, product attributes, behavior, troubleshooting
  • MARKETING.md - feature overview