Add pricing system with tiers, seasons, and calculator (v0.2.0)
All checks were successful
Create Release Package / build-release (push) Successful in 1m19s
All checks were successful
Create Release Package / build-release (push) Successful in 1m19s
- Create PricingTier enum for short/mid/long-term pricing - Add Season class for seasonal pricing with date ranges - Implement Calculator for price calculations with breakdown - Add pricing meta box to Room post type - Create Seasons admin page for managing seasonal pricing - Add Pricing settings tab with tier thresholds - Support weekend surcharges and configurable weekend days - Add price column to room list admin Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
159
src/Pricing/PricingTier.php
Normal file
159
src/Pricing/PricingTier.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* Pricing tier enumeration.
|
||||
*
|
||||
* Defines the pricing tiers for short, mid, and long-term stays.
|
||||
*
|
||||
* @package Magdev\WpBnb\Pricing
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
|
||||
namespace Magdev\WpBnb\Pricing;
|
||||
|
||||
/**
|
||||
* Pricing tier enum.
|
||||
*/
|
||||
enum PricingTier: string {
|
||||
|
||||
/**
|
||||
* Short-term stay (per night).
|
||||
* Default: 1-6 nights.
|
||||
*/
|
||||
case SHORT_TERM = 'short_term';
|
||||
|
||||
/**
|
||||
* Mid-term stay (per week).
|
||||
* Default: 7-27 nights (1-4 weeks).
|
||||
*/
|
||||
case MID_TERM = 'mid_term';
|
||||
|
||||
/**
|
||||
* Long-term stay (per month).
|
||||
* Default: 28+ nights (1+ months).
|
||||
*/
|
||||
case LONG_TERM = 'long_term';
|
||||
|
||||
/**
|
||||
* Get the label for this tier.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function label(): string {
|
||||
return match ( $this ) {
|
||||
self::SHORT_TERM => __( 'Short-term (Nightly)', 'wp-bnb' ),
|
||||
self::MID_TERM => __( 'Mid-term (Weekly)', 'wp-bnb' ),
|
||||
self::LONG_TERM => __( 'Long-term (Monthly)', 'wp-bnb' ),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unit label for this tier.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function unit(): string {
|
||||
return match ( $this ) {
|
||||
self::SHORT_TERM => __( 'per night', 'wp-bnb' ),
|
||||
self::MID_TERM => __( 'per week', 'wp-bnb' ),
|
||||
self::LONG_TERM => __( 'per month', 'wp-bnb' ),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unit label for this tier (singular).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function unitSingular(): string {
|
||||
return match ( $this ) {
|
||||
self::SHORT_TERM => __( 'night', 'wp-bnb' ),
|
||||
self::MID_TERM => __( 'week', 'wp-bnb' ),
|
||||
self::LONG_TERM => __( 'month', 'wp-bnb' ),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the unit label for this tier (plural).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function unitPlural(): string {
|
||||
return match ( $this ) {
|
||||
self::SHORT_TERM => __( 'nights', 'wp-bnb' ),
|
||||
self::MID_TERM => __( 'weeks', 'wp-bnb' ),
|
||||
self::LONG_TERM => __( 'months', 'wp-bnb' ),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default minimum nights for this tier.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function defaultMinNights(): int {
|
||||
return match ( $this ) {
|
||||
self::SHORT_TERM => 1,
|
||||
self::MID_TERM => 7,
|
||||
self::LONG_TERM => 28,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default maximum nights for this tier.
|
||||
*
|
||||
* @return int|null Null means unlimited.
|
||||
*/
|
||||
public function defaultMaxNights(): ?int {
|
||||
return match ( $this ) {
|
||||
self::SHORT_TERM => 6,
|
||||
self::MID_TERM => 27,
|
||||
self::LONG_TERM => null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the pricing tier based on number of nights.
|
||||
*
|
||||
* @param int $nights Number of nights.
|
||||
* @param int|null $short_term_max Maximum nights for short-term. Default 6.
|
||||
* @param int|null $mid_term_max Maximum nights for mid-term. Default 27.
|
||||
* @return self
|
||||
*/
|
||||
public static function fromNights( int $nights, ?int $short_term_max = null, ?int $mid_term_max = null ): self {
|
||||
$short_term_max = $short_term_max ?? (int) get_option( 'wp_bnb_short_term_max_nights', 6 );
|
||||
$mid_term_max = $mid_term_max ?? (int) get_option( 'wp_bnb_mid_term_max_nights', 27 );
|
||||
|
||||
if ( $nights <= $short_term_max ) {
|
||||
return self::SHORT_TERM;
|
||||
}
|
||||
|
||||
if ( $nights <= $mid_term_max ) {
|
||||
return self::MID_TERM;
|
||||
}
|
||||
|
||||
return self::LONG_TERM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all tiers.
|
||||
*
|
||||
* @return array<self>
|
||||
*/
|
||||
public static function all(): array {
|
||||
return self::cases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tier options for select fields.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function options(): array {
|
||||
$options = array();
|
||||
foreach ( self::cases() as $tier ) {
|
||||
$options[ $tier->value ] = $tier->label();
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user