chore: bootstrap module from working instance and add install guide

This commit is contained in:
Kelin Rescue Hub
2026-04-09 14:18:10 -04:00
parent 97ad7da6f4
commit 6cda47760e
35 changed files with 6267 additions and 4 deletions

View File

@@ -0,0 +1,108 @@
<?php
namespace humhub\modules\donations\services;
use humhub\modules\donations\events\DonationSettlementEvent;
use humhub\modules\donations\models\DonationGoal;
use humhub\modules\donations\models\DonationTransaction;
use yii\base\Event;
class DonationSettlementService
{
public const EVENT_AFTER_SUCCEEDED = 'afterSucceeded';
public const EVENT_AFTER_REFUNDED = 'afterRefunded';
public function markSucceededAndApply(DonationTransaction $transaction, array $metadata = []): void
{
$payload = $this->decodeMetadata($transaction->metadata_json);
$applied = !empty($payload['goal_amount_applied']);
$goal = null;
if ((int)$transaction->goal_id > 0) {
$goal = DonationGoal::findOne([
'id' => (int)$transaction->goal_id,
'contentcontainer_id' => (int)$transaction->contentcontainer_id,
]);
}
if (!$applied) {
if ($goal instanceof DonationGoal) {
$goal->current_amount = round((float)$goal->current_amount + (float)$transaction->amount, 2);
$goal->save(false);
$payload['goal_amount_applied'] = 1;
$payload['goal_amount_applied_at'] = date('c');
$payload['goal_amount_applied_value'] = (float)$transaction->amount;
}
}
foreach ($metadata as $key => $value) {
$payload[$key] = $value;
}
$transaction->status = DonationTransaction::STATUS_SUCCEEDED;
$event = new DonationSettlementEvent();
$event->transaction = $transaction;
$event->goal = $goal;
$event->payload = $payload;
Event::trigger(self::class, self::EVENT_AFTER_SUCCEEDED, $event);
if (is_array($event->payload)) {
$payload = $event->payload;
}
$transaction->metadata_json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$transaction->save(false);
}
public function markRefundedAndRevert(DonationTransaction $transaction, array $metadata = []): void
{
$payload = $this->decodeMetadata($transaction->metadata_json);
$applied = !empty($payload['goal_amount_applied']);
$reverted = !empty($payload['goal_amount_reverted']);
$goal = null;
if ((int)$transaction->goal_id > 0) {
$goal = DonationGoal::findOne([
'id' => (int)$transaction->goal_id,
'contentcontainer_id' => (int)$transaction->contentcontainer_id,
]);
}
if ($applied && !$reverted) {
if ($goal instanceof DonationGoal) {
$nextAmount = round((float)$goal->current_amount - (float)$transaction->amount, 2);
$goal->current_amount = max(0.0, $nextAmount);
$goal->save(false);
$payload['goal_amount_reverted'] = 1;
$payload['goal_amount_reverted_at'] = date('c');
$payload['goal_amount_reverted_value'] = (float)$transaction->amount;
}
}
foreach ($metadata as $key => $value) {
$payload[$key] = $value;
}
$transaction->status = DonationTransaction::STATUS_REFUNDED;
$event = new DonationSettlementEvent();
$event->transaction = $transaction;
$event->goal = $goal;
$event->payload = $payload;
Event::trigger(self::class, self::EVENT_AFTER_REFUNDED, $event);
if (is_array($event->payload)) {
$payload = $event->payload;
}
$transaction->metadata_json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$transaction->save(false);
}
private function decodeMetadata(?string $json): array
{
$data = json_decode((string)$json, true);
return is_array($data) ? $data : [];
}
}