How to apply subtraction in the query in laravel? - laravel

I have one array which contains all the records. I am passing all those records to a loop and there I am getting the sum of the clear column which has null upto.
This part is working fine, now my requirement is I want to add one more check which is based on the one more column refund.
If any column contains refund=1 that amount should be subtracted from the total, can you please help me to achieve the scenario
foreach ($row_data as $key => $value) {
$data_arr[$key]['total'] = ['Price'=> $value->whereIn('clear', null)->sum('amount')];
}
Data
data = [
{'amount' => 55, 'clear' => 'null', 'refund' => '0'},
{'amount' => 5, 'clear' => 'null', 'refund' => '1'},
{'amount' => 10, 'clear' => 'null', 'refund' => '0'},
];
Expected result is :-60
ACtual Result is :- 70

reduce should help.
$data = [
['amount' => 55, 'clear' => null, 'refund' => '0'],
['amount' => 5, 'clear' => null, 'refund' => '1'],
['amount' => 10, 'clear' => null, 'refund' => '0'],
];
You can be very explicit
// sum if refund is 0, substract if refund is 1
$sum = collect($data)
->where('clear', null)
->reduce(function ($carry, $item) {
if ($item['refund'] == '0') {
return $carry + $item['amount'];
} elseif ($item['refund'] == '1') {
return $carry - $item['amount'];
}
}, 0);
Or write it a bit shorter
// sum if refund is 0, substract otherwise
$sum = collect($data)
->where('clear', null)
->reduce(fn($carry, $item) => ($item['refund'] == '0')
? $carry + $item['amount']
: $carry - $item['amount']);
You can even do it without collections using php's array_reduce and array_filter functions. Works pretty much in the same way.
$sum = array_reduce(
array_filter($data, function ($item) {
return $item['clear'] == null;
}),
function($carry, $item) {
return $item['refund'] == '0'
? $carry + $item['amount']
: $carry - $item['amount'];
});
$sum = array_reduce(
array_filter($data, fn($item) => $item['clear'] == null)
fn($carry, $item) => $item['refund'] == '0'
? $carry + $item['amount']
: $carry - $item['amount']
);

I don't have all your code with variable declaration so I created logic snippet with your use case.
EDIT: You can simply get your total amount and substract you total refund as you can see in code below
/** #var Collection $data */
$data = collect([
['amount' => 55, 'clear' => null, 'refund' => false],
['amount' => 5, 'clear' => null, 'refund' => true],
['amount' => 10, 'clear' => null, 'refund' => false],
]);
$totalAmount = $data->whereNull('clear')->sum('amount');
$totalRefund = $data->whereNull('clear')
->where('refund', true)
->sum('amount'); // = 5
$subValue = $totalAmount - $totalRefund

Related

Laravel - How to update table multiple rows at once

