Steps to get product price based on promotion
Step 1:
calculateFinalPrice($product_id, $variant_id = null){
$prices = new PromotionalProduct($product_id, $variant_id = null);
$prices->calculateProductPrice();
}
class PromotionlProduct {
public $product_id = null;
public $variant_id = null;
public $isPromotion = false;
public $promotions;
public $product_promotion_details;
public product_details;
public function __construct($product_id,$variant_id=null){
$this->product_id = $product_id;
$this->variant_id = $variant_id;
}
public function calculateProductPrice(){
//Step 2
$this->isPromotion = $this->isAnyPromotionIsStartRightNow();
//Step 3
//$this->isProductInPromotion();
//Step 4
$this->fetchProductDetails();
//Step 5
$prices = $this->CalculateFinalPrice();
return $prices;
}
function isAnyPromotionIsStartRightNow(){
/*
Query promotion table to check is an promotion is start write now.
Apply query condition based on isCurrentDate is between start and end date and fetch all promotions.
*/
$current_date = now();
$this->promotions = Promotion::whereDate('start_date'<=$current_date)->whereDate('end_date'<=$current_date);
if(count($this->promotions) > 0 ){
/*At a time we may have multiple promotions, lets find those promotion which have this product. promotions_which_containing_this_products_array to find best discount from multiple promotions.
*/
$PWCthisPArray = array();
foreach($this->promotions as $promotion){
$inPromotion = isProductInPromotion($promotion->id);
if($inPromotion){
$this->PWCthisPArray[] = $inPromotion['id'];
}
}
$this->promotions = $this->PWCthisPArray();
if($this->promotions){
return true;
}
return false;
}else{
return false;
}
}
function isProductInPromotion($promotion_id){
$promotion = $this->promotions->first($promotion_id);
//based on promotion id find product in promtion_products table
$product_promotion_details = PromotionProduct::where('promotion_id',$promotion->id)->where('product_id', $this->product_id)->first();
return $this->product_promotion_details = $product_promotion_details;
}else{
return false;
// product not in promotions
}
}
function fetchProductDetails(){
$this->product_details = Product::find($this->product_id);
}
function calculateFinalPrice(){
if($this->product_details){
if($product_details->product_multiple_variants == 1){
$prices = ProductVariant::where('id',$this->variant_id)->first();
$prices = ['price' => $prices->price, 'compare_price' => 0];
}else{
$prices = ['price' => $this->product_details->price, 'compare_price' => $this->product_details- >compare_price];
}
if($this->isPromotion ){
$discountPercentage = $this->findBestPromotionDiscount();
if($discountPercentage > 0){
$discountedPrice = $prices['price'] - ($prices['price'] * $discountPercentage / 100);
$prices = ['price' => $this->product_details->price, 'compare_price' => $this- >product_details->$discountPrice];
}
}
return $prices;
}
function findBestPromotionDiscount(){
$this->promotions = Promotion::whereIn('id',$this->promotions)->get();
// Get the current date
$currentDate = new DateTime();
$bestDiscount = 0; // Initialize with no discount
$bestPromotion = null;
foreach ($promotions as $promotion) {
$startDate = new DateTime($promotion['start_date']);
$endDate = new DateTime($promotion['end_date']);
if ($currentDate >= $startDate && $currentDate <= $endDate) {
// The product is in the promotion period
$discountPercentage = (float) $promotion['discount_percentage'];
if ($discountPercentage > $bestDiscount) {
// This promotion offers a higher discount
$bestDiscount = $discountPercentage;
$bestPromotion = $promotion;
}
}
}
return $bestPromotion;
}
end function
}
end class
class Product
{
public $hasVariants;
public $price;
public $variantPrice;
public $isInPromotion;
public function calculateFinalPrice()
{
if ($this->hasVariants) {
$finalPrice = $this->variantPrice;
} else {
$finalPrice = $this->price;
}
if ($this->isInPromotion) {
$finalPrice -= ($finalPrice * 0.10); // Apply 10% discount
}
return $finalPrice;
}
}
// Example usage
$productWithoutVariants = new Product();
$productWithoutVariants->hasVariants = false;
$productWithoutVariants->price = 100;
$productWithoutVariants->isInPromotion = true;
$productWithVariants = new Product();
$productWithVariants->hasVariants = true;
$productWithVariants->variantPrice = 150;
$productWithVariants->isInPromotion = false;
$finalPriceWithoutVariants = $productWithoutVariants->calculateFinalPrice();
$finalPriceWithVariants = $productWithVariants->calculateFinalPrice();
echo "Final price without variants: $finalPriceWithoutVariants\n";
echo "Final price with variants: $finalPriceWithVariants\n";
CREATE TABLE promotions (
id INT AUTO_INCREMENT PRIMARY KEY,
product_id INT,
discount_percentage DECIMAL(5, 2),
start_date DATE,
end_date DATE
);
// Function to check if a product is in promotion
function isProductInPromotion($productId) {
// Implement logic to check the promotions table for the product's promotion status
// Return true if the product is in promotion, false otherwise
}
// Function to get the discount percentage for a product
function getDiscountPercentage($productId) {
// Implement logic to fetch the discount percentage for the product from the promotions table
// Return the discount percentage (e.g., 10 for a 10% discount)
}
// Function to calculate the final price of a product considering promotion
function calculateFinalPrice($productId, $price) {
if (isProductInPromotion($productId)) {
$discountPercentage = getDiscountPercentage($productId);
$discountedPrice = $price - ($price * $discountPercentage / 100);
return $discountedPrice;
} else {
return $price;
}
}
function isProductInPromotion($productId) {
// Get the current date
$currentDate = new DateTime();
// Query the promotions table to find the promotion for the given product
// Replace this with your actual database query logic
$promotionQueryResult = queryPromotion($productId);
if ($promotionQueryResult && count($promotionQueryResult) > 0) {
$promotion = $promotionQueryResult[0]; // Assuming you get the first matching promotion
// Parse the start and end dates from the database
$startDate = new DateTime($promotion['start_date']);
$endDate = new DateTime($promotion['end_date']);
// Check if the current date is within the promotion period
if ($currentDate >= $startDate && $currentDate <= $endDate) {
return true; // The product is in promotion
}
}
return false; // The product is not in promotion or no promotion found
}
// Example database query function (replace with your actual database logic)
function queryPromotion($productId) {
// Perform a database query to get the promotion for the given product
// Return an array of promotions or null if no promotion is found
// Replace this with your actual database query logic
}
When dealing with multiple overlapping promotions for a product, you need to implement logic to determine the most advantageous promotion for the customer. This might involve comparing the discounts offered by different promotions and selecting the one that results in the maximum savings for the customer. You can prioritize promotions based on certain criteria, such as the highest discount percentage or priority levels you define.
Here's a PHP function that checks for overlapping promotions, compares their discounts, and applies the most advantageous promotion:
```php
function calculateBestPromotion($productId) {
// Get the current date
$currentDate = new DateTime();
// Query the promotions table to find promotions for the given product
// Replace this with your actual database query logic
$promotions = queryPromotions($productId);
$bestDiscount = 0; // Initialize with no discount
$bestPromotion = null;
foreach ($promotions as $promotion) {
$startDate = new DateTime($promotion['start_date']);
$endDate = new DateTime($promotion['end_date']);
if ($currentDate >= $startDate && $currentDate <= $endDate) {
// The product is in the promotion period
$discountPercentage = (float) $promotion['discount_percentage'];
if ($discountPercentage > $bestDiscount) {
// This promotion offers a higher discount
$bestDiscount = $discountPercentage;
$bestPromotion = $promotion;
}
}
}
return $bestPromotion;
}
// Example database query function (replace with your actual database logic)
function queryPromotions($productId) {
// Perform a database query to get all promotions for the given product
// Return an array of promotions
// Replace this with your actual database query logic
}
```
In this code:
1. We iterate through all promotions associated with the product and calculate the discount percentage for each promotion.
2. If the current date is within the promotion period and the promotion offers a higher discount than the previous best promotion, we update the `bestDiscount` and `bestPromotion` variables.
3. After iterating through all promotions, the function returns the promotion that provides the highest discount (the most advantageous promotion). If there's no active promotion, it returns `null`.
You can then use the `calculateBestPromotion()` function to determine the best promotion for a product, apply the discount, and calculate the final price when a customer adds the product to their cart or during the checkout process.
Comments
Post a Comment