codym Posted May 23, 2020 Report Posted May 23, 2020 Hello everyone, I have a service with multiple configurable options. These configurable options are range-bound quantities. The client should be able to edit the quantities of these configurable options per-service. I am able to complete this task in the portal just fine and everything works as it should on both admin and client-side. I am trying to reproduce this behavior programmatically via the API but am running into some issues. Specifically, there are three variables which must be defined on the service_changes/add endpoint: service_id invoice_id vars I'm having trouble specifically with the invoice_id. (One would think the service_change endpoint would automatically create an invoice for the difference, but I digress!) I attempted to provide the endpoint with an invoice generated from the service I was attempting to modify, invoices/createFromServices, however I receive error 400: 'Invalid invoice ID.' What should I be doing here? Should this be a blank invoice? If so, how do I create a blank one? Additionally, I should be able to include my configurable option ID and the new quantity under vars once I have the invoice ID working properly, correct? Like so: vars[configoptions][config_option_id]=10 Here is a screenshot of my postman attempt: Thank you for your time! Quote
codym Posted May 25, 2020 Author Report Posted May 25, 2020 Since this post I've also tried: supplying the next available invoice_id without an invoice attached supplying the last invoice issued for the target service Both of which also gave an 'Invalid invoice ID.' error. I assume that I somehow need to manually create an invoice with the prorated data and the new options prorated as well? Quote
codym Posted May 25, 2020 Author Report Posted May 25, 2020 I have made some progress by reading through the app/controllers/client_services.php file. I see that Blesta is using various private functions to pull together the data it needs to GET the endpoint service_changes/getPresenter. This endpoint is what is providing the array of 'difference' data to create the invoice needed for the service change endpoint. However, once again documentation is sparse regarding this endpoint. I can successfully post to it and get a 200 OK, but the response is just an empty object. Assuming the service has no custom fields, this is what the post should look like and which gives me a 200 OK: The following values were pulled from the services/get endpoint with the service_id of '9', which is referred to as 'service': vars[pricing_id] = service.package_pricing.id vars[qty] = service.qty vars[configoptions][5] = service.options[option_id].qty vars[configoptions][6] = service.options[option_id].qty vars[configoptions][7] = service.options[option_id].qty vars[configoptions][9] = service.options[option_id].qty These are the only 4 configoptions which are available to this package and are all the correct IDs and within their defined ranges. This is confirmed by using the package_options/getAllByPackageId endpoint, just as Blesta has done under the Review() function of the app/controllers/client_services.php file. Finally, vars[use_module] = true in the screenshot below as that is set in the Review() function of the blesta code, however is not mentioned in the documentation. With or without this variable still gives me a 200 OK empty response. Quote
Jono Posted May 26, 2020 Report Posted May 26, 2020 Do you really mean to use a ServiceChange? Would Services::edit do what you want instead? Service changes are processed automatically via cron after their invoice is paid. An edit would happen immediately. use_module tells Blesta whether to invoke the module when making the edit, so yes it will work with or without it. That being said, I'm not sure of your question at this point. Are you asking what parameters should be submitted to getPresenter? codym 1 Quote
codym Posted May 26, 2020 Author Report Posted May 26, 2020 Thanks for the reply Jono! I think Services::edit would do what I want.... I'll play around with it and see what happens. I did some initial testing with it but it wasn't generating the prorated invoice for me. I'll get back to you on that. Quote
codym Posted May 26, 2020 Author Report Posted May 26, 2020 5 hours ago, Jono said: Do you really mean to use a ServiceChange? Would Services::edit do what you want instead? Service changes are processed automatically via cron after their invoice is paid. An edit would happen immediately. use_module tells Blesta whether to invoke the module when making the edit, so yes it will work with or without it. That being said, I'm not sure of your question at this point. Are you asking what parameters should be submitted to getPresenter? Jono, So, there is weird behavior with the Services::edit endpoint. When editing a service, all configurable option data and field data that is not included in the edit is deleted. Is this intended? As well, a prorated invoice is not generated for the service. Quote
Jono Posted May 26, 2020 Report Posted May 26, 2020 Yea, sorry about the learning curve there. As documented, all config options should be submitted. It is intended behavior that all others will be deleted. The lack of invoice is also intended behavior. A good place to reference is app/controllers/admin_clients.php. Particularly lines 5590-5689 Quote
codym Posted May 27, 2020 Author Report Posted May 27, 2020 10 hours ago, Jono said: Yea, sorry about the learning curve there. As documented, all config options should be submitted. It is intended behavior that all others will be deleted. The lack of invoice is also intended behavior. A good place to reference is app/controllers/admin_clients.php. Particularly lines 5590-5689 What is the name of the function I should look at? I'm on 4.4.1 Quote
codym Posted May 27, 2020 Author Report Posted May 27, 2020 So I think I found what you're talking about, which is app/controllers/admin_clients.php::editService. This function, when editing a service, uses the service_changes::getPresenter function to retrieve the prorated invoice details to generate an invoice for the service. So, the entire question circles back around to my reply right before your first reply where I am attempting to use the service_changes::getPresenter function to get prorated line items for an upgrade/downgrade to a service to manually create the invoice. I am receiving a 200 OK but empty response from that function, just as in that reply. Quote This endpoint is what is providing the array of 'difference' data to create the invoice needed for the service change endpoint. However, once again documentation is sparse regarding this endpoint. I can successfully post to it and get a 200 OK, but the response is just an empty object. Assuming the service has no custom fields, this is what the post should look like and which gives me a 200 OK: The following values were pulled from the services/get endpoint with the service_id of '9', which is referred to as 'service': vars[pricing_id] = service.package_pricing.id vars[qty] = service.qty vars[configoptions][5] = service.options[option_id].qty vars[configoptions][6] = service.options[option_id].qty vars[configoptions][7] = service.options[option_id].qty vars[configoptions][9] = service.options[option_id].qty These are the only 4 configoptions which are available to this package and are all the correct IDs and within their defined ranges. This is confirmed by using the package_options/getAllByPackageId endpoint, just as Blesta has done under the Review() function of the app/controllers/client_services.php file. Quote
Jono Posted May 27, 2020 Report Posted May 27, 2020 Is the service_id submitted valid? The only time you should get an empty response is when it is not. Quote
codym Posted May 29, 2020 Author Report Posted May 29, 2020 Here is a 'GET SERVICE' for the service ID I used in the getPresenter function: and here is the response from getPresenter using that ID: Quote
Jono Posted June 1, 2020 Report Posted June 1, 2020 I've seen no other reason this should return an empty response. I'm taking another look Quote
codym Posted June 3, 2020 Author Report Posted June 3, 2020 @Jono I've upgraded to the newest release and am still receiving the same behavior with the getPresenter endpoint Quote
Jono Posted June 3, 2020 Report Posted June 3, 2020 Alright, I'll try actually making the API call and see if I can replicate the issue. Quote
Jono Posted June 8, 2020 Report Posted June 8, 2020 Well the good news is that I get the same response as you. Now I'm looking into why that is. Hoping to give you an update before the end of the day. Thanks for your patience. Quote
Jono Posted June 8, 2020 Report Posted June 8, 2020 Seems that this kind of object can't be json encoded for some reason. Instead of calling getPresenter.json call getPresenter.php and that should work for you. Quote
codym Posted June 8, 2020 Author Report Posted June 8, 2020 @Jono Thanks for looking into it. Is there any way we can get a hotfix pushed that allows that endpoint to be JSON encoded? Otherwise we can't interface with that endpoint as it will return a PHP serialized object. Quote
Jono Posted June 9, 2020 Report Posted June 9, 2020 Is that a problem? Are you working in something other than PHP? I can spend some time looking into why the encoding is failing Quote
coreyman Posted June 9, 2020 Report Posted June 9, 2020 7 hours ago, Jono said: Is that a problem? Are you working in something other than PHP? I can spend some time looking into why the encoding is failing Yes we are working in nodejs. Thank you, The BitAccel Team Quote
Jono Posted June 11, 2020 Report Posted June 11, 2020 Well, the return is a php object referencing a php class, so I don't think there is a way to make that work. That being said, try ServiceChanges::getItems(). I know it's deprecated but I believe it will get the results you want in a way that can be sent to node. Quote
coreyman Posted June 11, 2020 Report Posted June 11, 2020 4 hours ago, Jono said: Well, the return is a php object referencing a php class, so I don't think there is a way to make that work. That being said, try ServiceChanges::getItems(). I know it's deprecated but I believe it will get the results you want in a way that can be sent to node. https://www.php.net/manual/en/jsonserializable.jsonserialize.php Quote
Jono Posted June 12, 2020 Report Posted June 12, 2020 I can mess with that, but it still won't make the class functions callable through node. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.