pos_loyalty_extend/README.md
2026-05-28 14:50:21 +07:00

4.9 KiB
Raw Blame History

POS Loyalty Extend

Version: 1.0 Author: Suherdy Yacob License: LGPL-3 Category: Sales / Point of Sale

Overview

pos_loyalty_extend is a custom Odoo 19 module that extends the built-in pos_loyalty module with additional reward applicability options in the Point of Sale interface.

The primary feature added is "Cheapest Product on Order" applicability for Buy X Get Y loyalty rewards — allowing merchants to automatically discount or give away the cheapest item(s) in a customer's cart based on the number of products purchased.


Features

🏷️ Cheapest Product Applicability

  • Adds a new reward_product_applicability field (cheapest) to loyalty.reward.
  • When set, the reward dynamically targets the cheapest product(s) in the current POS order instead of a pre-configured fixed product.

📊 Proportional Free Item Calculation

The number of free items scales automatically based on the buy ratio:

Products Bought Free Items
2 1
3 1
4 2
5 2
6 3

Formula: floor(points_earned / required_points_per_reward)

🛒 Multi-Product Free Lines

When multiple free items are awarded, each one targets a different cheapest product in the order (sorted by unit price ascending), rather than duplicating the single cheapest item:

  • Buy 4 items → 2 free: Terong Penyet (Rp 15,000) + Telor Penyet (Rp 19,000)
  • Buy 4 items → 2 free: 2× Terong Penyet (Rp 15,000)

Auto-Claim in POS

Cheapest product rewards are automatically discovered and claimed in the POS UI without requiring manual product configuration on the reward.


Dependencies

Module Purpose
point_of_sale Core POS framework
pos_loyalty Loyalty program UI and logic in POS
sale_loyalty Backend loyalty program models

Configuration

Setting Up a "Buy 2 Get 1 Free (Cheapest)" Program

  1. Go to Point of Sale → Products → Loyalty Programs
  2. Create a new program with type Loyalty Card or Promotion
  3. Under Conditional Rules:
    • Minimum Quantity: 2
    • Grant: 1 Credit per Unit Paid
  4. Under Rewards → Add a reward:
    • Reward Type: Free Product
    • Reward Product Applicability: Cheapest Product on Order (new field)
    • In Exchange of: 2 Credits (1 credit per product, 2 needed → 1 free)
    • Quantity Rewarded: 1

Important: Set "In Exchange of" to 2 (not 1) to get the correct buy 2 → 1 free ratio. The formula is floor(total_credits / credits_required) = free_items.


Technical Details

Modified Files

Python (Backend)

File Description
models/loyalty_reward.py Adds reward_product_applicability selection field; overrides _compute_multi_product to handle cheapest type
models/sale_order.py Overrides reward value computation for server-side cheapest product identification

JavaScript (Frontend)

File Description
static/src/app/models/pos_order.js Core reward logic patches — cheapest product detection, unclaimed qty computation, multi-product reward line generation, getClaimableRewards override
static/src/app/services/pos_store.js Patches getPotentialFreeProductRewards to surface cheapest rewards with no fixed reward_product_ids
static/src/app/screens/product_screen/control_buttons/control_buttons.js Patches _applyReward to route cheapest rewards through dynamic product resolution

Views

File Description
views/loyalty_reward_views.xml Adds the reward_product_applicability field to the loyalty reward form

Key Methods

  • _getCheapestProductInOrder(reward) — Returns the single cheapest non-reward product in the current order
  • _getCheapestProductsInOrder(reward, n) — Returns the N cheapest individual items (sorted by unit price), expanding multi-qty lines
  • _computeUnclaimedFreeProductQtyForCheapest(...) — Calculates how many free items are still unclaimed based on remaining loyalty points
  • getClaimableRewards(...) — Extended to include cheapest-type rewards that the core skips (due to null reward_product_id)

Installation

# Copy module to your custom addons path
cp -r pos_loyalty_extend /path/to/odoo/customaddons/

# Update addons list and install
./odoo-bin -c odoo.conf -u pos_loyalty_extend

Or via Odoo UI:

  1. Enable Developer Mode
  2. Go to Apps → Update Apps List
  3. Search for POS Loyalty Extend and install

Changelog

v1.0

  • Initial release
  • Added cheapest reward product applicability
  • Auto-claim cheapest product rewards in POS
  • Proportional multi-product free item generation (N cheapest products, not N× same product)
  • Fixed getClaimableRewards and getPotentialFreeProductRewards to surface cheapest rewards
  • Fixed _updateRewardLines deduplication for multiple reward lines per reward