I have this variable called $projectFieldOptions and it's output is like this:
https://prnt.sc/7HtxrfTy9HiI.
Now, In the Controller I need to update this. What I am doing this, first delete all the existing rows based on id_feed and id_project and then loop through this variable $projectFieldOptions and insert it. Like this:
if( $request->feed_type !== 'scrape' ) {
$delete_mapping = DB::connection($db_name)->table($db_name . '.feed_mappings')
->where('id_feed', '=', $id_feed)
->where('id_project', '=', $token)
->delete();
}
// now insert
$field_mapping = true;
if( $request->feed_type !== 'scrape' ) {
if( count($projectFieldOptions) ) {
foreach ($projectFieldOptions as $mapping) {
$data[] = [
'id_feed' => $id_feed,
'id_project' => $token,
'import_field_slug' => $mapping['value'],
'internal_field_slug' => $mapping['custom'] ? $mapping['custom_field'] : $mapping['text'],
'custom_field' => $mapping['custom'],
'updates' => $mapping['updates'],
'removes' => $mapping['removes'],
'import' => 1,
'date_add' => now(),
'date_upd' => now()
];
}
} else {
$data = [];
}
$field_mapping = DB::connection($db_name)->table($db_name . ".feed_mappings")->insert($data);
}
Now, I don't want to delete existing rows instead I want to update those rows based on the id_feed_mappings. Can you tell how can I do this?
Check if this would work, to update based on id_feed_mappings value, you can use the ->where('id_feed_mappings', '=' ,'a value or variable') before ->update($data)
if( $request->feed_type !== 'scrape' ) {
// try using update instead of insert
$field_mapping = true;
if( $request->feed_type !== 'scrape' ) {
if( count($projectFieldOptions) ) {
foreach ($projectFieldOptions as $mapping) {
$data[] = [
'id_feed' => $id_feed,
'id_project' => $token,
'import_field_slug' => $mapping['value'],
'internal_field_slug' => $mapping['custom'] ? $mapping['custom_field'] : $mapping['text'],
'custom_field' => $mapping['custom'],
'updates' => $mapping['updates'],
'removes' => $mapping['removes'],
'import' => 1,
'date_add' => now(),
'date_upd' => now()
];
}
} else {
$data = [];
}
$field_mapping = DB::connection($db_name)->table($db_name . ".feed_mappings")->update($data);
}

because it shows Undefined offset: 0, seeder laravel?

I have the following for in which I create the records
foreach ($v as $k => $f){
if($v[$k] != false && $f['zip_code'] !=''){
$state = State::whereCode($f['code'])->get();
var_dump($state[0]->id);
\App\Models\ZipCodes::create([
'uuid' => Uuid::generate(4)->string,
'zip_code' => $f['zip_code'],
'city' => $f['city'],
'county' => $f['county'],
'state_id' => $state[0]->id,
]);
}
}
I have noticed that the error appears in the field 'state_id' => $ state [0] -> id
since if I comment and delete it from the table it doesn't give me the error.
In fact if I just leave
foreach ($v as $k => $f){
if($v[$k] != false && $f['zip_code'] !=''){
$state = State::whereCode($f['code'])->get();
var_dump($state[0]->id);
}
}
The same generates the error.

How to pass zero if input text is blank?

I am getting a bit issue with my calculation, when I pass Discount and Debit values it is doing its job, but when Values of Discount and Debit is nothing it returns a blank page. Here is my Model.. CODEIGNITER.
function createInvoice() {
$this->load->helper('date');
$date = date('Y-m-d H:i:s');
$data = array(
'Date' => $date,
'Terms_Of_Payment' => $this->input->post('termsOfPayment'),
'Sub_Total' => $this->input->post('subTotal'),
'Total' => $this->input->post('total') - $this->input->post('discount'),
'Discount' => $this->input->post('discount'),
'Debit' => $this->input->post('debit'),
'Payment_Cridet' => $this->input->post('total') - $this->input->post('debit') - $this->input->post('discount'),
'Note' => $this->input->post('note'),
'Customer_ID' => $this->input->post('customerId'),
'User_ID' => $this->session->userdata('id'));
$this->db->insert('invoice', $data);
return ($this->db->affected_rows() != 1) ? false : true;
}
The best way is to use the ternary operator.
$subtotal = $this->input->post('subTotal') == "" ? 0 : $this->input->post('subTotal');
And if your php version is 7.0> then use
$subtotal = $this->input->post('subTotal') ?? 0;
Use ternary operator at data array when assinging the value of debit and discount.Code is looks like as below:
function createInvoice() {
$this->load->helper('date');
$date = date('Y-m-d H:i:s');
$data = array(
'Date' => $date,
'Terms_Of_Payment' => $this->input->post('termsOfPayment'),
'Sub_Total' => $this->input->post('subTotal'),
'Total' => $this->input->post('total') - isset($this->input->post('discount'))?$this->input->post('discount'):0,
'Discount' => isset($this->input->post('discount'))?$this->input->post('discount'):0',
'Debit' => isset($this->input->post('debit'))?$this->input->post('debit'):0,
'Payment_Cridet' => $this->input->post('total') - isset($this->input->post('debit'))?$this->input->post('debit'):0 - isset($this->input->post('discount'))?$this->input->post('discount'):0',
'Note' => $this->input->post('note'),
'Customer_ID' => $this->input->post('customerId'),
'User_ID' => $this->session->userdata('id'));
$this->db->insert('invoice', $data);
return ($this->db->affected_rows() != 1) ? false : true;
}
Ternary operator logic is the process of using (condition) ? (true return value) : (false return value) statements to shorten your if/else structures.
So, you can use ternary operator login for pass zero if input text is blank.
Now, some change in your createInvoice() function like me :
$subTotal = $this->input->post('subTotal') == "" ? 0 : $this->input->post('subTotal');
$total = $this->input->post('total') == "" ? 0 : $this->input->post('total');
$discount = $this->input->post('discount') == "" ? 0 : $this->input->post('discount');
$debit = $this->input->post('debit') == "" ? 0 : $this->input->post('debit');
$data = array(
'Date' => $date,
'Terms_Of_Payment' => $this->input->post('termsOfPayment'),
'Sub_Total' => $subTotal,
'Total' => ($total - $discount),
'Discount' => $discount,
'Debit' => $debit,
'Payment_Cridet' => $total - $debit - $discount,
'Note' => $this->input->post('note'),
'Customer_ID' => $this->input->post('customerId'),
'User_ID' => $this->session->userdata('id')
);

How would I combine two reject functions with PHP/ Laravel?

How would I refactor the code below so that there is only one reject function not two and have only one call to the db instead of three. I am also trying to not have any duplicates.
$latestListings = $repo->whereExclusive(['property_status' => 'Active'],['created_at' => 'desc'],[],0, 4);
$latestListingsIds = $latestListings->map(function (Listing $listing) {
return $listing->id;
})->toArray();
$highCflListings = $repo->whereExclusive(['property_status' => 'Active'],['cfl' => 'desc'],[],0, 4);
$highCflListingIds = $highCflListings->map(function (Listing $listing) {
return $listing->id;
})->toArray();
$highCflListingsOccupied = $repo->whereExclusive(
['property_status' => 'Active', 'occupied_percentage' => 100],
['cfl' => 'desc'],
[],
0,
12
)->reject(function (Listing $listing) use ($latestListingsIds) {
return in_array($listing->id, $latestListingsIds);
})->reject(function (Listing $listing) use ($highCflListingIds) {
return in_array($listing->id, $highCflListingIds);
})->take(4);
I don’t know how you’re setting $latestListingsIds and $highCflListingIds but if these are just arrays of IDs, combine them and reject on those:
$exclude = $latestListingsIds + $highCflListingIds;
$highCflListingsOccupied = $repo->whereExclusive(['property_status' => 'Active', 'occupied_percentage' => 100], ['cfl' => 'desc'], [], 0, 12)
->reject(function (Listing $listing) use ($exclude) {
return in_array($listing->id, $exclude);
})
->take(4);

Add custom options to dropdown via code in Magento

i had to add custom options automatically when a product is added , the code works fine but i need to create a drop down menu with options and i dont know how to add options to the drop down created ,
my code is
public function Add_CustomOptions_Automatically($observer) {
$product = $observer->getEvent()->getProduct();
$save = false; if (!$product->getOptions()) $save = true;
$optionData = array(
'previous_group' => 'text',
'title' => 'Size',
'type' => 'drop_down',
'is_require' => 0,
'sort_order' => 0,
'price' => 0,
'price_type' => 'fixed');
if($save):
$product->setHasOptions(1)->save();
$option = Mage::getModel('catalog/product_option')
->setProductId($product->getId())
->setStoreId($product->getStoreId())
->addData($optionData);
$option->save();
$product->addOption($option);
endif;
}
}
I've created 'type' => 'drop_down' but how can I add options? I have no idea how to add the options, and any help would be very much appreciated.
thanks,
You can supply an array of values to the option array, this will then be added
to the option. as below :-)
$product = Mage::getModel('catalog/product');
$product->load(200); // product id here
$opt = array(
'is_delete' => 0,
'is_require' => false,
'previous_group' => '',
'title' => 'New Example Option',
'type' => 'drop_down',
'price_type' => 'fixed',
'price' => '20.0000',
'sort_order' => 0,
/** array of values for this option **/
'values' => array(
array(
'is_delete' => 0,
'title' => 'Option One Here',
'price_type' => 'fixed',
'price' => 999,
'sku' => 'test-sku-here',
'option_type_id'=> -1,
),
array(
'is_delete' => 0,
'title' => 'Another Option',
'price_type' => 'fixed',
'price' => 999,
'sku' => 'another-sku-here',
'option_type_id'=> -1,
)),
);
$option = Mage::getModel('catalog/product_option')
->setProduct($product)
->addOption($opt)
->saveOptions();
public function Add_CustomOptions_Automatically($observer) {
$product = $observer->getEvent()->getProduct();
$optionData = array(
'previous_group' => 'text',
'title' => 'Size',
'type' => 'drop_down',
'is_require' => 0,
'sort_order' => 0,
'price' => 0,
'price_type' => 'fixed');
if(!(bool)$product->getOptions()):
$product->setHasOptions(true)->save();
$option = Mage::getModel('catalog/product_option')
->setProductId($product->getId())
->setStoreId($product->getStoreId())
->addData($optionData);
// Answer starts here
$value = Mage::getModel('catalog/product_option_value');
$value->setOption($option)
->setTitle('Hello world!');
$option->addValue($value);
// Answer ends here
$option->save();
$product->addOption($option);
endif;
}
As you can see you are adding a Mage_Catalog_Model_Product_Option_Value with a title and associating it with the $option you created. It can also have an SKU, price and sort order. Create as many values as you want in this way.
<!DOCTYPE html PUBLIC "-W3CDTD XHTML 1.0 TransitionalEN" "http:www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http:www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<pre>
<?php
$res = mysql_pconnect('localhost', 'your data base name', 'passward');
mysql_select_db('your database name');
mysql_query("SET NAMES 'utf8';", $res);
mysql_query("SET CHARACTER SET 'utf8';", $res);
$query = 'select entity_id from catalog_product_entity';
$res = mysql_query($query);
$products=array();
while ($ret = mysql_fetch_array($res)) {
$products[]=$ret[0];
$query = "UPDATE catalog_product_entity set has_options=1 where entity_id=$ret[0]";
//echo "$query<br>";
//$res1 = mysql_query($query);
}
echo "Set all products for has_options in catalog_product_entity.<br>";
//$res = mysql_query('DELETE from catalog_product_option');
//$res = mysql_query('DELETE from catalog_product_option_title');
//$res = mysql_query('DELETE from catalog_product_option_type_price');
//$res = mysql_query('DELETE from catalog_product_option_type_title');
//$res = mysql_query('DELETE from catalog_product_option_type_value');
echo "Deleted all rows from catalog_product_option* tables.<br>";
$ress=array();
foreach ($products as $product){
$query = "insert into catalog_product_option (product_id,type,is_require,image_size_x,image_size_y,sort_order) values ($product,'drop_down',0,0,0,0)";
echo "$query<br>";
$res1 = mysql_query($query);
$ress[] = array("option_id" => mysql_insert_id());
}
echo '<pre>';
print_r($ress);
echo "Populated catalog_product_option.<br>";
$option_titles=array('en_US'=> 'Warrenty' );// here change title of option titles #Optional Coating
$res = mysql_query('SELECT * FROM `core_config_data` WHERE path="general/locale/code"');
while ($ret = mysql_fetch_array($res)) {
$stores[$ret['value']][]=$ret['scope_id'];
}
$res = mysql_query('select * from catalog_product_option');// get all product here which agains data inserted
$sort_orders=array(
1,
2,
3,
4);
//while ($ret = mysql_fetch_array($res)) {
foreach ($ress as $key => $ret)
{
//echo '<br>'.$ret[$key]["option_id"];
foreach($stores as $locale=>$scopes){
foreach($scopes as $scope){
$query = "insert into catalog_product_option_title (option_id,store_id,title) values ($ret[option_id],$scope,'$option_titles[$locale]')";
echo "$query<br>";
$res1 = mysql_query($query);
}
}
foreach($sort_orders as $order){
$query = "insert into catalog_product_option_type_value (option_id,sort_order) values ($ret[option_id],$order)";
echo "$query<br>";
$res1 = mysql_query($query);
}
}
echo "Populated catalog_product_option_title.<br>";
echo "Populated catalog_product_option_type_value.<br>";
$prices=array(
0.00,//Standard (12 months)
29.95,//Silver (12 months +loan phone + pic up)
59.95,//Gold(12 months)
89.95//Platinum (24 months +loan phone + pic up)
);
$option_type_titles=array('en_US'=>array(
'Standard (12 months).',
'Silver (12 months +loan phone + pic up).',
'Gold(12 months).',
'Platinum (24 months +loan phone + pic up).'
)
);
$res = mysql_query('select * from catalog_product_option_type_value');
$i = 0;
$j = count($prices)-1;
while ($ret = mysql_fetch_array($res)) {
foreach($stores as $locale=>$scopes){
foreach($scopes as $scope){
$query = "insert into catalog_product_option_type_price (option_type_id,store_id,price,price_type) values ($ret[0],$scope,$prices[$i],'fixed')";
echo "$query<br>";
$res1 = mysql_query($query);
$query = "insert into catalog_product_option_type_title (option_type_id,store_id,title) values ($ret[0],$scope,'{$option_type_titles[$locale][$i]}')";
echo "$query<br>";
$res1 = mysql_query($query);
}
}
($j==$i) ? $i= 0 : $i++ ;
}
echo "<br>Populated catalog_product_option_type_price.<br>";
echo "<br>Populated catalog_product_option_type_title.<br>";
?>
</pre>
</body>
</html>
dear this code is work and i check it . but this code when excute it will add this custom option with all products in your shop. you can change sort ordar and price and option values and also dropdown name . i think its work better.
Try this, its working for me...
$eavSetup->addAttribute(CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,$attributeCode, [
'type' => 'varchar',
'label' => 'My Code',
'input' => 'select',
'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Table',
'required' => false,
'visible' => true,
'user_defined' => true,
'sort_order' => 101,
'position' => 101,
'system' => 0,
'option' =>
array (
'values' =>
array(
0 => 'January',
1 => 'February',
2 => 'March',
3 => 'April',
4 => 'May',
5 => 'June',
6 => 'July',
7 => 'August',
8 => 'September',
9 => 'October',
10 => 'November',
11 => 'December'
),
),
]);

Resources