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.
Related
In my app, the user can enter a number for pricing and based on the input, the database will return a plan with the same price. If there is no number/price corresponding to the user input, I would like the program to find the plan with the nearest value. How can I find the "nearest" value in a haystack?
Examples :
User inputs : $14, Returns the 15$ plan
User inputs : $20, Returns the 15$ plan
User inputs : 25$. Returns the 30$ plan
Etc...
This is what I have :
//Create pricing for each plan
$getplansql = "SELECT SUM(`Distributor Net Price`) AS dnetprice FROM `services` wspn
WHERE wspn.planName = '$planname_num[$pn]' AND wspn.planLevel = '$planlevels_num[$pl]'";
$resultplans = $conn->query($getplansql);
while($plan = mysqli_fetch_assoc($resultplans)) {// output data of each row
$inhousepricing = ($plan['dnetprice'] * 0.15) + ($plan['dnetprice']);
$finalpricing = round($inhousepricing);
if($planprice == $finalpricing) {//found matching row// there's a plan with that price
//put plan info in array
$planArray = array(
'planName' => $plan['name'],
'planPrice' => $finalpricing,
'planDescription' => $plan['description']
);
break;//stop statement and only get the first plan//row found
}else{//get the plan with the nearest value
//put plan info in array
}
Add 15% and find the closest price in the SQL query itself.
$getplansql = "name, description, dnetprice
FROM (
SELECT planName AS name, planDescription AS description, ROUND(SUM(`Distributor Net Price`) * 1.15) AS dnetprice
FROM `services` wspn
WHERE wspn.planName = '$planname_num[$pn]' AND wspn.planLevel = '$planlevels_num[$pl]'
) AS x
ORDER BY ABS(dnetprice - $planprice)
LIMIT 1";
$resultplans = $conn->query($getplansql);
$planArray = mysqli_fetch_assoc($resultplans);
This will just return the one row that you want, so you don't need a while loop.
Below I have stripped down my code to a simplified version. I am storing SQL SELECT results for:
last name (dlname)
category (category)
date this data was added to database (date_added)
clients name (client)
I have appended an additional field outside the SQL SELECT called 'days_on_list'. This field shows the number of days since the data was added to the database, making the table output 5 columns of user data. ALL 5 COLUMNS ARE TO BE SORTABLE.
I am using server-side JSON and have successfully been able to display this to the table and perform sorting on 4 of the 5 columns. The problem is that I am unable to sort the 'days_on_list' field as the PHP file containing the SQL code only allows me to sort the 4 fields from the select query. Is there a way I can make 'days_on_list' column be sortable in the table? I know I can add this field to the sql table, but I would have to run a scheduled event on the server to update this daily (which I am not comfortable with).
Is there another way to allow for this kind of flexible table sorting?
Sorry about the question title (may be confusing), I was having trouble putting this into a question.
/*SQL CODE ABOVE HERE STORES SELECT RETURNS IN $result*/
$cart = array();
$i = 0; //index the entries
// get variables from sql result.
if ($num_rows > 0) { //if table is populated...
while ($row = mysqli_fetch_assoc($result)) {
//calculate days on list by getting the number of days from
//the 'date_added' to today
$date1 = date_create($row['date_added']);
$today = date_create(date("d-m-Y"));
$interval = date_diff($date1, $today);
$doty = $interval - > format("%a");
$cart[$i] = array(
"dlname" => htmlspecialchars($row['dlname']),
"category" => htmlspecialchars($row['category']),
"date_added" => htmlspecialchars($row['date_added']),
"client" => htmlspecialchars($row['client']),
"days_on_list" => $doty, //date_added to now
);
$i = $i + 1; //add next row
}
//encoding the PHP array
$json_server_pagination_data = array(
"total" => intval($num_rows),
"rows" => $cart, //array data
);
}
echo json_encode($json_server_pagination_data);
Because days_on_list is calculated by simply comparing date_added to the current date, sorting by days_on_list should have exactly the reverse effect as sorting by date_added.
In other words, you don't actually need to sort by days_on_list. If the user selects days_on_list as the sort column, just use ORDER BY date_added (in the opposite direction ASC/DESC).
NOTE:
I'm new to php and mysql.
Background info:
I have +/- 30,000 products and they are from 7 different supplier and they have a lot of the same products
let's say i have 1 product and three of the suppliers have the it, i need to publish the product with the lowest price and the other two product stay unpublished
that is the basic idea and this must run through the 30,000 products and check and see if there are any matches and run the publishing function
SQL setup:
There are two tables xxxx_virtuemart_product and xxxx_virtuemart_product_prices
There are three rows in xxxx_virtuemart_product ▬▬▬ product_id,product_sku,published ▬▬▬
There are two rows in xxxx_virtuemart_product_prices ▬▬▬ product_id,product_price ▬▬▬
My little bit of code:
I have this little code because i'm stuck, how can i make a check to see if there are any matches and then run a query to change the published value of the product with the lowest price?
i know there is a way to use the query to check for matches, but do not understand how to do is
$query = "SELECT `product_sku` FROM `xxxx_virtuemart_product`";
$query_run = mysql_query($query) or die (mysql_error());
while($row = mysql_fetch_assoc($query_run)){
foreach ($row as $key => $ps){
}
}
The below code is to check the price (not query optimize just a rough draft)
$z = //products price;
$x = //products price;
$c = //products price;
if ($z >= $x && $c >= $x) {
//the this products published value to 1
}else if ($x >= $z && $c >= $z) {
//the this products published value to 1
}else if ($z >= $c && $x >= $c) {
//the this products published value to 1
}
Can anyone please help me with this?
Thanks for reading
any questions are welcome.
Your problem is not about to compare arrays but more algorithm.
I will try this way.
1)SQL query to retrieve all the products : sql_products
2)construct a hashmap those key is product SKU (see : PHP Array)
To construct PHP hashmap : use arrays of arrays.
Example :
product_map[] = array();
foreach sql_product of sql_products :
- product_map[sql_product[SKU]][] = array(sql_product[supplier], sql_product[price], sql_product[information])
end of loop
Then loop again over the map of products constructed and sort each product record by price : that means you have to write a function to sort array (supplier, price, information).
Now you have a map of product : SKU => array(of array (supplier, price, information))
I am creating an intranet for a vehicle hire company
I set the default price as such:
$dayRate = '90.00';
I have created a field on my table to store a discount day rate if needed, called disc_day_rate which defaults to 0.
I pull the discount price as such
$discDayRate = $hire['disc_day_rate'];
I wish to find the lowest of these two numbers, but I think the default disc_day_rate of 0 is causing issues
I have tried using min(); and if ($discDayrate == "0") methods but after finding many answers on stackoverflow without having to post my own It's time to ask for help with an elegant solution
This ensures the 0.00 will never cause you a problem.
if ($discDayRate == 0.00) { ## don't use quotes here; it should be saved as a DECIMAL or INT in the database
$the_rate = $dayRate; ## back to the default
}
else {
if ($discDayRate < $dayRate) {
$the_rate = $diskDayRate;
}
else {
$the_rate = $dayRate;
}
}
$the_rate has your desired rate.
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.