include support for defining custom invoice date, due date, period begin and end

This commit is contained in:
Jon Goldberg 2019-09-18 15:43:12 -04:00
parent 51d3cedd25
commit bc15e9e42a
No known key found for this signature in database
GPG Key ID: C2D2247364F9DB13
2 changed files with 106 additions and 37 deletions

View File

@ -7,12 +7,20 @@ class CRM_Tbusainvoicegen_Timebank {
const BILLABLEMEMBERFIELD = 'custom_236';
const BILLINGPERIODFIELD = 'custom_228';
const TBCREATED = 'custom_114';
const INVOICEDATE = 'custom_244';
const DUEDATE = 'custom_245';
const PERIODBEGIN = 'custom_246';
const PERIODEND = 'custom_247';
// Local dev settings.
// const TBBILLABLEFIELD = 'custom_9';
// const BILLABLEMEMBERFIELD = 'custom_10';
// const BILLINGPERIODFIELD = 'custom_11';
// const TBCREATED = 'custom_27';
// const TBBILLABLEFIELD = 'custom_9';
// const BILLABLEMEMBERFIELD = 'custom_10';
// const BILLINGPERIODFIELD = 'custom_11';
// const TBCREATED = 'custom_27';
// const INVOICEDATE = 'custom_30';
// const DUEDATE = 'custom_31';
// const PERIODBEGIN = 'custom_32';
// const PERIODEND = 'custom_33';
/**
* Set the pricing here.
@ -59,6 +67,30 @@ class CRM_Tbusainvoicegen_Timebank {
*/
private $creationDate;
/**
* The date the invoice is generated.
* @var DateTime
*/
private $invoiceDate;
/**
* The date the invoice is due.
* @var DateTime
*/
private $invoiceDueDate;
/**
* The date the invoice period begins.
* @var DateTime
*/
private $periodBegin;
/**
* The date the invoice period begins.
* @var DateTime
*/
private $periodEnd;
/**
* An array of all the contact IDs for whom a contribution already exists in this billing period.
* @var array
@ -86,7 +118,14 @@ class CRM_Tbusainvoicegen_Timebank {
* @param str $billingPeriod The billing period (e.g "2019-2" for the second 2019 payment)
* @return array APIv3 standard response.
*/
public static function generate($cid = NULL, $billingPeriod = NULL) {
public static function generate($params) {
$cid = $billingPeriod = NULL;
if (isset($params['contact_id'])) {
$cid = $params['contact_id'];
}
if (isset($params['billing_period'])) {
$billingPeriod = $params['billing_period'];
}
self::setBillingPeriod($billingPeriod);
// Get a list of contact IDs for everyone to generate an invoice for.
$contacts = civicrm_api3('Contact', 'get', [
@ -105,6 +144,9 @@ class CRM_Tbusainvoicegen_Timebank {
continue;
}
$tb->creationDate = new DateTime($contact[self::TBCREATED]);
$tb->setInvoiceDate($params);
$tb->setDueDate($params);
$tb->setPeriodBeginEndDate($params);
$tb->setPrice();
$tb->createContribution();
}
@ -152,6 +194,18 @@ class CRM_Tbusainvoicegen_Timebank {
return $this->price;
}
/**
* Sets the due date
*/
private function setInvoiceDate($params = []) {
if (isset($params['invoice_date'])) {
$this->invoiceDate = new DateTime($params['invoice_date']);
}
else {
$this->invoiceDate = new DateTime();
}
}
/**
* If the first annual anniversary of the TB is before the billing period, then the TB pays for the full billing period (6 months).
* If the first annual anniversary of the TB is during any of the first 5 months of the billing period, then the TB pays a pro-rated fee for the number of full billing period months after the first annual anniversary of the TB (1 to 5 months).
@ -160,7 +214,7 @@ class CRM_Tbusainvoicegen_Timebank {
private function monthsProRated() {
// By default, we bill all 6 months in a billing period.
$monthsProRated = 6;
$beginDate = $this->calculatePeriodBeginDate(self::$billingPeriod);
$beginDate = $this->periodBegin;
$firstAnniversary = $this->creationDate->modify("+1 year");
$interval = $beginDate->diff($firstAnniversary);
// First anniversary is before the billing period.
@ -182,10 +236,12 @@ class CRM_Tbusainvoicegen_Timebank {
if (!$this->price) {
return;
}
$dueDate = $this->calculateDueDate(self::$billingPeriod);
civicrm_api3('Contribution', 'create', [
'financial_type_id' => 'CW License Fee',
'date_received' => $dueDate,
self::DUEDATE => $this->invoiceDueDate->format('Y-m-d'),
self::INVOICEDATE => $this->invoiceDate->format('Y-m-d'),
self::PERIODBEGIN => $this->periodBegin->format('Y-m-d'),
self::PERIODEND => $this->periodEnd->format('Y-m-d'),
'total_amount' => $this->price,
'contact_id' => $this->cid,
'contribution_status_id' => 'Pending',
@ -195,42 +251,51 @@ class CRM_Tbusainvoicegen_Timebank {
}
/**
* Returns the due date as a string.
* @return string
* Sets the due date
*/
public static function calculateDueDate($billingPeriod) {
list($year, $number) = explode('-', $billingPeriod);
if ($number == 1) {
$dueDate = $year . '-03-31';
private function setDueDate($params = []) {
if (isset($params['due_date'])) {
$this->invoiceDueDate = new DateTime($params['due_date']);
}
else {
$dueDate = $year . '-09-30';
list($year, $number) = explode('-', self::$billingPeriod);
if ($number == 1) {
$this->invoiceDueDate = new DateTime($year . '-03-31');
}
else {
$this->invoiceDueDate = new DateTime($year . '-09-30');
}
}
return $dueDate;
}
/**
* Returns the first day of the billing period as a date.
* This is to calculate the "new timebank" pro-rated value.
* @return Date
* Sets the period begin/end date.
*/
private static function calculatePeriodBeginDate($billingPeriod) {
list($year, $number) = explode('-', $billingPeriod);
if ($number == 1) {
$beginDate = new DateTime($year . '-01-01');
private function setPeriodBeginEndDate($params) {
if (isset($params['period_begin_date'])) {
$this->periodBegin = new DateTime($params['period_begin_date']);
}
else {
$beginDate = new DateTime($year . '-07-01');
list($year, $number) = explode('-', self::$billingPeriod);
if ($number == 1) {
$this->periodBegin = new DateTime($year . '-01-01');
}
else {
$this->periodBegin = new DateTime($year . '-07-01');
}
}
if (isset($params['period_end_date'])) {
$this->periodEnd = new DateTime($params['period_end_date']);
}
else {
list($year, $number) = explode('-', self::$billingPeriod);
if ($number == 1) {
$this->periodEnd = new DateTime($year . '-06-30');
}
else {
$this->periodEnd = new DateTime($year . '-12-31');
}
}
return $beginDate;
}
public static function calculatePeriod($billingPeriod) {
$beginDate = self::calculatePeriodBeginDate($billingPeriod);
$endDate = clone $beginDate;
$endDate->add(new DateInterval('P6M'))->sub(new DateInterval('P1D'));
$period = $beginDate->format('n/j/Y') . '-' . $endDate->format('n/j/Y');
return $period;
}
/**
@ -242,8 +307,7 @@ class CRM_Tbusainvoicegen_Timebank {
* @param str $billingPeriod
*/
public static function invoiceData($contactId, $billingPeriod) {
$invoiceData[0] = self::calculateDueDate($billingPeriod);
$invoiceData[1] = self::calculatePeriod($billingPeriod);
self::setBillingPeriod($billingPeriod);
$invoiceData[2] = self::calculateTotalDue($contactId);
return $invoiceData;
}

View File

@ -10,8 +10,13 @@ use CRM_Tbusainvoicegen_ExtensionUtil as E;
* @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
*/
function _civicrm_api3_invoicegen_Generate_spec(&$spec) {
$spec['contact_id']['api.required'] = 1;
$spec['contact_id']['description'] = 'Specify a timebank\'s contact ID to generate the invoice for, or leave blank to select all active timebanks.';
$spec['billing_period']['description'] = 'The year, a dash, and a 1 or 2 for the first or second half of the year. E.g. 2019-2 for 7/1/19-12/31/19.';
$spec['billing_period']['api.required'] = 1;
$spec['invoice_date']['description'] = 'Date of the invoice(s) to generate, or leave blank for today\'s date. Format as: 2019-7-25';
$spec['due_date']['description'] = 'Due date of the invoice(s), or leave blank for March 31st/September 30th (based on billing period. Format as: 2019-7-25';
$spec['period_begin_date']['description'] = 'Period begin date, or leave blank for January 1st/July 1st (based on billing period). Format as: 2019-7-25';
$spec['period_end_date']['description'] = 'Period end date, or leave blank for June 30th/December 31st (based on billing period). Format as: 2019-7-25';
}
/**
@ -24,6 +29,6 @@ function _civicrm_api3_invoicegen_Generate_spec(&$spec) {
* @throws API_Exception
*/
function civicrm_api3_invoicegen_Generate($params) {
$returnValues = CRM_Tbusainvoicegen_Timebank::generate($params['contact_id'], $params['billing_period']);
$returnValues = CRM_Tbusainvoicegen_Timebank::generate($params);
return civicrm_api3_create_success($returnValues, $params, 'Invoicegen', 'generate');
}