Woo-commerce Variable Regular and Sale price - categories

I am trying to display the regular and sale price of a variable product. I know it can be achieved from get_post_meta( $post->ID, '_regular_price', true); but it isnt working in variable products only a simple product.
I looked into the classes and also saw that woocommerce updates the post meta of _regular_price itself when storing a variable product price.
Is there anything I am missing?
Thanks

The best code for solve this is:
#Step 1: Get product varations
$available_variations = $product->get_available_variations();
#Step 2: Get product variation id
$variation_id=$available_variations[0]['variation_id']; // Getting the variable id of just the 1st product. You can loop $available_variations to get info about each variation.
#Step 3: Create the variable product object
$variable_product1= new WC_Product_Variation( $variation_id );
#Step 4: You have the data. Have fun :)
$regular_price = $variable_product1 ->regular_price;
$sales_price = $variable_product1 ->sale_price;

If you don't have any variation in your product then, you can simple get product price using product ID like:-
add_action('init', 'test');
function test() {
global $woocommerce;
$product = new WC_Product(268);
echo $product->get_price();
}
If product have variation and each variation have different price then need to get price using variation ID.

That's because variable product is not keeping any price information itself but it is the parent of another kind of child posts named "product_variation" each having their own price and variation information. So if you want to do something on price of variable products in a WP_Query loop you have to filter your loop through post_type => 'product_variation' and then you can access their parent id from their post_parent property for getting other related information of those variable products variations such as name, description, images, ...
Here is an example:
$query = new WP_Query(array(
'post_type' => 'product_variation', // <<== here is the answer
'posts_per_page' => 5,
'post_status' => 'publish',
'orderby' => 'meta_value_num',
'meta_key' => '_price',
'order' => 'asc',
));
while ($query->have_posts()) {
$query->the_post();
$pid = $query->post->ID;
$parent = $query->post->post_parent;
$price = get_post_meta($pid, '_price', true);
$regular_price = get_post_meta($pid, '_regular_price', true);
$sale_price = get_post_meta($pid, '_sale_price', true);
$title_product = get_the_title($parent);
$title_variation = get_the_title($pid);
echo "$title_variation: $price <br />";
}

Related

Understanding issue get one row from database with 2 parameters

I thought it would work find, but it doesn't.
I have a method in my modelclass like this:
public function getUnitbyName2($unitname, $ProjectID)
{
//$id = (int) $id;
$rowset = $this->tableGateway->select(['Unitname' => $unitname], ['ProjectID' => $ProjectID]);
$row = $rowset->current();
if (! $row) {
// throw new RuntimeException(sprintf(
// 'Could not find row with identifier %d',
// $unitname
// ));
$row=0;
}
return $row;
}
If I give an existing unitname and a non existent project_ID I expect to get some 0 value. But I always get the number of the unit in the first project with the given unitname. It is common that the unitname exists in several different projects.
The function is supposed to get the right record if exist using both parameters.
My question is, what's wrong with using 2 parameters connected by AND?
AbstractTableGateway::select() accepts one argument, you are passing 2:
You need to pass 1, combine the 2 arrays.
Change your code to:
$rowset = $this->tableGateway->select(['Unitname' => $unitname, 'ProjectID' => $ProjectID]);
Zend table Gateways

Magento 2 : How to set product name and product price in custom email template?

I want to ask how can we set values of product name and product price in my custom email template.
$product_id = 'get id';
$model = Mage::getModel('catalog/product') //getting product model
$_product = $model->load($product_id); //getting product object for particular product id
$name = $_product->getName(); //product name
$price = $_product->getPrice(); //product's regular Price
This the way to get name and price. Now use $name and $price like this.
echo $name;
echo $price;

How can I get a subtotal by looping. Using SugarCRM CE 6.5.13

