Skip Navigation

[Resolved] Creating Functions for Inventory Management

This support ticket is created 6 years, 6 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 48 replies, has 2 voices.

Last updated by Christian Cox 6 years, 5 months ago.

Assisted by: Christian Cox.

Author
Posts
#579639

On Item 2, I have tested and found the following:

I set up 3 Variations (A, B and C)

Parent Ticket has 10 available
Variation A with 10 available
Variation B with 5 available
Variation C with 5 available

Ok, so if I mark 2 of Variation A as sold, it will affect the Parent Ticket but not the Siblings, which is correct behaviour.
But if I mark 2 of Variation C as sold, the availability of Variation A will be reduced from 10 to 3, bringing it to the same availability as the other siblings, whereas it should have simply had 2 taken away from its value.

Might you know the cause of that?

#579665

Parent Ticket has 10 available
Variation A with 10 available
Variation B with 5 available
Variation C with 5 available

I must be confused. I was under the impression that the number of available Places across all Variations had to add up to the total number available for the parent ticket. Is that not accurate?

#579675

Ah I see, I'll try to outline it in an example, though do let me know if I need to clarify further.

So imagine that a Ticket is set up to manage the availability in a 10 berth room.
The price for a bed in the room is different depending on your age, so the Variations within the Ticket are "Under 25" and "26 and Over", allowing us to offer places at the different prices.

In the first example it doesn't matter how many people of each age group book a bed in the room, so we need to make 10 places available for each. That would make 20 places available for a room with only 10 beds, which is why we control the overall availability at the Ticket Level, so that if somebody books 2 places for the Under 25 Variation, it will influence the availability for the 26 and Over Variation too, to make sure we don't overbook.

The above functionality was already implemented in the first block of code you sent me, so achieving that isn't a problem.

In the second example, it may be that we'd like - for a room with 10 beds (the Ticket) - to make 10 places available to those Aged Over 26, but only 5 available to those aged Under 25. There are still only 10 beds, as set by the Ticket parent.
In this case, if somebody booked 2 places for the Over 26 Variation (10 available), it would not affect the amount that could be booked for the other Variation (5 available) as there will still be 8 beds remaining available in that room.

In the third example, where there are again 10 places available to those Aged Over 26 and only 5 available to those aged Under 25, somebody makes a booking for the Under 25 Variation. Now, because the number available for this Variation (5) is lower than the available number on its sibling (10), it will impact how many are available for its sibling.

In all examples, any booking made will impact the availability at the Ticket Level.

I do hope that hasn't caused more confusion!

#579715

Okay thanks, I will consider this and get back to you tomorrow with some modifications.

#579885

Updated foreach loop:

foreach ($siblingVariations as $sibling) {
    $sibVariationsAvailable = intval(get_post_meta($sibling->ID, 'wpcf-total-available-for-variation', true));
    // update the number of variations available for sibling posts
    if (
        // case 1: this sibling has more available than the total number of tickets available, so we need to update available
        $sibVariationsAvailable > ($ticketsAvailable - $soldPlaces)
        ||
        // case 2: this sibling IS the sibling being edited, so we need to update available
        $sibling->ID == $variationID
      )
    {
      // if total tickets available minus sold places is less than sibling variations available, use new total tickets available
      // otherwise, use sibling variations available reduced by number of places sold
      $newVariationsAvailable = $ticketsAvailable - $soldPlaces < $sibVariationsAvailable ? $ticketsAvailable - $soldPlaces : $sibVariationsAvailable - $soldPlaces;
      update_post_meta($sibling->ID, 'wpcf-total-available-for-variation', $newVariationsAvailable);
    }
  }

Try this out and let me know if there are other edge cases we need to consider.

#579896

Ok, just run a couple of texts with results as follows...

Ticket Parent availability was 10

I set up 3 siblings to that Ticket...

Variation A (1 Available)
Variation B (6 Available)
Variation C (10 Available)

Test 1: Making a booking for 2 of Variation C
Result: Parent Ticket Availability was affected but Sibling availability was not - this is correct behaviour.

Test 2: Making a booking for 3 of Variation B
Result: Availability was updated correctly for the Ticket Parent and the sibling with higher availability
Issue: The Variation the booking was made against had only 1 taken away from its own availability, whereas it should have been reduced by 3

Test 3: Making a booking for 1 of Variation A
Result: Availability for Ticket Parent and all siblings was correctly updated

So, the only issue found appears in Test 2

#579988

Okay one more adjustment here to fix that issue:

