Latest News: (loading..)
blucollarguy

Multi_Vendor_Shipping new thread

4,998 posts in this topic

This is getting too confusing for a first attempt. I suggest we make this contribution and provide some limitations. Maybe after the first pass, we can look at enhancing this for specific instances, but I think that should come for a $price$ unless it is something that you need to do your business and you will provide your own labor. This way we can make a disclaimer that this contribution may not fit everyone's needs.

 

Something else that I am thinking is, are we too far into the shipping quote process? I mean should we be looking for some function called "getQuote($vendor['zipcode'])" that we could change to "getQuote($vendor[$i]['zipcode'])" or something like this and just call this method for each vendor's zip code we have and let the quote write out the display as normal with a line separator for each vendor? The problem is finding that specific location in the code.

Share this post


Link to post
Share on other sites

Alright, I think I am finally getting it, thanks Joey. But Dax, I still don't know how do we show the zipcodes to the ship module? I am still lost on this one piont. Maybe it is a simple code part but, man, it has been driving me crazy. The query in the classes/shopping_cart file is no problem, but then, don't we have to some how "define" the "origininfo" from here as well, so it can then be passed to the classes/shipping file and then to the ship module? I am not trying to be dense here, it seems to just come naturally. Craig :)

Share this post


Link to post
Share on other sites

I am working on a vendor shipping class that extends the original shipping class, I should have a semi working version in a day or 2. You can then see what my ideas are and it will include something like

getQuote($vendor[$i]['zipcode'])

 

By making a variable "global" you can access from any function anywhere in the script , so this is what it is doing, changing a variable and then the including modules use the changed variable you could also use $GLOBALS['origininfo'] to get the info in the modules.

Share this post


Link to post
Share on other sites
By making a variable "global" you can access from any function anywhere in the script , so this is what it is doing, changing a variable and then the including modules use the changed variable you could also use $GLOBALS['origininfo'] to get the info in the modules.

 

Dax,

 

This may be an obsolete observation, but I remember something about osCommerce having some kind of problem with registering/enabling global variables???

 

Take a look at this thread:

http://forums.oscommerce.com/index.php?&showtopic=93343

 

This might be a mute point, but I wanted to bring it to everyone's attention anyway. :rolleyes:

 

Thx,

 

-Codi

Share this post


Link to post
Share on other sites

Codi, I have read about the "register globals" problem. I believe it is, in fact no longer a real issue. It was a security issue at one point and code to not allow osC to run was used for a time. But I am pretty sure that is no longer the case since I have globals enabled on my test server at home and everything runs fine.

Dax, I will play with global variable some more, but I had tried to get it working before with no success. It could have been an issue with the older version of php that was on my live site (the globals issue) or my code was probably not right. I am in the process of changing hosts and I will now have 4.3.3 to work with out in the real world. Good luck with the code Dax, if you need anything, let us know. Craig :)

Share this post


Link to post
Share on other sites

Joey-

This is getting too confusing for a first attempt. I suggest we make this contribution and provide some limitations. Maybe after the first pass, we can look at enhancing this for specific instances, but I think that should come for a $price$ unless it is something that you need to do your business and you will provide your own labor. This way we can make a disclaimer that this contribution may not fit everyone's needs.

We must expect that we will not be able to cover every possibility, but I do think we should try to make this as complete as possible, within reason of course. And it is certainly confusing me too. But I am pretty fired up about getting this to work without having to use a separate shipping module. This ability will enable most any new ship module to be easily included for use since this code should be quite universal. Perhaps changes as to where exactly it is placed in the code, but the code itself should be useful in any other module.

 

I am a little behind on reading the posts. Just updated myself. After a conversation with Codi, I have begun to think that we will ultimately need to limit in some way the quote displayed to the customer.

 

Consider the possiblilty that there are:

order with 6 items- 1,2,3,4,5, and 6

Items 1 and 2 are from Vendor A

Item 3 from Vendor B

Items 4 and 5 from Vendor C and

Item 6 from Vendor D.

If we display a separate quote for cusotmer selection from each Vendor, which would include the shipping options enabled for each individually, this could become rather intimidating for the customer. What do you guys think?

 

Some options I have thought of:

