Korištenje Pravila sa komercijalnim fondovima

Submitted by victor.bourgade on Tue, 08/27/2019 - 21:33

Tokom rada sa Commerce Funds vjerojatno ćete naići na potrebu da ih kombinirate sa Pravilima (Rules) kako bi postigli razinu fleksibilnosti koja je potrebna pri izradi web stranice.

Podsjetimo se, Pravila nam omogućavaju da definiramo uvjetovano izvršavanje akcija bazirano na ponavljajućim događajima. Ovo bi značilo da možete kreirati akcije koje će se aktivirati posebno odabranim događajima. Na primjer, možemo kreirati novu transakciju nakon spremanja node-a. U nastavku donosimo upravo to - kako kreirati novu transakciju za depozitno plaćanje.

Na samom početku ćemo kreirati novi tip sadržaja kojeg ćemo nazvati “depozitno plaćanje” (“escrow payment”), u koji će nam dati formu za pohranu podataka za plaćanje. 
Nadalje, za plaćanje su nam potrebna 2 obavezna polja: iznos transakcije i primatelj kojemu ćemo poslati novac. Za iznos transakcije ćemo koristiti polje “Cijena” (“Price”), dok ćemo za primatelja koristiti ćemo “Referencu entiteta” (“Entity reference”):

Escrow payment content type

U ovoj fazi korisnik može unijeti iznos u formu i izabrati primatelja transakcije, no transakcija neće biti provedena. Da bi omogućili provođenje transakcije moramo dodati nova Pravila za događaj “Nakon spremanja novog elements sadržaja” ("After saving a new content item") sa “Uvjetima” ("Conditions") i “Akcijama” ("Actions") opisanima u nastavku ovo tutoriala.

Na kraju bi trebali dobiti sljedeće:

Create escrow payment Rule

UVJETI

Da bi izložili polja tipa sadržaja Pravilima, moram postaviti uvjet “Entitet je od paketa” (“Entity is of bundle”) sa ispod prikazanim vrijednostima:

  • entity = data_selector : node,
  • type = value : node,
  • bundle = value : content_type_machine_name (escrow_payement here).

Ovaj uvjet nam omogućava korištenje tek kreiranih polja u Pravilima, u svrhu provođenja akcije “Create a new transaction”.

AKCIJE

Akcija se sastoji od tri procesa:

  1. Kreiranje nove transakcije popunjavanjem različtih dijelova potrebnih informacija, sa podacima danima tokom popunjavama forme “depozitno plaćanje” od strane korisnika.
  2. Podatke spremamo u bazu kako bi ih naknadno mogli pratiti.
  3. Izvedba transakcije na način da se korisnički računi ažuriraju pravovremeno.

1. Transakcija je puno više od samo informacija o iznosu i primatelju. To je znatno kompleksniji objekt sa dodatnim parametrima kao što su datum kreiranja, pošiljatelj, valuta, itd. Da bi kreirali transakciju moramo osigurati Pravila sa prethodno navedenim informacijama.

Dodajmo akciju "Create a new transaction" sa sljedećim pravilima:

  • Transaction type = value : escrow (Commerce Funds omogućavaju 6 tipova transakcija: deposit, transfer, escrow, payment, withdrawal_request, conversion)
  • Issuer = data_selector : node.uid.target_id (korisnik koji kreira node)
  • Recipient = data_selector : node.field_to_user.target_id (tkorisnik koji se upisuje u polje field field_to_user)
  • Payment method = value : internal
  • Brut amount = data_selector : node.field_amount.number (iznos upisan od strane pošiljatelja)
  • Net amount = value : empty (neto iznos se ostavlja prazan jer se računa automatski)
  • Fee = value : empty||value. Ostavite prazno kako bi koristili konfiguraciju postavljenu u Commerce Funds. Ukoliko želite fiksan iznos pristojbi, popunite ovo polje.
  • Currency = data_selector: node.field_amount.currency_code (valuta koja se odnosi na iznos)
  • Status = value : Pending (Polje je osjetljivo na mala i velika slova. Postoje 3 različite vrijednosti koje se mogu upisati u ovo polje: Pending, Completed, Cancelled).

Ukoliko želite polje za ostavljanje komentara na transakciju, možete ga dodati putem implementacije dvije nove akcije “set a data value”.

Prvo "set a data value":

  • Data = data_selector : entity.notes (odabire zabilješke iz transakcije)
  • Value = data_selector : node.body.value (dodajemo vrijednost body kao transakcijsku bilješku)

