How to do raw query in Bookshelf.js - bookshelf.js

I want to achieve this
SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
from https://developers.google.com/maps/articles/phpsqlsearch_v3?hl=fr#createtable
How can I make this query with Bookshelf.
I have this now:
var raw = '( 3959 * acos( cos( radians(37) ) * cos( radians( '+ req.params.lat + ' ) ) * cos( radians( '+req.params.lng+' ) - radians(-122) ) + sin( radians(37) ) * sin( radians( '+req.body.lng+' ) ) ) ) AS distance';
new Places().query(function(qb) {
qb.where('lat',req.params.lat);
qb.where('lng',req.params.lng);
qb.column(raw);
qb.having('distance', '>', 25);
}).fetch({ debug: false }).then(function(collection) {
console.log(collection);
if (collection === undefined) {
// no such result
res.json(404,{error: "No Places found."});
} else {
// found, list json
res.json(200, collection);
}
});

I found this to work .. no qb. instance/reference required:
var Bookshelf = require('bookshelf').mysqlAuth;
var rawSql = 'SELECT .. <etc>';
Bookshelf.knex.raw(rawSql).then(..);

Its.
qb.column(qb.knex.raw(raw));

i Tried something like this which worked fine
return **Location**.query(qb => {
return ***query***
})
.fetchAll()
.then(data => data.toJSON());
With:
Location is a Model (I am doing it inside strapi services)
query can be any raw query.

Related

updating product subtotal in cart contents

