Files
wc-tier-and-package-prices/CLAUDE.md
magdev 937e80fce3 Release version 1.2.4 - Fix admin table borders and checkbox layout
Fixed:
- Admin table borders still visible despite v1.2.3 fix - added !important flags
- Help icon positioning at right edge instead of next to label - changed to flexbox layout
- Increased checkbox margin from 8px to 12px for better spacing

Technical:
- Added border-collapse: collapse !important to force borderless tables
- Changed label layout from float to inline-flex for proper help-tip positioning
- Added comprehensive border removal with !important on all table elements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-30 00:02:34 +01:00

30 KiB

WooCommerce Tier and Package Prices - AI Context Document

Last Updated: 2025-12-29 Current Version: 1.2.4 Author: Marco Graetsch Project Status: Production-ready WordPress plugin

Project Overview

This is a WooCommerce plugin that adds flexible pricing capabilities to products through two distinct pricing models:

  1. Tier Pricing (Volume Discounts): Progressive discounts based on quantity ranges (e.g., 1-9 items @ $12, 10-24 @ $10, 25+ @ $8)
  2. Package Pricing (Fixed Bundles): Exact quantity packages at fixed prices (e.g., exactly 10 items for $95, exactly 25 for $200)

Key Fact: 100% AI-Generated

This project is proudly "vibe-coded" using Claude.AI - the entire codebase was created through AI assistance.

Technical Stack

  • Language: PHP 7.4+
  • Framework: WordPress Plugin API
  • E-commerce: WooCommerce 8.0+ (tested up to 10.x)
  • Template Engine: Twig 3.0 (via Composer)
  • Frontend: Vanilla JavaScript + jQuery
  • Styling: Custom CSS
  • Dependency Management: Composer
  • Internationalization: WordPress i18n (.pot/.po/.mo files)

Dependencies

{
  "twig/twig": "^3.0",
  "symfony/polyfill-ctype": "^1.x",
  "symfony/polyfill-mbstring": "^1.x"
}

Architecture

Directory Structure

wc-tier-and-package-prices/
├── wc-tier-and-package-prices.php    # Main plugin file (entry point)
├── includes/                         # PHP classes
│   ├── class-wc-tpp-admin.php        # Admin settings integration
│   ├── class-wc-tpp-settings.php     # WooCommerce settings page
│   ├── class-wc-tpp-product-meta.php # Product edit page meta boxes
│   ├── class-wc-tpp-frontend.php     # Product page display logic
│   ├── class-wc-tpp-cart.php         # Cart price calculations
│   └── class-wc-tpp-template-loader.php # Twig template loader
├── templates/                        # Twig templates
│   ├── admin/                       # Admin interface templates
│   │   ├── tier-row.twig           # Single tier input row
│   │   └── package-row.twig        # Single package input row
│   └── frontend/                    # Customer-facing templates
│       ├── pricing-table.twig       # Main pricing display wrapper
│       ├── tier-pricing-table.twig  # Tier pricing display
│       └── package-pricing-display.twig # Package buttons/cards
├── assets/
│   ├── css/
│   │   ├── admin.css               # Backend styling
│   │   └── frontend.css            # Product page & cart styling
│   └── js/
│       ├── admin.js                # Meta box interaction (add/remove rows)
│       └── frontend.js             # Dynamic price updates, package selection
├── languages/                       # Translation files
│   ├── *.pot                       # Translation template
│   ├── *.po                        # Translation sources
│   └── *.mo                        # Compiled translations
├── vendor/                          # Composer dependencies (included in releases)
├── releases/                        # Release packages (not in git)
└── *.md                            # Documentation files

Class Responsibilities

1. WC_Tier_Package_Prices (Main Plugin Class)

  • Location: wc-tier-and-package-prices.php
  • Pattern: Singleton
  • Responsibilities:
    • Plugin initialization and bootstrapping
    • Loading all component classes via includes()
    • HPOS (High-Performance Order Storage) compatibility declaration
    • Text domain loading for internationalization
    • Activation/deactivation hooks

