News:

You may pay someone to create your store, or you visit our seminar and become a professional yourself with the silver certification

Main Menu

Getting a full product price list for customer, from back end

Started by bcohen0, September 02, 2017, 07:12:42 AM

Previous topic - Next topic

bcohen0

Hello - I need a full price list output capability, for employees to generate for customers. This is a very common need for businesses which maintain accounts, or do quotes for supply. This needs to be accurate as the cart would be, taking into account all markup, discount, specials, etc.

It looked to me like the best way to do this is through the calculationHelper, using the method getProductPrices. However, calculationHelper can only work off the currently logged in user and it can't take an alternate user. It keeps a copy of the instance of itself, which it returns in further queries.  If it were possible to pass in a user and instantiate an independent copy of calculationHelper, then it can be used to generate a price sheet for a particular customer and then released.   To do this, modifications to take a user object (or userid) need to be made in the constructor, the method getInstance, and setShopperGroupIds. Country id also must be set, or the prices will not be preserved by the getProductPrices method.

In an effort not to change the virtuemart code, after testing the above changes, I instead created a php extension of the helper class calculationHelper. It's pretty small, and uses the base class getProductPrices method.  I have to duplicate the whole constructor because it's private in the base class. Anyhow, here is the extension class:


class calculationHelper2 extends calculationHelper
{
   private function __construct($user)
   {

      $this->_db = JFactory::getDBO();
      $this->_app = JFactory::getApplication();
      //$this->_cart =& VirtuemartCart::getCart();
      //We store in UTC and use here of course also UTC
      $jnow = JFactory::getDate();
      $this->_now = $jnow->toSQL();
      $this->_nullDate = $this->_db->getNullDate();

      $this->productVendorId = 1;

      if (!class_exists('CurrencyDisplay')) require(VMPATH_ADMIN . DS . 'helpers' . DS . 'currencydisplay.php');
      $this->_currencyDisplay = CurrencyDisplay::getInstance();
      $this->_debug = false;

      if(!empty($this->_currencyDisplay->_vendorCurrency)){
         $this->vendorCurrency = $this->_currencyDisplay->_vendorCurrency;
         $this->vendorCurrency_code_3 = $this->_currencyDisplay->_vendorCurrency_code_3;
         $this->vendorCurrency_numeric = $this->_currencyDisplay->_vendorCurrency_numeric;
      }


      $this->setShopperGroupIds(0, 1, $user);

      $model = VmModel::getModel('user');
      $model->setId($user->id);
      $virtuemart_userinfo_id_BT = $model->getBTuserinfo_id();

      $dataT = $model->getTable('userinfos');
      $data  = $dataT->load($virtuemart_userinfo_id_BT);
      if (!empty($data->virtuemart_country_id))
         $this->_deliveryCountry = $data->virtuemart_country_id;

      $this->setVendorId($this->productVendorId);

      $this->rules['Marge'] = array();
      $this->rules['Tax']    = array();
      $this->rules['VatTax']    = array();
      $this->rules['DBTax'] = array();
      $this->rules['DATax'] = array();

      //round only with internal digits
      $this->_roundindig = VmConfig::get('roundindig',FALSE);

   }