I've trying to write my campaign plugin.
Here is the problem,
I want to update, line_subtotal and line_total in a product in $cart_items.
1- woocommerce_cart_product_subtotal is not really working.
2- I tried to redefine array's element by cart_item_key
foreach($cartItems as $hash => $perProduct)
{
if($perProduct['product_id'] = $lastItemsProductId)
{
if($lastItemsQuantity > 1)
{
$lineSubtotal = data_get($lastItemInCart, 'line_subtotal');
$lineTotal = data_get($lastItemInCart, 'line_total');
$newQuantity = $lastItemsQuantity-1;
$lastItemInCart['line_subtotal'] = $newQuantity * $lastItemsPrice;
$lastItemInCart['line_total'] = $newQuantity * $lastItemsPrice;
$cartItems[$lastItemsKey] = $lastItemInCart;
WC()->cart->calculate_totals();
} else {
}
}
}
Also this function runs, in woocommerce_before_calculate_totals action.
When i try it, with woocommerce_get_cart_contents filter, my cart empty itself .
3- The scenario :
When i add A product, (if is selected by system) and if quantity is more than 2, i want to make discount about this product.
Any helps ? Thanks.
Here is the answer
/**
* Add filter for order list
*
* #param [int] $product_subtotal
* #param [object] $product
* #param [int] $quantity
* #param [array] $cart
* #return void
*/
public function filterWoocommerceCartProductSubtotal($product_subtotal, $product, $quantity, $cart) : string
{
$appliedCoupons = $cart ? $cart->get_applied_coupons() : null;
$cartCount = $cart ? count($cart->get_cart()) : 0;
$cartItems = $cart->get_cart();
$lastItemInCart = last($cartItems);
$lastItemsProductId = data_get($lastItemInCart, 'product_id', data_get($lastItemInCart, 'product_id'));
$lastItemsPrice = $lastItemInCart['data']->get_regular_price();
$lastItemsQuantity = data_get($lastItemInCart, 'quantity');
$lastItemsKey = data_get($lastItemInCart, 'key');
if( in_array('3al2ode', $appliedCoupons)){
if($lastItemsQuantity > 1) {
if(#data_get($product,'id') == $lastItemsProductId)
{
$newSubTotal = 0;
$price = $product->get_price();
$newQuantity = $lastItemsQuantity-1;
$quantity = $newQuantity;
$newSubTotal += $price * $quantity;
return $newSubTotal ? wc_price($newSubTotal) : $product_subtotal;
}
}
}
return $product_subtotal;
}
The right, filter should be like;
add_filter( 'woocommerce_cart_product_subtotal', [$this,'filterWoocommerceCartProductSubtotal'], 10, 4);
As per your current scenario - When I add A product, (it is selected by the system) and if the quantity is more than 2, I want to make a discount on this product.
You should try this-
add_action( 'woocommerce_cart_calculate_fees','woocommerce_add_discount',10, 1 );
function woocommerce_add_discount() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$cart_qty = count($woocommerce->cart->get_cart());
if($cart_qty > 2)
{
$percentage = 0.5;
$cart_subtotal = $woocommerce->cart->get_subtotal() ?: 0;
//$cart_total = $woocommerce->cart->cart_contents_total;
//$shipping_total = $woocommerce->cart->get_shipping_total() ?: 0;
//$tax_total = $woocommerce->cart->get_taxes_total() ?: 0;
//$grand_total = $cart_total + $shipping_total + $tax_total;
// Calculate the amount to reduce
$discount = $cart_subtotal * $percentage;
$woocommerce->cart->add_fee( 'Discount 50%', -$discount, true, '' );
}
}
You can update/modify condition accordingly.
/**
* Add filter for order list
*
* #param [int] $product_subtotal
* #param [object] $product
* #param [int] $quantity
* #param [array] $cart
* #return void
*/
public function filterWoocommerceCartProductSubtotal($product_subtotal, $product, $quantity, $cart) : string
{
$appliedCoupons = $cart ? $cart->get_applied_coupons() : null;
$cartCount = $cart ? count($cart->get_cart()) : 0;
$cartItems = $cart->get_cart();
$lastItemInCart = last($cartItems);
$lastItemsProductId = data_get($lastItemInCart, 'product_id', data_get($lastItemInCart, 'product_id'));
$lastItemsPrice = $lastItemInCart['data']->get_regular_price();
$lastItemsQuantity = data_get($lastItemInCart, 'quantity');
$lastItemsKey = data_get($lastItemInCart, 'key');
if( in_array('3al2ode', $appliedCoupons)){
if($lastItemsQuantity > 1) {
if(#data_get($product,'id') == $lastItemsProductId)
{
$newSubTotal = 0;
$price = $product->get_price();
$newQuantity = $lastItemsQuantity-1;
$quantity = $newQuantity;
$newSubTotal += $price * $quantity;
return $newSubTotal ? wc_price($newSubTotal) : $product_subtotal;
}
}
}
return $product_subtotal;
}
The right, filter should be like;
add_filter( 'woocommerce_cart_product_subtotal', [$this,'filterWoocommerceCartProductSubtotal'], 10, 4);

How to create an equation from the result of a function with symbolic arguments

The result of calculation PQ1(p=1,q,A)-PQ1(p=0,q,A) is "2 - 8*q"
I need to transform the result into an equation 2 - 8*q = 0 to find q
But my code produces the error below
Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl, :
SyntaxError: ("no viable alternative at input '0'", ('', 1, 168, '__Rsympy= Eq( ( ( ( ( ( 1 * q ) + ( 5 * ( 1 - q ) ) ) + ( 0 * q ) ) + ( 0 * ( 1 - q ) ) ) - ( ( ( ( 0 * q ) + ( 0 * ( 1 - q ) ) ) + ( 7 * q ) ) + ( 3 * ( 1 - q ) ) ) ) 0)\n'))
A=matrix(c(1,7,5,3), nrow=2)
library(rSymPy) #symbolic calculations
p<-Var('p')
q<-Var('q')
PQ1 <- function (p,q,matr){
result<-(matr[1,1]*p*q+matr[1,2]*p*(1-q)+matr[2,1]*(1-p)*q+matr[2,2]*(1-p)*(1-q))
return(result)
}
PQ1(p=1,q,A)-PQ1(p=0,q,A)
str<-PQ1(p=1,q,A)-PQ1(p=0,q,A)
print(str)
sympy("Eq(",str,"0)") # create an equation

Warning: A non-numeric value encountered in wordpress plugin error

Warning: A non-numeric value encountered in /customers/1/2/3/websiteurl/httpd.www/wp-content/plugins/videonab/lib/plugin-classes/video.php on line 123,124,125
Code is (Line no 123,124,125)
public static function seconds_to_time( $seconds ){
$hours = floor($seconds / 3600); /* line no 123 */
$mins = floor(($seconds - ($hours*3600)) / 60);/* line no 124 */
$secs = floor($seconds % 60);/* line no 125 */
return array(
'hours' => $hours,
'minutes' => $mins,
'seconds' => $secs,
);
}
Please try to check for is_numeric or is_integer, and convert it to (int) before manipulating for any type of calculation.
public static function seconds_to_time( $seconds ) {
if( is_numeric( $seconds ) ) {
$hours = floor( (int)$seconds / 3600);
$mins = floor(( (int)$seconds - ($hours*3600)) / 60);
$secs = floor( (int)$seconds % 60);
return array(
'hours' => $hours,
'minutes' => $mins,
'seconds' => $secs,
);
} else {
return array();
}
}
Hope this one helps :)

