I'm trying to do a onchange event with ajax and php according to country selected from a dropdown. My problem is that the response set the last price in the array on every item and I can't figure out a way to solve this.
Here is my code so far:
$("#field-organization-country-iso").on('change', (e) => {
e.preventDefault();
e.stopPropagation();
const CountryIso = $('#field-organization-country-iso').val();
Request.get(`/myrequested_file`, {
data: { CountryIso },
})
.done((response) => {
for (let i = 0; i < response.data.itemPrice.length; i++) {
const price = response.data.itemPrice[i];
$('.checkout-table tr').find('.hide-if-odd-or-sub').eq(i).html(price);
}
});
});
And the php-function:
public function change_currencyIso(Request $request, $summaryService): JSONResponse
{
$countryIso = $request->query->get('CountryIso');
$response = new JSONResponse();
$orderSummary = $summaryService->Summary(Cart::getCurrentCart(), User::currentUserOrNull(), $countryIso, null, null);
$items = $orderSummary->getItems();
$currencies = new ISOCurrencies();
$numberFormatter = new NumberFormatter(Environ::getLocale(), NumberFormatter::CURRENCY);
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, $currencies);
$prices = [];
foreach ($items as $item) {
$price = $moneyFormatter->format($item->getLocalPrice());
$prices[] = $price;
}
$response->setVar('itemPrice', $prices);
return $response;
}
$prices returns the array with item prices but I know response writes over it. Can I loop through the array and add the response to each price?
My response with 'itemPrice' is only returning one of the existing prices.
{itemPrice: Array(2)}
itemPrice: Array(2)
0: "245,00 US$"
1: "32,90 US$"
length: 2
Now itemPrice returns the array but still puts everything on the same row. Tried a each but that didn't help.
You should add more details about the html structure, however I suppose you have a table with a row for each item, and the cells with the price have the class "hide-if-odd-or-sub". Also table rows are in the same order of the prices returned by the server. So, you have to assign each price to the correspondig table row:
foreach (var i in response.data.itemPrice) {
var price = response.data.itemPrice[i];
$('.checkout-table tr').eq(i).find('.hide-if-odd-or-sub').html(price);
}
This is not mush robust, because if the user change the items in the cart in another browser's tab and goes back to previous tab and updates the country, then the prices returned by the server won't correspond to items in the table, however it should work under normal usage.
Related
I am constructing a function that is making a call with API to db and returns me JSON data. The json contains orders and I have already decoded them in php array. Every order has properties such as "product_id" and "quantity". I want to temporarily store the "quantity" property somewhere because I need to sum all the products with the same product_id. Any suggestion how to do this?
I'm in a bit of a hurry, but wanted to see if I could help you out.
$quantities = [];
//Loop through all the orders
foreach ($orders as $order) {
//Loop through the orderrows
foreach ($order->getOrderRows() as $orderRow) {
if (array_key_exists($orderRow->getProductName(), $quantities)) {
//The product is already in the quantities array, so the quantity of this orderrow is added to the total
$quantities[$orderRow->getProductName()] =
($quantities[$orderRow->getProductName()] + (int) $orderRow->getItemQuantity());
} else {
//If this is the first time the product is encountered add the product and its quantity to the quantities array
$quantities[$orderRow->getProductName()] = (int) $orderRow->getItemQuantity();
}
}
}
This is going to have the following result, showing you the product names along with their quantities:
$quantities = [
'foo' => 12,
'bar' => 3,
];
You may use the session variable to store these values.
I have database data like text [mydata] some text [otherdata] some more text and I want to replace those [mydata] , [otherdata] with dynamic info such as category title for instance.
So the result of my data would be like:
text Category Title some text Category Desc some more text
instead of
text [mydata] some text [otherdata] some more text
I think that can be happen by preg_replace but not quite sure.
code
View::composer('*', function ($view) {
$notes = Notes::all();
foreach($notes as $note){
$descrip= $note->description;
}
$view->with('descrip', $descrip);
});
More
So basically $note->description content is this data:
text [mydata] some text [otherdata] some more text
I want to replace those elements by data from categories table.
Any idea?
Update
well i was digging and get code below (useing str_replace) however it has some issues,
View::composer('*', function ($view) {
//getting categories and pull out the values i want to use as `[....]`
$catC = Category::all();
foreach($catC as $catD){
$meta_title = $catD->title;
$meta_desc = $catD->meta_description;
$meta_tags = $catD->meta_tags;
}
//replace those categories values with element in database `[......]`
$seotemplates = SeoTemplate::all();
foreach($seotemplates as $seotemplate){
$myCustom = str_replace_array('[cattitle]', [$meta_title, $meta_desc, $meta_tags], $seotemplate->categories_desc_template);
}
$view->with('myCustom', $myCustom);
});
Issues
I can only get [cattitle] but what about [catmeta] & [cattags]?
$meta_title will always return first value from categories table (for example if i'm visiting HP category page it return ACER as [cattitle] or any other category pages i visit. It's always ACER
Update 2
I solved the issue 1 of my first update but still issue 2 remained, here is updated code
View::composer('*', function ($view) {
//categories
$catC = Category::all();
$catD = [];
foreach($catC as $catD){
$catD = [
$cattitle = $catD->title,
$catmeta = $catD->meta_tags,
$catdesc = $catD->meta_description
];
}
$a1 = array("[cattitle]","[catmeta]","[catdesc]");
$seotemplates = SeoTemplate::all();
foreach($seotemplates as $seotemplate){
$myCustom = str_replace($a1, $catD, $seotemplate->categories_desc_template);
}
$view->with('myCustom', $myCustom);
});
Current issue:
$meta_title will always return first value from categories table (for example if i'm visiting HP category page it return ACER as
[cattitle] or any other category pages i visit. It's always ACER
I see a couple of issues with your code that I think will help with getting the solution that you are after.
First like mentioned by #hktang said in his comment you are duplicating your variables and then assigning it's value over and over again instead of adding to it. Try this:
$catE = [];
foreach($catC as $catD){
$catE[] = [
$cattitle = $catD->title,
$catmeta = $catD->meta_tags,
$catdesc = $catD->meta_description
];
}
Second you are also resetting the value of $myCustom with each loop of the for each. Try this:
$myCustom = []
foreach($seotemplates as $seotemplate){
$myCustom[] = str_replace($a1, $catE, $seotemplate->categories_desc_template);
}
This should result in you getting an array of seotemplates with the values replaced but I have not testing this.
I have the next issue - I have a table invoices and a table with receipts. An invoice is created by an agent and I want to get the sold for each agent but the numbers are wrong.
Here is what I've tried:
$agents = Agent::get();
$invoices_receipts_agent = array();
foreach ($agents as $agent) {
$payment_invoice = 0;
$payment_recepit = 0;
$id_agent = $agent->id_agent;
$invoices = Invoice::whereAgent_id($id_agent)->get();
foreach ($invoices as $invoice) {
$payment_invoice = $payment_invoice + $invoice->total_pay;
$recepits = Recepit::whereInvoice_id($invoice->id_invoice)->get();
if (count($recepits) > 0) {
foreach ($recepits as $recepit) {
$payment_recepit = $payment_recepit + $recepit->amount_payd;
}
}
}
$total = $payment_invoice - $payment_recepit;
$total_agents = ['name' => $agent->name, 'total' => $total];
array_push($invoices_receipts_agent, $total_agents);
}
I made a test and created two invoices for the agent with ID 5
First invoice: 10
Second invoice : 20
Total invoices: 30
Then I did a recepit for the second invoice and found the expected total:
Total: 10 + 20 - 20 = 10 (correct total)
And that's great, but I have an agent with 3600 invoices and something is wrong the total. The total (total = invoices - recepits) is too big, but I can't figure out why.
Extra detail: the fields for the numbers are float.
First of all, you have an easier way to handle this issue using Eloquent Relationships.
In this case, can define One-to-Many relationship between Agent and Invoice as:
class Agent {
...
function invoices(){
return $this->hasMany('App-Namespace\Invoice')
}
}
...and define the inverse relationship on Invoice.
Then, you must do same between Invoice and Receipt models, since an Invoice can have one to many receipts.
So, if Agents table primary key is id you could say:
$agent = Agent::find($agent_id)->invoices->get();
...to get an agent invoices; or:
$invoice = Invoice::find($invoice_id)->receipts->get();
...to get all receipts for a specific invoice.
And finally implement your code:
$agents = Agent::all();
$invoices_receipts_agent = array();
foreach ($agents as $agent) {
$payment_invoice = 0;
$invoices = $agent->invoices->get();
foreach ($invoices as $invoice){
$payment_invoice += $invoice->total_pay;
$payment_receipt += $invoice->receipts->sum('amount_paid');
}
$total = $payment_invoice + $payment_receipt;
$invoices_receipts_agent[] = ['name' => $agent->name, 'total' => $total];
}
Note: I have used sum collection function to get sum of values of column amount_paid of a particular receipt. You could do same to get sum of total_pay column of an invoice like:
$total_paid = $agent->invoices()->sum('total_pay');
Can you confirm it this current version of your code?
I see some typos like in:
$recepits = Recepit::whereInvoice_id($invoice->id_invoice)->get();
if (count($receipts) > 0) {
Here we have issues:
Variable is named $recepits, but then called in next line with other name ($receipts).
$receipts should be a collection (result of Eloquent query) not an array. So to get count you have to say: $receipts->count()
If this is your final code, those are definitly error which are affecting your result.
I made a simple import script and I'm trying to programatically save 3 custom attributes (att1, att2, att3) together with all other info (name, description, price, category..).
So basically I have:
public function insert_product($data) {
$product = Mage::getModel('catalog/product');
try {
$sku = $data['code'];
if ($this->prodottiImportati[$sku]) {
$sku = $data['code'] . '-1';
}
$this->prodottiImportati[$sku] = true;
$product->setSku($sku);
$product->setName($data['name']);
$product->setDescription($data['desc']);
$product->setShortDescription($data['short_desc']);
$product->setManufacturer('');
$product->setPrice($data['price']);
$product->setTypeId('simple');
$product->setAttributeSetId($this->attributeSet);
$categorie = $this->get_categories($data);
$product->setCategoryIds($categorie);
$product->setWeight($data['peso']);
$product->setTaxClassId(2); // taxable goods
$product->setVisibility(4); // catalog, search
$product->setStatus(1); // enabled
$product->setWebsiteIds($data['store_id']);
$stockData = $product->getStockData();
$stockData['qty'] = $data['qty'];
if ($data['quantita'] > 0) {
$stockData['is_in_stock'] = 1;
} else {
$stockData['is_in_stock'] = 0;
}
$stockData['manage_stock'] = 1;
$stockData['use_config_manage_stock'] = 0;
$product->setStockData($stockData);
$product->setIsMassupdate(true)->setExcludeUrlRewrite(true);
$product->save();
$productID = $product->getId();
} catch(Exception $e) {
echo ($e->getMessage());
}
return $productID;
}
First thing I tryed was adding a
$productID = $this->insert_product($data);
Mage::getSingleton('catalog/product_action')->updateAttributes(
array($productID), array(
'att1' => $data['att1'],
), $data['store_id']);
So basically updating things after the insert function was called, using the ID got after the insert. store_id is the ID of the store in that given language. Didn't save anything.
Second attempt, I follwed this: Magento add custom options with programmatically importing products
I tryed that within the insert_product function and also outside after $productID = $this->insert_product($data); Neither worked.
Last I tryed a magical $product->setAtt1('value'); witin the insert_product function, not sure how Magento would understand how to set att1 that way, but...you know, I read it somewhere and I gave it a try ;)
att1, att2 and att3 are spelled lowercase, althoug they have an uppercase label (think that dosen't matter here), they are part of an attribute group (I'm passing it with $product->setAttributeSetId($this->setAttributi)) and they are all multiple selection attributes, so I could in teory pass multiple values to them.
I'm sure I'm missing something on the way. Can anyone help?
After 10 more minutes since I wrote here, I was able to find the way. I took me forever to solve it.
The clue of this is that you have to add attributes ID, not values. That happens at least for me with multiple selection attributes, not sure if it's true all the time.
Here is how I did:
In the function insert_product I added:
$optionId = $this->get_option_id_by_code('att1', 'Value of the attribute you need to add');
$product->setAtt1($optionId);
So if yor attribute is named, let's say "brand" it will be:
$optionId = $this->get_option_id_by_code('brand', 'Nike');
$product->setBrand($optionId);
If your attribute can have multiple values, you need to change the code above to:
$optionId = array();
foreach ($myAttributesArray as $someValues) {
$optionId[] = $this->get_option_id_by_code('att1', $someValues);
}
$product->setAtt1($optionId);
The foreach is just an example, you need to loop through your mutiple values and get the respective ID and add them all toghether with setAtt1 passing them as an array. I'm working on an improved version where the get_option_id_by_code function does all at once in a more efficient way. This is kust a "basic" version that works, feel free to make it fancy and smart.
Then I created an other function called get_option_id_by_code like this:
protected function get_option_id_by_code($attrCode, $optionLabel) {
$attrModel = Mage::getModel('eav/entity_attribute');
$attrID = $attrModel->getIdByCode('catalog_product', $attrCode);
$attribute = $attrModel->load($attrID);
$options = Mage::getModel('eav/entity_attribute_source_table')
->setAttribute($attribute)
->getAllOptions(false);
foreach ($options as $option) {
if ($option['label'] == $optionLabel) {
return $option['value'];
}
}
return false;
}
To be honest I found this with a collage of other sources / authors, so I need to be thankful to a bunch of smarter programmers here and there, since it took a while for me to strouggle with this simple task I wrote the solution here hoping to help you guys. Thanks!
I am trying to add conversion tracking to my magento store. I know I need to add the following code and customize it so magento will share info with CA.
<script type="text/javascript">
var _caq = _caq || [];
var products = [];
products.push({Sku: 'ProductID', UnitPrice: 'item price here', Quantity: 'quantity here'});
products.push({Sku: 'ProductID', UnitPrice: 'item price here', Quantity: 'quantity here'});
_caq.push(["Order", {OrderId: 'OrderID', Revenue: 'oVal', CurrencyCode: '3 letter currency code here', Products: products}]);
so far i have been trying to get the data from the order with the following code:
<?php $orderId = $this->getOrderId();
$order = Mage::getModel('sales/order')->load($orderId);
$items = $order->getAllItems();
$_grand = $order->getGrandTotal();
$custname = $order->getCustomerName();
$itemcount=count($items);
foreach ($items as $itemId => $item)
{
$sObject2->Item_name__c = $item->getName();
$sObject2->Unit_price__c = $item->getPrice();
$sObject2->Sku__c = $item->getSku();
$sObject2->Quantity__c = $item->getQtyToInvoice();
}
echo $_grand;
echo $custname;
?>
When i try to echo the customers name and grand total, i get a blank for the total and Guest for the customer name. Even if i make the $orderId a number of an order this happens.
When you're passing in the number of an order are you passing the entity_id or the increment_id? Usually the number you see in admin will be the increment_id. Look in the address bar of the browser to pick out the entity_id.
$order = Mage::getModel('sales/order')->load($orderId); // $orderId should be the entity_id.
Try this method of retrieving the order instead (Works on the success page):
$orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$order = Mage::getModel("sales/order")->loadByIncrementId($orderId);
Also, make sure to call the correct method for getting the grand total:
$_grand = $order->getGrandTotal(); // Gets the grand total in the store currency.
$_grand = $order->getBaseGrandTotal(); // Gets the grand total in the base currency.
It's probably more useful for your tracking purposes to use the base currency. If you only have one store, or use one currency, it probably won't make any difference. But, if you ever use multiple currencies you'll need to get this right.
i am using these functions please take a look :
function get_all_orders($fromdate,$todate)
{
$getsales = mysql_query("SELECT * FROM `sales_flat_order` WHERE `created_at`>='$fromdate' AND `created_at`<='$todate'");
if(mysql_num_rows($getsales)> 0)
return $getsales;
else
return FALSE;
}
function num_items_under_order($order_entity_id)
{
$getorder_num = mysql_query("SELECT * FROM `sales_flat_order_item` WHERE `order_id`='$order_entity_id'");
if(mysql_num_rows($getorder_num) == 1)
return TRUE;
elseif(mysql_num_rows($getorder_num) > 1 )
return FALSE;
}
function get_order_item_details($order_entity_id)
{
$getsales = mysql_query("SELECT * FROM `sales_flat_order_item` WHERE `order_id`='$order_entity_id'");
if(mysql_num_rows($getsales) == 1)
{
return mysql_fetch_object($getsales);
}
elseif(mysql_num_rows($getsales) > 1)
{
return $getsales;
}
else
return FALSE;
}
Thanks