2. WC_TPP_Admin

  • Location: includes/class-wc-tpp-admin.php
  • Pattern: Singleton
  • Responsibilities:
    • Enqueues admin CSS/JS
    • Registers WooCommerce settings page via filter
    • Manages settings page instance (cached to prevent duplicates)
    • Product meta box asset loading

3. WC_TPP_Settings

  • Location: includes/class-wc-tpp-settings.php
  • Extends: WC_Settings_Page (WooCommerce core)
  • Responsibilities:
    • Creates "Tier & Package Prices" tab in WooCommerce settings
    • Defines global plugin settings (enable/disable features, display position, etc.)
    • Setting persistence through WooCommerce options API

Global Settings:

  • wc_tpp_enable_tier_pricing (yes/no)
  • wc_tpp_enable_package_pricing (yes/no)
  • wc_tpp_display_table (yes/no) - Show pricing tables on product pages
  • wc_tpp_display_position (before_add_to_cart / after_add_to_cart / after_price)
  • wc_tpp_restrict_package_quantities (yes/no) - Global quantity restrictions

4. WC_TPP_Product_Meta

  • Location: includes/class-wc-tpp-product-meta.php
  • Responsibilities:
    • Adds tier/package pricing fields to product edit page
    • Renders Twig templates for meta box rows
    • Saves tier/package data to post meta
    • Nonce verification and capability checks for security
    • Prevents autosave from corrupting data

Product Meta Keys:

  • _wc_tpp_tiers - Array of tier objects [{min_qty, price, label}]
  • _wc_tpp_packages - Array of package objects [{qty, price, label}]
  • _wc_tpp_restrict_to_packages - Per-product quantity restriction (yes/no)

5. WC_TPP_Frontend

  • Location: includes/class-wc-tpp-frontend.php
  • Responsibilities:
    • Enqueues frontend CSS/JS on product pages
    • Displays pricing tables via Twig templates
    • Localizes currency settings to JavaScript
    • Hides quantity inputs for restricted products
    • Modifies catalog "Add to Cart" buttons to "View Options" for restricted products
    • Static methods for price lookups (get_tier_price(), get_package_price())

6. WC_TPP_Cart

  • Location: includes/class-wc-tpp-cart.php
  • Responsibilities:
    • MOST CRITICAL CLASS - Handles all cart price calculations
    • Applies tier/package pricing during cart totals calculation
    • Stores pricing metadata in cart items for display
    • Customizes cart item display (price labels, quantity indicators)
    • Validates package quantities on add-to-cart
    • Hides/disables quantity inputs for restricted products (classic cart + blocks)
    • WooCommerce Blocks support via woocommerce_store_api_product_quantity_editable filter

Price Calculation Priority (in apply_tier_package_pricing()):

  1. Check for exact package match → Use package price if found
  2. Check for tier match → Use tier price if found
  3. Fall back to regular product price

7. WC_TPP_Template_Loader

  • Location: includes/class-wc-tpp-template-loader.php
  • Pattern: Singleton
  • Responsibilities:
    • Initializes Twig environment with proper paths
    • Renders Twig templates from both admin and frontend directories
    • Handles template caching and error handling

Important Implementation Details

Price Calculation Logic

Package Pricing (exact match):

// In cart: if quantity == 10 and package exists for 10, use package price
if ($quantity == $package['qty']) {
    $unit_price = $package['price'] / $quantity;  // Total price divided by quantity
    $product->set_price($unit_price);  // WooCommerce expects unit price
}

Tier Pricing (range-based):

// In cart: if quantity >= 10, use tier price for quantities 10+
foreach ($tiers as $tier) {
    if ($quantity >= $tier['min_qty']) {
        $applicable_price = $tier['price'];  // This is already unit price
    }
}
$product->set_price($applicable_price);

Quantity Restriction Feature

Products can be configured to ONLY allow purchase in package quantities:

  • Global setting: wc_tpp_restrict_package_quantities
  • Per-product setting: _wc_tpp_restrict_to_packages
  • When enabled:
    • Quantity inputs are hidden on product page, cart, and mini-cart
    • Customers must use package selection buttons
    • Validation prevents arbitrary quantities from being added
    • Catalog buttons change to "View Options" instead of "Add to Cart"

WooCommerce Blocks Compatibility