I am trying to get a total from the rows returned for the selected opportunity.
When a opportunity is selected each product they have purchased and its price is listed. I am trying to use the price for each purchased product to get a subtotal for all sales made with that opportunity.
Here is the code I have:
function total(&$focus, $event, $arguments)
{
$total = 0;
foreach ($this->bean->Product_Sales['sales_price_c'] as $entry) {
$total += unformat_number($entry['sales_price_c']);
}
$this->bean->ss->assign('total_sales_c', format_number($total));
}
Example of how rows are returned:
[Product_Name_Field] [Product_Price_Field] [Sales_Person_Field] [Etc_Field]
Only qty(1) Product sold per returned row.
What am I doing wrong?
Thanks in advance.
Okay I figured it out!!!!
This is File view.detail.php in Custom/Module/Opportunities/Views/
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
require_once('include/MVC/View/views/view.detail.php');
class OpportunitiesViewDetail extends ViewDetail {
function OpportunitiesViewDetail(){
parent::ViewDetail();
}
function display() {
$account = new Opportunity();//var = new ModuleName() in singular form
$account->retrieve($_REQUEST['record']);//This grabs the record
$contacts = $account->get_linked_beans('opportunities_op_ps_product_sales_1','Contact');
//this uses the get_linked_beans(Param 1 is the linked var name found in the vardefs ,Param 2 is the name of the object you are creating. The name can be anything you like.)
// loop through the created associations to get fields.
foreach ( $contacts as $contact ) {
$total += $contact->sales_price_c;//add the value of each sale to the variable
}
//populate the field you want with the value in the $total var
echo "
<script>
var total = '$total';
$(document).ready(function(){
$('#total_sales_c').after(total); });
</script>";
parent::display();
}
}
?>
Hopefully this will help others.

DoctrineODM Priming of Multi-Level References

Sorry for the awkward title but I have no better naming for the issue (comments on how to properly name the question are welcome).
Let's say I have 3 Documents:
Category
Product
Version
A Category has many Products. A Product has many Versions.
Now I want to Query for all Categories and list all Products and Versions of each Category.
I know about priming priming.
Is it possible to write a query like:
$qb = $dm->createQueryBuilder('Category')
->field('products')->prime(true)
->field('products.versions')->prime(true)
$query = $qb->getQuery();
Alright it seems that in the current state doctrine-odm does not support multi-level priming. This is a known issue on GitHub.
I found a solution in the GitHub Issue that passes a closure to the prime method to allow at least two level priming. Hope this helps someone.
$myPrimer = function(DocumentManager $dm, ClassMetadata $class, array $ids, array $hints) {
$qb = $dm->createQueryBuilder($class->name)
->field($class->identifier)->in($ids);
if ( ! empty($hints[Query::HINT_SLAVE_OKAY])) {
$qb->slaveOkay(true);
}
if ( ! empty($hints[Query::HINT_READ_PREFERENCE])) {
$qb->setReadPreference($hints[Query::HINT_READ_PREFERENCE], $hints[Query::HINT_READ_PREFERENCE_TAGS]);
}
$results = $qb->getQuery()->toArray();
$nestedPrimers = array(
'address' => true, // List of fields to prime
);
$uow = $dm->getUnitOfWork();
$referencePrimer = new ReferencePrimer($dm, $uow);
foreach ($nestedPrimers as $fieldName => $primer) {
$primer = is_callable($primer) ? $primer : null;
$referencePrimer->primeReferences($class, $results, $fieldName, $hints, $primer);
}
};
The Closure can the be passed to the Primer:
->field('club')->prime($myPrime)

Zend Dojo FilteringSelect from joined tables How can this be done with Doctrine