Filter for common ship methods, and then show the customer 1 "set" of selections. For instance, UPS and FedEx are the only common ship methods to each Vendor my scenario order- Now we show a message that states something to the effect"Your order contains items that may ship from multiple locations." or whatever, and the selections available will show the TOTALS of each ship method that is common(add UPS from each Vendor and add FedEx from each Vendor).

Another option is to simply isolate one method for the quote and just add it all up to show one ship selection along with the message.

I am inclined to offering my customers shipping choices. What do you guys think? Criag :)

Share this post


Link to post
Share on other sites

Craig,

 

Now you are thinking what I was thinking, limit the scope of this project, at least initially, for all the shipping possiblities.

 

I think the display will definitely need to a whole discussion in itself (at least 2 pages worth). I have a couple of ideas for it and like you said, we have to display it so the customer completely understands what is going on and that may mean us taking our time on these details. For now I suggest that we just focus our gray matter on solving this first programming part then the display part then whatever else.

 

On the topic of registered globals, another option that is possible is to pass the order_id around or get it from the query string and use that to get whatever information we from the database again.

 

Just throwing around ideas.

 

Joey

Share this post


Link to post
Share on other sites

Well so far I have a working version of the multivendor shipping. There are a still alot of things I need to get working.

 

Right now it gets aquote for each vendor for each module. It then adds the price of each method with the other methods, from different vendors. It then displays the quote.

This all hinges on each vendor using the exact same modules, and the modules returning the same methods.

 

here is my new class

<?php

/**
* vendor_shipping.php
* 
* @version $Id$
* @copyright 2004
*/

require_once(DIR_WS_CLASSES . 'shipping.php');
define('USE_VENDOR_SHIPPING', 1); //configure in admin later
class vendorShipping extends shipping {
   function quote($method = '', $module = '')
   {
       global $total_weight, $shipping_weight, $shipping_quoted, $shipping_num_boxes, $cart, $origininfo;

       if (USE_VENDOR_SHIPPING == 1) {
           // vendor specific methodes
           $sortvendor = $this->sortProductsByVendor($cart->get_products());
           if (is_array($this->modules)) {
               foreach($sortvendor as $vendor) {
                   $origininfo = array();
                   $shipping_quoted = '';
                   $shipping_weight = '';
                   $shipping_num_boxes = 1;
                   $shipping_weight = $vendor['weight'];
                   $origininfo['zipcode'] = $vendor['vendors_ship_zip'];
                   $origininfo['country'] = $vendor['vendors_ship_country'];
                   $origininfo['state'] = $vendor['vendors_ship_state'];
                   if (SHIPPING_BOX_WEIGHT >= $shipping_weight * SHIPPING_BOX_PADDING / 100) {
                       $shipping_weight = $shipping_weight + SHIPPING_BOX_WEIGHT;
                   } else {
                       $shipping_weight = $shipping_weight + ($shipping_weight * SHIPPING_BOX_PADDING / 100);
                   } 

                   if ($shipping_weight > SHIPPING_MAX_WEIGHT) { // Split into many boxes
                       $shipping_num_boxes = ceil($shipping_weight / SHIPPING_MAX_WEIGHT);
                       $shipping_weight = $shipping_weight / $shipping_num_boxes;
                   } 

                   $include_quotes = array();

                   $include_quotes = $this->getValidVendorModules($vendor['vendors_id']);

                   $size = sizeof($include_quotes);

                   for ($i = 0; $i < $size; $i++) {
                       $quotes = $GLOBALS[$include_quotes[$i]]->quote('');
                       if (is_array($quotes)) {
                           $quotes_array[$vendor['vendors_id']][] = $quotes;
                       } 
                   } 
               } 

               if (tep_not_null($method) && substr($module, 0, 6) == 'vendor') {
                   $temp_quotes = $this->processQuotes($quotes_array); 
                   // $quotes_array = $quotes_array[$module][$method];
                   $key = array_search($module, $temp_quotes);
                   foreach ($temp_quotes as $key => $quote) {
                       if (array_search($module, $quote)) {
                           $index = $key;

                           foreach($quote['methods'] as $key3 => $value) {
                               if (array_search($method, $value)) {
                                   $index2 = $key3;
                               } 
                           } 
                       } 
                   } 

                   $quotes_array[0]['methods'][0] = $temp_quotes[$index]['methods'][$index2];
                   return $quotes_array;
               } 
           } 
           return $this->processQuotes($quotes_array);
       } else {
           return parent::quote($method, $module);
       } 
   } 