CRITICAL BUG FIXED in v1.1.20:

  • Filter woocommerce_store_api_product_quantity_editable passes WC_Product object, NOT cart item array
  • Previous code tried to use product object as array → fatal error
  • Fixed by accepting product object and using $product->get_id()

Cart Item Metadata

The plugin stores additional data in cart items for display purposes:

WC()->cart->cart_contents[$cart_item_key]['wc_tpp_pricing_type'] = 'package' | 'tier';
WC()->cart->cart_contents[$cart_item_key]['wc_tpp_total_price'] = 99.99;  // For packages
WC()->cart->cart_contents[$cart_item_key]['wc_tpp_unit_price'] = 9.99;   // For tiers

This metadata is used by display filters to show "(Package price)" or "(Volume discount)" labels.

Common Patterns & Conventions

Class Instantiation Pattern

All classes auto-instantiate at the end of their file:

if (!class_exists('WC_TPP_Frontend')) {
    class WC_TPP_Frontend {
        // class code
    }
}
new WC_TPP_Frontend();  // Auto-instantiate

Exception: Admin and Settings classes use singleton pattern to prevent duplicates.

Security Best Practices

  • All user inputs are sanitized (integers for quantities/prices)
  • Nonce verification on form submissions
  • Capability checks (edit_products) before saving
  • Output escaping in templates (esc_attr, esc_html, esc_js)
  • Direct file access prevention via ABSPATH check

Translation Ready

All user-facing strings use:

__('Text to translate', 'wc-tier-package-prices')
_e('Text to translate', 'wc-tier-package-prices')

Text domain: wc-tier-package-prices

Available Translations (as of v1.1.22):

  • en_US - English (United States)
  • de_DE - German (Germany, formal)
  • de_DE_informal - German (Germany, informal "du")
  • de_CH - German (Switzerland, formal "Sie")
  • de_CH_informal - German (Switzerland, informal "du")
  • fr_CH - French (Switzerland)
  • it_CH - Italian (Switzerland)

Note: Swiss locales use CHF currency formatting in examples (e.g., "CHF 50.-")

Known Issues & Historical Context

Settings Page Duplication Saga (v1.1.15-1.1.19)

Multiple versions attempted to fix settings page appearing twice:

  • Root cause: Settings file auto-instantiation + Composer autoloader
  • Solution: Removed auto-instantiation from settings file, explicit instantiation in admin class
  • Prevention: Singleton pattern + duplicate detection in array

Class Redeclaration Issues (v1.1.8-1.1.14)

Plugin was completely non-functional:

  • Cause: Incorrect initialization pattern without class_exists() guards
  • Solution: Added guards and restored direct instantiation pattern
  • Lesson: Always wrap class declarations in class_exists() checks

WooCommerce Blocks Fatal Error (v1.1.19 → v1.1.20)

Fatal error: Cannot use object of type WC_Product_Simple as array
Location: includes/class-wc-tpp-cart.php:233
  • Cause: Filter signature mismatch - expected array, received product object
  • Fix: Changed method signature to accept WC_Product $product instead of $cart_item array
  • Status: FIXED in v1.1.20

Release Process

Version Bumping

Update version in 3 places:

  1. wc-tier-and-package-prices.php - Plugin header comment (line 7)
  2. wc-tier-and-package-prices.php - WC_TPP_VERSION constant (line 26)
  3. composer.json - version field (optional, not critical)

Creating Release Package

CRITICAL: The zip command must be run from the parent directory of the plugin folder to create proper archive structure.

# From parent directory (/home/magdev/workspaces/node)
cd /home/magdev/workspaces/node

# Create zip excluding dev files - note the correct path structure
zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/ \
  -x 'wc-tier-and-package-prices/.git*' \
  'wc-tier-and-package-prices/*.log' \
  'wc-tier-and-package-prices/.claude/*' \
  'wc-tier-and-package-prices/CLAUDE.md' \
  'wc-tier-and-package-prices/releases/*' \
  'wc-tier-and-package-prices/node_modules/*' \
  'wc-tier-and-package-prices/.DS_Store' \
  'wc-tier-and-package-prices/Thumbs.db' \
  'wc-tier-and-package-prices/.vscode/*' \
  'wc-tier-and-package-prices/.idea/*' \
  'wc-tier-and-package-prices/*.sublime-*' \
  'wc-tier-and-package-prices/notes.*' \
  'wc-tier-and-package-prices/logs/*' \
  'wc-tier-and-package-prices/templates/cache/*' \
  'wc-tier-and-package-prices/composer.lock'

