I'm try to fetch due month which, students not submitted there fee in his profile its show like your fee is due in this month,example- if a student not paid his/her fee in february and january then its his account that you fee is due in february and january please submit fee.I'm able to fetch all students who not submitted fee but how to show month(<=current month) all previous month fee dues
here is my code for profile
public function show($reg_no = null)
{
$s = Student::where('reg_no', $reg_no)->with('courses','states','sections','city','ccity','sstates')->first();
return view('students.student',compact('s'));
}
for students who not submitted fee in current month all students
$dt = Carbon::now();
$query = Student::where('status',1)->whereDoesntHave('subscriptions', function ($queryt) use($dt) {
$queryt->whereMonth('created_at','=',$dt->month);
})->with('courses')->paginate(15);
and here is my subscriptions table
I'll show you an example, but don't just copy paste, because this code is only to help you to understand how to achieve it. You'll need to make some change to fit in your app.
$messages = array();
foreach ($Student->subcriptions as subcription) {
if ($subcription->late_fee != null) {
$month = $subcription->month->month(); // I'm not sure if Carbon will handle this part. If not, you'll need to do an explode of $subcription->month then take the $month[1]...
if ($month == 1) {$month = 'January';}
if ($month == 2) {$month = 'February';}
... //Do it for every month...
$message = 'Your fee are due for '.$month; //Or you can only push the month then into the view then implode the array.
array_push($messages, $message);
}
}
Into your view, if you are using blade, you simply do this where you want to show the messages. Don't forget to pass $messages to the view.
#foreach($messages as $message)
<span>{{$message}}</span>
#endforeach
There is multiple way to do what you want. But this will show every month where the student have late_fee not null. Now adapt it to your code.
Don't forget that if you don't want something like:
Your fee are due for January.
Your fee are due for February.
Your fee are due for Mars.
....
Look for implode of the messages array without adding Your fee are due for into the loop then don't use the for each loop into the view, simply display the new imploded variable.
Related
Im using cyrildewit/eloquent-viewable package to get page views. When I check out the documentation, I don't see a method where I can only get views for a single date. It uses Period and Carbon to get dates in a particular period so the (since and upTo) functions.
Any fix or alternative package to get page views.
I am trying to create a analytics page.
public function pastDateViewsChart(){
$days = [];
$view_count = [];
foreach($this->views as $v){
//get views for the past 28 days
if($v->viewed_at >= Carbon::create("28 days ago")){
if(!in_array(Carbon::parse($v->viewed_at)->format('Y-m-d'),$days,true))
array_push($days, Carbon::parse($v->viewed_at)->format('Y-m-d'));
}
}
//get views for each day
$count = views($this)
->period(Period::upto(Carbon::parse($days[0])))
->count();
array_push($view_count,$count);
return $view_count;
}
You're not limited to since and upto, Period has (as per what I can see there https://github.com/cyrildewit/eloquent-viewable/blob/master/src/Support/Period.php) a create method that can take any date as start and end:
->period(Period::create(
Carbon::parse($days[0])->startOfDay(),
Carbon::parse($days[0])->endOfDay()
))
I have a record where I am getting data with timestamps (created_at, updated_at) for last 4 months. Next, I want to divide this data into week wise and month wise (last 4 weeks and last 4 months.)
What I am trying is to manually create variables for each months and then write if logic to enter data into each month. Is there any function that already does it?
// for student population - Last 4 months data
$from = Carbon::now()->subMonth(4);
$to = Carbon::now();
$invoice =invoice::where('instructor_id', '=', $id)
->whereBetween('created_at',[$from,$to])->get();
$week_1=$week_2=$week_3=$week_4=$month_1=$month_2=$month_3=$month_4=[];
// write if logic and enter data for each week separately
No, there is no function that already does it, afaik, in Eloquent or Carbon.
I would suggest looping through the Eloquent Collection.
Here is a hint for you :
$from = Carbon::now()->subMonth(4);
$to = Carbon::now();
$invoices = invoice::where('instructor_id', '=', $id)->whereBetween('created_at', [$from, $to])->get();
// ...
$invoicesLastWeek = $invoices->whereBetween('created_at', [
Carbon::now()->subWeeks(1)->startOfWeek(),
Carbon::now()->subWeeks(1)->endOfWeek()
]);
// ...
$invoicesTwoMonthsAgo = $invoices->whereBetween('created_at', [
Carbon::now()->subMonths(2)->startOfMonth()),
Carbon::now()->subMonths(2)->endOfMonth()
]);
// ...
I would loop and increment parameters for ->subWeeks($i)-> and ->subMonths($i)->, and populate the needed variables.
I would start setting each week vars first, so that I can pop out of the Collection all invoices in that range (for performance). Then for each month vars, I would add weekN + weekN+1 + weekN+2 + weekN+3 vars (and pop them out of the Collection as well, so that I loop faster on a Collection that is getting smaller everytime).
I have a array of events with unixtimestamp and i want to show them according to year. Mean section wise.
2015
Event 1
Event 2
Event 3
2014
Event 1
Event 2
Event 3
What i do:
$yearlyEvents=array();
foreach ($events as $event) {
$eventPost = get_post($event->post_id);
$timestamp=$event->start;
$eventYear=gmdate("Y", $timestamp);
if($index=in_array($eventYear, $yearlyEvents, true)){
print_r($index);
}
else{
$tempObj['name']=$eventYear;
$tempObj['events']=$event;
$yearlyEvents[]=$tempObj;
}
}
But not get the desired results.Anybody help?
You need to get events as sub arrays of year.
Add sub arrays, one for each year append events to it.
This is my preferred logic, please feel free to change it in accordance with your project needs.
Corrected Code:
$yearlyEvents=array();
foreach ($events as $event) {
$eventPost = get_post($event->post_id);
$timestamp=$event->start;
$eventYear=gmdate("Y", $timestamp);
if($index=in_array($eventYear, $yearlyEvents, true)){
print_r($index);
}
else{
$tempObj['name']=$eventYear;
$tempObj['events']=$event;
$yearlyEvents[$eventYear][] = $tempObj; // Check here.
}
}
first of all you need to get result from Database in such a format which is easy to manipulate for your output.
Here you are trying to display events years wise in descending order and events in ascending order. So first of all get result from database like
SELECT * FROM events ORDER by events.start DESC,events.post_id ASC
Now it is in an order which is easy to display. loop through and display result until next year found. check if next year come display year too.
I have a matrix of inputs boxes which contain prices for dates. If there is no price in the database for a particular date the input box displays 0. I have the following code which saves into the database the prices typed into the input boxes. It does not save all the 0 values only the new prices.
Which is fine. However I have now discovered an issue. If one of the inputs dislays a value from the database, say $10 and I want to set it now to 0, the code will not do it.
It will only save if the values and above 0. I have not been able to do this final check.
The conditions for saving are
1. If the value is numeric
2. If it is 0 and already has an entry in the database then save
3. If it has no value in the database and is greater than 0
4. If it is 0 and has no value in the database then do not save
if (isset($this->data['Rate'])){
// for each rate
foreach($this->data['Rate'] as $rate_id => $room){
// for each room type
foreach($room as $room_id => $room){
$price_for_today = isset($room['Price'][$key]) ? $room['Price'][$key] : 0;
// get existing availabilities is num (get this from previous date loop)
$today = ''.$date.' 00:00:00';
$conditions = array('Availability.date' => $today,'Availability.room_id'=>$room_id);
$this->Availability->contain();
$result = $this->Availability->find('all',array('order'=>'Availability.room_id ASC', 'conditions'=>$conditions));
$avail_id = $result[0]['Availability']['id'];
// check prices
$check_prices = "SELECT * FROM prices
WHERE rate_id = '".$rate_id."' AND availability_id = '".$avail_id."'";
$prices_result = $this->Availability->query($check_prices);
// if new prices > 0.00
if($price_for_today>0 && is_numeric($price_for_today)){
// better checking needed!
if($prices_result){
$setprices = "UPDATE prices SET price = '".$price_for_today."'
WHERE rate_id = '".$rate_id."' AND availability_id = '".$avail_id."'";
$update = $this->Availability->query($setprices);
} else {
$setprices = "INSERT INTO prices (price, availability_id, rate_id)
VALUES ('".$price_for_today."', '".$avail_id."', '".$rate_id."')";
$insert = $this->Availability->query($setprices);
}
}
//$errors[] = $setprices;
} // end rooms loop
} // end Rates loop
Your problem is in
> // if new prices > 0.00
> if($price_for_today>0 &&
> is_numeric($price_for_today)){
here you specify that $prices_for_today have to be >0, so if you had a price and want to put it 0 today then you will not do anything... You should use
if(($price_for_today>0 && is_numeric($price_for_today)) || (!empty($prices_result) && $price_for_today==0 && is_numeric($price_for_today))){
if you change it it will now enter in the if and do the change.
I sugest that you do NOT use the query function unless is extremely necesary. you should create a model for price (if you haven't done that already) and then use the associations (hasMany, HasOne, HABTM) or load the model directly in the controller with $this->loadModel('Price'). Then use a find 'all' as always with conditions and fields. This recomendation is to use cake as it was intended, not indispensable. Also the save, updatefield, read can be done if you do this... leaving the checks and everything to cake.
In our order proces it is possible to send an invoice for a partial order. So when a couple of order lines are being shipped, an invoice have to be send also.
To make this possible I use this code:
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($items);
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
$invoice->register();
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
$invoice->sendEmail();
$invoice->setEmailSent(true);
$invoice->save();
Where the $items variable is an array containing the order ids and the amount of products to be invoiced.
The created invoice shows the correct products to be invoiced, but somehow the totals aren't updated. The totals still are the totals of the complete order, instead of the partial invoice.
I probably have to update or recalculate the totals but can't find the right code to force the update.
Anyone around who can put me in the right direction?
Well, it seems I have found the problem. The functionality as described above works manually executing it in the administrator interface. The code as enclosed above I only got to work by changing a core file of Magento.
If you change line 103 of Mage_Sales_Model_Service_Order from continue; to $qty = 0; the functionality works.
In short, this is what happens. With continue the second row item isn't added to the invoice which the invoice makes thinks the curren item is the last item of the whole order and therefore needs to invoice the complete outstanding amount. In my case the invoice I did want to invoice and the row I didn't want to invoice.
I've submitted it as issue on the Magento issue list.
Today I faced with exactly this problem, but I found a more elegant way to solve it without editing the core. The solution is to pass the products that we don't want to invoice, with 0 quantity.
In this way, the code you changed in core will act exactly like in your solution :)
As an example if I have 2 products in my order:
array(
1234 => 1,
1235 => 2
)
passing this array:
$qtys = array(
1234 => 1,
1235 => 0
)
will force this code:
// Mage_Sales_Model_Service_Order: lines 97-103
if (isset($qtys[$orderItem->getId()])) { // here's the magic
$qty = (float) $qtys[$orderItem->getId()];
} elseif (!count($qtys)) {
$qty = $orderItem->getQtyToInvoice();
} else {
continue; // the line to edit according to previous solution
}
to act exactly like in your solution, so you don't have to edit core code.
Hope it helps :)
OK - took me a bit, but now I see how to correctly create the array.
foreach ($items as $itemId => $item) {
$itemQtyToShip = $item->getQtyToShip()*1;
if ($itemQtyToShip>0) {
$itemQtyOnHand = $stockItem->getQty()*1;
if ($itemQtyOnHand>0) {
//use the order item id as key
//set the amount to invoice for as the value
$toShip[$item->getId()] = $itemQtyToShip;
} else {
//if not shipping the item set the qty to 0
$toShip[$item->getId()] = 0;
}
}
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice($toShip);
This creates a proper invoice.