Hoofdmenu

libAcumulus voorbeeld?

Gestart door fgd007, 26 maart, 2022, 22:24:46

Vorige topic - Volgende topic

fgd007

Ik wil heel graag libAcumulus gebruiken (https://github.com/SIELOnline/libAcumulus) maar tot mijn verbazing kan ik nergens een stuk voorbeeld code vinden.
Hoe zet je een Api verbinding op? Die autoloader heb ik niet nodig, ik laad het via composer in.
Het gaat om een 'pure' ApiClient verbinding (dus geen specifieke shop implementatie). Meest logische ingang leek me ApiClient/Acumulus, maar een heel intuïtief begin is dit niet:

public function __construct(ApiCommunicator $apiCommunicator, Container $container, Config $config)

Iemand een voorbeeld hoe je een verbinding opzet?

erwin-burorader

libAcumulus is gegroeid vanuit het gemeenschappelijke dat steeds terugkeert in elke webshop plugin. Omdat het niet vanaf het begin is opgezet met het idee dat onderdelen ervan los ergens anders gebruikt kunnen worden, zitten er meer onderlinge afhankelijkheden in dan gewenst. (Het is geen Symfony of Zend framework.)

In versie 7 worden een aantal van deze problemen aangepakt met het doel om de library ook in te kunnen voor alleen het communicatiegedeelte zonder dat daarvoor custom code nodig is anders dan het instantiëren van de Container en het  het meegeven van een aantal instellingen/opties. Versie 7 is te vinden onder de dev branche, maar daar zal zeker nog het een en ander aan gewijzigd worden.
bv:
- Log => PSR3 logger interface, wat al door veel projecten gebruikt word en wat dus misschien al voorhanden is in jouw omgeving, of anders snel toegevoegd met composer.
- Dat gedeelte van de Config dat nodig is als een $options array doorgeven aan de constructor ipv het hele Config .object.

NB: Dat die constructor niet intuïtief is, is een gevolg van het dependency injection principe, dat er juist voor zorgt dat een class minder kennis hoeft te hebben van zijn omgeving. Gebruik dus die Container die precies weet wat er nodig is om een object te maken. Je ziet dat de meeste webshop modules code als hieronder gebruiken om de boel op te zetten en vervolgens te gebruiken:

<?php
    // Get language
    $languageCode = get_bloginfo('language');
    if (empty($languageCode)) {
        $languageCode = 'nl';
    }
    $languageCode = substr($languageCode, 0, 2);

    $shopNamespace = 'WooCommerce';
    $container = new Container($shopNamespace, $languageCode);

    // Ready to go
    $source = $container->getSource(Source::Order, $order instanceof WC_Order ? $order : $orderId);
    $container->getInvoiceManager()->sourceStatusChange($source);

    // Or:
    $acumulusApiClient = $container->getAcumulusApiClient();
    $token = '...'; // token for the invoice to set to paid.
    $paymentStatus = Api::PaymentStatus_Paid;
    $paymentDate = '...';
    $acumulusResult = $this->acumulusApiClient->setPaymentStatus(
        $token,
        $paymentStatus,
        $paymentDate
    );
?>

NB: Ik ben erg geïnteresseerd in feedback over het gebruik van libAcumulus in andere situaties, dus neem direct contact met mij op (support at burorader dot com) en ik zal jouw bevindingen zeker meenemen in versie 7.

fgd007

Hi Erwin,

Veel dank voor je reactie.

Begrijp ik goed dat libAcumulus dus niet perse geschikt is om standalone te gebruiken en bijv. facturen in te schieten in Acumulus? Of zou het wel moeten kunnen?
In de vorige versie van het project waar ik mee bezig ben produceerde ik zelf XML strings en pushte ik die via PHP Curl in Acumulus. Dat werkte prima, maar kan mooier.
Nu ik dit onderdeel opnieuw aan het implementeren ben in een Laravel framework, had ik gehoopt dat libAcumulus de key zou zijn tot een schonere en effectievere implementatie.

Kun je een voorbeeld sturen inclusief het opzetten configuratie? Dat lijkt nog te ontbreken in het Woocommerce voorbeeld.

Mijn grootste feedback zou in dit stadium zijn: documentatie toevoegen. Als is het maar een beginnetje, niet elke method hoeft uitvoerig beschreven worden natuurlijk.


erwin-burorader

De phpdocs zijn redelijk compleet, zo ongeveer elke method is beschreven, een groot gedeelte van alle classes, en alle namespaces (in de file documentation.php) die zich in elke (niet webshop-speciffieke) namespace bevindt. Alleen dat soort documentatie is meer ter referentie en te gebruiken tijdens het programmeren, minder om ergens mee te beginnen.

Wat die config betreft, veel instellingen zijn op het niveau van wat een shop kan, of wanneer zaken verstuurd moeten worden. De test config (class \Siel\Acumulus\TestWebShop\Config\ConfigStore) is een minimale config waarmee ik het communicatiegedeelte kan testen, die zou je kunnen gebruiken.

Wat je vervolgens met libAcumulus bereikt is dat je niet zelf meer die xml string moet opzetten, maar dat je met arrays werkt die de xml-structuur nabootsen en die doorgeeft aan de Acumulus Api client. Die client voegt de "basic submit" toe, dus jij hoeft alleen maar het inhoudelijke gedeelte door te geven. Kijk voor voorbeelden in de class met test-aanroepen: \Siel\Acumulus\Unit\ApiClient\ApiRequestResponseExamples, jij zet het 'submit' gedeelte op, de rest doet libAcumulus.


fgd007

Ik zie geen concreet voorbeeld van hoe je in een paar regels een verbinding op zet.
Moet ik een eigen config class opzetten die de ConfigStore extend? Is dat the way to go? Maar waar 'set' ik die config? Of ben ik genoodzaakt een eigen implementatie te maken a la Src/WooCommerce of Src/PrestaShop?

Hoe ik verwacht dat het zou werken (in gesimplificeerde pseudocode):


use Siel\Acumulus;

...

$acumulus = new Acumulus($config);
$invoiceResponse = $acumulus->addInvoice($invoiceData);

erwin-burorader

1)
Om gebruik te kunnen maken van de library dien je een aantal zaken te programmeren die specifiek voor jouw omgeving zijn. Dit doe je door classes uit libAcumulus te "extenden" in je eigen namespace specifiek voor jouw omgeving. De help voor class Container specificeert aan welke eisen die namespace dient te voldoen, maar dat komt simpel neer op het toevoegen van de naam van jouw omgeving: \Siel\Acumulus\{MijnOmgeving} (zoals is gedaan voor WooCommerce, PrestaShop,...). Dit doe je in een folder in je eigen omgeving niet in de vendor/siel/... folder die Composer voor jou aanmaakt, zodat je die kunt blijven updaten.

