| @@ -86,10 +86,15 @@ | ||
| 86 | 86 | */ |
| 87 | 87 | if ( isset( $this->item['disco_forced_qty'] ) ) { |
| 88 | 88 | $forced = max( 0, (int) $this->item['disco_forced_qty'] ); |
| 89 | 89 | $this->discounted_quantities = $forced; |
| 90 | + $amount = 0.0; | |
| 90 | 91 | |
| 91 | - return apply_filters( 'disco_final_discounted_amount', $forced > 0 ? (float) $fixed_discount : 0, 'fixed' ); | |
| 92 | + if ( $forced > 0 ) { | |
| 93 | + $amount = (float) $fixed_discount * $this->pooled_bundle_count( $forced ); | |
| 94 | + } | |
| 95 | + | |
| 96 | + return apply_filters( 'disco_final_discounted_amount', $amount, 'fixed' ); | |
| 92 | 97 | } |
| 93 | 98 | |
| 94 | 99 | $min = $this->rule['min'] ? (int) $this->rule['min'] : 0; // phpcs:ignore |
| 95 | 100 | $max = $this->rule['max'] ? (int) $this->rule['max'] : 0; // phpcs:ignore |
| @@ -180,7 +185,35 @@ | ||
| 180 | 185 | return $this->item['line_subtotal'] - $discount; |
| 181 | 186 | } |
| 182 | 187 | |
| 183 | 188 | return 0.0; |
| 189 | + } | |
| 190 | + | |
| 191 | + /** | |
| 192 | + * How many times a flat amount is charged for a pooled group. | |
| 193 | + * | |
| 194 | + * The pooled path hands this class the whole qualifying quantity on a single | |
| 195 | + * line, so the bundle count comes from that quantity rather than from a per | |
| 196 | + * line multiplier. A non recursive rule is charged once however large the | |
| 197 | + * pool; a recursive one is charged once per whole bundle in it. | |
| 198 | + * | |
| 199 | + * @param int $pooled_quantity Qualifying quantity across the pooled lines. | |
| 200 | + */ | |
| 201 | + private function pooled_bundle_count( int $pooled_quantity ): int { | |
| 202 | + if ( ! isset( $this->rule['recursive'] ) || 'yes' !== $this->rule['recursive'] ) { | |
| 203 | + return 1; | |
| 204 | + } | |
| 205 | + | |
| 206 | + $minimum = 0; | |
| 207 | + | |
| 208 | + if ( isset( $this->rule['min'] ) ) { | |
| 209 | + $minimum = absint( $this->rule['min'] ); | |
| 210 | + } | |
| 211 | + | |
| 212 | + if ( $minimum < 1 ) { | |
| 213 | + return 1; | |
| 214 | + } | |
| 215 | + | |
| 216 | + return max( 1, (int) floor( $pooled_quantity / $minimum ) ); | |
| 184 | 217 | } |
| 185 | 218 | |
| 186 | 219 | } |