CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • PledgePayment API
Pages: [1] 2

Author Topic: PledgePayment API  (Read 3315 times)

SarahG (FountainTribe)

  • Ask me questions
  • ****
  • Posts: 782
  • Karma: 29
  • CiviCRM version: 4.4.7
  • CMS version: Drupal 6, Drupal 7
  • MySQL version: 5.5
  • PHP version: 5.3
PledgePayment API
April 09, 2011, 04:50:33 am
I have backported the v3 API into CiviCRM version 3.3.5.


I am using the API  "  civicrm_api('PledgePayment','Create', $pledge_payment_parms )

In many cases this works fine, such as when the original pledge was for $1500. and the pledge payment is $1500. 

However, in the case where the original pledge was for $1500, and the pledge payment was only $1000 then the "pledge status" is incorrectly changed to "completed even though there is a balance of $500.   

Worse yet, there is no way to record a $500 payment using the user interface.

Any ideas?
Did I help you? Please donate to the Civi-Make-It-Happen campaign  CiviCRM for mobile devices! 

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: PledgePayment API
April 09, 2011, 08:17:09 pm
Hi,

I have only used the pledge payment api for the situation where the original payment plan is adhered to - you are dealing with a situation where it changes 'on-the-fly'?
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

SarahG (FountainTribe)

  • Ask me questions
  • ****
  • Posts: 782
  • Karma: 29
  • CiviCRM version: 4.4.7
  • CMS version: Drupal 6, Drupal 7
  • MySQL version: 5.5
  • PHP version: 5.3
Re: PledgePayment API
April 09, 2011, 08:30:50 pm
My situation is that I have written a batch import script that calls the Pledge, Contributions, and PledgePayment APIs in order to get all the data loaded.

Unfortunately there is no "schedule" in the data that I am trying to load.

I have tried 2 approaches:
a)  In the batch script, I create the pledge for the full amount with a schedule of 1 installment.    When the payment(s) get applied in my script, the pledge balance is accurate, but the pledge status is "complete" and there is no means of using the UI to make the next payment.

b) In the batch script, I create the pledge for the full amount with a schedule of 4 installments. When the payments get applied in my script, the balance is accurate, but the remaining installment(s) amount are not adjusted.  Worse, even for pledges that are paid in full CiviCRM still shows 3 remaining overdue installments.






« Last Edit: April 09, 2011, 08:43:05 pm by sgladstone »
Did I help you? Please donate to the Civi-Make-It-Happen campaign  CiviCRM for mobile devices! 

SarahG (FountainTribe)

  • Ask me questions
  • ****
  • Posts: 782
  • Karma: 29
  • CiviCRM version: 4.4.7
  • CMS version: Drupal 6, Drupal 7
  • MySQL version: 5.5
  • PHP version: 5.3
Re: PledgePayment API
April 10, 2011, 06:40:43 pm
I found a solution to my issue, although it required modifying the implementation for the PledgePayment API.

Step 1)  I updated the PledgePayment API function called "civicrm_api3_pledge_payment_create"

I removed the 'contribution_id' from the list of mandatory fields as follows:

 //  civicrm_apto i3_verify_mandatory($params,null,array('pledge_id','status_id', 'contribution_id'));
   
civicrm_api3_verify_mandatory($params,null,array('pledge_id','status_id'));

Step 2)

I updated my batch script so that immediately after applying a completed contribution as a completed pledge payment, I check how much money is still owed toward the pledge.   If there is any money still owed, I call the API to create a new pledge payment, this time the status is "pending" and the contribution id is null.

Seems like "step 2" should be internal to the API.  If a developer does not do step 2, there is a good chance of ending up with a pledge in an invalid condition. ( ie money is owed against the pledge, yet the status is "completed" and there is no way to record the final payment. )


Did I help you? Please donate to the Civi-Make-It-Happen campaign  CiviCRM for mobile devices! 

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: PledgePayment API
April 11, 2011, 05:31:21 pm
I had a talk with Dave G on IRC about this. It seems that there are 2 possible desired behaviours for the pledge_payment_create api when no pledge_payment id is passed in

1) load the oldest unpaid pledge against the api and update that (this is current behaviour & what I would expect it to be doing)
2) create a new pledge payment against the pledge - this is what you want

