Updating the product array in opencart - opencart

I am trying to update both the quantity and total of a product in the current cart in a new file i have created in the root opencart folder.
First I grab the total and quantity which have been posted here from another file. Then I load the products array. Then if $total and $quantity exist and are not equal to 0, I update the products array with the new values for quantity and total. My problem is I am not quite sure how to load the products array and update it with the new values for quantity and total.
This is what I have come up with so far. Any help would be greatly appreciated.
<?php
$total = mysql_real_escape_string(htmlentities($_POST['total']));
$quantity = mysql_real_escape_string(htmlentities($_POST['quantity']));
$this->data['products'] = array();
$products = $this->cart->getProducts();
if ($total && $total != 0 && $quantity && $quantity != 0){
product['quantity'] = $quantity;
product['total'] = $total;
}
?>

If you mean how can you update the current live cart items, they're stored in a key value pair in the session under the cart key, so you can manipulate/read them from
$this->session->data['cart']
To see the inner workings of how the cart reads them, you can take a look at the getProducts()method in /system/library/cart.php

Related

Opencart 3.0: Get the 'Product_Id' of the Last Item Added To Cart

I'm working with Opencart 3.0 to set up a product cross-sell to display similar items to the user when they add something to the cart. I thought I had seen a pattern with the array of products in the cart that put the last item of cart at the end. So my php looked something like this:
$this->load->model('catalog/product');
$related_product_id = $products;
$related_product_id = end($related_product_id);
$related_product_id = $related_product_id['product_id'];
$related = $this->model_catalog_product->getProductRelated($related_product_id);
foreach ($related as $related) {
//..do something
}
Using the end() method in the above code would take the very last Key=>Value (Product_id) in the array so I could use it to display the product on the page.
This worked for a while until I noticed that it was not always accurate. If someone added something already in the cart, it wouldn't place it at the end of the array, and also other certain products for some reason didn't show up at the end of the array.
Is there another way to get the Product_Id of the last item a user added to the cart than the way I'm going about it? My way doesn't seem very consistent. Thanks!
I was able to figured it out adding my own function to /system/libray/cart/cart.php
I added this function
public function getProductsInCart() {
$product_data = array();
$cart_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "cart WHERE api_id = '" . (isset($this->session->data['api_id']) ? (int)$this->session->data['api_id'] : 0) . "' AND customer_id = '" . (int)$this->customer->getId() . "' AND session_id = '" . $this->db->escape($this->session->getId()) . "' ORDER BY date_added ASC");
foreach ($cart_query->rows as $cart) {
$product_data[] = array(
'cart_id' => $cart['cart_id'],
'product_id' => $cart['product_id'],
'date_added' => $cart['date_added'],
);
}
return $product_data;
}
And instead of using the $this->cart->getProducts() line to get products from the cart, I'm using my new function $this->cart->getProductsInCart().
This works way more consistent. The only thing it doesn't take into consideration is when someone goes back to a product already added. It doesn't count it as a new product added, but instead just updates it quantity.
Let me know if someone finds a better solution.

DAX Previous Year Normalized Amount

I have a column called "Normalize Data" which has 2 values "yes" and "no".
Requirement:
When the user clicks on "yes", I want my measure(called Prev_YR_Trans) to do one thing, but if the user clicks "no" I want the measure to do another thing.
Let me explain with an example - My measure Prev_YR_Trans displays the transactions for the previous time period. Let's the say current time period is "25", then it will display the transactions for time period "24". Now, if the user clicks on "Yes", then I want the previous year's transactions to get "normalized" i.e. I want it to get multiplied by the variance b/w the 2 time periods.
What I have tried:
Prev_YR_Trans =
#getting the current & previous time period from Table "X"
VAR prevSeason = CALCULATE(MAX('X'[Time Period]))-1
VAR maxSeason = CALCULATE(MAX('X'[Time Period]))
#getting variance b/w prev and current time periods
VAR maxSeason_footfall = CALCULATE(SUM('Y'[Park_Footfall]),'Y'[Time Period]=maxSeason)
VAR prevSeason_footfall = CALCULATE(SUM('Y'[Park_Footfall]),'Y'[Time Period]=prevSeason)
VAR footfall_variance = 1+((maxSeason_footfall-prevSeason_footfall)/prevSeason_footfall)
#trying to get the option that the user clicks on(?)
VAR bb = CALCULATE(('X'[Normalize data]))
#returns normalized numbers if user chooses "Yes" else returns actual numbers
RETURN
IF(bb="Yes",
CALCULATE(SUM('X'[Receipt Count]),'X'[Time Period]= prevSeason)*footfall_variance,
CALCULATE(SUM('X'[Receipt Count]),'X'[Time Period]= prevSeason)
)
In my above measure, the "VAR bb = CALCULATE(('X'[Normalize data]))" is giving me an error as it needs some aggregation like max,min,sum,etc.
How do I resolve my measure so that it displays the correct numbers?
Edit (Solved) More on "Normalize Data" column:
I've solved the "Normalize Data" column by creating a new table called "Normalize Slicer" with yes/no values. Here is the link
Also, if you could help me out with my "Normalize Data" column too then that would great!
So with the "Normalize Data" column - I just want it to display 2 options "Yes" and "No" but I realized I need to create it as a column for the slicer functionality to work.
So for my formula I'd like to display "Yes" if the "Time Period" is less than or equal to the previous time period and "No" otherwise.
I tried to do the following:
Normalize data = IF('X'[Time Period]<=(CALCULATE(MAX('X'[Time Period]))-1),"Yes","No")
But above column just displays "No" for all the values so as a workaround I manually entered the previous time period in the formula:
Normalize data = IF('X'[Time Period]<=24,"Yes","No")
The above formula does work but I'd like it to be dynamic and not a manually entered value.
Insted of
VAR bb = CALCULATE(('X'[Normalize data]))
Use this:
var bb = SELECTEDVALUE('X'[Normalize data])
https://dax.guide/selectedvalue/