Problem nastaje radi toga što trenutno nemamo postavljen tekstualni format za transakcijske bilješke, što znači da će tekst unutar HTML tijela biti renderiran kao običan tekst. Stoga je potrebno dodati drugu akciju.

Drugo "set a data value":

  • Data = data_selector : entity.notes.format 
  • Value = data_selector : node.body.format 

Now we have prepared our transaction entity, we need to save it in the database.

2. Dodavanje akcije "Save entity":

  • Entity = data_selector : entity (Transaction)
  • Force saving = 1 (to force the saving, 0 otherwise)

Sada smo kreirali transakcijski entitet i spremili ga u bazu podataka. No u ovom trenutku transakcija ne izvršava nikakve akcije nad stanjem korisničkih računa. Iznos transakcije se ne oduzima niti dodaje na račune.

3. Dodavanje akcije "Perform transaction":

  • Transaction = data_selector : entity (Transaction)

Ova akcija će pokrenuti izvođenje transakcije koja će utjecati na stanje korisničkih računa.

VALIDACIJA FORME

Jedini problem sa korištenjem Pravila pri izvođenju transakcija Commerce Funds jest taj što ne postoji oblik validacije forme prije njenog izvođenja. Čak ni u Drupal 7, Pravila nisu izvorno osiguravala integraciju forme. Da bi to postigli u Drupalu 7, možemo dodati modul za Rules Forms Support.

U ovom slučaju, naše jedino rješenje je implementacija hook validacije u prilagođenom modulu. Ukoliko ne znate kako kreirati prilagođeni modul za Drupal, pogledajte članak.
Commerce Funds implementiraju dva ograničenja za validaciju. Ograničenja nam omogućavaju da postavimo određeni validacijski set na polja. Pošto su naša polja kreirana sa API formom, ograničenja ćemo primjeniti putem hook_entity_bundle_field_info_alter().

U module_name.module datoteku dodajte sljedeći kod:
 

/**
 * Implements hook_entity_bundle_field_info_alter().
 *
 * Alter custom form for validation.
 */
function MODULE_NAME_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
  if ($entity_type->id() == 'node' && $bundle == 'CONTENT_TYPE_MACHINE_NAME') {
    if (!empty($fields['FIELD_AMOUNT_MACHINE_NAME'])) {
      $fields['FIELD_AMOUNT_MACHINE_NAME']->addConstraint('NetAmountBelowBalance'); // Add the validation set "NetAmountBelowBalance"
    }
    if (!empty($fields['FIELD_RECIPIENT_MACHINE_NAME'])) {
      $fields['FIELD_RECIPIENT_MACHINE_NAME']->addConstraint('IssuerEqualsCurrentUser'); // Add the validation set "IssuerEqualsCurrentUser"
    }
  }
}

Imena napisana velikim slovima je potrebno zamijeniti sa imenom koje sami odredite. U ovom slučaju će biti:

/**
 * Implements hook_entity_bundle_field_info_alter().
 *
 * Alter custom form for validation.
 */
function MODULE_NAME_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
  if ($entity_type->id() == 'node' && $bundle == 'escrow_payment') {
    if (!empty($fields['field_amount'])) {
      $fields['field_amount']->addConstraint('NetAmountBelowBalance');
    }
    if (!empty($fields['field_to_user'])) {
      $fields['field_to_user']->addConstraint('IssuerEqualsCurrentUser');
    }
  }
}

Ukoliko imate nekoliko tipova sadržaja koji koriste Pravila kao pokretač transakcije, trebate ponovno dodati cijeli prvi “if” blok (if bundle == "OTHER_CONTENT_TYPE") i postaviti imena polja unutar novih “if” uvjeta.

Time ćete postići validacije forme: 

Form validation

I to bi bilo to. Kroz ovaj tutorial smo vidjeli kako u potpunosti maknuti forme Commerce Funds i implementirati vlastite korištenjem modula Pravila. 

U slučaju da imate bilo kakvih nejasnoća ili pitanja, slobodno ostavite komentar na članak ili se javite preko kontakt forme na stranici. 
 

About the writer

victor.bourgade

Victor is a web developer passionnated in drupal and bootstrap technologies. He likes challenges and beautiful designs.

When not behind his computer you'll find him drinking beers with friends or in the middle of nowhere hiking with his dog.