Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
CustomerValue
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
2 / 2
7
100.00% covered (success)
100.00%
1 / 1
 getSimpleCLV
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMRR
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Business\Marketing
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Business\Marketing;
16
17/**
18 * Marketing CustomerValue
19 *
20 * @package phpOMS\Business\Marketing
21 * @license OMS License 2.0
22 * @link    https://jingga.app
23 * @since   1.0.0
24 */
25final class CustomerValue
26{
27    /**
28     * Simple customer lifetime value
29     *
30     * Hazard Model
31     *
32     * @param float $margin        Margin per period (or revenue/sales)
33     * @param float $retentionRate Rate of remaining customers per period (= average lifetime / (1 + average lifetime))
34     * @param float $discountRate  Cost of capital to discount future revenue
35     *
36     * @return float
37     *
38     * @since 1.0.0
39     */
40    public static function getSimpleCLV(float $margin, float $retentionRate, float $discountRate) : float
41    {
42        return $margin * $retentionRate / (1 + $discountRate - $retentionRate);
43    }
44
45    /**
46     * Normalized measure of recurring revenue
47     *
48     * @param array $revenues    Revenues
49     * @param int   $periods     Amount of revenue periods
50     * @param float $lowerCutoff Normalization cutoff (which lower values should be ignored)
51     * @param float $upperCutoff Normalization cutoff (which upper values should be ignored)
52     *
53     * @return float
54     *
55     * @since 1.0.0
56     */
57    public static function getMRR(array $revenues, int $periods = 12, float $lowerCutoff = 0.1, float $upperCutoff = 0.0) : float
58    {
59        if ($lowerCutoff === 0.0 && $upperCutoff === 0.0) {
60            return \array_sum($revenues) / $periods;
61        }
62
63        \sort($revenues);
64
65        $sum = 0.0;
66        foreach ($revenues as $revenue) {
67            if ($revenue >= $lowerCutoff && $revenue <= $upperCutoff) {
68                $sum += $revenue;
69            }
70        }
71
72        return $sum / $periods;
73    }
74}