2)
Om alleen het communicatiegedeelte te gebruiken, dien je binnen die namespace minimaal de volgende classes en methods te definiëren:
- class \Siel\Acumulus\{MijnOmgeving}\Config\ConfigStore
  * load()
  * save()
- class \Siel\Acumulus\{MijnOmgeving}\Config\ShopCapabilities
  * getShopEnvironment()
  * alle abstract methods van de parent class
- class \Siel\Acumulus\{MijnOmgeving}\Helpers\Log
  * write()

3)
Deze kun je het beste kopiëren van de namespace \Siel\Acumulus\TestWebShop en dan de volgende zaken aanpassen:
- ConfigStore: de plek waar je je config.json opslaat. Maak deze config.json ook aan en vul jouw contractgegevens en het log level in. Hou deze config.json dus voor jezelf, sla deze dus niet op in b.v. een github project, vandaar die rare plek die de in MyTestShop gebruikt wordt. Log level 1 is: ook communicatie loggen.
- ShopCapabilities: de naam en versie van jouw omgeving en de versie van jouw eigen module.
- Log: de naam en plek van je log file. Deze file moet schrijfbaar zijn.

4)
Nu kun je de library gebruiken door *via de Container* een Acumulus ApiClient te verkrijgen. die Container zorgt ervoor dat de benodigde en juiste  classes geïnstantieerd worden. NB: de Container bevat geen autoloader, daar gebruik je composer voor, of als je dat niet gebruikt, SielAcumulusAutoloader.php. De container gaat er dus wel vanuit dat er een autoload mechanisme is voor de classes onder de namespace /Siel/Acumulus.

5)
Voorbeeldcode:

<?php
    $shopNamespace = '{MijnOmgeving}';
    $language = 'nl'; // of 'en'
    $container = new Container($shopNamespace, $language);

    $acumulus = $container->getAcumulusApiClient();

    // Voeg factuur toe:
    $invoiceResult = $acumulus->addInvoice($invoiceData);
    $invoiceResponse = $invoiceResult->getMainResponse();
    if ($invoiceResponse !== null) {
        $token = $invoiceResponse['token'];
        // store token in combination with shop order id for future use.
    }

    // of Zet betaald:
    $token = '...'; // token for the invoice to set to paid.
    $paymentStatus = Api::PaymentStatus_Paid;
    $paymentDate = date(Api::DateFormat_Iso); // today
    $paymentResponse = $acumulus->setPaymentStatus(
        $token,
        $paymentStatus,
        $paymentDate
    );
?>

fgd007

Yes, super, dit zocht ik inderdaad! Ik heb het nu aan de praat.
- In composer autoload/psr-4 inderdaad verwijzing naar namespace gemaakt:  "Siel\\Acumulus\\{EigenNamespace}\\": "pad/naar/namespace/{EigenNamespace}/"
- verder bleek method getShopDefaults ook verplicht een array te moeten teruggeven (in ShopCapabilities)

Veel dank voor je hulp!

Nu ik er langer mee bezig ben begrijp ik beter waarom e.e.a. in elkaar zoals het in elkaar zit.
Ik weet niet hoe groot de groep gebruikers is die de library gebruikt in een custom omgeving, maar je laatste instructie is een goede leidraad om e.e.a standalone te gebruiken. Dus ik zou die stappen zeker in de Readme opnemen op Github. Ben eventueel ook bereid tot het doen van een PR.




                                                 
                         (@@@@@@                 
                         @@@@@@@@@&               
                    @@@@@@/@@@@@@@@@             
                     @@@@@@@/@@@@@@@@@           
                       @@@@@@//@@@@@@@@           
                        %@@@@@//@@@@@@@@         
                @@@@@@@@@@@@*////@@@@@@@@         
           *@@@@@@@@@@@@@@@@@@@@@@//@@@@@@       
          @@@@@@@@@@@@@@@@@@@@@@@@@@//@@@@@       
          %@@@@@@@@       @@@@@@@@@@@@@@@@@       
          @@@#               @@@@@@@@@@@@@@       
        @@@@@@@@             @@@@@@@@@@@@@@       
        @@@@@@@@@            @@@@@@@@@@@@@       
         @@@@@@@@@@@       @@@@@@@@@@@@@@@       
          @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         
           @@@@@@@@@@@@@@@@@@@@@@@@@@@@@         
             @@@@@@@@@@THANKS@@@@@@@@@@           
               @@@@@@@@@@@@@@@@@@@@@@@           
                 /@@@@@@@@@@@@@@@@/               


erwin-burorader

Ik ga je feedback zeker verwerken, ook al zijn ons niet veel voorbeelden bekend van andere gebruikers. De library is n.l. wel bedoeld voor breder gebruik.