DAX: How do i create a table for a burndown chart? What status was current on certain dates

I'm creating a dashboard for a sprint overview and want to visualize the progress of the team in a burndown chart. The chart should give information about the amount of user stories that are each new, active and closed. So that in the beginning all user stories are open, then they become active and in the end, there are no open and active stories left.
Now my problem is in modeling the data using DAX.
The data is stored in a big table with a row for each user story that contains all the information on that date. Now, if the information gets modified like in the event of changing the status from new to active or correcting a spelling mistake, the program just adds a new row with a new date.
like in here
The table I want should have the columns date, new, active, and closed. For the date column i have written the following code:
CALENDAR(
FIRSTNONBLANK(
CurrentIterations[StartDate];
CurrentIterations[StartDate] );
FIRSTNONBLANK(
CurrentIterations[FinishDate];
CurrentIterations[FinishDate])
)
But now, oriented on that dates i want the other columns to calculate themselves. In every row I want the amount of user stories in the original table that are active and the latest version on that date.
Examples:
Original table
Wanted table
Wanted burndown chart
Any help greatly appreciated!
Here's another approach.
Calculated table:
MaxRev = CROSSJOIN(VALUES(Test[Id]), VALUES(Test[Date]))
Add the following calculated columns to this table:
MaxRev = CALCULATE(MAX(Test[Rev]),
FILTER(Test, Test[Id] = MaxRev[Id] && Test[Date] <= MaxRev[Date]))
Status = LOOKUPVALUE(Test[State], Test[Id], MaxRev[Id], Test[Rev], MaxRev[MaxRev])
Then use this to create a new calculated table:
Wanted = SUMMARIZE(MaxRev, MaxRev[Date],
"New", CALCULATE(COUNT(MaxRev[Id]), MaxRev[Status] = "New") + 0,
"Active", CALCULATE(COUNT(MaxRev[Id]), MaxRev[Status] = "Active") + 0,
"Solved", CALCULATE(COUNT(MaxRev[Id]), MaxRev[Status] = "Solved") + 0)
Well, it isn't as beatiful, but it does the job. I've created an extra table, to get the last Rev per Id and Day. At least, that's what I thought you meant.
I'm open for better solutions, I'm convinced it can be done better/easier.
'Test' is your original table, make a link on Date to your already created table (Wanted) with the Date column.
Calculated table:
MaxRev =
SUMMARIZE(Test; Tabel[Date]; Test[Id]; "Max"; MAX(Test[Rev]))
Column New (add to table with single date column):
New =
CALCULATE (
DISTINCTCOUNT ( Test[Id] );
CALCULATETABLE (
FILTER (
CROSSJOIN ( 'MaxRev'; Test );
'MaxRev'[Id] = Test[Id]
&& 'MaxRev'[Date] = Test[Date]
&& 'MaxRev'[Max] = Test[Rev]
)
);
Test[State] = "New"
) + 0
Repeat this column, also for Active and Solved.
PBIX file

CAML Query to get only non duplicates

My first goal is to get all items that has a status of 'Pending' in my sharepoint list. My code so far is like this :
using (var clientContext = new ClientContext(spSite.Trim()))
{
clientContext.Credentials = GetNetworkCredential();
var approvalLists = clientContext.Web.Lists.GetByTitle(approvalLibraryName);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View>" +
"<Query>" +
"<Where>" +
"<Eq>" +
"<FieldRef Name='IsApproved'/><Value Type='Choice'>Pending</Value>" +
"</Eq>" +
"</Where>" +
"</Query>" +
"</View>";
ListItemCollection approvalListItem = approvalLists.GetItems(query);
clientContext.Load(approvalListItem);
clientContext.ExecuteQuery();
}
It is working but I then realize that a particular item can be inserted more than 1 in that list. So for example for item request_100, it can have one row for pending and another row for approved. So I need to only get those non duplicates items with status 'Pending'. Is it possible to have group by then fetch only those who have count = 1? Because I'm thinking if I could just load all items then manipulate it in using linq list. Or do you guys have another suggestion for this?
My first thought was indeed also using linq on the ItemCollection which should be working just fine.
But just a thought, if you select only the 'pending' rows, you won't get duplicates will you? Or can there be more than one item like 'request_100' with statusses 'Pending'?
Check this question which is alike to yours: https://sharepoint.stackexchange.com/questions/43262/how-to-use-groupby-in-caml-query

Obtain product custom field value in Virtuemart

I am trying to obtain value of a custom field of a product. I only have ID of that product. I know title of the custom field.
How can I get value of that custom field?
Please help.
PS: I know PHP well but I am new to Joomla/Virtuemart.
This will work for VM2.x
VM is storing the custom field values in #__virtuemart_customs
The relation between the product and the custom field is maintaining in the #__virtuemart_product_customfields
You have title and Product Id so you can try this
$db = &JFactory::getDBO();
$sql = "SELECT F.custom_value #__virtuemart_customs AS C LEFT JOIN #__virtuemart_product_customfields AS F ON F.virtuemart_customfield_id = C.virtuemart_custom_id where (C.custom_title='$your_customtitle' and F.virtuemart_product_id = '$product_id')";
$db->setQuery($sql);
$db->query();
$res = $db->loadAssoc();
echo $res['custom_value'];
Also you try with inner sub query .
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('virtuemart_product_id,custom_value');
$query->from('#__virtuemart_product_customfields');
$db->setQuery((string)$query);
$results = $db->loadObjectList();
if ($results){
foreach($results as $result)
{
// do your stuff here
}