# Return to project directory
cd wc-tier-and-package-prices

# Generate checksums
cd releases
md5sum wc-tier-and-package-prices-X.X.X.zip > wc-tier-and-package-prices-X.X.X.zip.md5
sha256sum wc-tier-and-package-prices-X.X.X.zip > wc-tier-and-package-prices-X.X.X.zip.sha256
cd ..

IMPORTANT NOTES:

  • The vendor/ directory MUST be included in releases (Twig dependency required for runtime)
  • Running zip from wrong directory creates empty or malformed archives
  • Exclusion patterns must match the relative path structure used in zip command
  • Always verify the package with unzip -l and test extraction before committing

Verification Steps

After creating the release package, always verify:

# Check package size (should be ~400-450KB, NOT 8MB+ or near 0)
ls -lh releases/wc-tier-and-package-prices-X.X.X.zip

# Verify exclusions worked
unzip -l releases/wc-tier-and-package-prices-X.X.X.zip | grep -E "CLAUDE\.md|\.claude/|\.git" && echo "ERROR: Excluded files found!" || echo "OK: No excluded files"

# Test extraction
cd /tmp && rm -rf test-extract && unzip -q /path/to/releases/wc-tier-and-package-prices-X.X.X.zip -d test-extract && ls -la test-extract/wc-tier-and-package-prices/

# Verify version in extracted package
head -30 /tmp/test-extract/wc-tier-and-package-prices/wc-tier-and-package-prices.php | grep -E "Version:|WC_TPP_VERSION"