I have a number of FilteringSelect elements within my Zend Framework application that are working fine but they are based on simple queries.
I now need to create a FilteringSelect that will allow me to select the id of one table while displaying the text of field in a related table, i.e. I have two tables groomservices and groomprocedures which are related (i.e. groomprocedures.groomProceduresID has many groomservices.procedure).
The form I'm trying to create is for an appointments table which has many groomservices.groomServicesID values. I want the user to be able to see the name of the procedure while saving the value of the groomservices.groomServicesID using the FilteringSelect.
So far I've not been able to do this in that my FilteringSelect displays nothing, I'm sure this can be done just that the fault is with my inexperience with Zend,Doctrine and Dojo
I'm not sure if my problem is with my autocomplete action(including the query) or with the FilteringSelect element.
Can anyone spot where I've gone wrong in the code sections below, I need to get this working.
My autocomplete action within my controller
public function gserviceAction()
{
// disable layout and view rendering
$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender(true);
// get a list of all grooming services IDs and related procedures
$qry= Doctrine_Query::create()
->select('g.groomServicesID,p.groomProcedure')
->from('PetManager_Model_Groomservices g')
->leftJoin('g.PetManager_Model_Groomprocedures p');
$result=$qry->fetchArray();
//generate and return JSON string
$data = new Zend_Dojo_Data('g.groomServicesID',$result);
echo $data->toJson();
}
My FilteringSelect element code
// Create a autocomplete select input for the service
$gservice = new Zend_Dojo_Form_Element_FilteringSelect('gapmtService');
$gservice->setLabel('Proceedure');
$gservice->setOptions(array(
'autocomplete' => true,
'storeID' => 'gserviceStore',
'storeType' => 'dojo.data.ItemFileReadStore',
'storeParams' => array('url' => "/groomappointments/appointment/gservice"),
'dijitParams' => array('searchAttr' => 'groomProcedure')))
->setRequired(true)
->addValidator('NotEmpty', true)
->addFilter('HTMLEntities')
->addFilter('StringToLower')
->addFilter('StringTrim');
Many thanks in advance,
Graham
P.S. orgot to mention I tried the following query in mysql and I gave me what I'm looking for I believe the Doctine query evaluates to the same.
select groomservices.groomservicesID,groomprocedures.groomprocedure from groomprocedures left join groomservices on groomprocedures.groomproceduresID =groomservices.groomProcedure
But I'm not sure if I formatted the query correctly in Doctrine.
EDIT in relation to the flammon's comments
Ok I've set the code to the following but I'm still not getting anything to display.
public function gserviceAction()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContexts(array(
'gservice' => 'json'
));
// get a list of all grooming services IDs and related procedures
$qry= Doctrine_Query::create()
->select('g.groomServicesID AS id,p.groomprocedure AS name')
->from('PetManager_Model_Groomservices g')
->leftJoin('g.PetManager_Model_Groomprocedures p');
$this->view->model = (object) array();
$this->view->model->identifier = 'id';
$this->view->model->label = 'name';
$this->view->model->items = array();
$tableRows = $this->dbTable->fetchAll($qry);
foreach ($tableRows as $row) {
$this->view->model->items[] = $row->toArray();
}
}
I'm sure the fault lies with me.
It looks like there's a problem with the data that you're putting in the ItemFileReadStore.
Here are a few pointers.
Consider extending Zend_Rest_Controller for your services. It'll be easier to manage your contexts and your views. You'll be able to do something like this:
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContexts(array(
'gservice' => 'json'
));
}
And it will eliminate the need for the following in each of you service actions.
// disable layout and view rendering
$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender(true);
You'll need to either pass the format parameter or use the following plugin to help with the context switch. Passing the format parameter is simpler but it pollutes the url with ?format=json. Here's the Zend documentation on AjaxContext.
Here's a plugin that you can use if you don't want to pass the format parameter.
class Application_Plugin_AcceptHandler extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
if (!$request instanceof Zend_Controller_Request_Http) {
return;
}
$header = $request->getHeader('Accept');
switch (true) {
case (strstr($header, 'application/json')):
Zend_Registry::get('logger')->log('Setting format to json', Zend_Log::INFO);
$request->setParam('format', 'json');
break;
case (strstr($header, 'application/xml')
&& (!strstr($header, 'html'))):
Zend_Registry::get('logger')->log('Setting format to xml', Zend_Log::INFO);
$request->setParam('format', 'xml');
break;
default:
Zend_Registry::get('logger')->log('Setting format to html', Zend_Log::INFO);
break;
}
}
}
In your controller, instead of echoing the data, create view variables that dojo expects. See this document for the format.
$this->view->model = (object) array();
$this->view->model->identifier = 'id';
$this->view->model->label = 'name';
$this->view->model->items = array();
In your controller, fetch your table rows:
$tableRows = $this->dbTable->fetchAll($select);
or, if you've put model code in a function, it might look more like:
$tableRows = $this->dbTable->fetchGroomProcedures();
Put your row data in the model->items[] array:
foreach ($tableRows as $row) {
$this->view->model->items[] = $row->toArray();
}
Create a view, view/scripts/appointment/gservice.json.phtml and in it put
Zend_Json::encode($this->model)
Use Firebug to see what is returned from your service.