Symfony Date to Hijri date conversion in twig file

In symfony template we can use the formatters like
{{ news.created|date('Y-m-d') }}
I need something similar for the hijri date conversion. Meaning I provide the date in gregorian and it convert it to hijri in the twig template file may be something like
{{ news.created|hijridate }}
I searched a lot on forums etc but did not find something relevant specifically in twig template.
After not finding any solution I make my own twig extension. I am pasting it hopefully it will help any one the input is the date object like
{{ newsitem.created|hdate }} and ouput is
الأربعاء 10 رمضان 1437 هـ
Write a twig extension in src/AppBundle/Twig/HdateExtension.php with the following code.
<?php
namespace AppBundle\Twig;
class HdateExtension extends \Twig_Extension
{
public function getFilters()
{
return array(
new \Twig_SimpleFilter('hdate', array($this, 'hdateConvert') )
);
}
public function hdateConvert($date)
{
if($date instanceof \DateTime){
$dateDay = $date->format('N');
$date->modify('+1 day');
$year = $date->format('Y');
$month = $date->format('m');
$day = $date->format('d');
}
$dayH = array("الأثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت","الأحد");
// actual calculation
$newDate = $dayH[$dateDay-1]." ".HdateExtension::Greg2Hijri($day, $month, $year, true );
return $newDate;
}
public function getName()
{
return 'hdate_extension';
}
public function Greg2Hijri($day, $month, $year, $string = false)
{
$day = (int) $day;
$month = (int) $month;
$year = (int) $year;
if (($year > 1582) or (($year == 1582) and ($month > 10)) or (($year == 1582) and ($month == 10) and ($day > 14)))
{
$jd = HdateExtension::intPart((1461*($year+4800+HdateExtension::intPart(($month-14)/12)))/4)+HdateExtension::intPart((367*($month-2-12*(HdateExtension::intPart(($month-14)/12))))/12)-
HdateExtension::intPart( (3* (HdateExtension::intPart( ($year+4900+ HdateExtension::intPart( ($month-14)/12) )/100) ) ) /4)+$day-32075;
}
else
{
$jd = 367*$year-HdateExtension::intPart((7*($year+5001+HdateExtension::intPart(($month-9)/7)))/4)+HdateExtension::intPart((275*$month)/9)+$day+1729777;
}
$l = $jd-1948440+10632;
$n = HdateExtension::intPart(($l-1)/10631);
$l = $l-10631*$n+354;
$j = (HdateExtension::intPart((10985-$l)/5316))*(HdateExtension::intPart((50*$l)/17719))+(HdateExtension::intPart($l/5670))*(HdateExtension::intPart((43*$l)/15238));
$l = $l-(HdateExtension::intPart((30-$j)/15))*(HdateExtension::intPart((17719*$j)/50))-(HdateExtension::intPart($j/16))*(HdateExtension::intPart((15238*$j)/43))+29;
$month = HdateExtension::intPart((24*$l)/709);
$day = $l-HdateExtension::intPart((709*$month)/24);
$year = 30*$n+$j-30;
$mname = array("محرّم","صفر","ربيع الأوّل"," ربيع الثاني","جمادى الأولى","جمادى الثانية","رجب","شعبان","رمضان","شوّال","ذو القعدة","ذو الحجّة");
$date = array();
$date['year'] = $year;
$date['month'] = $mname[$month-1];
$month = $mname[$month-1];
$date['day'] = $day;
if (!$string)
return $date;
else
return "{$day} {$month} {$year} هـ ";
}
public function intPart($float)
{
if ($float < -0.0000001)
return ceil($float - 0.0000001);
else
return floor($float + 0.0000001);
}
}
Then add the following in the services.yml file
app.twig_extension:
class: AppBundle\Twig\HdateExtension
public: false
tags:
- { name: twig.extension }
thanks for your code,
symfony 5:
<?php
namespace App\Twig;
use Exception;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class HdateExtension extends AbstractExtension {
/**
* #return TwigFilter[]
*/
public function getFilters(): array {
return [
new TwigFilter(
'hdate', [
$this, 'hdateConvert'
])
];
}
/**
* #param $arg
* #return string
* #throws Exception
*/
public function hdateConvert($arg): string {
if ($arg instanceof \DateTime) {
$dayNumber = $arg->format('N');
$arg->modify('+1 day');
$year = $arg->format('Y');
$month = $arg->format('n');
$day = $arg->format('j');
$dayH = [
"الأثنين",
"الثلاثاء",
"الأربعاء",
"الخميس",
"الجمعة",
"السبت",
"الأحد"
];
return $dayH[$dayNumber - 1] . " " . HdateExtension::Greg2Hijri($day, $month, $year);
}
throw new Exception('Invalid date');
}
/**
* #return string
*/
public function getName(): string {
return 'hdate_extension';
}
/**
* #param int $day
* #param int $month
* #param int $year
* #return string
*/
public function Greg2Hijri(int $day, int $month, int $year): string {
if (
($year > 1582) or
(($year == 1582) and ($month > 10)) or
(($year == 1582) and ($month == 10) and ($day > 14))
) {
$jd = HdateExtension::intPart((1461 * ($year + 4800 + HdateExtension::intPart(($month - 14) / 12))) / 4) + HdateExtension::intPart((367 * ($month - 2 - 12 * (HdateExtension::intPart(($month - 14) / 12)))) / 12) -
HdateExtension::intPart((3 * (HdateExtension::intPart(($year + 4900 + HdateExtension::intPart(($month - 14) / 12)) / 100))) / 4) + $day - 32075;
} else {
$jd = 367 * $year - HdateExtension::intPart((7 * ($year + 5001 + HdateExtension::intPart(($month - 9) / 7))) / 4) + HdateExtension::intPart((275 * $month) / 9) + $day + 1729777;
}
$l = $jd - 1948440 + 10632;
$n = HdateExtension::intPart(($l - 1) / 10631);
$l = $l - 10631 * $n + 354;
$j = (HdateExtension::intPart((10985 - $l) / 5316)) * (HdateExtension::intPart((50 * $l) / 17719)) + (HdateExtension::intPart($l / 5670)) * (HdateExtension::intPart((43 * $l) / 15238));
$l = $l - (HdateExtension::intPart((30 - $j) / 15)) * (HdateExtension::intPart((17719 * $j) / 50)) - (HdateExtension::intPart($j / 16)) * (HdateExtension::intPart((15238 * $j) / 43)) + 29;
$month = HdateExtension::intPart((24 * $l) / 709);
$day = $l - HdateExtension::intPart((709 * $month) / 24);
$year = 30 * $n + $j - 30;
$mname = [
"محرّم",
"صفر",
"ربيع الأوّل",
" ربيع الثاني",
"جمادى الأولى",
"جمادى الثانية",
"رجب",
"شعبان",
"رمضان",
"شوّال",
"ذو القعدة",
"ذو الحجّة"
];
return "{$day} {$mname[$month - 1]} {$year} هـ ";
}
/**
* #param $float
* #return false|float
*/
private function intPart($float) {
if ($float < -0.0000001)
return ceil($float - 0.0000001);
else
return floor($float + 0.0000001);
}
}

