Altinn / altinn-studio

Next generation open source Altinn platform and applications.
https://docs.altinn.studio
BSD 3-Clause "New" or "Revised" License
111 stars 70 forks source link

How can we support dynamic prices configuration within Studio #12468

Closed framitdavid closed 3 weeks ago

framitdavid commented 6 months ago

The payment system is implemented in the backend of the app, currently tjenesteutviklere needs to manually implement C# code in order to facilitate payments with dynamic pricing through forms. The backend has implemented an interface called IOrderDetailsCalculator where one implements the logic for what needs to be paid (order lines).

I would like to challenge this to see if we can create an interface between Studio and Apps that can somehow provide a setup of dynamic pricing from Studio as well, without requiring the tjenesteutvikler to manually write C# code.

This task is an analysis task to determine what possibilities we have to offer this. This topic must also involve developers from the teams apps to explore good solutions together

Link to the IOrderDetailsCalculator interface. https://github.com/Altinn/app-lib-dotnet/blob/feat/payment-nets/src/Altinn.App.Core/Features/Payment/IOrderDetailsCalculator.cs

### Acceptance criteria
- [ ] Figureout if we can support dynamic prices configuration within Studio
- [ ] Create new issues what we should do next if we can support this feature, otherwise close this issue with documentation with why we cannot continue.

Additional information

This is how basic payment within in app can be configured today:

  1. The DataType for payment within a app

    {
      "id": "paymentInformation",
      "allowedContentTypes": [
        "application/json"
      ],
      "maxCount": 0,
      "minCount": 0,
      "enablePdfCreation": false,
      "enableFileScan": false,
      "validationErrorOnPendingFileScan": false,
      "enabledFileAnalysers": [],
      "enabledFileValidators": []
    }
  2. Add the payment step into Process. (This can be done within Studio after #12467 is implemented)

    <bpmn:task id="Task_5" name="Payment"> //oppdater
      <bpmn:incoming>Flow_193kyi8</bpmn:incoming> //oppdater
      <bpmn:outgoing>Flow_1jrbtd2</bpmn:outgoing> //oppdater
      <bpmn:extensionElements>
        <altinn:taskExtension>
          <altinn:taskType>payment</altinn:taskType>
          <altinn:actions>
            <altinn:action>pay</altinn:action>
            <altinn:action>reject</altinn:action>
          </altinn:actions>
          <altinn:paymentConfig>
            <altinn:paymentDataType>paymentInformation</altinn:paymentDataType>
          </altinn:paymentConfig>
        </altinn:taskExtension>
      </bpmn:extensionElements>
    </bpmn:task>
  3. Implement the IOrderDetailsCalculator interface. This can be achieved using the code provided below. Here are the manual steps that need to be completed today. Is there a way we can enhance this method to support visual configuration in Studio?

    
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Altinn.App.Core.Features.Payment;
    using Altinn.App.Core.Features.Payment.Models;
    using Altinn.Platform.Storage.Interface.Models;

namespace Altinn.App.Custom.Payment;

///

/// Calculating order details for payment /// public class OrderDetailsCalculator : IOrderDetailsCalculator { public Task CalculateOrderDetails(Instance instance) { List things = [ new Thing { Description = "A thing", Price = 50 }, new Thing { Description = "Another thing", Price = 100 } ];

    List<PaymentOrderLine> paymentOrderLines = things
        .Select((x, index) =>
            new PaymentOrderLine
            {
                Id = index.ToString(), Name = x.Description, PriceExVat = x.Price, Quantity = 1, VatPercent = 25.00M
            })
        .ToList();

    var orderDetails = new OrderDetails { Currency = "NOK", OrderLines = paymentOrderLines };

    return Task.FromResult(orderDetails);
}

private class Thing
{
    public required string Description { get; init; }
    public required decimal Price { get; init; }
}

}


4. Register payment within Program.cs

void RegisterCustomAppServices(IServiceCollection services, IConfiguration config, IWebHostEnvironment env) { // Register your apps custom service implementations here. services.AddNetsPaymentServices(config); //Hvis vi vil ha mer out-of-the-box-uten-kode løsning så kan denne alltid addes som en del av library sin setup. services.AddTransient<IOrderDetailsCalculator, OrderDetailsCalculator>(); //Vi kunne hatt en standardimplementasjon av denne i library som leser en fastpris fra et bestemt sted. }


5. Add the needed config within the AppSettings.

"NetsPaymentSettings": { "SecretApiKey": "test-secret-key-a09d53d0e6e348b596eb301f125ccc72", "BaseUrl": "https://test.api.dibspayment.eu/", "TermsUrl": "https://www.yourwebsite.com/terms", "ShowOrderSummary": true, "ShowMerchantName": true }

RonnyB71 commented 6 months ago

One thing that could be an alternative way of connecting the BPMN task is to reference the id of the implementation in c#. I don't think we have an id on IOrderDetailsCalculator today, but we could consider it. An id is basically a name implementation, and the same concept we use when we identify the implementation to use when resolving code list implementations. That way you could add a property in the BPMN editor stating the implementation to use.

ivarne commented 6 months ago

Shouldn’t we first look at how many apps actually use payment and see what kind of configuration they actually would benefit from, before we spend more time on a pretty niche use of Altinn 3?

framitdavid commented 6 months ago

From my point of view, I agree with what you, @ivarne , wrote about waiting to see how many actually adopt the payment feature, and then gathering information about what configurations customers need or want. On the other hand, could we see increased usage of the payment feature if it were more available for "non coders" and not just in C# code? Perhaps we would also receive more feedback on the payment feature. Could a more accessible payment configuration increase the use of forms for both other areas among existing customers and attract new customers? 🤔

This task is labeled as "analysis," so I think it's healthy and good that we discuss the topic and choose either to wait or to implement a solotuon. Regardless, the choice should be based on what is most suitable given the insights and goals we have. 😊

So, this task is not just about implementing support for dynamic pricing just for the sake of achieving it, but rather about digging deeper and gaining insight into what is expected and should be delivered to our users. Like the second task on this issue is addressing: "Create new issues what we should do next if we can support this feature, otherwise close this issue with documentation with why we cannot continue."

nkylstad commented 3 weeks ago

Closing this issue for now. Re-open if we see the need.