Form Calculations.

I am creating a Yii app that collects customer information and calculates ticket prices for an event.

The customer will have a dropdown like

Adult Tickets - $8.00/ea- Quantity: 1

Child tickets - $4.00/ea- Quantity: 2

In this case the user "selected" 1 adult and 2 child tickets. These will be dropdowns to select the # of each type of ticket

The form must calculate the count of all tickets * the price of each ticket type and return a total to the controller on submit.

I think I can get the data back to the controller, but is there anything in Yii to help with the calculation piece?

I also have to limit the total number of tickets to < the available seats for the event. Just looking for guidance on how you would accomplish this.

Dear Friend

To simulate your scenario I have created a Model Booking.

attributes: id,booking_date,name,adult,children,total_amount.

Booking.php (relevant portoins)




class Booking extends CActiveRecord

{   

    public  $daily_ceiling=100;//only hundred tickets are alloted for each day.

    public static $adult_pricing=8;

    public static $child_pricing=4;

	

	

    public function rules()

    {

	//We are defining two custom validators for bookin_date and and daily_ceiling. 	


	return array(

		array('booking_date, name, phone, adult, children, total_amount', 'required'),

		array('phone, adult, children, total_amount', 'numerical', 'integerOnly'=>true),

		array('name', 'length', 'max'=>64),

		array('booking_date', 'validateDate'),

		array('daily_ceiling', 'validateCeiling'),

		array('id, booking_date, name, phone, adult, children, total_amount', 'safe', 'on'=>'search'),

		);

    }

    

    public function validateCeiling($attribute,$params)

    {

	$bookings=Booking::model()->findAllByAttributes(array('booking_date'=>$this->booking_date));

	$total_booked=0;

	foreach($bookings as $booking)

	{

			$total_booked+=$booking->adult;

			$total_booked+=$booking->children;		

	}

    //We are going to throw errors if current booking exceeds the daily alloted booking.


	if(($total_booked+$this->adult+$this->children) >$this->daily_ceiling)

		$this->addError('daily_ceiling',"	We have only ".($this->daily_ceiling-$total_booked)." tickets left on ". $this->booking_date);

    }


    public function validateDate($attribute,$params)

    {   

        //We are going to throw errors if user erroneously enter a date in the past.

	if($this->booking_date < date('Y-m-d'))

		$this->addError($attribute,"You have entered a date in the past.");


        //Booking are possibly for next one month,not more than that.

	if($this->booking_date > date('Y-m-d',time()+30*24*60*60))

		$this->addError($attribute,"Booking are allowed for only next 30 days.");

    }

	


	

    public static function dropDownArray($number)

    {   

        //creating a array source used in dropDownList

	$arr=array(0=>'select');

	for($i=1;$i<=$number;$i++)

	    $arr[$i]=$i;

	return $arr;

    }	

}



_form.php




<?php




<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'booking-form',

	'enableAjaxValidation'=>false,

       )); ?>


<p class="note">Fields with <span class="required">*</span> are required.</p>


<?php echo $form->errorSummary($model); ?>


<div class="row">

   <?php echo $form->labelEx($model,'booking_date'); ?>


<!-- We are using a date picker to enter the date. -->


   <?php $this->widget('zii.widgets.jui.CJuiDatePicker',array(

	   'model'=>$model,

           'attribute'=>'booking_date',   

           'options'=>array(

               'showAnim'=>'fold',

               'dateFormat'=>'yy-mm-dd', //this format is important to avoid errors in database storage.

         ),

      

         ));?>

    <?php echo $form->error($model,'booking_date'); ?>

	</div>


<div class="row">

    <?php echo $form->labelEx($model,'name'); ?>

    <?php echo $form->textField($model,'name',array('size'=>60,'maxlength'=>64)); ?>

    <?php echo $form->error($model,'name'); ?>

</div>


<div class="row">

    <?php echo $form->labelEx($model,'phone'); ?>

    <?php echo $form->textField($model,'phone'); ?>

    <?php echo $form->error($model,'phone'); ?>

</div>


<!-- assigning id for adult and children inputs -->


<div class="row">

    <?php echo $form->labelEx($model,'adult'); ?>

    <?php echo $form->dropDownList($model,'adult',Booking::dropDownArray(10),array("id"=>"adult")); ?>

    <?php echo $form->error($model,'adult'); ?>

</div>


<div class="row">

    <?php echo $form->labelEx($model,'children'); ?>

    <?php echo $form->dropDownList($model,'children',Booking::dropDownArray(10),array('id'=>'children')); ?>

    <?php echo $form->error($model,'children'); ?>

</div>


<div class="row">

    <?php echo $form->labelEx($model,'total_amount'); ?>

    <?php echo $form->textField($model,'total_amount',array('id'=>'total')); ?>

    <?php echo $form->error($model,'total_amount'); ?>

</div>




<!-- The following field has no inputs for dail_ceiling. The purpose of this is to only throw errors when daily ceiling is exceeded -->

<div class="row">

    <?php echo $form->error($model,'daily_ceiling'); ?>

</div>


<div class="row buttons">

    <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>

</div>


<?php $this->endWidget(); ?>


</div><!-- form -->


<?php

//Registering a script to calculate the total amount on client side.

Yii::app()->clientScript->registerScript('totalAmount','

$("#children,#adult").change(function(){

	var child_pricing="'.$model::$child_pricing.'";

	var adult_pricing="'.$model::$adult_pricing.'";

	child_pricing=parseFloat(child_pricing);

	adult_pricing=parseFloat(adult_pricing);

	var child_total=$("#children").val()*child_pricing;

	var adult_total=$("#adult").val()*adult_pricing;

	$("#total").val(child_total+adult_total);

	

	

	});


');




Regards.

Great help! Thank you. I will implement something similar to this.

That’s great… thank you… thats what i need… :D

helpful thanks ;)