Calculate percentage saved between two numbers?

I have two numbers, the first, is the original price, the second, is the discounted price.
I need to work out what percentage a user saves if they purchase at the second price.
example
25, 10 = 60%
365, 165 = 55%
What I dont know is the formula to calculate this.
I know this is fairly old but I figured this was as good as any to put this. I found a post from yahoo with a good explanation:
Let's say you have two numbers, 40 and 30.
30/40*100 = 75.
So 30 is 75% of 40.
40/30*100 = 133.
So 40 is 133% of 30.
The percentage increase from 30 to 40 is:
(40-30)/30 * 100 = 33%
The percentage decrease from 40 to 30 is:
(40-30)/40 * 100 = 25%.
These calculations hold true whatever your two numbers.
Original Post
((list price - actual price) / (list price)) * 100%
For example:
((25 - 10) / 25) * 100% = 60%
I see that this is a very old question, but this is how I calculate the percentage difference between 2 numbers:
(1 - (oldNumber / newNumber)) * 100
So, the percentage difference from 30 to 40 is:
(1 - (30/40)) * 100 = +25% (meaning, increase by 25%)
The percentage difference from 40 to 30 is:
(1 - (40/30)) * 100 = -33.33% (meaning, decrease by 33%)
In php, I use a function like this:
function calculatePercentage($oldFigure, $newFigure) {
if (($oldFigure != 0) && ($newFigure != 0)) {
$percentChange = (1 - $oldFigure / $newFigure) * 100;
}
else {
$percentChange = null;
}
return $percentChange;
}
The formula would be (original - discounted)/original. i.e. (365-165)/365 = 0.5479...
function calculatePercentage($oldFigure, $newFigure)
{
$percentChange = (($oldFigure - $newFigure) / $oldFigure) * 100;
return round(abs($percentChange));
}
100% - discounted price / full price
If total no is: 200
and getting 50 number
then take percentage of 50 in 200 is:
(50/200)*100 = 25%
I have done the same percentage calculator for one of my app where we need to show the percentage saved if you choose a "Yearly Plan" over the "Monthly Plan". It helps you to save a specific amount of money in the given period. I have used it for the subscriptions.
Monthly paid for a year - 2028
Yearly paid one time - 1699
1699 is a 16.22% decrease of 2028.
Formula: Percentage of decrease = |2028 - 1699|/2028 = 329/2028 = 0.1622
= 16.22%
Code:
func calculatePercentage(monthly: Double, yearly: Double) -> Double {
let totalMonthlyInYear = monthly * 12
let result = ((totalMonthlyInYear-yearly)/totalMonthlyInYear)*100
print("percentage is -",result)
return result.rounded(toPlaces: 0)
}
Usage:
let savingsPercentage = self.calculatePercentage(monthly: Double( monthlyProduct.price), yearly: Double(annualProduct.price))
self.btnPlanDiscount.setTitle("Save \(Int(savingsPercentage))%",for: .normal)
The extension usage for rounding up the percentage over the Double:
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
I have attached the image for understanding the same:
This is function with inverted option
It will return:
'change' - string that you can use for css class in your template
'result' - plain result
'formatted' - formatted result
function getPercentageChange( $oldNumber , $newNumber , $format = true , $invert = false ){
$value = $newNumber - $oldNumber;
$change = '';
$sign = '';
$result = 0.00;
if ( $invert ) {
if ( $value > 0 ) {
// going UP
$change = 'up';
$sign = '+';
if ( $oldNumber > 0 ) {
$result = ($newNumber / $oldNumber) * 100;
} else {
$result = 100.00;
}
}elseif ( $value < 0 ) {
// going DOWN
$change = 'down';
//$value = abs($value);
$result = ($oldNumber / $newNumber) * 100;
$result = abs($result);
$sign = '-';
}else {
// no changes
}
}else{
if ( $newNumber > $oldNumber ) {
// increase
$change = 'up';
if ( $oldNumber > 0 ) {
$result = ( ( $newNumber / $oldNumber ) - 1 )* 100;
}else{
$result = 100.00;
}
$sign = '+';
}elseif ( $oldNumber > $newNumber ) {
// decrease
$change = 'down';
if ( $oldNumber > 0 ) {
$result = ( ( $newNumber / $oldNumber ) - 1 )* 100;
} else {
$result = 100.00;
}
$sign = '-';
}else{
// no change
}
$result = abs($result);
}
$result_formatted = number_format($result, 2);
if ( $invert ) {
if ( $change == 'up' ) {
$change = 'down';
}elseif ( $change == 'down' ) {
$change = 'up';
}else{
//
}
if ( $sign == '+' ) {
$sign = '-';
}elseif ( $sign == '-' ) {
$sign = '+';
}else{
//
}
}
if ( $format ) {
$formatted = '<span class="going '.$change.'">'.$sign.''.$result_formatted.' %</span>';
} else{
$formatted = $result_formatted;
}
return array( 'change' => $change , 'result' => $result , 'formatted' => $formatted );
}
I think this covers this formula sufficiently,
((curr value - base value) / (curr value)) * 100%
Basically we just (in programming):
perform the calculation if both numbers are not 0.
If curr value is 0 then we return -100 % difference from the base,
if both are 0 then return 0 (we can't divide by 0)
Powershell example:
Strip any non numeric from vars and perform calculation
Function Get-PercentageSaved {
#((curr value - base value) / (curr value)) * 100%
param(
[Parameter(Mandatory = $false)][string]$CurrVal = $null,
[Parameter(Mandatory = $false)][string]$BaseVal = $null
)
$Result = $null
Try {
$CurrVal = [float]($CurrVal -replace '[^0-9.]', '')
$BaseVal = [float]($BaseVal -replace '[^0-9.]', '')
if (-Not($null -eq $CurrVal) -And (-Not($null -eq $BaseVal))) {
if ($CurrVal -eq 0) {
If ($BaseVal -eq 0) {
$Result = 0
} Else {
$Result = -100
}
}
else {
$Result = [math]::Round([float]((($CurrVal - $BaseVal) / $CurrVal) * 100),2)
}
}
}
Catch {}
Return [float]$Result
}

Resources