# Verify template changes (if applicable)
grep 'class="regular"' /tmp/test-extract/wc-tier-and-package-prices/templates/admin/*.twig

Git Workflow for Releases

Standard workflow: Work on dev branch → merge to main → tag → push

# 1. Ensure you're on dev branch with all changes committed
git checkout dev
git add [files]
git commit -m "Release version X.X.X - [description]

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"

# 2. Merge dev to main
git checkout main
git merge dev --no-edit  # Should be fast-forward

# 3. Create annotated tag
git tag -a vX.X.X -m "Release version X.X.X - [description]"

# 4. Push everything
git push origin main
git push origin vX.X.X

# 5. Update dev and push
git checkout dev
git rebase main  # Should be up-to-date already
git push origin dev

# 6. If you have uncommitted local changes (like .claude/settings.local.json)
git stash push -m "Local development settings"
# ... do git operations ...
git stash pop

Important Git Notes:

  • Always commit from dev branch first
  • Tags should use format vX.X.X (e.g., v1.1.22)
  • Use annotated tags (-a) not lightweight tags
  • Commit messages should follow the established format with Claude Code attribution
  • .claude/settings.local.json changes are typically local-only (stash before rebasing)

What Gets Released

  • All plugin source files
  • Compiled vendor dependencies
  • Translation files (.mo compiled from .po)
  • Assets (CSS, JS)
  • Documentation (README, CHANGELOG, etc.)

What's Excluded

  • Git metadata (.git/)
  • Development files (.vscode/, .claude/, CLAUDE.md)
  • Logs and cache files
  • Previous releases
  • composer.lock (but vendor/ is included)

Testing Checklist

When making changes, test these critical paths:

Admin

  • Settings page appears once under WooCommerce > Tier & Package Prices
  • Settings save correctly
  • Product edit page shows tier/package meta boxes
  • Adding/removing tiers works
  • Adding/removing packages works
  • Data saves when clicking "Update" on product

Frontend (Product Page)

  • Pricing tables display when configured
  • Package buttons update quantity selector
  • Price updates dynamically when quantity changes
  • Restricted products hide quantity input
  • "View Options" appears on catalog for restricted products

Cart & Checkout

  • Correct prices applied for tier pricing
  • Correct prices applied for package pricing
  • Cart displays pricing type labels
  • Package quantities can't be edited if restricted
  • Prices recalculate if quantity changed (non-restricted products)
  • Checkout totals are correct

WooCommerce Blocks (Critical!)

  • Mini cart block doesn't throw fatal errors
  • Cart block works correctly
  • Checkout block processes orders
  • Quantity editable flag works for blocks

Development Tips for Future AI Assistants

Common Pitfalls and Solutions

Release Package Creation

Problem: Empty or corrupted zip files (0 bytes or wrong structure) Cause: Running zip command from wrong directory or incorrect path patterns Solution: Always run from parent directory (/home/magdev/workspaces/node) and use full relative paths in exclusions

Problem: Development files included in release (CLAUDE.md, .claude/, .git) Cause: Exclusion patterns don't match actual paths used in zip command Solution: Test with unzip -l | grep to verify exclusions before committing

Problem: Package size is 8MB+ instead of ~400KB Cause: Development files not excluded (especially .git directory) Solution: Follow verification steps and check package size immediately after creation

UI Changes in Admin

WooCommerce CSS Classes:

  • short - Small input fields (~60px width)
  • regular - Medium input fields (~120px width)
  • long - Large input fields (~200px+ width)

When modifying admin input fields in Twig templates, use WooCommerce's standard classes for consistency.

Location: templates/admin/*.twig for admin UI changes

Git Workflow Issues

Problem: Cannot rebase due to uncommitted changes Solution: Stash local config files (.claude/settings.local.json) before git operations

Problem: Tag already exists Solution: Delete with git tag -d vX.X.X locally and git push --delete origin vX.X.X remotely

Problem: Wrong branch for commits Solution: Always start on dev branch, merge to main, never commit directly to main

Working with Twig Templates

The plugin uses Twig 3.0 for templating. Key files:

  • templates/admin/tier-row.twig - Single tier input row in product edit page
  • templates/admin/package-row.twig - Single package input row in product edit page
  • templates/frontend/*.twig - Customer-facing pricing displays

Template rendering: Done via WC_TPP_Template_Loader singleton class

When modifying templates:

  1. Templates are cached - clear cache or test in development mode
  2. Always escape output: use Twig's built-in filters or |esc_attr, |esc_html
  3. Translation strings: {{ 'Text'|__('wc-tier-package-prices') }}
  4. Keep consistent with WooCommerce admin UI patterns

Complete Release Workflow Summary

Based on v1.1.22, v1.2.2, and v1.2.3 release experience, here's the complete workflow:

  1. Fix bugs/add features on dev branch
  2. Update version numbers (3 files: main plugin file header, constant, composer.json)
  3. Update CHANGELOG.md with detailed changes
  4. Update CLAUDE.md version number and roadmap
  5. Create release package from parent directory with correct exclusions
  6. Verify package (size, contents, exclusions, extraction test)
  7. Commit changes to dev branch with proper message format
  8. Merge to main (fast-forward merge)
  9. Create annotated tag (vX.X.X)
  10. Push all (main, tag, dev)
  11. Verify remote (check repository web UI)

Time estimate: 15-20 minutes for full release cycle

Files typically changed in a release:

  • wc-tier-and-package-prices.php - Version bumps
  • composer.json - Version bump
  • CHANGELOG.md - Release notes
  • CLAUDE.md - Version and roadmap updates
  • releases/wc-tier-and-package-prices-X.X.X.zip* - Package and checksums
  • Feature-specific files (templates, PHP classes, etc.)

Release Package Creation - Critical Notes

IMPORTANT: The zip command must be run from the parent directory to create proper archive structure.

Correct command (from /home/magdev/workspaces/php):

cd /home/magdev/workspaces/php
zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/ \
  -x '*/\.git/*' '*/.git/*' 'wc-tier-and-package-prices/.git/*' \
  '*.gitignore' '*.log' '*/.claude/*' '*/CLAUDE.md' \
  '*/releases/*' '*/wordpress/*' '*/node_modules/*' \
  '*/.DS_Store' '*/Thumbs.db' '*/.vscode/*' '*/.idea/*' \
  '*.sublime-*' '*/notes.*' '*/logs/*' '*/templates/cache/*' \
  '*/composer.lock'

