Statistic Calculations in laravel - class

I'm working on a project for golfstatistics. Right now I made it so far to enter and edit golfstatistics. I'm working with laravel 5 btw.
My database schema works like this:
Every round you play saves one entry in the round table with information like (date, playid, weather, courseid)
for every hole played an entry in the score table is made. There I have a reference to the roundid and information like (score, fairwayhit, greenhit, putts, penalties, ....)
No I want to create reports where I can filter for date and course etc.
What I did for now is. I created a Statistic class where I can pass the date, playerid, roundid, courseid in the construct. The construct will query all the rounds played, matching those filters.
Then, foreach statistic I made a public function ex. scoring_average, greenhit_percantage, putts_per_round, putts_per_greeninregulation etc. there are about 15 stats.
So my question is: is that right what I'm doing here? because I have about 15 functions just to calculate statistics.
Please give me some advice if you have a better solution.
Thank you

class Statistic {
/**
* The table associated with the model.
*
* #var string
*/
public $rounds = [];
public function __construct($user_id, $roundid = null, $start = "2000-01-01", $end = "2030-01-01", $courseid = 0){
$this->rounds = Round::where('user_id', '=', $user_id)->get();
}
public function score(){
if(count($this->rounds) > 0){
$avg = 0;
foreach($this->rounds as $round){
$scores = Score::where('round_id', '=', $round->id)->get(['score']);
foreach($scores as $score){
$avg += $score->score;
}
}
return $avg / count($this->rounds);
} else {
return "N/A";
}
}
public function fir(){
if(count($this->rounds) > 0){
$fairway = [];
foreach($this->rounds as $round){
$scores = Score::where('round_id', '=', $round->id)->get(['fir']);
foreach($scores as $score){
if($score->fir != 0){
array_push($fairway, $score->fir);
}
}
}
$hits = array_count_values($fairway);
//unset($hits[0]); //unsets par 3 with value 0
return self::percArray($hits);
return $perc;
} else {
return "N/A";
}
}

Related

Eloquent: check extra pivot column

Inside my User model I would like to make a isMember function.
public function isMember()
{
return(\Auth::check() && "get the status value here" == 1)
}
I got two models. User, Club.
Their pivot table: club_user
user_id
club_id
status
The 'status' column holds 0 or 1.
Now, how do i check the value for the extra column 'status'?
Update:
It's a many-to-many relationship.
Try This:
public function isMember(){
if(\Auth::check())
return (bool) $this->status;
return false;
Well, I got it to work. If somebody got some suggestions how to make it better, please fell free.
public function isMember($clubId)
{
$user = Club::find($clubId)->user()->where('club_user.user_id', \Auth::id())->first();
if (is_object($user))
{
$status = $user->pivot->status;
else
{
$status = 0;
}
return (\Auth::user() && $status == 1);
}

Amount change on Opportunity Apex Trigger

I'm trying to create trigger if record type is Revenue Risk then amount should be saved in negative value, Here's my code in which I'm having error, I tried it two ways, second is in comments.. none of them is working
public with sharing class amountValidator {
//pull data of Opportunity in list
public static void validateAmount (list<Opportunity> oppList){
oppList = [Select amount FROM Opportunity WHERE RecordType.Name IN ('Revenue Risk')];
for(Opportunity opportunities : oppList){
if(oppList.amount >= '0'){
oppList.amount = oppList.amount * '-1';
}
}
/*Map<String,Schema.RecordTypeInfo> rtMapByName = d.getRecordTypeInfosByName();
Schema.RecordTypeInfo rtByName = rtMapByName.get('Revenue Risk');
for(Opportunity each : oppList){
if(rtByName.size == 0){
}
else{
if(oppList.Amount >= 0){
oppList.Amount = oppList.Amount*-1;
}
}
}*/
The error is very clear:
if(oppList.amount >= '0'){ // THIS LINE WILL THROW AN ERROR: 'Comparison arguments must be compatible types: Integer (or Double), String
oppList.amount = oppList.amount * '-1'; // THIS ONE TOO: 'Arithmetic expressions must use numeric arguments'
}
Your second code snippet is also wrong (same for first one).
if(oppList.Amount >= 0){
oppList.Amount = oppList.Amount*-1;
// MUST BE each.Amount = each.Amount * - 1; Please try not to use reserved words as variable names
}
You may want to take a look at a previous post describing strongly typed programming languages: Strongly Typed
Since we can't add comments just yet, we're going to add a new answer:
You're not updating/inserting the updated amount for your opportunity.
The correct way of doing this is to create a separate List of Opportunities (i.e. List oppsToUpdate) and add the updated opportunities to this list.
public static void validateAmount (list<Opportunity> oppList){
oppList = [Select amount FROM Opportunity WHERE RecordType.Name IN ('Revenue Risk')]; // Why are you requerying the Opportunity if you already have it??
List<Opportunity> oppsToUpdate = new List<Opportunity>();
for(Opportunity opportunities : oppList){
if(opportunities.amount > 0){
opportunities.amount = opportunities.amount * -1;
oppsToUpdate.add(opportunities);
}
}
upsert opportunities;
}
Remember to enclose your function with try-catch statements with system debugs to see what's going on with your code.
And this is the link to the input parameter modifications and why this is bad practice: Input Parameters
Working Code:
trigger Risk_NegativeQuantity on OpportunityLineItem (before insert) {
set<id> oppid = new set<id>();
for (OpportunityLineItem oli : trigger.new)
{
oppid.add(oli.opportunityid);
}
Id RevenueRisk= Schema.SObjectType.Opportunity.getRecordTypeInfosByName().get('Revenue Risk').getRecordTypeId();
list<opportunity> opplist = [select id, recordtype.name,recordtypeid from opportunity where id in : oppid ];
for (OpportunityLineItem oli : trigger.new)
{
for (opportunity opp: opplist)
{
if (oli.opportunityid == opp.id)
{
if(opp.recordtype.name == 'Revenue Risk')
{
if(oli.Quantity > 0)
{
oli.Quantity = oli.Quantity * -1;
}
}
}
}
}
}

Creating cumulative pdf of orders in magento

I want to create a pdf of first 300 orders in magento. I want a functionality in which i will get first 300 orders and print their images(each order has different image) in a pdf. So how can i implement this functionality in magento. Is there any extension for that?
Take a look at /app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php
public function pdfinvoicesAction(){
$orderIds = $this->getRequest()->getPost('order_ids');
$flag = false;
if (!empty($orderIds)) {
foreach ($orderIds as $orderId) {
$invoices = Mage::getResourceModel('sales/order_invoice_collection')
->setOrderFilter($orderId)
->load();
if ($invoices->getSize() > 0) {
$flag = true;
if (!isset($pdf)){
$pdf = Mage::getModel('sales/order_pdf_invoice')->getPdf($invoices);
} else {
$pages = Mage::getModel('sales/order_pdf_invoice')->getPdf($invoices);
$pdf->pages = array_merge ($pdf->pages, $pages->pages);
}
}
}
if ($flag) {
return $this->_prepareDownloadResponse(
'invoice'.Mage::getSingleton('core/date')->date('Y-m-d_H-i-s').'.pdf', $pdf->render(),
'application/pdf'
);
} else {
$this->_getSession()->addError($this->__('There are no printable documents related to selected orders.'));
$this->_redirect('*/*/');
}
}
$this->_redirect('*/*/');
}
From the above function you could assign the first 300 order ids to $orderIds (or modify Mage::getResourceModel('sales/order_invoice_collection to get the first 300 records)
See magento orders list query
Changes :
public function pdfinvoicesAction(){
$orderIds = $this->getRequest()->getPost('order_ids');
To (something like)
public function pdfinvoices($orderIds){
$orderIds = (array) $orderIds; // first 300 record ids
Change line to save pdf to file
return $this->_prepareDownloadResponse(
'invoice'.Mage::getSingleton('core/date')->date('Y-m-d_H-i-s').'.pdf', $pdf->render(),
'application/pdf'
);
To
$pdf->render();
// use the order_id for the pdf name like
$pdf->save("{$orderId}.pdf");
see Error in generated pdf file using zend_pdf under Magento
You could also delete the $this->_redirect('//')

Is this a valid way to check if db_row exists?

I am working with Zend and I needed to check whether a row in the DB already exists (A simple solution to get rid of the duplicate key error I was getting). I tried several things but nothing seemed to work... (for example the Zend_Validate_Db_NoRecordExists method)
So I wrote the following the code and I was wondering if this is a valid way to do it, or if I should do things differently:
In the model:
$where = $condition = array(
'user_id = ' . $user_id,
'page_id = ' . $page_id
);
$check = $this->fetchRow($where);
if(count($check) > 0) {
return null;
}else{
// Here I create a new row, fill it with data, save and return it.
}
And then in my view:
if($this->result != null) { /* do stuff */ }else{ /* do other stuff */ }
It does work but it does seem to take more time (duh, because of the extra query) and I am a bit unsure whether I should stick with this..
Any recommendation is welcome :)
Assuming you have coded your function in your controller
$row = $this->fetchRow($where); //If no row is found then $row is null .
if(!$row)
{
$row = $dbTb->createNew($insert); //$insert an associative array where it keys map cols of table
$row->save();
$this->view->row_not_found = true;
}
return $row;
In your view you can do this
if($this->row_not_found)
{
}else {
}

Zend Db query to select all IDs

How would I write an Zend DB query to select all from the column ID?
So far I have tried:
public function getLatestUserID()
{
$ids = $this->select()
->where('id = ?');
return $ids;
}
But to no avail.
You just want the id column,
You failed to call an execute command.
try:
//assuming you are using a DbTable model
public function getLatestUserID()
{
$ids = $this->fetchAll('id');
return $ids;
}
I would do it like this, because I use the select() object for everything:
public function getLatestUserID()
{
$select = $this->select();
//I'm not sure if $this will work in this contex but you can out the table name
$select->from(array($this), array('id'));
$ids = $this->fetchAll($select);
return $ids;
}
The first two examples should return just the id column of the table, now if you actually want to query for a specific id:
public function getLatestUserID($id)
{
$select = $this->select();
$select->where('id = ?', $id);
//fetchAll() would still work here if we wanted multiple rows returned
//but fetchRow() for one row and fetchRowset() for multiple rows are probably
//more specific for this purpose.
$ids = $this->fetchRow($select);
return $ids;
}
make sure your class containing getLatestUserID does extend Zend_Db_Table_Abstract also :
$ids = $this->select()->where('id = ?'); can't work because where('id = ?'); expects an id value like where('id = ?', $id);
if what you want is the latest inserted row's Id use :
$lastInsertId = $this->getAdapter()->lastInsertId();
(however if you are using an oracle database this will not work and you should use $lastInsertId = $this->getAdapter()->lastSequenceId('USER_TABLE_SEQUENCE'); )