foreach ($siblingVariations as $sibling) {
    $sibVariationsAvailable = intval(get_post_meta($sibling->ID, 'wpcf-total-available-for-variation', true));
    // update the number of variations available for sibling posts
    if (
        // case 1: this sibling has more available than the total number of tickets available, so we need to update available
        $sibVariationsAvailable > ($ticketsAvailable - $soldPlaces)
        ||
        // case 2: this sibling IS the sibling being edited, so we need to update available
        $sibling->ID == $variationID
      )
    {
      // if total tickets available minus sold places is less than sibling variations available, use new total tickets available
      // otherwise, use sibling variations available reduced by number of places sold
      $reducedTickets = $ticketsAvailable - $soldPlaces;
      $reducedVariations = $sibVariationsAvailable - $soldPlaces;
      $newVariationsAvailable = $reducedTickets < $reducedVariations ? $reducedTickets : $reducedVariations;
      update_post_meta($sibling->ID, 'wpcf-total-available-for-variation', $newVariationsAvailable);
    }
#580031

Fantastic, as far as I can tell so far this has done the trick, I'll keep on at it to see if theres any other issues appear.

I have a quick question on getting grandparent, great grandparent data etc.
(again, do suggest another ticket if you think that's best)

To get the Vessel, Voyage and Tickets for a Booking I have the following Content Templates...

[wpv-post-body view_template="view-booking-grandparent-great-grandparent-and-great-great-grandparent" id="$ticket-variation"]

The above then contains these...

[wpv-post-body view_template="view-booking-grandparent" id="$ticket-variation"]
[wpv-post-body view_template="view-variation-grandparent-and-great-grandparent" id="$ticket"]

The first problem I have is that, as far as I can tell, if I want to have two different formats of how the Great-great-grandparent is presented, I need to create 3 more content templates to do so.

The second problem is that I can't quite figure out how to display a post title and link for the great-great-grandparent without also having to show the title of the great-grandparent and also the grandparent. I imagine it's possible with the content template setup, but it would require many many new templates to be made for each individual requirement.

Now, I wonder if it's possible to access each ancestor individually though php, and then create a custom shortcode for each so that I can arrange and format them freely on the Booking page? I'd likely then do the same for each other post type where required.

Do you think that would be a better solution?

If this is possible, it may be the method we use to get the data for reports also as I found an export plugin that allows for php functions.

#580035

The first problem I have is that, as far as I can tell, if I want to have two different formats of how the Great-great-grandparent is presented, I need to create 3 more content templates to do so.
Depending on the logic used to determine which of the 3 formats should be applied to the ancestor, you might be able to use conditional HTML in a single Content Template:
https://toolset.com/documentation/user-guides/conditional-html-output-in-views/
If you'd like to explore in more detail, please create a separate ticket for conditional HTML requirements. Thanks!

Now, I wonder if it's possible to access each ancestor individually though php, and then create a custom shortcode for each so that I can arrange and format them freely on the Booking page
If you can create a custom shortcode that returns the numeric ID of a specified-level ancestor, then you can use that as a post ID filter for any View - see "passing arguments into Views" here:
https://toolset.com/documentation/user-guides/passing-arguments-to-views/

[wpv-view name="some-view-slug" ids="[your-custom-shortcode]"]

This would give you the flexibility to use a View's output area to display lots of different information about an ancestor post, using Types fields or Views shortcodes. Or, you could create a custom shortcode that returns a simple title and link instead. It's up to you, I can see pros and cons for each approach here.

#580051

Okay, so on the php route, I've managed to create a shortcode for the grandparent, but the great-grandparent one (second section of code below) doesn't seem to work - it outputs the text but not the $voyage_id element.

Now, again I'm not the best at php, I surprised myself when the first block worked first time, but can you advise eon if this is the correct approach, and if you know what the issue is with accessing the great-grandparent?

add_shortcode( 'booking_view-ticket', 'booking_grandparent_shortcode' );

function booking_grandparent_shortcode() {
	$booking_id = get_the_ID();
        $variation_id = get_post_meta(get_the_ID(), '_wpcf_belongs_ticket-variation_id', true);
	$ticket_id = get_post_meta(get_the_ID($variation_id), '_wpcf_belongs_ticket_id', true);

	return 'This booking is for the ticket:' . $ticket_id . ' ';
}
add_shortcode( 'booking_view-voyage', 'booking_great_grandparent_shortcode' );

function booking_great_grandparent_shortcode() {
	$booking_id = get_the_ID();
        $variation_id = get_post_meta(get_the_ID(), '_wpcf_belongs_ticket-variation_id', true);
	$ticket_id = get_post_meta(get_the_ID($variation_id), '_wpcf_belongs_ticket_id', true);
	$voyage_id = get_post_meta(get_the_ID($ticket_id), '_wpcf_belongs_voyage_id', true);

	return 'This booking is for the voyage:' . $voyage_id . ' ';
}

Also, when creating a shortcode like this, does it need a closing tag? e.g. [booking_view-ticket][/booking_view-ticket]

#580262

I don't think these shortcodes need closing tags because you're not passing anything into the shortcode. Here's what I'm noticing:

$booking_id = get_the_ID();
$variation_id = get_post_meta(get_the_ID(), '_wpcf_belongs_ticket-variation_id', true);
$ticket_id = get_post_meta(get_the_ID($variation_id), '_wpcf_belongs_ticket_id', true);

When you call get_the_ID(), you get the numeric ID of the current post in the loop. So $booking_id = get_the_ID() will work only in a Booking post. If you want to make this shortcode more flexible, pass the Booking post ID into the shortcode as an argument.

The get_the_ID() function returns an ID, so get_the_ID($variation_id) is redundant - you already know the variation ID is $variation_id.

$variation_id = get_post_meta($booking_id, '_wpcf_belongs_ticket-variation_id', true);
$ticket_id = get_post_meta($variation_id, '_wpcf_belongs_ticket_id', true);
#580324

Ok great, that appears to be working now, though only with [booking_view-ticket /] or [booking_view-ticket][/booking_view-ticket] otherwise some of the page won't render.

So I'm using the following to get the Voyage Name to appear as a link to the voyage and I wonder, is it possible to switch the link element on or off via a shortcode attribute or should I be making a separate shortcode if I don't want to have the URL present in a specific cases?

 function booking_great_grandparent_shortcode() {
	$booking_id = get_the_ID();
	$variation_id = get_post_meta($booking_id, '_wpcf_belongs_ticket-variation_id', true);
	$ticket_id = get_post_meta($variation_id, '_wpcf_belongs_ticket_id', true);
	$voyage_id = get_post_meta($ticket_id, '_wpcf_belongs_voyage_id', true);
	$voyage_name = get_post_meta($voyage_id, 'wpcf-voyage-name', true);
	$voyage_url = get_permalink($voyage_id);

	return '<a href=".$voyage_url.">' .$voyage_name. '</a>';
 }
 add_shortcode( 'booking_view-voyage', 'booking_great_grandparent_shortcode' );
#580365

I think adding an attribute to your shortcode that lets you determine whether to return a formatted link or just the name is a great idea. Use conditionals to set the values of two different variables like $prefix and $suffix, and build your output string with those variables and $voyage_name:

$prefix = "";
$suffix = "";
if ( your conditional code here ) {
  $prefix = "<a href...";
  $suffix = "</a>";
}
return $prefix . $voyage_name . $suffix;
#581071

Great, I have got the above working with the code below...

// Create shortcode to output the Voyage name for a Booking with option of including url link to voyage
function booking_great_grandparent_shortcode($atts) {
   $booking_id = get_the_ID();
   $variation_id = get_post_meta($booking_id, '_wpcf_belongs_ticket-variation_id', true);
   $ticket_id = get_post_meta($variation_id, '_wpcf_belongs_ticket_id', true);
   $voyage_id = get_post_meta($ticket_id, '_wpcf_belongs_voyage_id', true);
   $voyage_name = get_post_meta($voyage_id, 'wpcf-voyage-name', true);
   $voyage_url = get_permalink($voyage_id);
   shortcode_atts( array(
    'url' => 'true',
), $atts );
   $prefix = "";
   $suffix = "";
   if ('true' == $atts['url']) {
     $prefix = "<a href=".$voyage_url.">";
     $suffix = "</a>";
   } 
   return $prefix . $voyage_name . $suffix;

//   return '<a href=".$voyage_url.">' .$voyage_name. '</a>';
}
add_shortcode( 'booking_view-voyage', 'booking_great_grandparent_shortcode' );

Now because the Ticket and Variation CPT titles are stored as a taxonomy (so that the user can add new ones as they wish and use select fields in the forms) I need to figure out how to get the taxonomy title (without archive link) to show in a similar way as the above.

I have tried the following but with no luck...

 function booking_grandparent_shortcode() {
	$booking_id = get_the_ID();
        $variation_id = get_post_meta($booking_id, '_wpcf_belongs_ticket-variation_id', true);
	$ticket_id = get_post_meta($variation_id, '_wpcf_belongs_ticket_id', true);
	$ticket_taxonomy = do_shortcode($ticket_id, '[wpv-post-taxonomy type="ticket-type" format="name"]');

	return 'This booking is for the ticket:' . $ticket_taxonomy . ' ';
 }
 add_shortcode( 'booking_view-ticket', 'booking_grandparent_shortcode' );
#581230

I wouldn't try to use do_shortcode here. I would use the standard WP function wp_get_post_terms.
https://codex.wordpress.org/Function_Reference/wp_get_post_terms
Example:

$term_list = wp_get_post_terms($ticket_id, 'ticket-type');
foreach($term_list as $term_single) {
echo $term_single->name . ' '; // modify this if necessary
}
This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.