I mean, I have a referral system which is every parent_id has parent and the parent_id of that parent until it gets to the last parent which is the Senior.
Given that a user has purchased an item and it is successful, now I am calling the insertEarnings function to insert the corresponding amount to his parent_id, if his parent_id is Junior his parent_id will get 100.
This is how the question begin, what if his parent doesn't have a rank meaning not active, the amount to be insert to his parent_id will go through the next rank which is the Premium so the Premium will no have 250 total, after that proceed the normal insertion of the amount to the parent_id of Premium which is the Advanced- he will get the corresponding amount which is 200, because the rank below him which is the Premium is existing, the insertion will go through until it gets to the last rank which is the Senior
Imagine that it is looping through the parent until it gets to the last rank - Senior.
The ranks are in order
Junior
Premium
Advanced
Senior
Ranks with their corresponding amount value
Junior - 100
Premium - 150
Advanced - 200
Senior - 250
Users table
+------+------------+-------------+------------+
| id | username | parent_id | rank |
+------+------------+-------------+------------+
| 1 | john | NULL | Senior |
| 2 | jane | 1 | Advanced |
| 3 | josh | 2 | Premium |
| 4 | joey | 3 | Junior |
| 5 | jade | 4 | Basic |
+----------------------------------------------+
Code
$user_id = 5; // jade
$parent_id = 4;
// call the function to insert the earnings
self::insertEarnings($user_id,$parent_id);
private function insertEarnings($user_id,$parent_id) {
if ($parent_id > 0) {
$user_parent = $parent_id;
$has_parent = true;
// start iteration
while($has_parent == true){
$account = User::where('id',$user_parent)->first();
$amount = 0;
if ($account->rank == "Junior" ) {
$amount = 100;
} elseif ($account->rank == "Premium") {
$amount = 150;
// for example this user/parent does not exist the amount(150) for him will be added to the next rank which is the Advance
} elseif ($account->rank == "Advanced") {
$amount = 200;
} elseif ($account->rank == "Senior") {
$amount = 250;
// set to false to stop the iteration
$has_parent = false;
}
$earnings = new Earnings;
$earnings->user_id = $account->id;
$earnings->amount = $amount;
$earnings->save();
$next_parent = User::where('id',$user_parent)->first();
$user_parent = $next_parent->parent_id;
if($user_parent == 0){
$has_parent = false;
}
}
}
}
The $user_id is not used in this example, but there's a use to that that didn't included in the question because that is not the main problem.
I have two tables in my MySQL database:
1 named "stock"
id | product | qty
----------------------
1 | 1 | 15
----------------------
2 | 1 | 20
And the second one named "orders"
id | product | qty | stock_id
----------------------------
1 | 1 | 7 | 1
-----------------------------
2 | 1 | 8 | 1
So, before register a new "order", I need to verify which "stock.id" has free product to sell, with SUM all existent orders.qty and subtract it to stock.qty, for this example I'm going to insert a new order of 10 pieces of product with id '1' ($new_order = '10' (pieces):
for each stock.id { SUM(orders.qty) as total | then verify if 'total' >= $new_order | if(total >= $new_order){select that stock.id} if don't { continue looking for an stock.id with free product for sale } }
Hoping to make myself known, I need your help to structure MySql query from PHP for that function.
UPDATE
I've solved with this double query:
<?
$queryL = "SELECT id,unidades,producto FROM stock WHERE `producto` = '$producto'";
$resultL = $mysqli->query($queryL);
/* array asociativo */
while($rowL = mysqli_fetch_array($resultL, MYSQLI_ASSOC))
{
$id_lote = $rowL['id'];
$unidades = $rowL['unidades'];
$queryD = "SELECT SUM(cantidad) as total FROM `pedidos` WHERE `lote` = $id_lote";
$resultD = $mysqli->query($queryD);
/* array asociativo */
if($rowD = mysqli_fetch_array($resultD, MYSQLI_ASSOC)){
$ventas = $rowD['total'];
$disponible = $unidades - $ventas;
if($disponible >= $cantidad){ $lote = $id_lote; }
}
}
?>
Can someone help me simplifying this?
I need If Statement (php) to :
if (Modem = ModemNotReceived) and (CheckModem = Done)
Total + 50
And
if (Modem = ModemReceived) and (CheckModem = Done)
Total - 50
How i can do that in one if statement?
My Table :
| ID | Modem | CheckModem | Total
------------------------------------------------
| 1 | ModemReceived | Done | 120
------------------------------------------------
| 2 | ModemNotReceived | Null | 90
------------------------------------------------
| 3 | ModemReceived | Null | 100
If I understand what you're saying correctly, this code is what you mean:
<?php
if ($Modem == 'ModemNotReceived' && $CheckModem == 'Done') {
$Total += 50;
} else if ($Modem == 'ModemReceived') && $CheckModem == 'Done' {
$Total -= 50;
}
?>
I'm in the process of finding an efficient way to track returning users.
List of options I went over so far:
save (update) login count per user, per day/week/month
save (update) which users have logged in, in a Text field (bad choice?), per day/week/month
deduce returning users via other database resources (user-added records from several tables)
I think this last option is most efficient, since I won't need to create a separate logging table.
However, a logging table seems more accurate, period-wise, right?
Update:
Accuracy still has the priority for this, so I went with the first option, together with some logic in PHP.
I've opted to store the login counts per week (of the year), like: 201433.
Question: regarding the PHP code, is there a way to combine the two queries, and leave out the nested loop (efficiency)?
Database Table:
+----+--------+--------+-----------+
| id | userId | logins | year_week |
+----+--------+--------+-----------+
| 1 | 1 | 4 | 201432 |
| 2 | 1 | 3 | 201433 |
| 3 | 2 | 2 | 201433 |
+----+--------+--------+-----------+
Queries:
SELECT
userId,
SUM(logins) as total
FROM
User_Logins
GROUP BY
userId
ORDER BY
userId
-----------
// get first year_week
SELECT
userId,
year_week
FROM
User_Logins
GROUP BY
userId
ORDER BY
userId
Query results:
+--------+-------+
| userId | total |
+--------+-------+
| 1 | 7 |
| 2 | 2 |
+--------+-------+
+--------+-----------+
| userId | year_week |
+--------+-----------+
| 1 | 201432 |
| 2 | 201433 |
+--------+-----------+
PHP code:
$returningUsers = 0;
$userLogins = $this->model->firstQuery();
$userLoginWeeks = $this->model->secondQuery();
$today = new DateTime();
function weeksPassed($today, $year, $week)
{
$today->setISODate($today->format('Y'), $today->format('W'));
// year and week from user first login
$yearWeek = new DateTime();
$yearWeek->setISODate($year, $week);
$daysPassed = $today->diff($yearWeek)->days;
$weeksPassed = $daysPassed / 7;
return $weeksPassed;
}
if ($userLogins && $userLoginWeeks)
{
foreach ($userLoginWeeks as $userLoginWeek)
{
$userId = $userLoginWeek->userId;
$year_week = $userLoginWeek->year_week;
$year = (int) substr($year_week, 0, 4);
$week = (int) substr($year_week, 4);
$weeksPassed = weeksPassed($today, $year, $week);
$totalLogins = 0;
// Look up user logins from other query
foreach ($userLogins as $logins)
{
if ($logins->userId == $userId)
{
$totalLogins = $logins->total;
break;
}
}
$avgLogins = $totalLogins;
// Average calculated over weeks that have passed since first login
if ($weeksPassed > 0)
{
$avgLogins = $totalLogins / $weeksPassed;
}
// if average >= 1 per week => returning user
if ($avgLogins >= 1)
{
$returningUsers++;
}
}
}
return $returningUsers;
I am in a bit of a pinch. I am using WHMCS and building a custom report but am running into trouble with one of my queries. Here is an overview:
I have 2 tables; tblinvoices which has the subtotal, tax, total, etc. of the invoice and tblinvoiceitems which has the individual line items that appear on the invoice. I am wanting to run a query that returns all of the individual line items and their price which I have been able to do. I run into problems when I do 'GROUP BY' and group the results by invoice numder, then it only returns the first line item for each invoice. I want to group them by invoice number so it only has 1 line in the report. Here is my query:
$query = "SELECT date_format(tblinvoices.datepaid,'%m-%d-%Y') AS datepaid,
tblinvoices.userid,
tblinvoices.id,
tblinvoices.subtotal,
tblinvoices.credit,
tblinvoices.tax,
tblinvoices.tax2,
tblinvoices.total,
tblinvoices.taxrate,
tblinvoices.taxrate2,
tblinvoiceitems.description,
tblinvoiceitems.amount,
tblinvoices.status,
FROM tblinvoices
INNER JOIN tblinvoiceitems ON tblinvoices.id = tblinvoiceitems.invoiceid
GROUP BY tblinvoices.id";
$result = mysql_query($query);
# Math Operations
$statement = array();
$count = 0;
if ($result !== false) {
while ($data = mysql_fetch_object($result)) {
$invoiceid = $data->id;
$datepaid = $data->datepaid;
$description = $data->description;
$item_amount = $data->item_amount;
$subtotal = $data->subtotal;
$credit = $data->credit;
$tax = $data->tax;
$tax2 = $data->tax2;
$total = $data->total;
if ($export != true) {
$client_link = '<a href=clientssummary.php?userid='.$data->userid.'>'.$data->userid;
$invoice_link = '<a href=invoices.php?action=edit&id='.$data->id.'>'.$data->id;
}
else {
$client_link = $data->userid;
$invoice_link = $data->id;
}
if (strpos($description, 'Setup') !== false) {
$setup = $item_amount;
}
else {
$setup = 0;
}
if (strpos($description, 'Addon') !== false) {
$addon = $item_amount;
}
else {
$addon = 0;
}
if (strpos($description, 'Tax Guide: No => Yes') !== false) {
$taxguide = $item_amount;
}
else {
$taxguide = 0;
}
if (strpos($description, 'Reading Rack Bundle') !== false) {
$reading = $item_amount;
}
else {
$reading = 0;
}
if (strpos($description, 'Toolkit Bundle') !== false) {
$toolkit = $item_amount;
}
else {
$toolkit = 0;
}
$hosting = $subtotal - $setup - $addon - $taxguide - $reading - $toolkit;
$statement[$invoiceid."_".$count] = array($datepaid,$client_link,$promo,$dtn,$company,$state,$invoice_link,$setup,$addon,$taxguide,$reading,$toolkit,$hosting,$subtotal,$credit,$tax+$tax2,$total);
$count++;
}
}
foreach ($headings AS $k=>$v) {
$reportdata["tableheadings"][] = $v;
}
//ksort($statement);
foreach ($statement AS $invoiceid=>$entry) {
$reportdata["tablevalues"][] = array(
$entry[0], // datepaid
$entry[1], // clientid
$entry[2], // promocode
$entry[3], // dtn
$entry[4], // companyname
$entry[5], // state
$entry[6], // invoiceid
formatCurrency($entry[7]), // setup
formatCurrency($entry[8]), // addon
formatCurrency($entry[9]), // taxguide
formatCurrency($entry[10]), // reading
formatCurrency($entry[11]), // toolkit
formatCurrency($entry[12]), // hosting
formatCurrency($entry[13]), // subtotal
formatCurrency($entry[14]), // credit
formatCurrency($entry[15]), // tax
formatCurrency($entry[16]) // total
);
}
mysql_free_result($result);
I will be happy to provide any additional information/code if it helps. I though this might be a more general type question...thanks!
With the result you are describing your result set would look like:
userid | id | subtotal | credit | tax | status | desc | amount
______________________________________________________________
1 | 1 | 20 | 0 | .7 | 1 | item1| 10
1 | 1 | 20 | 0 | .7 | 1 | item2| 10
1 | 2 | 30 | 0 | 2.1 | 1 | item3| 15
1 | 2 | 30 | 0 | 2.1 | 1 | item3| 15
1 | 3 | 10 | 0 | .7 | 0 | item1| 10
1 | 4 | 1 | 0 | .07 | 0 | item4| 1
Is this what you are looking for?
So try group by invoice.id and invoice.userid, and then maybe invoice.subtotal....
May run into some issues if you later decide to aggregate anything but this should do it.