first commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @defgroup decision Decision
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file classes/decision/Decision.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2000-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class Decision
|
||||
*
|
||||
* @ingroup decision
|
||||
*
|
||||
* @see DAO
|
||||
*
|
||||
* @brief An editorial decision taken on a submission, such as to accept, decline or request revisions.
|
||||
*/
|
||||
|
||||
namespace APP\decision;
|
||||
|
||||
use PKP\decision\Decision as BaseDecision;
|
||||
|
||||
class Decision extends BaseDecision
|
||||
{
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
// Some constants are not redefined here because they never existed as global constants
|
||||
define('SUBMISSION_EDITOR_DECISION_EXTERNAL_REVIEW', Decision::EXTERNAL_REVIEW);
|
||||
define('SUBMISSION_EDITOR_DECISION_ACCEPT', Decision::ACCEPT);
|
||||
define('SUBMISSION_EDITOR_DECISION_DECLINE', Decision::DECLINE);
|
||||
define('SUBMISSION_EDITOR_DECISION_PENDING_REVISIONS', Decision::PENDING_REVISIONS);
|
||||
define('SUBMISSION_EDITOR_DECISION_RESUBMIT', Decision::RESUBMIT);
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/decision/Repository.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2000-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class Repository
|
||||
*
|
||||
* @brief A repository to find and manage editorial decisions.
|
||||
*/
|
||||
|
||||
namespace APP\decision;
|
||||
|
||||
use APP\decision\types\Accept;
|
||||
use APP\decision\types\SkipExternalReview;
|
||||
use APP\notification\Notification;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use PKP\decision\types\BackFromCopyediting;
|
||||
use PKP\decision\types\BackFromProduction;
|
||||
use PKP\decision\types\CancelReviewRound;
|
||||
use PKP\decision\types\Decline;
|
||||
use PKP\decision\types\InitialDecline;
|
||||
use PKP\decision\types\NewExternalReviewRound;
|
||||
use PKP\decision\types\RecommendAccept;
|
||||
use PKP\decision\types\RecommendDecline;
|
||||
use PKP\decision\types\RecommendResubmit;
|
||||
use PKP\decision\types\RecommendRevisions;
|
||||
use PKP\decision\types\RequestRevisions;
|
||||
use PKP\decision\types\Resubmit;
|
||||
use PKP\decision\types\RevertDecline;
|
||||
use PKP\decision\types\RevertInitialDecline;
|
||||
use PKP\decision\types\SendExternalReview;
|
||||
use PKP\decision\types\SendToProduction;
|
||||
use PKP\plugins\Hook;
|
||||
|
||||
class Repository extends \PKP\decision\Repository
|
||||
{
|
||||
/** The valid decision types */
|
||||
protected ?Collection $decisionTypes;
|
||||
|
||||
public function getDecisionTypes(): Collection
|
||||
{
|
||||
if (!isset($this->decisionTypes)) {
|
||||
$decisionTypes = new Collection([
|
||||
new Accept(),
|
||||
new Decline(),
|
||||
new InitialDecline(),
|
||||
new NewExternalReviewRound(),
|
||||
new RecommendAccept(),
|
||||
new RecommendDecline(),
|
||||
new RecommendResubmit(),
|
||||
new RecommendRevisions(),
|
||||
new Resubmit(),
|
||||
new RequestRevisions(),
|
||||
new RevertDecline(),
|
||||
new RevertInitialDecline(),
|
||||
new SendExternalReview(),
|
||||
new SendToProduction(),
|
||||
new SkipExternalReview(),
|
||||
new BackFromProduction(),
|
||||
new BackFromCopyediting(),
|
||||
new CancelReviewRound(),
|
||||
]);
|
||||
Hook::call('Decision::types', [$decisionTypes]);
|
||||
$this->decisionTypes = $decisionTypes;
|
||||
}
|
||||
|
||||
return $this->decisionTypes;
|
||||
}
|
||||
|
||||
public function getDeclineDecisionTypes(): array
|
||||
{
|
||||
return [
|
||||
new InitialDecline(),
|
||||
new Decline(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getReviewNotificationTypes(): array
|
||||
{
|
||||
return [Notification::NOTIFICATION_TYPE_PENDING_EXTERNAL_REVISIONS];
|
||||
}
|
||||
|
||||
public function getDecisionTypesMadeByRecommendingUsers(int $stageId): array
|
||||
{
|
||||
$recommendatorsAvailableDecisions = [];
|
||||
switch($stageId) {
|
||||
case WORKFLOW_STAGE_ID_SUBMISSION:
|
||||
$recommendatorsAvailableDecisions = [
|
||||
new SendExternalReview()
|
||||
];
|
||||
}
|
||||
|
||||
Hook::call('Workflow::RecommendatorDecisions', [&$recommendatorsAvailableDecisions, $stageId]);
|
||||
|
||||
return $recommendatorsAvailableDecisions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/decision/types/Accept.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2000-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class Accept
|
||||
*
|
||||
* @brief Extend the Accept decision to support APC payments
|
||||
*/
|
||||
|
||||
namespace APP\decision\types;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\decision\Decision;
|
||||
use APP\decision\types\traits\RequestPayment;
|
||||
use APP\submission\Submission;
|
||||
use Illuminate\Validation\Validator;
|
||||
use PKP\context\Context;
|
||||
use PKP\decision\Steps;
|
||||
use PKP\decision\types\Accept as TypesAccept;
|
||||
use PKP\submission\reviewRound\ReviewRound;
|
||||
use PKP\user\User;
|
||||
|
||||
class Accept extends TypesAccept
|
||||
{
|
||||
use RequestPayment;
|
||||
|
||||
public function validate(array $props, Submission $submission, Context $context, Validator $validator, ?int $reviewRoundId = null)
|
||||
{
|
||||
parent::validate($props, $submission, $context, $validator, $reviewRoundId);
|
||||
|
||||
if (!isset($props['actions'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ((array) $props['actions'] as $index => $action) {
|
||||
$actionErrorKey = 'actions.' . $index;
|
||||
switch ($action['id']) {
|
||||
case $this->ACTION_PAYMENT:
|
||||
$this->validatePaymentAction($action, $actionErrorKey, $validator, $context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function runAdditionalActions(Decision $decision, Submission $submission, User $editor, Context $context, array $actions)
|
||||
{
|
||||
parent::runAdditionalActions($decision, $submission, $editor, $context, $actions);
|
||||
|
||||
foreach ($actions as $action) {
|
||||
switch ($action['id']) {
|
||||
case self::ACTION_PAYMENT:
|
||||
$this->requestPayment($submission, $editor, $context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getSteps(Submission $submission, Context $context, User $editor, ?ReviewRound $reviewRound): Steps
|
||||
{
|
||||
$steps = parent::getSteps($submission, $context, $editor, $reviewRound);
|
||||
|
||||
// Request payment if configured
|
||||
$paymentManager = Application::getPaymentManager($context);
|
||||
if ($paymentManager->publicationEnabled()) {
|
||||
$steps->addStep($this->getPaymentForm($context), true);
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/decision/types/SkipExternalReview.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2000-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class SkipExternalReview
|
||||
*
|
||||
* @brief Extend the skip review decision to handle APC payments.
|
||||
*/
|
||||
|
||||
namespace APP\decision\types;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\decision\Decision;
|
||||
use APP\decision\types\traits\RequestPayment;
|
||||
use APP\submission\Submission;
|
||||
use Illuminate\Validation\Validator;
|
||||
use PKP\context\Context;
|
||||
use PKP\decision\Steps;
|
||||
use PKP\decision\types\SkipExternalReview as PKPSkipExternalReview;
|
||||
use PKP\submission\reviewRound\ReviewRound;
|
||||
use PKP\user\User;
|
||||
|
||||
class SkipExternalReview extends PKPSkipExternalReview
|
||||
{
|
||||
use RequestPayment;
|
||||
|
||||
public function validate(array $props, Submission $submission, Context $context, Validator $validator, ?int $reviewRoundId = null)
|
||||
{
|
||||
parent::validate($props, $submission, $context, $validator, $reviewRoundId);
|
||||
|
||||
if (!isset($props['actions'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ((array) $props['actions'] as $index => $action) {
|
||||
$actionErrorKey = 'actions.' . $index;
|
||||
switch ($action['id']) {
|
||||
case self::ACTION_PAYMENT:
|
||||
$this->validatePaymentAction($action, $actionErrorKey, $validator, $context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function runAdditionalActions(Decision $decision, Submission $submission, User $editor, Context $context, array $actions)
|
||||
{
|
||||
parent::runAdditionalActions($decision, $submission, $editor, $context, $actions);
|
||||
|
||||
foreach ($actions as $action) {
|
||||
switch ($action['id']) {
|
||||
case self::ACTION_PAYMENT:
|
||||
$this->requestPayment($submission, $editor, $context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getSteps(Submission $submission, Context $context, User $editor, ?ReviewRound $reviewRound): Steps
|
||||
{
|
||||
$steps = parent::getSteps($submission, $context, $editor, $reviewRound);
|
||||
|
||||
// Request payment if configured
|
||||
$paymentManager = Application::getPaymentManager($context);
|
||||
if ($paymentManager->publicationEnabled()) {
|
||||
$steps->addStep($this->getPaymentForm($context), true);
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/decision/types/traits/RequestPayment.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2000-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class decision
|
||||
*
|
||||
* @brief Helper functions for decisions that may request a payment
|
||||
*/
|
||||
|
||||
namespace APP\decision\types\traits;
|
||||
|
||||
use APP\components\forms\decision\RequestPaymentDecisionForm;
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use APP\mail\mailables\PaymentRequest;
|
||||
use APP\notification\Notification;
|
||||
use APP\notification\NotificationManager;
|
||||
use APP\payment\ojs\OJSPaymentManager;
|
||||
use APP\submission\Submission;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Validation\Validator;
|
||||
use PKP\context\Context;
|
||||
use PKP\decision\steps\Form;
|
||||
use PKP\user\User;
|
||||
|
||||
trait RequestPayment
|
||||
{
|
||||
protected string $ACTION_PAYMENT = 'payment';
|
||||
|
||||
/**
|
||||
* Get the form to request or waive payment
|
||||
*/
|
||||
protected function getPaymentForm(Context $context): Form
|
||||
{
|
||||
return new Form(
|
||||
$this->ACTION_PAYMENT,
|
||||
__('editor.article.payment.requestPayment'),
|
||||
'',
|
||||
new RequestPaymentDecisionForm($context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the decision action to request or waive payment
|
||||
*/
|
||||
protected function validatePaymentAction(array $action, string $actionErrorKey, Validator $validator, Context $context)
|
||||
{
|
||||
$paymentManager = Application::getPaymentManager($context);
|
||||
if (!$paymentManager->publicationEnabled()) {
|
||||
$validator->errors()->add($actionErrorKey . '.requestPayment', __('payment.requestPublicationFee.notEnabled'));
|
||||
} elseif (!isset($action['requestPayment'])) {
|
||||
$validator->errors()->add($actionErrorKey . '.requestPayment', __('validator.required'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request payment from authors
|
||||
*/
|
||||
protected function requestPayment(Submission $submission, User $editor, Context $context)
|
||||
{
|
||||
$paymentManager = Application::getPaymentManager($context);
|
||||
$queuedPayment = $paymentManager->createQueuedPayment(
|
||||
Application::get()->getRequest(),
|
||||
OJSPaymentManager::PAYMENT_TYPE_PUBLICATION,
|
||||
$editor->getId(),
|
||||
$submission->getId(),
|
||||
$context->getData('publicationFee'),
|
||||
$context->getData('currency')
|
||||
);
|
||||
$paymentManager->queuePayment($queuedPayment);
|
||||
|
||||
// Notify authors that this needs payment.
|
||||
$notificationMgr = new NotificationManager();
|
||||
$authorIds = $this->getAssignedAuthorIds($submission);
|
||||
foreach ($authorIds as $authorId) {
|
||||
$notificationMgr->createNotification(
|
||||
Application::get()->getRequest(),
|
||||
$authorId,
|
||||
Notification::NOTIFICATION_TYPE_PAYMENT_REQUIRED,
|
||||
$context->getId(),
|
||||
Application::ASSOC_TYPE_QUEUED_PAYMENT,
|
||||
$queuedPayment->getId(),
|
||||
Notification::NOTIFICATION_LEVEL_TASK
|
||||
);
|
||||
|
||||
$mailable = new PaymentRequest($context, $submission, $queuedPayment);
|
||||
$template = Repo::emailTemplate()->getByKey($context->getId(), $mailable::getEmailTemplateKey());
|
||||
$mailable->from($context->getData('contactEmail'), $context->getData('contactName'))
|
||||
->recipients([Repo::user()->get($authorId)])
|
||||
->subject($template->getLocalizedData('subject'))
|
||||
->body($template->getLocalizedData('body'));
|
||||
|
||||
Mail::send($mailable);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user