Critical Exclusions:

  • */wordpress/* - MUST be excluded! The project has a symlink to WordPress installation that zip will follow, creating 129MB+ packages instead of ~430KB
  • .git/* - All git metadata (multiple patterns needed for reliability)
  • .claude/* and CLAUDE.md - Development documentation
  • releases/* - Prevents including previous releases in new ones
  • composer.lock - Not needed in production (vendor/ is included)

Expected Package Size: ~430-431KB (383 files)

Package Size Alert: If >1MB, exclusions failed (likely wordpress symlink included)

Verification Steps:

# 1. Check size (should be ~430KB)
ls -lh releases/wc-tier-and-package-prices-X.X.X.zip

# 2. Verify file count (should be 383 files)
unzip -l releases/wc-tier-and-package-prices-X.X.X.zip | tail -1

# 3. Check for excluded files
unzip -l releases/wc-tier-and-package-prices-X.X.X.zip | grep -E "CLAUDE\.md|\.claude/|\.git/|wordpress/"
# Should return nothing (exit code 1)

# 4. Verify version in package
unzip -p releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/wc-tier-and-package-prices.php | head -30 | grep -E "Version:|WC_TPP_VERSION"

Future Features and Roadmap

The is a hierarchical list for upcoming features and can be considered as a Roadmap for the upcoming development.

Version 1.1.x (Completed)

  1. Add translations for de_CH, de_DE_informal, fr_CH, it_CH COMPLETED in v1.1.21
  2. The double-install bug is back again. A new version of the plugin is installed as new plugin instead of updating the previous version. DOCUMENTED in v1.1.22 - Added workaround to CHANGELOG. Root cause: No automatic update mechanism (requires WordPress.org repository or custom update server).
  3. Make the label fields in the backend for tierprices and package-prices twice as long as it is. COMPLETED in v1.1.22
  4. Make the plugin work with variable products COMPLETED in v1.2.0 - Full variation-level pricing support with independent configuration per variation, AJAX-based frontend display, and complete WooCommerce Blocks compatibility.

Version 1.2.x

Bugfixes (Completed in v1.2.1)
  1. The admin templates are not show right. The row templates didn't match the new table structure. The table-body columns didn't fit the table-head columns. FIXED in v1.2.1 - Updated admin.css to remove flexbox styling that was breaking the new <table>/<tr>/<td> structure introduced in v1.2.0. The CSS was still using flexbox layout from the old <div>/<p> structure.

  2. The tier and package prices are not shown on simple product pages FIXED in v1.2.1 - Removed global enable/disable checks from frontend template. Pricing tables now display if configured on a product AND the "Display Pricing Table" setting is enabled, regardless of "Enable Tier Pricing" or "Enable Package Pricing" global settings. Cart calculations still respect global enable settings.

Bugfixes (Completed in v1.2.2)
  1. Remove the table borders in admin on variable product to better fit the surrounding element styles. FIXED in v1.2.2 - Added CSS rules to remove table borders specifically for variation pricing tables (.wc-tpp-variation-pricing), matching WooCommerce's borderless variation UI style.

  2. Add missing translations in admin templates ("Price", "Tier & Package Pricing", "Min Quantity") for all languages used in this project. FIXED in v1.2.2 - Added missing translation entries for "Min Quantity", "Price", and "Label (optional)" to all .po files (de_DE, de_DE_informal, de_CH, de_CH_informal, fr_CH, it_CH, en_US) and recompiled .mo files.

  3. Check the template for wc_tpp_restrict_to_packages[] checkbox elements in admin on variable products and fix the rendering. FIXED in v1.2.2 - Fixed checkbox value parameter in variation pricing fields. Changed from ternary expression to direct value assignment, allowing WooCommerce's woocommerce_wp_checkbox() to properly handle the checked state.

Bugfixes (Completed in v1.2.3)
  1. Style the tier and packages tables in admin on simple products according to the styles on variable products. FIXED in v1.2.3 - Applied borderless table styling to all tier/package tables (both simple and variable products). Removed borders from table, th, and td elements to match WooCommerce's clean admin UI style.

  2. The checkbox styles from 1.2.2 bug 3 are still not looking correct. The helptext is written instead of hidden after the help icon and the margin between checkbox and label are to small. FIXED in v1.2.3 - Added desc_tip => true to variation checkbox to show tooltip instead of inline text. Added CSS rules to increase checkbox-label margin (8px) and hide inline description text when tooltip is used.

Bugfixes (Completed in v1.2.4)
  1. Bug 1 in v1.2.3 is not fixed. Now both table display have border again. they shouldn't have border. FIXED in v1.2.4 - Added !important flags and border-collapse: collapse to table CSS to override WooCommerce's default table styling. Added comprehensive border removal for all table elements (table, thead, tbody, tr, th, td) to ensure truly borderless tables across all browsers.

  2. Bug 2 in v1.2.3: Increase the margin between checkbox and label and put the help icon right next to the label, not at the right border FIXED in v1.2.4 - Increased checkbox right margin from 8px to 12px. Repositioned help tip icon to display inline right next to the label text using flexbox layout with display: inline-flex, removing float positioning that caused it to appear at the right edge.

New Features
  1. Create different, selectable templates for tierprices and packages to use in the frontend. Make the new templates selectable globally on the settings-page, not per product.

When Debugging Cart Issues

  1. Check includes/class-wc-tpp-cart.php first
  2. The apply_tier_package_pricing() method runs on woocommerce_before_calculate_totals
  3. Always validate product objects with is_a($product, 'WC_Product')
  4. Remember: WooCommerce expects UNIT prices, not total prices (except for internal calculations)

When Working with WooCommerce Hooks

  • WooCommerce has both classic and block-based systems
  • Classic cart uses different hooks than Store API (blocks)
  • Always check filter/action documentation for parameter types
  • Don't assume cart item arrays everywhere - sometimes it's product objects!

When Adding Features

  • Follow the existing pattern: add setting → add UI → add logic → add template
  • Use Twig for all new templates (consistency)
  • Add translations for all user-facing strings
  • Test with both simple products and variable products (if applicable)
  • Consider both classic and block-based cart/checkout

When Fixing Bugs

  1. Check CHANGELOG.md for historical context
  2. Look for similar issues in past versions
  3. Always add detailed changelog entry explaining root cause
  4. Consider edge cases (guest checkout, logged-in users, AJAX add-to-cart, etc.)

File Locations Quick Reference

Task File(s)
Change version wc-tier-and-package-prices.php (2 places)
Add global setting includes/class-wc-tpp-settings.php
Modify product meta box includes/class-wc-tpp-product-meta.php + templates/admin/*.twig
Change product page display includes/class-wc-tpp-frontend.php + templates/frontend/*.twig
Fix cart pricing includes/class-wc-tpp-cart.php
Update styles assets/css/frontend.css or assets/css/admin.css
Fix JavaScript bugs assets/js/frontend.js or assets/js/admin.js
Add translations languages/*.po then compile to .mo
Document changes CHANGELOG.md

Compatibility Notes

WordPress

  • Minimum: 6.0
  • Tested up to: 6.9.x
  • Uses standard plugin API, no deprecated functions

WooCommerce

  • Minimum: 8.0
  • Tested up to: 10.x
  • HPOS compatible (declared via FeaturesUtil::declare_compatibility)
  • Blocks compatible (with proper filter handling)

PHP

  • Minimum: 7.4
  • Uses modern PHP features (type hints acceptable in new code)
  • Composer autoloader handles namespacing

Browsers

  • Modern browsers (ES6+ JavaScript)
  • Responsive CSS (mobile-friendly)
  • jQuery dependency (WooCommerce provides)

Support & Resources

Final Notes

This is a production-quality plugin with real-world usage. Any changes should:

  1. Maintain backward compatibility with existing tier/package configurations
  2. Not break WooCommerce core functionality
  3. Work with both classic and block-based themes
  4. Be thoroughly tested before release
  5. Include proper error handling and validation
  6. Update CHANGELOG.md with detailed explanations

The plugin architecture is solid and well-tested. Most bugs arise from:

  • WooCommerce API changes (especially blocks)
  • Filter/action signature changes
  • Edge cases in cart calculations
  • Settings persistence issues

Always refer to this document when starting work on this project. Good luck!