   protected function setShopperGroupIds($shopperGroupIds=0, $vendorId=1, $customUser=null) {

      if (!empty($shopperGroupIds)) {
         $this->_shopperGroupId = $shopperGroupIds;
      } else {
         $user = $customUser;

         $this->_shopperGroupId = array();
         if (!empty($user->id)) {
            $this->_db->setQuery('SELECT `usgr`.`virtuemart_shoppergroup_id` FROM #__virtuemart_vmuser_shoppergroups as `usgr`
                              JOIN `#__virtuemart_shoppergroups` as `sg` ON (`usgr`.`virtuemart_shoppergroup_id`=`sg`.`virtuemart_shoppergroup_id`)
                              WHERE `usgr`.`virtuemart_user_id`="' . $user->id . '" AND `sg`.`virtuemart_vendor_id`="' . (int) $vendorId . '" ');
            $this->_shopperGroupId = $this->_db->loadColumn();
            if (empty($this->_shopperGroupId)) {

               $this->_db->setQuery('SELECT `virtuemart_shoppergroup_id` FROM #__virtuemart_shoppergroups
                        WHERE `default`="'.($user->guest+1).'" AND `virtuemart_vendor_id`="' . (int) $vendorId . '"');
               $this->_shopperGroupId = $this->_db->loadColumn();
            }
         }
         if(!$this->_shopperGroupId) $this->_shopperGroupId = array();
         $shoppergroupmodel = VmModel::getModel('ShopperGroup');
         $site = JFactory::getApplication ()->isSite ();
         $shoppergroupmodel->appendShopperGroups($this->_shopperGroupId,$user,$site,$vendorId);
      }
   }


   static public function getInstance($user)
   {
      if (!empty($user))
      {
         $customInstance = new calculationHelper2($user);

         return $customInstance;
      }
      else
      {
         return null;
      }

   }
}


I guess I'm not sure what I expect from this post. The above works, but it would be better if Virtuemart could do a customer price list. If it can, and I've just missed it, let me know.

Oh, and I forgot to mention the other drawback of doing it this way, which is that getting the product list ends up going through the very same price calculations using the logged in user, and the existing calculationHelper.  Then afterward, I have to create the new calculationHelper2 with the correct user, and redo all the price calculations. It works, but I hate having to do this twice.



GJC Web Design

#1
Is this not what the "Allow Administrators to change the current Shopper" setting is for

When enabled .. if u login the FE as the admin you can choose what user you want the cart to display as -- the prices will all be as if the "user" was logged in

------ oops------- just saw you wanted this from the BE

the http://www.artio.net/faqs/vm-invoice can create new orders as existing customers with all the SG restrictions, shipping etc
GJC Web Design
VirtueMart and Joomla Developers - php developers https://www.gjcwebdesign.com
VM4 AusPost Shipping Plugin - e-go Shipping Plugin - VM4 Postcode Shipping Plugin - Radius Shipping Plugin - VM4 NZ Post Shipping Plugin - AusPost Estimator
Samport Payment Plugin - EcomMerchant Payment Plugin - ccBill payment Plugin
VM2 Product Lock Extension - VM2 Preconfig Adresses Extension - TaxCloud USA Taxes Plugin - Virtuemart  Product Review Component
https://extensions.joomla.org/profile/profile/details/67210
Contact for any VirtueMart or Joomla development & customisation

bcohen0

That's interesting, I hadn't thought of going for a full-on invoice extension. 

I'm pretty new to Virtuemart 3, and I hadn't tried out front end admin. So when I try to login as super user in the front end I discover that the template I'm using gets an exception. :/    Ah well.

GJC Web Design

QuoteSo when I try to login as super user in the front end I discover that the template I'm using gets an exception. :/    Ah well.

Yes.. you have discovered that there are some very badly coded templates out there.... 
You should do this sort of experimentation with the stock templates (Beez or Protostar)
then u know the standard VM template files are being used.. then go kick the template wally
GJC Web Design
VirtueMart and Joomla Developers - php developers https://www.gjcwebdesign.com
VM4 AusPost Shipping Plugin - e-go Shipping Plugin - VM4 Postcode Shipping Plugin - Radius Shipping Plugin - VM4 NZ Post Shipping Plugin - AusPost Estimator
Samport Payment Plugin - EcomMerchant Payment Plugin - ccBill payment Plugin
VM2 Product Lock Extension - VM2 Preconfig Adresses Extension - TaxCloud USA Taxes Plugin - Virtuemart  Product Review Component
https://extensions.joomla.org/profile/profile/details/67210
Contact for any VirtueMart or Joomla development & customisation

Milbo

There is no need to extend the calculationhelper.

The correct way is to enhance the product model or just to add an extra helper. then the shoppergroups (as you did) and a normal getProduct list, plus getProduct with prices, for example. Just a level higher.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/