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:
@@ -11,6 +11,8 @@ declare( strict_types=1 );
|
||||
|
||||
namespace Magdev\WpBnb\PostTypes;
|
||||
|
||||
use Magdev\WpBnb\Pricing\Calculator;
|
||||
use Magdev\WpBnb\Pricing\PricingTier;
|
||||
use Magdev\WpBnb\Taxonomies\Amenity;
|
||||
use Magdev\WpBnb\Taxonomies\RoomType;
|
||||
|
||||
@@ -147,6 +149,15 @@ final class Room {
|
||||
'normal',
|
||||
'default'
|
||||
);
|
||||
|
||||
add_meta_box(
|
||||
'bnb_room_pricing',
|
||||
__( 'Room Pricing', 'wp-bnb' ),
|
||||
array( self::class, 'render_pricing_meta_box' ),
|
||||
self::POST_TYPE,
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -327,6 +338,87 @@ final class Room {
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render pricing meta box.
|
||||
*
|
||||
* @param \WP_Post $post Current post object.
|
||||
* @return void
|
||||
*/
|
||||
public static function render_pricing_meta_box( \WP_Post $post ): void {
|
||||
$pricing = Calculator::getRoomPricing( $post->ID );
|
||||
$currency = get_option( 'wp_bnb_currency', 'CHF' );
|
||||
?>
|
||||
<table class="form-table bnb-pricing-table">
|
||||
<tr>
|
||||
<th scope="row" colspan="2">
|
||||
<h4><?php esc_html_e( 'Base Prices', 'wp-bnb' ); ?></h4>
|
||||
</th>
|
||||
</tr>
|
||||
<?php foreach ( PricingTier::cases() as $tier ) : ?>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="bnb_room_price_<?php echo esc_attr( $tier->value ); ?>">
|
||||
<?php echo esc_html( $tier->label() ); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<div class="bnb-price-input-wrapper">
|
||||
<input type="number"
|
||||
id="bnb_room_price_<?php echo esc_attr( $tier->value ); ?>"
|
||||
name="bnb_room_price_<?php echo esc_attr( $tier->value ); ?>"
|
||||
value="<?php echo esc_attr( $pricing[ $tier->value ]['price'] ?? '' ); ?>"
|
||||
class="small-text"
|
||||
min="0"
|
||||
step="0.01">
|
||||
<span class="bnb-price-unit">
|
||||
<?php echo esc_html( $currency ); ?> <?php echo esc_html( $tier->unit() ); ?>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr>
|
||||
<th scope="row" colspan="2">
|
||||
<h4><?php esc_html_e( 'Adjustments', 'wp-bnb' ); ?></h4>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="bnb_room_price_weekend_surcharge">
|
||||
<?php esc_html_e( 'Weekend Surcharge', 'wp-bnb' ); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<div class="bnb-price-input-wrapper">
|
||||
<input type="number"
|
||||
id="bnb_room_price_weekend_surcharge"
|
||||
name="bnb_room_price_weekend_surcharge"
|
||||
value="<?php echo esc_attr( $pricing['weekend_surcharge']['price'] ?? '' ); ?>"
|
||||
class="small-text"
|
||||
min="0"
|
||||
step="0.01">
|
||||
<span class="bnb-price-unit">
|
||||
<?php echo esc_html( $currency ); ?> <?php esc_html_e( 'per night', 'wp-bnb' ); ?>
|
||||
</span>
|
||||
</div>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Additional amount charged for weekend nights (Friday/Saturday by default).', 'wp-bnb' ); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: Link to pricing settings */
|
||||
esc_html__( 'Seasonal pricing and tier thresholds can be configured in %s.', 'wp-bnb' ),
|
||||
'<a href="' . esc_url( admin_url( 'admin.php?page=wp-bnb-settings&tab=pricing' ) ) . '">' . esc_html__( 'Pricing Settings', 'wp-bnb' ) . '</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save post meta.
|
||||
*
|
||||
@@ -410,6 +502,23 @@ final class Room {
|
||||
implode( ',', $ids )
|
||||
);
|
||||
}
|
||||
|
||||
// Pricing fields.
|
||||
$pricing_data = array();
|
||||
foreach ( PricingTier::cases() as $tier ) {
|
||||
$key = 'bnb_room_price_' . $tier->value;
|
||||
if ( isset( $_POST[ $key ] ) && '' !== $_POST[ $key ] ) {
|
||||
$pricing_data[ $tier->value ] = floatval( $_POST[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_POST['bnb_room_price_weekend_surcharge'] ) ) {
|
||||
$pricing_data['weekend_surcharge'] = floatval( $_POST['bnb_room_price_weekend_surcharge'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $pricing_data ) ) {
|
||||
Calculator::saveRoomPricing( $post_id, $pricing_data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -433,6 +542,7 @@ final class Room {
|
||||
$new_columns['room_number'] = __( 'Room #', 'wp-bnb' );
|
||||
$new_columns['taxonomy-bnb_room_type'] = __( 'Room Type', 'wp-bnb' );
|
||||
$new_columns['capacity'] = __( 'Capacity', 'wp-bnb' );
|
||||
$new_columns['price'] = __( 'Price/Night', 'wp-bnb' );
|
||||
$new_columns['status'] = __( 'Status', 'wp-bnb' );
|
||||
}
|
||||
}
|
||||
@@ -483,6 +593,16 @@ final class Room {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'price':
|
||||
$pricing = Calculator::getRoomPricing( $post_id );
|
||||
$nightly = $pricing[ PricingTier::SHORT_TERM->value ]['price'] ?? null;
|
||||
if ( $nightly ) {
|
||||
echo esc_html( Calculator::formatPrice( $nightly ) );
|
||||
} else {
|
||||
echo '<span class="bnb-no-price">' . esc_html__( 'Not set', 'wp-bnb' ) . '</span>';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'status':
|
||||
$status = get_post_meta( $post_id, self::META_PREFIX . 'status', true ) ?: 'available';
|
||||
$statuses = self::get_room_statuses();
|
||||
|
||||
Reference in New Issue
Block a user