30, '49' => 60, '79' => 90, '119' => 160, '149' => 200, '199' => 240, '249' => 340, '349' => 440, '499' => 590, '749' => 880, '1000' => 1200, '9999999' => 9999, ]; /** * The contact ID of this timebank. * @var int */ private $contactId; /** * The number of billable members. * @var int */ private $memberCount; /** * The price for one period of this timebank. * @var float */ private $price; /** * An array of all the contact IDs for whom a contribution already exists in this billing period. * @var array */ public static $contributionExists = []; /** * A string that represents the current billing period - e.g. "2019-2". * First number is the year; second is 1 for Jan-Jun, 2 for Jul-Dec. * @var string */ public static $billingPeriod = NULL; /** * Class constructor. */ public function __construct($cid, $memberCount) { $this->cid = $cid; $this->memberCount = $memberCount; } /** * Generate invoices (called from API). * @param int $cid * @return array APIv3 standard response. */ public static function generate($cid = NULL, $billingPeriod = NULL) { self::setBillingPeriod($billingPeriod); // Get a list of contact IDs for everyone to generate an invoice for. $contacts = civicrm_api3('Contact', 'get', [ 'return' => ["id", self::BILLABLEMEMBERFIELD], 'contact_id' => $cid, 'contact_type' => 'Organization', self::TBBILLABLEFIELD => 1, 'options' => ['limit' => 0], ])['values']; self::setContributionExists(); foreach ($contacts as $k => $contact) { if (!in_array($k, self::$contributionExists)) { $tb = new CRM_Tbusainvoicegen_Timebank($k, $contact[self::BILLABLEMEMBERFIELD]); $tb->setPrice(); $tb->createContribution(); } } } public static function setBillingPeriod($billingPeriod) { if ($billingPeriod) { self::$billingPeriod = $billingPeriod; } else { // Should we try to auto-calculate it here? Or nah? } } /** * Generate an array of contacts who already have a contribution created in this billing period. */ public static function setContributionExists() { $existing = []; $result = civicrm_api3('Contribution', 'get', [ self::BILLINGPERIODFIELD => self::$billingPeriod, ]); if ($result['count']) { foreach ($result['values'] as $contrib) { $existing[$contrib['contact_id']] = $contrib['contact_id']; } } self::$contributionExists = $existing; } private function setPrice() { if ($this->price) { return $this->price; } $adjustedMemberCount = $this->memberCount - 2; foreach ($this->priceArray as $members => $cost) { if ($adjustedMemberCount <= $members) { $this->price = $cost; break; } } return $this->price; } private function createContribution() { $dueDate = $this->calculateDueDate(); civicrm_api3('Contribution', 'create', [ 'financial_type_id' => 'CW License Fee', 'date_received' => $dueDate, 'total_amount' => $this->price, 'contact_id' => $this->cid, 'contribution_status_id' => 'Pending', self::BILLINGPERIODFIELD => self::$billingPeriod, ]); } /** * Returns the due date as a string. * @return string */ private function calculateDueDate() { list($year, $number) = explode('-', self::$billingPeriod); if ($number == 1) { $dueDate = $year . '-03-31'; } else { $dueDate = $year . '-09-30'; } return $dueDate; } }