I think either is a valid use of the api & am leaning towards introducing another param such as $params['create_new'] =1 to indicate the second behaviour.

However, this being the Api team nothing is done without a lively debate over a warm beer - Europe team - speak up now
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Dave Greenberg

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 5760
  • Karma: 226
    • My CiviCRM Blog
Re: PledgePayment API
April 11, 2011, 05:39:47 pm
It makes sense to me to keep the api quite granular and not make lots of assumptions. For your use case of actual payment != scheduled amount, I think the following sequence make sense and would be good to support via the api:

1. Call pledge_payment_create w/ the pledge_id, contribution_id and actual payment amount (if different from scheduled amount). This results in completed pledge payment for actual amount paid. I think the api currently supports this step.

2. If you want to update the next payment to reflect remainder - call pledge_payment_create w/ id of next due pledge_payment. Pass update payment_amount, and do not pass contribution_id. This should update amount of next due payment only. This requires changing the api to make contribution_id NOT required as you've done.

2a. If you want to modify total pledge amount instead, then (hopefully) you can do that w/ the pledge api.

In general I also think it will be useful (and is consistent) to allow pledge_payment api to used to insert pledge payments. Currently this is not supported (based on my conversation w/ Eileen) since the api assumes that you are trying to make a payment against the "next / oldest pending" payment. I think Eileen is planning on chatting w/ api team about this issue.
Protect your investment in CiviCRM by  becoming a Member!

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: PledgePayment API
April 11, 2011, 05:45:54 pm
NB - I have removed the contribution_id from being mandatory - I think we should be pretty flexible on removing things from being mandatory as a general rule
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

SarahG (FountainTribe)

  • Ask me questions
  • ****
  • Posts: 782
  • Karma: 29
  • CiviCRM version: 4.4.7
  • CMS version: Drupal 6, Drupal 7
  • MySQL version: 5.5
  • PHP version: 5.3
Re: PledgePayment API
April 11, 2011, 08:08:04 pm
When I call the PledgePayment API to create a new installment:  I pass the status parm to "pending", the "scheduled_amount" value as the the amount that I have previously calculated that is still owed on the pledge.

For example:

1) My batch script creates a pledge of $1,000. with one scheduled installment of $1,000.

(processes many records not related to this pledge)

2) The batch script finds a payment record of $100 for the previous pledge.  So I create a contribution, then call the create PledgePayment,passing in the contrib. id of this $100 contribution.

At this point the pledge looks like:

Total pledge amount: $1000,  paid so far: $100, balance: $900.    It contains one installment, that has the actual amount paid as "$100" and status as completed.  ( IMHO, this means the pledge is in an invalid condition. Money is owed, yet there is no way to record it and the pledge status wrongly shows as completed. )

3) Now I calculate the total pledge amount minus the amount paid  and set it to the variable "amount_due".   

If "amount_due" is more than zero, I call the the API for create "PledgePayment" again. This status is "pending", "scheduled_amount" = "amount_due" and contribution ID is empty.   

4) The script continues reading more records. If it encounters another record describing a payment for the same pledge,  then I repeat steps 2 and 3.

After processing the complete input file, The pledge of $1000 may have 4 payments of $100, a fifth payment of $150. So the pledge balance is "$450" and there are 5 completed payments as well as a single pending payment of $450 in the pledge payment list.

The problem with the data in the input file is that there is no schedule. The person paid basically arbitrary amounts in each payment against a certain obligation/pledge.     In some situations, the obligation is paid off in full over many payments. In other situations ( as I described in more detail) there is a balance due.   

The other possibility is that they end up paying more than the original obligation. In this case, I am still deciding if I should a) Adjust the pledge amount to the higher number or b) record the "extra" money as a contribution, but do not link it to the pledge.

My concern is that from a developers point of view, the pledge should act as a "container" for all the pledge payments. It does not make sense that I can arbitrarily manipulate the payments ( scheduled or completed) in a manor that creates a flawed pledge.  But maybe this issue is really related to the planned changes for the "CiviAccounts" project, where there is a cleaner structure for tracking what someone owes. 



« Last Edit: April 11, 2011, 08:09:53 pm by sgladstone »
Did I help you? Please donate to the Civi-Make-It-Happen campaign  CiviCRM for mobile devices! 

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: PledgePayment API
April 13, 2011, 01:08:47 am
Isn't it an issue that a status "partially paid" (and possibly overpaid) is missing ?

