Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement PaymentProcessor and PaymentProcessorType APIv4 Entities #15624

Merged
merged 1 commit into from
Jan 12, 2020

Conversation

seamuslee001
Copy link
Contributor

Overview

Adds PaymentProcesor and PaymentProcessorType entities to APIv4

Before

Entities don't exist in APIv4

After

Entities exist in APIv4

Technical Details

There are some changes to the DAO to set some defaults and also make it clearer some fields are required. This was done after consulting the create specs in the APIv3 versions of these Entities

ping @eileenmcnaughton @mattwire @colemanw

@civibot
Copy link

civibot bot commented Oct 27, 2019

(Standard links)

@civibot civibot bot added the master label Oct 27, 2019
@seamuslee001 seamuslee001 force-pushed the payment_processor_api4 branch 2 times, most recently from 3c3333d to ceb8de8 Compare October 27, 2019 03:42
Comment on lines 212 to 213
'description' => ts('Payment Processor Name.'),
'required' => TRUE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an obvious typo not caused by this PR but can we fix please - description "Payment Processor Title". In fact, shouldn't these be "Payment Processor Type Name" and "Payment Processor Type Title"?

@@ -116,6 +119,7 @@ public function testDel() {
'title' => 'Test Del Payment Processor',
'billing_mode' => 1,
'is_active' => 1,
'class_name' => 'CRM_Core_Payment_Dummy',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the DB class_name is stored as Payment_Dummy - shouldn't it be here too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think so

@mattwire
Copy link
Contributor

@seamuslee001 Couple of minor clarifications. And, shouldn't we have a DB upgrader step as we are setting various fields to be required?

$item['payment_instrument_id'] = $paymentProcessorType['payment_instrument_id'];
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think setting these field defaults would be better addressed by a SpecProvider, and we should avoid overriding the writeObjects function if at all possible.

See for example
https://github.com/civicrm/civicrm-core/blob/5.19/Civi/Api4/Service/Spec/Provider/NavigationSpecProvider.php#L50-L50

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colemanw how would you handle the situation say in L58 where setting the payment instrument is dependant on if they have passed in one or if not then get it from the Payment Processor Type ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! I don't think that can be done with SpecProvider, you make a good point there.

However, as it's written this function is problematic because it assumes a complete record is being passed in but (in the case of update) that may not be the case.

My vote is to move this logic to the BAO (and only fire it if payment_processor_id is passed in) :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have rebased this now that the code has shifted to the BAO level

@seamuslee001
Copy link
Contributor Author

@colemanw in APIv4 is there a way to define a pseudo field? so in this case financial_account_id is not actually in the schema spec for PaymentProcessor but we use it to define the financial account relationship for the payment processor @eileenmcnaughton ?

protected function writeObjects($items) {
foreach ($items as &$item) {
if (empty($item['financial_account_id'])) {
$item['financial_account_id'] = \CRM_Financial_BAO_PaymentProcessor::getDefaultFinancialAccountID();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colemanw had to add here as financial_account_id isn't in the DAO spec and not sure how to add on new fields

* @inheritDoc
*/
public function modifySpec(RequestSpec $spec) {
$spec->getFieldByName('payment_instrument_id')->setRequired(FALSE)->setDefaultValue(1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colemanw i tried using 'Credit Card' as the value but didn't seem to work right

@seamuslee001 seamuslee001 force-pushed the payment_processor_api4 branch 3 times, most recently from 0b08bf8 to b2893c0 Compare October 27, 2019 23:53
@colemanw
Copy link
Member

@colemanw in APIv4 is there a way to define a pseudo field? so in this case financial_account_id is not actually in the schema spec for PaymentProcessor but we use it to define the financial account relationship for the payment processor @eileenmcnaughton ?

Yes, there is, via a specProivider. Here's an example of one: https://github.com/civicrm/civicrm-core/blob/5.19/Civi/Api4/Service/Spec/Provider/EventCreationSpecProvider.php#L54-L58

But I would ask anyone contemplating adding pseudofields to the spec to be very judicious about it. Api3 IMO has way too many pseudofields that don't belong, so before adding one to api4 please ensure that you:

  • Ask yourself - would it be better represented as a param?
  • If it belongs to another entity, check if it can already be handled by api joins.
  • Limit it to only the action(s) it applies to.

@eileenmcnaughton
Copy link
Contributor

"Ask yourself - would it be better represented as a param?
If it belongs to another entity, check if it can already be handled by api joins.
Limit it to only the action(s) it applies to."

I'm inclined to think this IS a legit pseudofield. I could make a pretty strong case for adding it as a column to the payment_processor table but probably it will remain as an additional field that is stored in a convoluted way

@seamuslee001 seamuslee001 force-pushed the payment_processor_api4 branch 2 times, most recently from ea5e4e9 to 8c91f60 Compare October 29, 2019 22:12
'description' => ts('Payment Processor Name.'),
'title' => ts('Payment Processor Type Title'),
'description' => ts('Payment Processor Type Title.'),
'required' => TRUE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required? For processor it isn't maybe it is for type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wel that is the DAO for the Type ;)

*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2019
* $Id$
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ids$ should go

@seamuslee001
Copy link
Contributor Author

@eileenmcnaughton @colemanw what can we do to move this forward now?

@seamuslee001 seamuslee001 force-pushed the payment_processor_api4 branch 3 times, most recently from 2216c0b to 8685927 Compare December 15, 2019 20:16
@seamuslee001 seamuslee001 force-pushed the payment_processor_api4 branch from 8685927 to 985815f Compare January 10, 2020 23:41
tests/phpunit/api/v3/PaymentProcessorTest.php Show resolved Hide resolved
$item['payment_instrument_id'] = $paymentProcessorType['payment_instrument_id'];
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! I don't think that can be done with SpecProvider, you make a good point there.

However, as it's written this function is problematic because it assumes a complete record is being passed in but (in the case of update) that may not be the case.

My vote is to move this logic to the BAO (and only fire it if payment_processor_id is passed in) :)

@seamuslee001 seamuslee001 force-pushed the payment_processor_api4 branch from 985815f to 8fe21e5 Compare January 11, 2020 21:20
@seamuslee001
Copy link
Contributor Author

hi @colemanw thanks for the pointers i have split off into a separate PR #16279 about the moving of the handling of the payment_instrument_field for PaymentProcessor to the Create BAO function. and have updated the tests

];
if ($version === 3) {
// In APIv3 If a field is default NULL it is not returned.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colemanw not sure if this is deliberate but it seems a noticeable change between the API versions, i assume it is documented somewhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is deliberate.
civicrm/org.civicrm.api4#116

You could simplify this patch by deleting NULL values from the api result instead of adding them to the expected result :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok have updated based on your suggestion @colemanw

// Billing mode is copied across from the payment processor type field in the BAO::create function.
$spec->getFieldByName('billing_mode')->setRequired(FALSE);

$financial_account_id = new FieldSpec('financial_account_id', 'PaymentProcessor', 'Integer');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eileenmcnaughton this may or may not be useful for you in understanding how to create pseudo fields in APIv4

@seamuslee001 seamuslee001 force-pushed the payment_processor_api4 branch from 8fe21e5 to 8617314 Compare January 11, 2020 23:04
Move default values to spec as per Coleman

Fix class name in tests and fix default values on tables

Mock financial_account_id field

Fix headers and remove some unnessary code

Update api v4 code following move of the handling to the BAO and update tests as per Coleman
@seamuslee001
Copy link
Contributor Author

Jenkins re test this please

@seamuslee001 seamuslee001 merged commit 0b28857 into civicrm:master Jan 12, 2020
@seamuslee001 seamuslee001 deleted the payment_processor_api4 branch January 12, 2020 03:57
@colemanw
Copy link
Member

Great work @seamuslee001

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants