Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
I made a patch that expose all (almost all for now) shipping data to views.
Comment | File | Size | Author |
---|---|---|---|
#47 | package_contents_view.txt | 4.4 KB | DanZ |
#47 | package_view.txt | 6.38 KB | DanZ |
#47 | shipment_view.txt | 5.54 KB | DanZ |
#44 | ubercart_shipping_views-1911278-44.patch | 30.69 KB | DanZ |
#44 | interdiff-37-44.txt | 14.98 KB | DanZ |
Comments
Comment #1
TR CreditAttribution: TR commentedLooks like you're missing the actual handlers ...
Comment #2
SilviuChingaru CreditAttribution: SilviuChingaru commented:-) I didn't know that when I add new files to git i have to make the patch like this:
Is it the correct way?
Comment #3
SilviuChingaru CreditAttribution: SilviuChingaru commentedComment #4
DanZ CreditAttribution: DanZ commentedWonderful!
This is on my to-do list, but I have other stuff in the way. This is something that's glaringly missing from Ubercart.
Once this is done, some standard views can be added to the shipping interface, I think.
Using "git status -v" often helps when making a diff that deals with new files. Give it a try and look at the output.
I note that you don't expose packages. I'll just weigh in and say that it's important.
I would like to be able to set up a view of packages and add a Views Bulk Operations field to it. From there, I would like to bulk-print packing slips. Apart from the Views integration, this requires adding a template and an action for printing packing slips, but it's just something to keep in mind as you develop this. It would make Ubercart shipping much more practical.
Do you need separate tables for origin and destination country codes?
I think you have too many t()s here:
Some minor naming issues:
"shipment", not "user".
The 'link_to_sid' should be 'link_to_shipment'.
Comment #5
SilviuChingaru CreditAttribution: SilviuChingaru commentedPackages support added.
Comment #7
SilviuChingaru CreditAttribution: SilviuChingaru commentedFixed line endings.
Comment #9
SilviuChingaru CreditAttribution: SilviuChingaru commentedI realy don't get it... I converted all the lines to UNIX style. Another try.
Comment #10
SilviuChingaru CreditAttribution: SilviuChingaru commented#7: expose_shipping_data_to_views_with_packages-4.patch queued for re-testing.
Comment #11
SilviuChingaru CreditAttribution: SilviuChingaru commentedAnd the last one made like mentioned in Advanced patch contributor guide. Hope this one is ok.
Comment #12
DanZ CreditAttribution: DanZ commentedBravo! I wish I'd had this when I started writing the Stamps.com module.
A few more notes:
See #1884512: Make ordered products entity fieldable. I don't know much about constructing Views, but I think that this does not work for fieldable entities. Or maybe it does. Can you check?
This is not true. If an order has multiple packages, you can put some of the packages in one shipment, and some of the packages in a different shipment. In fact, this is necessary when some of the products are back-ordered.
Since this comes from the carrier, I don't think you can guarantee that it is numeric. It's a varchar(255) in the database schema. The same is true for the tracking ID.
Technically, there shouldn't even be a tracking ID on the shipment. It should be on the package. However, it's in both places in the schema....
That's not required. Any module that inserts that number can override it. Or, anyone who builds the view manually can use a rewrite rule to put in a URL.
It exists because the packages are created before the shipments are created. When there are no shipments, the packages still have to be tied to the orders.
Yes, it is essential. Unfortunately, it is not kept in the database. The weight is computed by uc_shipping_package_load() by just summing up the weight of the individual packaged products. This is incorrect, as it does not account for tare weight. Ideally, the {uc_packages} schema would include either the tare weight or the total weight.
That said, $package->weight could be put in as "total product weight".
Also, Views filters, sorts, and aggregation are based entirely on SQL. The value has to be either be in the database or have a handler that uses an SQL formula to compute the value. Anything computed with PHP doesn't work with aggregation. It should have a handler that contains this:
Comment #13
SilviuChingaru CreditAttribution: SilviuChingaru commentedYou are right about shipment, I'll make it relation to order and not expose fields directly. This way will work also for any fieldable entity, including ordered products.
Transaction should exist for order / invoice or so at the carrier, because you have one order / invoice for multiple packages. This way you can keep track of this also. You are right about transaction as string. I'll make it string.
About order_id on packages then I'll expose it as relation to order.
About package weight I think the best way is to make a handler that use a subquery directly on SQL to get weight on products and so it will not be php and will be sortable.
Comment #14
SilviuChingaru CreditAttribution: SilviuChingaru commentedComment #15
DanZ CreditAttribution: DanZ commentedThis is already done for Ordered Products. See #1876496: Calculate additional Ordered Product fields for Views. Perhaps you can use that technique. Keep in mind that it still can't calculate total weight for the package, because Ubercart still doesn't have tare weight. Call it "net weight" or "total product weight" or something like that.
Comment #16
SilviuChingaru CreditAttribution: SilviuChingaru commentedFixed: Exposed as relation so it will work for sure with entities.
Fixed: Exposed as relation so an order can have unlimited number of shipments. It will create one row for each shipment.
Fixed: Is defined as string now. My mistake I also have invoices for shipments like URG-XXXXX or DIV-XXXX.
:-))) Removed the TODO.
Fixed: There are 2 relations now, one on Order: Packages and other on Shipment: Packages. So it should work fine now for any scenario.
TODO: I did not have enaugh time to look at your code, in fact at the parent code to see how to SUM not just one product with qty but all products. Some help here will be great.
Comment #17
SilviuChingaru CreditAttribution: SilviuChingaru commentedJust to force test bot to check if everything is fine by now. Still needs work.
Comment #18
DanZ CreditAttribution: DanZ commentedSee the uc_order_handler_field_weight_total handler class for some hints. It overrides the query() method to use an SQL formula ($table.$field * $table.qty) to calculate the total weight.
Summing over all the different products in the package will require an SQL subquery. I don't know how to do that, much less with Views. I'll research it and let you know if I figure it out.
Comment #19
DanZ CreditAttribution: DanZ commentedYou still have the shipment transaction ID and tracking number fields as numeric. I also don't think you want to use 'handler' => 'uc_shipping_handler_field_sid' for the package tracking number.
This should be:
...for consistency with the definitions in uc_order_views_data().
Comment #20
SilviuChingaru CreditAttribution: SilviuChingaru commentedTODO: Because we now expose order_id or order_product_id or any other field from shipping tables used in a relationship we need to make them indexes because, if not, all querys where they are joined are very slow. Tested on mysql that scans the whole table on join. I've got querys with 40000ms exec time for a view with same records as orders but with a field that requires a relationship to any of this tables.
Also, #1785434: Ubercart is not implementing the foreign keys setting correctly in schema needs to be finished when this work is done.
The same problem seems to be present in uc_payment module where fields were exposed to views recently too.
Comment #21
SilviuChingaru CreditAttribution: SilviuChingaru commentedComment #22
DanZ CreditAttribution: DanZ commentedAs you know, Drupal 7 does not use foreign keys. You can define them in the schema, but they don't do anything. They are essentially just documentation. This may change for Drupal 8. See http://drupal.org/node/146939.
Adding an index to a table requires a schema update. db_add_index() in a hook_update_N() would do it.
Comment #23
SilviuChingaru CreditAttribution: SilviuChingaru commentedThis is almost the final patch. There are still few todo left for your consideration.
Added:
- dimensions fields;
- package weight (this cannot be based on SQL subquery because there is no way to determine in SQL weight_units for each product in package).
- indexes for uc_shipping, uc_packages and cu_packaged_products in schema.
- update indexes using hook_update_N.
Comment #24
longwaveThanks for working on this. I have a 90 minute train ride later today during which I will try and review this patch and the comments raised above.
Comment #25
SilviuChingaru CreditAttribution: SilviuChingaru commentedWith pleasure longwave. I'll always try to help where I can and when I'll have time. And by the way, thank you for hard work on maintaining this vast project!!!
Comment #26
DanZ CreditAttribution: DanZ commentedOk, I've given this an initial look.
Per hook_update_N() docs, I think this should be named uc_shipping_update_7300().
The header block comments appear on the page when update.php runs. They should be a little more descriptive, so:
Does there also need to be an index on package_id? That will be necessary for finding out what products are in a package.
Actually, it can be done. It requires converting everything to a common weight unit in SQL, which requires conversion tables and mathematical formulas. This would be some difficult code, so it might be a good idea to add add a field with that later.
Note that package length/width/height fields have the same issue.
It would be nice to have a field that combined the weight and weight unit values into one formatted display with uc_weight_format(). It would also be nice to have a field that combined the length values and dimensions into one display field. (This could be done with rewriting, but it would be nice to have.)
Gotta go. I'll review it more later.
Comment #27
SilviuChingaru CreditAttribution: SilviuChingaru commentedI think this update should be run for all upgrades of ubercart including 6.x-2.x to 7.x-4.x for example not only for 7.x-3.x, or not?! I don't know, maybe a maintainer could explain more here.
package_id is the primary key so it is already indexed.
This issue is "Expose shipping data to views" so we should keep focusing on this. It can be done but it should be done also in products. This is a very complex task and should have it's own issue. Weight untis should not be stored in db for products or any other tables. There should be an accepted standard weight unit for all weights and conversion to any other metric should be made before and after the standard weight is inserted / extracted from db.
The implementation is similar to uc_product so I don't see where is the issue here?!
Already done that. Do you mean something else?
I don't realy see the use of this because you can rewrite dimensions as you like. Anyway it is easy to implement if maintainers want to.
Comment #28
longwaveThis looks really good. I barely use the shipping module, so real-world testing from those of you that do use this would be appreciated! As this is entirely new and is very unlikely to break any existing implementations, I'm also thinking to commit this early and deal with fixes and additional feature requests in followup issues.
An updated patch and interdiff are attached, the changes are mostly string and comment fixes, plus the addition of hook_date_views_* instead of using date_views_filter_handler_simple, which I believe is the correct way to integrate Date and Views into other Drupal modules. (uc_order does use the simple handler but we can't revert this now without affecting existing users)
This looks odd, but is correct, and saves a bit of work for the translators (possibly at the expense of slightly incorrect grammar in some languages, but that doesn't really matter too much here).
As I understand it, when you use a composite primary key, the first field in the key (which here is the package_id) is automatically indexed.
I suggested this way back in #730120-15: Dimension and package quantity fields in Views but it has not yet been implemented - and as this isn't yet available for products, it's probably outside the scope of this issue. As noted, it's already possible using Views' field rewriting.
hook_update_N numbering doesn't actually matter, it's just a convention; all updates are run in order. However, using 7300 here leaves 7002 to 7099 free to allow us to fix any as-yet unidentified bugs in the 6.x to 7.x upgrade process.
Comment #29
DanZ CreditAttribution: DanZ commentedI suppose this is as good a place to bring this up as any. First, some definitions:
Ubercart only considers net weight. It gets it by adding up the weights of the products being shipped. It has no concept of gross weight or tare weight.
Shippers (UPS, Fedex, etc.) only care about gross weight. They absolutely require it for calculating shipping costs. Gross weight can be significantly different than net weight.
This is a problem, because it means that Ubercart shipping doesn't fully support any shipper. Shipping modules have to add on gross weight functionality in order to get the numbers right, as the Stamps.com module does. It really ought to be in Ubercart proper, since most shipping methods have to worry about this.
Unfortunately, fixing this is a big problem. It requires overhauling the shipping system, updating the schema to store tare or gross weight, etc. It may have to wait until D8/U4.
So why am I bringing this up here, if it won't be fixed here? Here's why: Leave room for Ubercart to do it right in the future without breaking existing views. The field that calculates the weight of all the products shouldn't be called "Weight". It should be called "Net weight". The machine name (array index) should be 'net_weight'.
Comment #30
SilviuChingaru CreditAttribution: SilviuChingaru commentedI don't see why and how tare weight will be calculated or even how ubercart should store it in db. Is simple to add a field for package and update the schema but the calculation differ from carrier to carrier so this is how I propose to implement it:
Product weight = product gross weight
You can calculate trough rules for example the tare weight. If a product has certain dimenssion you will need a diffrent box or packing materials. Also if the product has a certain weight you need a different box. All this calculations are a report of dimensions and weight right?
Uc should provide the quote via rules and we can set custom rules for every carrier based on type (fragile, regular), dimmensions and weight. In some cases also the cod value and insurance value. From those 5 factors exposed we could calculate any shipping from any courier, right?
So, why uc should store tare weight different than weight and if yes how you see this in a real life scenario? I implemented the rules calculations from here #1902622: Allow shipping quotes to use rules for shipping cost calculation and I can calculate all my shippings from interface.
Comment #31
DanZ CreditAttribution: DanZ commentedThat's an design/architecture discussion for a different issue. There are some decisions to be made.
For today, I just want you to leave room for it by calling the package net weight "Net weight", not "Weight" in Views.
Comment #32
SilviuChingaru CreditAttribution: SilviuChingaru commentedAt least, at currently state of weight in uc is confusing to name a fielde "Net Weight" when everywhere is named just "Weight". The user will ask his self "Hmmm, but where is the weight that I entered in product form? There was no net weight...".
I think that we need to build uc around what already is not around something MAYBE at some point will be and create confusions by doing so.
Comment #33
DanZ CreditAttribution: DanZ commentedWell, see the definition. "Net weight" only applies to packages. You can see net weight on products you buy at the grocery store.
I don't think that calling the net weight "Net weight" will be confusing. More importantly, it is correct. If it gets called "weight" here, that will be confusing. Is that "weight" the net weight or the gross weight? It is better to do it correctly.
You would expect "Package weight" to be the weight of the package. Well, here, it's not. It's the weight of the products in the package. So, calling it just "weight" is more confusing, because it's not true.
It could also be called "Total product weight", but that is longer. "Net weight" is the common English term for this concept.
In other news, I intend to see if I can use these views with the Stamps.com module. That module uses the package tracking number field when processing packages. It can store the value "queued" or "exported" before the package gets a shipping label. This stores the state of the shipping process for those packages. The module displays a table of all queued packages and exports their data in an XML file. It has queries to look up all the queued packages.
So, it would be useful to have an index on the tracking number field in the packages table, at least for that module. Is it worth doing adding this index here? Admins who want this to run faster can always add the index to the database manually, right?
Regardless, I'll be testing this new feature to see how it works with the Stamps.com module.
Comment #34
longwaveI have no real preference for "weight" vs "net weight" and can see arguments for both sides. However at present it seems unlikely we will implement tare weight until D8 (and perhaps even then that would be better off left to Packaging module?), we have not used the term "net weight" in Ubercart until now (consider translations), the machine name doesn't ultimately matter that much, and changing labels is possible at any point without breaking existing code, so perhaps "weight" will do for now.
Comment #35
SilviuChingaru CreditAttribution: SilviuChingaru commentedIt is easy, if we implement gross / tare weight we set that machine name tare_weight / gross_weight and let existing field as weight. Still I don't understand why uc should care about tare weight unless as package info which are 20 lines of code to implement?!
Comment #36
DanZ CreditAttribution: DanZ commentedFYI, I'll set up some views to test this new code this weekend.
Comment #37
DanZ CreditAttribution: DanZ commentedRe-rolling #28 so it will apply to current -dev.
Comment #38
DanZ CreditAttribution: DanZ commentedJust a heads-up. I've confirmed my suspicions about the hook_update_N() run sequence.
#1916806: Packages not deleted when order is deleted contains uc_shipping_update_7301(). Installing it first interferes with this patch, which contains uc_shipping_update_7300(). It prevents uc_shipping_update_7300() from running.
The two patches need to be pushed at the same time, or this one needs to be first, or the hook_update_N() numbers need to be adjusted.
Comment #39
DanZ CreditAttribution: DanZ commentedWell, here's a rather basic problem: I can't make a Shipment view or Package view.
I made a test site and created some orders, packages, and shipments. I applied the patch, and can see the new files, and the update ran. I cleared the caches. I have the Shipping module enabled. I even rebooted.
However, when I go to create a new view, I can see all sorts of options (like Content and Orders), but Shipment and Package aren't there. So, I can't create a Shipment view or a Package view.
I don't know if that's intentional or not, but package views would be very very useful for my shipping module.
I created an order view, and added a shipment relationship. I then added all the shipment fields. That worked fine.
Did the same thing with an order->packages relationship. That also worked.
I note that the names of some of the field were a little weird. I don't know if this is a Views thing.
Why is there both "(package) Package: Height (Height)" and "Package: Width (Width)"?
I'll be away from my test host until next weekend. I can run more tests then.
Comment #40
DanZ CreditAttribution: DanZ commentedThis needs lines like data['uc_shipments']['table']['base'] = array(...); to be defined. That's why shipments and packages aren't showing up as base tables.
I'm out of time for now, but I'll try to take a shot at it later if I get a chance.
Comment #41
SilviuChingaru CreditAttribution: SilviuChingaru commentedThe packages are dependent to orders. I don't think they should be defined as base. This is why I didn't defined them in first place.
Comment #42
DanZ CreditAttribution: DanZ commentedThe stamps.com shipping module would do very well with a view of packages awaiting export to XML. By the time packages get there, it doesn't need the order information. So, it's better for the packages to be the base table.
Also, I hope to make views of packages for VBO, for batch printing packing lists and/or shipping labels, exporting to stamps.com, etc. I believe that the packages have to be a base table for VBO to work on them.
In another issue, the update 7300 fails if those table indexes already exist (unlikely, but it could happen).
I'm testing a solution for both of these and trying to figure out how to make an interdiff when files are being added as part of the patch.... I'll post it when I'm done.
Comment #43
DanZ CreditAttribution: DanZ commentedI found a bug:
That's supposed to be:
Also, since it's possible to have packages without shipments, there needs to be a relationship from packages directly to orders.
I'm working on this now....
Comment #44
DanZ CreditAttribution: DanZ commentedThis patch update:
Adds a check to see if the table indexes already exist before creating them.
Establishes packages as a base table.
Establishes shipments as a base table.
Fixes the uc_packages => shipments bug mentioned in #43.
Fixes some comment language and punctuation style issues.
Adds a relationship from packages to their orders.
Adds a relationship from shipments to their orders.
Exposes the sid field to packages. This allows a link to the shipment edit page without setting up the relationship and its join.
Exposes the order_id field for packages and shipments. This allows a link to the order page without setting up the relationship and its join.
Rearranges data so that the order for each type is: group declaration, base table declaration, relationships, then fields.
Fixes the sid link handler to work with non-shipment (i.e., package) tables, so long as "order_id" is present.
I made the relationships separate declarations. I suspect that the declarations of relationships from packages to shipments and from packages and shipments to orders should have been wrapped into the declarations for the fields. This way works, though.... Should they be together or separate?
For example, I added the field for the sid to the uc_packages data. Should I have moved the relationship from packages to shipments into the declarations for that field, or just left them separate?
...and I think this interdiff will work....
Comment #45
longwaveI have only very briefly tested this but it looks good to me. If both DanZ and fiftyz are happy I think this can be committed, and any remaining bugs or features can be ironed out in followups.
I don't think this matters either way really, it's consistent whichever way you look at it and should be fine as long as we don't go changing the declarations around after people start making Views with this.
Comment #46
DanZ CreditAttribution: DanZ commentedThe only part I haven't tested yet is with the packaged products. After I or someone else test that, yes, I'd like to see it committed so I can build some new features into the stamps.com module.
One strange thing I noticed.... Why can order ID numbers be made to link to the order list page, instead of to the actual individual orders? Just curious.
Comment #47
DanZ CreditAttribution: DanZ commentedOk, I tested the packaged products, and it looks great. I'll attach the test views I used.
One thing I noticed is that the relationship to the packaged products isn't real useful, as it only gives quantity. It becomes useful when you add an additional relationship to ordered products. That also has a quantity, but it's the quantity ordered, not the quantity packaged. I guess this is the best way.
The next step is to add a field to packages that lists the contents in a simple way. There should be options for listing by SKU or product title, and for using a comma-separated list or a bullet list. It should be themable, of course. That can go into a separate issue, though.
Comment #48
longwaveCommitted to 7.x-3.x. Thanks to both fiftyz and DanZ for working on this.