   function sortProductsByVendor($products)
   {
       foreach ($products as $product) {
           $sortvendor[$product['vendors_id']]['vendors_id'] = $product['vendors_id'];
           $sortvendor[$product['vendors_id']][] = $product;
           $sortvendor[$product['vendors_id']]['weight'] += $product['weight'];
       } 

       foreach ($sortvendor as $vendor) {
           $vendor_info_query = tep_db_query("Select * from vendors where vendors_id='" . $vendor['vendors_id'] . "'");
           $vendor_info = tep_db_fetch_array($vendor_info_query); 
           // print_r($vendor_info);
           $sortvendor[$vendor['vendors_id']] = array_merge($sortvendor[$vendor['vendors_id']], $vendor_info);
       } 
       return $sortvendor;
   } 

   function getValidVendorModules($vendorid)
   { 
       // returns the modules that the vendor ship with
       reset($this->modules);
       while (list(, $value) = each($this->modules)) {
           $class = substr($value, 0, strrpos($value, '.'));
           if ($GLOBALS[$class]->enabled) {
               $include_quotes[] = $class;
           } 
       } 
       return $include_quotes;
   } 

   function processQuotes($quotes)
   {
       $vendorlist = array_keys($quotes);
       $numvendors = count($vendorlist);

       for($i = 0;$i < $numvendors;$i++) {
           $numquotes = count($quotes[$vendorlist[$i]]);
           for($j = 0;$j < $numquotes;$j++) {
               $finalquote[$j]['id'] = 'vendor' . $j;
               $finalquote[$j]['module'] = $quotes[$vendorlist[$i]][$j]['module'];

               for($k = 0;$k < count($quotes[$vendorlist[$i]][$j]['methods']);$k++) {
                   $finalquote[$j]['methods'][$k]['id'] = $quotes[$vendorlist[$i]][$j]['methods'][$k]['id'];
                   $finalquote[$j]['methods'][$k]['title'] = $quotes[$vendorlist[$i]][$j]['methods'][$k]['title'];
                   $finalquote[$j]['methods'][$k]['cost'] += $quotes[$vendorlist[$i]][$j]['methods'][$k]['cost'];
               } 
           } 
       } 

       return $finalquote;
   } 

   function _getCheapest($quotes)
   {
       for ($i = 0, $n = sizeof($quotes['methods']); $i < $n; $i++) {
           if (isset($quotes['methods'][$i]['cost']) && tep_not_null($quotes['methods'][$i]['cost'])) {
               $rates[] = array('id' => $quotes['id'] . '_' . $quotes['methods'][$i]['id'],
                   'title' => $quotes['module'] . ' (' . $quotes['methods'][$i]['title'] . ')',
                   'cost' => $quotes['methods'][$i]['cost']);
           } 
       } 
       $cheapest = false;
       for ($i = 0, $n = sizeof($rates); $i < $n; $i++) {
           if (is_array($cheapest)) {
               if ($rates[$i]['cost'] < $cheapest['cost']) {
                   $cheapest = $rates[$i];
                   print_r($cheapest);
                   echo '<br>';
               } 
           } else {
               $cheapest = $rates[$i];
           } 
       } 
       return $cheapest;
   } 
}

 

you have to change a checkout_shipping.php

replace

// load all enabled shipping modules

  require(DIR_WS_CLASSES . 'shipping.php');

  $shipping_modules = new shipping;

with

// load all enabled shipping modules

  //## vendor shipping

  require(DIR_WS_CLASSES . 'vendor_shipping.php');

  $shipping_modules = new vendorShipping;

 

I had to make a few changes, in other places but I can't remember where, I will have to do a diff at some point.

This all depends on a few things, like the vendor id is attached to the product in the shopping cart.

I put this code here mainly to help you guys get somewhere.

Share this post


Link to post
Share on other sites

I agree Joey, and I think the display and the needs that everyone will encounter with it, will evolve into the proper solution. When we start seeing the quotes we will know quickly what we need to show our customers.

and...

Great Dax I will work with what you've given us and see if I can get some quotes.

Share this post


Link to post
Share on other sites

