Jump to content

Sort children by the sum of two fields


diegonella
 Share

Recommended Posts

Hi all

I'm making a list of products and need to sort by price, the problem is that I have on one side the net and on the other the VAT percentage and this percentage can be changed by making products in the list of the final price, display incorrectly.

For example:

Title: Product A

- Field: Price: 100

- Field: VAT: 21%

Title: Product B

- Field: Price: 101

- Field: VAT: 10.5%

By making a list, sorted by price ASC, shows

Product A ........................ $ 121.00

Product B ........................ $ 111.60

As I can do to make sort = price + VAT

Thank you!

Link to comment
Share on other sites

There's no "easy" way. There this new module by Ryan, http://modules.proce...eldtype-concat/ but that isn't for this case and use in find().

But you could find the pages and foreach the resulting PageArray, then cycle them and calculate the prices and store them to the page temporarely. Then sort by that property. For example:

foreach($products as $p) {
   $p->endprice = $p->price + ($p->price / 100 * $p->vat);
}

foreach($products->sort("-endprice") as $p) {
   echo $p->endprice;
}

You could make a module that creates a function to $pages, so you could use $pages->findProducts();. Or have an php include with functions that you can use the above with a simple call like "echo getProductsList();" in your templates

  • Like 2
Link to comment
Share on other sites

If the number of products isn't large (say less than 100) then the best way is probably to sort them in memory like the way Soma mentioned. But if you need something that can scale infinitely, then you'd want to keep your endprice as a field on the page that you can use for sorting directly from the $pages->find() query. Perhaps as a hidden field that is automatically populated via Pages::saveReady hook. It would be fairly easy to implement, let us know if you'd like an example.

  • Like 1
Link to comment
Share on other sites

Let's try with a couple of pointers and such first.

Take a look at site/modules/HelloWorld.module (included with default installation) for an example of an autoload module and hooking methods - example 1 is really close to what you need. As Ryan said, you're aiming for Pages::saveReady with your hook. See http://wiki.processw...Module_Creation for more details on creating modules. This information should be enough to make an autoload module of your own, and have some method there run every time a page is saved.

Of course you also need a field for the total price. Create a new field and set its visibility to hidden. Save the field once first to see this option in input tab. Then just add it to your product template.

Getting further, you'd probably want to do your magic only for pages with the product template. And sanitize the price and vat before any calculations. You can set fields for the page in your hook like this (and they get saved magically):

$page->nameOfYourField = "this is the value";

Now just go and try to create the module. :)

. . .

And now that you've tried and got it actually working (right? ;) ), you can see an example of a working module here: https://gist.github.com/4462130. This calculates the area of a box with given width and height on a page with certain template - sounds a bit familiar, doesn't it?

  • Like 3
Link to comment
Share on other sites

  • 10 months later...

What kind of field do I have to use if I want to sort by price?

If I use a textfield, I can use commas, but it will not sort correctly.

If I use an integer field, I somehow cannot use a comma... Is there somewhere an option to have the possibility to use commas in the integer field and avoid the behaviour that the value is truncated to a vaklue without comma?

Or is there another possibility to sort by price like follow, without having to enter "Euro" and "Cent" seperately:

569,00

799,00

799,50

850,00

900,00

Link to comment
Share on other sites

Well isn't that pretty much by the definition of an integer not to have decimals? ;)

:-[

Try using fieldtype Float for the price instead, that should solve your problem I think.

This works fine - just have to find out how I can display the prices than always with all decimals.

At the moment prices will be dispayed like this:

33

69.5

599

I would like to have:

33.00

69.50

599.00

Or best would be with "," instead of the point

Or would there be another possibility to sort prices like described above?

Link to comment
Share on other sites

I have set the "Number of decimal digits to round to" to 7 - this should be correct to make prices possible up to 99999.99 - but it always rounds the zeros away, so I would need a method to display the integer in a different format.

Just couldn't find any information about this in the API or in the forum.

Link to comment
Share on other sites

Fieldtype Float lacks the possibility to specify output format at the moment (see https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeFloat.module#L56).

But of course you can use number_format() yourself wherever you're outputting prices:

echo number_format($page->price, 2, ',', ' '); 

This gives "12 345,67" for the value 12345.67.

If you've got several places where this field is being used (and/or several price fields), another option would be yet another hidden text field for storing the formatted value when the page is being saved.

I have set the "Number of decimal digits to round to" to 7 - this should be correct to make prices possible up to 99999.99, right?

Nope :). That option is to specify how many digits are being saved after the decimal separator, not before it. See http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html for the limits of float in the database - I don't think they will be an issue here.

  • Like 1
Link to comment
Share on other sites

Nope :). That option is to specify how many digits are being saved after the decimal separator, not before it. See http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html for the limits of float in the database - I don't think they will be an issue here.

Once again:  :-[

Fieldtype Float lacks the possibility to specify output format at the moment (see https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeFloat.module#L56).

But of course you can use number_format() yourself wherever you're outputting prices:

echo number_format($page->price, 2, ',', ' '); 

This gives "12 345,67" for the value 12345.67.

If you've got several places where this field is being used (and/or several price fields), another option would be yet another hidden text field for storing the formatted value when the page is being saved.

Absolute fantastico - thanks a lot, nik!

Link to comment
Share on other sites

  • 7 months later...

this just saved me

This thread just keeps saving bacons.

Just applied this solution to sort images by their aspect ratio so the layout looks better (client request):

foreach ($koneet as $kone)
{    
    $kone->aspectratio = $kone->images->first()->width / $kone->images->first()->height;
}

The field aspectratio is type float, hidden in the form so the client won't even know it's there.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...