As for the create_new, understand the need, but that's introducing more black magic undocumented behaviour. Shouldn't the api returns the amount still to pay (balance) either always (assuming we need to calculate it anyway to set the proper status) or if there is a return=balance param ?

Then do a simple second api call to create the new pledge payment based on the balance returned.

X+

P.S. I never used the pledge, so that's more about general api behaviour
P.S2 If the API team ever end up agreeing on the chaining syntax, the create_new could be part of the same api call without having to introduce hidden params
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: PledgePayment API
April 13, 2011, 01:19:27 am
Nah, this is a pretty special scenario - the pledge payments are created by the pledge API and ......  I won't go into it unless you REALLY want to get your head around it. It is different to the chaining / nesting concept.

You probably just want to focus on the syntax side of it per the new thread you started
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: PledgePayment API
April 13, 2011, 04:19:01 am
Hi,

Not so much indeed. Still having civicrm_api ('PledgePayment', 'Create) that returns the balance seems to be a pretty logical one, but you are right, I don't know anything about the Pledge and not looking to learn it right now.

For the discussion about my syntax concern:
http://forum.civicrm.org/index.php/topic,19460.0.html

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: PledgePayment API
April 13, 2011, 04:40:04 am
Yep, we have PledgePayment create & pledge create. Pledge creates the pledge and the pledge payments and pledgePayment updates the pledge payments - except in extremely rare use cases it now needs to create them too - clear as mud?

Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Dave Greenberg

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 5760
  • Karma: 226
    • My CiviCRM Blog
Re: PledgePayment API
April 13, 2011, 06:42:39 am
Having pledge_payment return the current outstanding balance does seem quite "helpful" (but no idea if this makes sense from an api architecture point of view). In thinking a bit more on this I also realized that I don't know whether the existing pledge_payment api currently includes "as needed" updates to the enclosing pledge status. In the UI / BAO - changes to pledge payment records do trigger pledge record updates in certain cases. Primary example is when the last pledge payment is updated to "Completed" status - we also update the Pledge record status to "Completed".
Protect your investment in CiviCRM by  becoming a Member!

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: PledgePayment API
April 13, 2011, 07:14:16 am
Hi,

The API is a thin wrapper around the DAO/BAO
Code: [Select]
   $dao = CRM_Pledge_BAO_Payment::add( $paymentParams );

in that case it has an extra line that should do the trick:

Code: [Select]
     CRM_Pledge_BAO_Payment::updatePledgePaymentStatus( $params['pledge_id']);

One of the issue we encountered in the API is that some features that should have been in the BAO was in the Form class, so we had to refactor or duplicate code between the form and the API.

In general when developing it would be great to check if it's an UI related task (in that case that's in the form) or something that is about the business model and should be shared between the UI and the API (and be in the BAO).

Will mail the planning list next time I stumble upon one.

X+


-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: PledgePayment API
April 13, 2011, 12:16:29 pm
Here's the code - Xavier - the line you mentioned is in there. The issue is around the dealing with no 'id'. For the pre-pogstone sponsored behaviour of pledge this was the only handling that made sense. Now there are two - the way we deal with 'normal' pledges that follow the schedule & ones that change on the fly.

I think the api should support two behaviours & the developer should be able to indicate which via some syntax being discussed now

Code: [Select]
    require_once 'CRM/Pledge/BAO/Payment.php';
    if (empty($params['id'])){
      $paymentDetails = CRM_Pledge_BAO_Payment::getOldestPledgePayment($params['pledge_id']);
      $paymentParams = array_merge($params,$paymentDetails);
    } else{
      $paymentParams =$params;
    }
   
    $dao = CRM_Pledge_BAO_Payment::add( $paymentParams );
     _civicrm_api3_object_to_array($dao, $result[$dao->id]);
   
   
    //update pledge status
     CRM_Pledge_BAO_Payment::updatePledgePaymentStatus( $params['pledge_id']);

I don't think there is current BAO to support returning the amount owing. If there is it should probably be an optional return value (at least we have a syntax for that)
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Pages: [1] 2
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • PledgePayment API

This forum was archived on 2017-11-26.