ALRIGHT Dax! I can follow what you have done quite well. The queries I had already written fit very nicely with your vendor class. Great job! I hope to finish my host transfer tonight or tomorrow and be testing for quotes then. But I can get the proper data to echo to my screen at points I was not able to before so I am confident you have definitely made the big break we needed. A thought about the module dependancy issue: what if we select the common modules only from the $vendor list to be used for the quote? This way, we would not have to configure each Vendor individually to use the same shippers. Since you are replacing the classes/shipping.php rather than modifying it to include the vendor class, we will need to create a "Default" Vendor in order for this to work, each product will have to have a 'vendors_id' assigned to it or there would be no quote. Is this correct?

I had thought this might be the case and had already come up with the idea of simply using the SHOP info to create 'vendor_id' '1' and populate these fields during the install from the CONFIGURATION table. We would need to change the install sql (ALTER TABLE `products` ADD `vendors_id` VARCHAR( 11 ) DEFAULT NULL ; ) to ALTER TABLE `products` CHANGE `vendors_id` `vendors_id` VARCHAR( 11 ) DEFAULT '1'. What do you guys think? This would add the STORE info to each product at install and make sure anyone could install and use this mod immediately, rather than going through their db and configuring each product before they can get quotes for everything.

I do think this is ultimately the best solution anyway since from what I have already done and what I see from Dax, we may have difficulty passing products without a 'vendors_id' to the ship module. as well as products with a 'vendors_id'. Craig :)

Share this post


Link to post
Share on other sites

Any activity lately on this puppy?

 

I'd hate to see it put to sleep.... :huh:

 

thx,

 

-Codi

Share this post


Link to post
Share on other sites

Not asleep, I personally have had a few minor emergencies crop up, but have worked with it a bit, and I think Dax has broken through the major issues. We will still need to resolve some of the display issues and create some options, but I think we are progressing well. I should be back to full attention on this issue within the next couple of days and have more to report. We will get this done, Craig :)

Edited by blucollarguy

Share this post


Link to post
Share on other sites

Craig & Co...

 

 

How are things moving forward? The silence is frightening. ;)

 

-Codi

Share this post


Link to post
Share on other sites

Codi, still working through the new class Dax offered up and trying to work out the options that will be available. My time has been a bit split with other more pressing issues, but I have been working on it. I hope to have some code for some beta testing soon, perhaps over the weekend. Stay tuned and it will come. Craig :)

Share this post


Link to post
Share on other sites

Hey Everyone:

 

I'm back from our family summer vacation, sorry for dropping off the face of the earth. Codi, I got your voice mail and called you back but it was Saturday, thanks for working so hard to keep this ball rolling.

 

Craig, whenever you get caught up just drop by again.

 

PM me if you have any issues.

 

Thanks,

 

Joey

Share this post


Link to post
Share on other sites

Joey,

 

I'll try to give you a ring sometime this weekend, if you dont mind. I believe between you and Craig, there's hope for the osComm community.

 

I've just recruited the TIGHTEST web designer that specializes in osCommerce, but her strength isnt back-end coding...mostly skin work and some module design. Anyway, we'll try to help you guys if we can!

 

thx,

 

-Codi

Share this post


Link to post
Share on other sites

BTW....

 

Our company has done a TON of code work on our site since you may have looked at it last: Click HERE

 

Thx,

 

-Codi

Share this post


Link to post
Share on other sites

Codi, Joey and I are sharing some code and we will update you when we get something to update. Craig :)

Share this post


Link to post
Share on other sites

BTW Codi, site is looking pretty good. I need to find my login info and check prices on some of your stock. Might be good! Craig :)

Share this post


Link to post
Share on other sites

I have been looking for a contribution that gives the customers a shipping price for a particular product and have the shipping method be dependent on a product. I have found a contribution for the latter but not the former...from reading this thread it seems like what you guys are working on is what I need. I wish you all good luck!

Share this post


Link to post
Share on other sites
BTW Codi, site is looking pretty good. I need to find my login info and check prices on some of your stock. Might be good! Craig 

 

Craig,

 

Glad you like the site. :) Keep me posted on your continued conversation with Joey. We all could benefit from a more intuitive shipping cost module.

 

thx,

 

-Codi

Share this post


Link to post
Share on other sites

vincenzo, this will enable you to have each product sorted by Vendor so that if you are dropshipping from multiple Vendors your shipping quotes will be accurate according to the zipcode of that particular Vendor. Does that get you away from the wall? Craig :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now