From 687e57ddae4514ab88c41c9e6790c26005fba65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Hud=C3=A1k?= Date: Wed, 13 Mar 2024 09:16:45 +0000 Subject: [PATCH] Add refund page with advanced refund process form The page allows to execute complex refund process extendable by widgets and data providers. With actual refund it: - Stops or changes the subscription linked to the payment. - Stops recurrent payment linked to the payment. - Displays information about payment, subscription, and their owner. Dropdown list of payment statuses (used to change the status) is extracted to widget and is now reused across the different places. Refund selection doesn't change the status immediately, but redirects user to the refund page. remp/crm#2960 --- .../PaymentStatusDropdownMenuWidget.php | 23 ++ .../payment_status_dropdown_menu_widget.latte | 24 ++ .../RefundPaymentItemsListWidget.php | 26 ++ .../refund_payment_items_list_widget.latte | 67 ++++ .../user_payments_listing.latte | 26 +- ...PaymentRefundFormDataProviderInterface.php | 16 + src/Forms/PaymentRefundFormFactory.php | 199 ++++++++++++ src/PaymentsModule.php | 12 + .../PaymentsRefundAdminPresenter.php | 44 +++ src/Repositories/PaymentsRepository.php | 2 +- src/config/config.neon | 3 + src/lang/payments.cs_CZ.yml | 42 ++- src/lang/payments.de_DE.yml | 47 +++ src/lang/payments.en_US.yml | 30 ++ src/lang/payments.hu_HU.yml | 50 +++ src/lang/payments.sk_SK.yml | 30 ++ src/templates/PaymentsAdmin/default.latte | 23 +- src/templates/PaymentsAdmin/edit.latte | 7 + src/templates/PaymentsAdmin/show.latte | 20 +- .../PaymentsRefundAdmin/default.latte | 295 ++++++++++++++++++ 20 files changed, 931 insertions(+), 55 deletions(-) create mode 100644 src/Components/PaymentStatusDropdownMenuWidget/PaymentStatusDropdownMenuWidget.php create mode 100644 src/Components/PaymentStatusDropdownMenuWidget/payment_status_dropdown_menu_widget.latte create mode 100644 src/Components/RefundPaymentItemsListWidget/RefundPaymentItemsListWidget.php create mode 100644 src/Components/RefundPaymentItemsListWidget/refund_payment_items_list_widget.latte create mode 100644 src/DataProviders/PaymentRefundFormDataProviderInterface.php create mode 100644 src/Forms/PaymentRefundFormFactory.php create mode 100644 src/Presenters/PaymentsRefundAdminPresenter.php create mode 100644 src/templates/PaymentsRefundAdmin/default.latte diff --git a/src/Components/PaymentStatusDropdownMenuWidget/PaymentStatusDropdownMenuWidget.php b/src/Components/PaymentStatusDropdownMenuWidget/PaymentStatusDropdownMenuWidget.php new file mode 100644 index 0000000..78d5334 --- /dev/null +++ b/src/Components/PaymentStatusDropdownMenuWidget/PaymentStatusDropdownMenuWidget.php @@ -0,0 +1,23 @@ +template->payment = $payment; + $this->template->setFile(__DIR__ . DIRECTORY_SEPARATOR . $this->templateName); + $this->template->render(); + } +} diff --git a/src/Components/PaymentStatusDropdownMenuWidget/payment_status_dropdown_menu_widget.latte b/src/Components/PaymentStatusDropdownMenuWidget/payment_status_dropdown_menu_widget.latte new file mode 100644 index 0000000..4ecce3c --- /dev/null +++ b/src/Components/PaymentStatusDropdownMenuWidget/payment_status_dropdown_menu_widget.latte @@ -0,0 +1,24 @@ +{var $btn_class = 'btn-default'} +{if $payment->status == \Crm\PaymentsModule\Repositories\PaymentsRepository::STATUS_PAID} + {var $btn_class = 'btn-success'} +{elseif $payment->status == \Crm\PaymentsModule\Repositories\PaymentsRepository::STATUS_FORM} + {var $btn_class = 'btn-info'} +{elseif $payment->status == \Crm\PaymentsModule\Repositories\PaymentsRepository::STATUS_FAIL || $payment->status == \Crm\PaymentsModule\Repositories\PaymentsRepository::STATUS_TIMEOUT} + {var $btn_class = 'btn-danger'} +{/if} + + \ No newline at end of file diff --git a/src/Components/RefundPaymentItemsListWidget/RefundPaymentItemsListWidget.php b/src/Components/RefundPaymentItemsListWidget/RefundPaymentItemsListWidget.php new file mode 100644 index 0000000..8ae75fb --- /dev/null +++ b/src/Components/RefundPaymentItemsListWidget/RefundPaymentItemsListWidget.php @@ -0,0 +1,26 @@ +template->paymentItems = $payment->related('payment_items'); + + $this->template->setFile(__DIR__ . DIRECTORY_SEPARATOR . $this->templateName); + $this->template->render(); + } +} diff --git a/src/Components/RefundPaymentItemsListWidget/refund_payment_items_list_widget.latte b/src/Components/RefundPaymentItemsListWidget/refund_payment_items_list_widget.latte new file mode 100644 index 0000000..9061fac --- /dev/null +++ b/src/Components/RefundPaymentItemsListWidget/refund_payment_items_list_widget.latte @@ -0,0 +1,67 @@ +
+
+ {_payments.admin.payments.show.payment_items} +
+
+ + + + + + + + + + + + {var $totalAmount = 0} + {var $totalAmountWithoutVat = 0} + {foreach $paymentItems as $paymentItem} + + + + + + + + + {php $totalAmount += $paymentItem->amount * $paymentItem->count} + {php $totalAmountWithoutVat += $paymentItem->amount_without_vat * $paymentItem->count} + {/foreach} + +
+ {_payments.admin.payments.show.payment_item} + + {_payments.admin.payments.show.payment_item_type} + + {_payments.admin.payments.count} + + {_payments.admin.payments.short_unit_price} + + {_payments.admin.payments.amount} +
{$paymentItem->name} + {$paymentItem->type} + {$paymentItem->count}{$paymentItem->amount|price}{($paymentItem->amount * $paymentItem->count)|price}
+ +
+ +
+
+ + + + + + + + + + + + + +
{_payments.admin.payments.amount}{$totalAmount|price}
{_payments.admin.payments.amount_without_vat}{$totalAmountWithoutVat|price}
{_payments.admin.payments.vat_rate}{($totalAmount-$totalAmountWithoutVat)|price}
+
+
+
+
\ No newline at end of file diff --git a/src/Components/UserPaymentsListing/user_payments_listing.latte b/src/Components/UserPaymentsListing/user_payments_listing.latte index 1ac458d..175b9f1 100644 --- a/src/Components/UserPaymentsListing/user_payments_listing.latte +++ b/src/Components/UserPaymentsListing/user_payments_listing.latte @@ -54,31 +54,7 @@ - + {control simpleWidget 'admin.payment.status.dropdown_menu', $payment} diff --git a/src/DataProviders/PaymentRefundFormDataProviderInterface.php b/src/DataProviders/PaymentRefundFormDataProviderInterface.php new file mode 100644 index 0000000..153664e --- /dev/null +++ b/src/DataProviders/PaymentRefundFormDataProviderInterface.php @@ -0,0 +1,16 @@ +addProtection(); + $form->setTranslator($this->translator); + $form->setRenderer(new BootstrapRenderer()); + + $payment = $this->paymentsRepository->find($paymentId); + + $form->addHidden(self::PAYMENT_ID_KEY)->setRequired()->setDefaultValue($payment->id); + + // For case, if you want to change final payment status via dataProvider + $form->addHidden(self::NEW_PAYMENT_STATUS) + ->setRequired() + ->setDefaultValue(PaymentsRepository::STATUS_REFUND); + + $now = new DateTime(); + if ($payment->subscription && $payment->subscription->end_time > $now) { + if ($payment->status != PaymentsRepository::STATUS_REFUND) { + $form->addText( + self::SUBSCRIPTION_ENDS_AT_KEY, + 'payments.admin.payment_refund.form.cancel_subscription_date' + ) + ->setRequired('payments.admin.payment_refund.form.required.subscription_ends_at') + ->setHtmlAttribute('class', 'flatpickr') + ->setHtmlAttribute('flatpickr_datetime', "1") + ->setHtmlAttribute('flatpickr_datetime_seconds', "1") + ->setHtmlAttribute('flatpickr_mindate', $now->format('d.m.Y H:i:s')) + ->setDefaultValue($now->format('Y-m-d H:i:s')); + } + + $form->addHidden('subscription_default_ends_at') + ->setRequired() + ->setHtmlId('subscription_default_ends_at') + ->setDefaultValue($payment->subscription->end_time); + + $form->addHidden('subscription_starts_at') + ->setRequired() + ->setHtmlId('subscription_starts_at') + ->setDefaultValue($payment->subscription->start_time); + } + + if ($this->recurrentPaymentCanBeStoppedInRefund($payment) && $payment->status != PaymentsRepository::STATUS_REFUND) { + $form->addCheckbox( + self::STOP_RECURRENT_CHARGE_KEY, + 'payments.admin.payment_refund.form.stop_recurrent_charge' + ) + ->setDisabled() + ->setDefaultValue(true); + } + + if ($payment->status != PaymentsRepository::STATUS_REFUND) { + $form->addSubmit('submit', 'payments.admin.payment_refund.confirm_refund') + ->getControlPrototype() + ->setName('button') + ->setAttribute('class', 'btn btn-danger'); + } + + /** @var PaymentRefundFormDataProviderInterface[] $providers */ + $providers = $this->dataProviderManager->getProviders( + PaymentRefundFormDataProviderInterface::PATH, + PaymentRefundFormDataProviderInterface::class + ); + foreach ($providers as $provider) { + $form = $provider->provide(['form' => $form]); + } + + $form->onSuccess[] = [$this, 'formSucceeded']; + + return $form; + } + + public function formSucceeded(Form $form, ArrayHash $values): void + { + $payment = $this->paymentsRepository->find($values[self::PAYMENT_ID_KEY]); + $newEndTime = $values[self::SUBSCRIPTION_ENDS_AT_KEY] ?? null; + $newPaymentStatus = $values[self::NEW_PAYMENT_STATUS] ?? $payment->status; + $stopRecurrentPayment = $values[self::STOP_RECURRENT_CHARGE_KEY] ?? true; + + if ($newEndTime && $payment->subscription_id) { + $this->updateSubscriptionOnSuccess($payment->subscription, new DateTime($newEndTime)); + } + + if ($stopRecurrentPayment && $this->recurrentPaymentCanBeStoppedInRefund($payment)) { + $this->stopRecurrentChargeInRefundedPayment($payment); + } + + $this->paymentsRepository->update($payment, ['status' => $newPaymentStatus]); + + /** @var PaymentRefundFormDataProviderInterface[] $providers */ + $providers = $this->dataProviderManager->getProviders( + PaymentRefundFormDataProviderInterface::PATH, + PaymentRefundFormDataProviderInterface::class + ); + foreach ($providers as $provider) { + [$form, $values] = $provider->formSucceeded($form, $values); + } + + if (isset($this->onSave)) { + ($this->onSave)($values[self::PAYMENT_ID_KEY]); + } + } + + protected function updateSubscriptionOnSuccess(ActiveRow $subscription, DateTime $newEndTime): void + { + if ($newEndTime <= new DateTime()) { + $this->stopSubscriptionHandler->stopSubscription($subscription, true); + } else { + $this->shortenSubscription($subscription, $newEndTime); + } + } + + protected function recurrentPaymentCanBeStoppedInRefund(ActiveRow $payment): bool + { + $recurrentPayment = $this->recurrentPaymentsRepository->recurrent($payment); + + if (!$recurrentPayment) { + return false; + } + + $lastRecurrentPayment = $this->recurrentPaymentsRepository->getLastWithState( + $recurrentPayment, + RecurrentPaymentsRepository::STATE_ACTIVE, + ); + + return $lastRecurrentPayment + && $this->recurrentPaymentsRepository->canBeStopped($lastRecurrentPayment); + } + + protected function stopRecurrentChargeInRefundedPayment(ActiveRow $payment): void + { + $recurrentPayment = $this->recurrentPaymentsRepository->recurrent($payment); + $lastRecurrentPayment = $this->recurrentPaymentsRepository->getLastWithState( + $recurrentPayment, + RecurrentPaymentsRepository::STATE_ACTIVE, + ); + + $this->recurrentPaymentsRepository->stoppedByAdmin($lastRecurrentPayment); + } + + protected function shortenSubscription(ActiveRow $subscription, DateTime $newEndTime): void + { + $note = '[Admin shortened] From ' . $subscription->end_time->format('Y-m-d H:i:s') . ' to ' . $newEndTime->format('Y-m-d H:i:s'); + if (!empty($subscription->note)) { + $note = $subscription->note . "\n" . $note; + } + + $this->subscriptionsRepository->update($subscription, [ + 'end_time' => $newEndTime, + 'note' => $note, + ]); + + $this->emitter->emit(new SubscriptionShortenedEvent($subscription, $newEndTime)); + } +} diff --git a/src/PaymentsModule.php b/src/PaymentsModule.php index a5948dd..3b0e307 100644 --- a/src/PaymentsModule.php +++ b/src/PaymentsModule.php @@ -57,8 +57,10 @@ use Crm\PaymentsModule\Components\ParsedMailsFailedNotification\ParsedMailsFailedNotification; use Crm\PaymentsModule\Components\PaymentDonationLabelWidget\PaymentDonationLabelWidget; use Crm\PaymentsModule\Components\PaymentItemsListWidget\PaymentItemsListWidget; +use Crm\PaymentsModule\Components\PaymentStatusDropdownMenuWidget\PaymentStatusDropdownMenuWidget; use Crm\PaymentsModule\Components\PaymentToSubscriptionMenu\PaymentToSubscriptionMenu; use Crm\PaymentsModule\Components\ReactivateFailedRecurrentPaymentWidget\ReactivateFailedRecurrentPaymentWidget; +use Crm\PaymentsModule\Components\RefundPaymentItemsListWidget\RefundPaymentItemsListWidget; use Crm\PaymentsModule\Components\RefundPaymentsListWidget\RefundPaymentsListWidget; use Crm\PaymentsModule\Components\SubscribersWithPaymentWidget\SubscribersWithPaymentWidgetFactory; use Crm\PaymentsModule\Components\SubscriptionDetailWidget\SubscriptionDetailWidget; @@ -338,10 +340,20 @@ public function registerLazyWidgets(LazyWidgetManagerInterface $widgetManager) SubscriptionDetailWidget::class ); + $widgetManager->registerWidget( + 'admin.payment.status.dropdown_menu', + PaymentStatusDropdownMenuWidget::class + ); + $widgetManager->registerWidget( 'subscriptions.admin.user_subscriptions_listing.action.menu', PaymentToSubscriptionMenu::class, ); + + $widgetManager->registerWidget( + 'admin.refund_payment.show.left', + RefundPaymentItemsListWidget::class + ); } public function registerCommands(CommandsContainerInterface $commandsContainer) diff --git a/src/Presenters/PaymentsRefundAdminPresenter.php b/src/Presenters/PaymentsRefundAdminPresenter.php new file mode 100644 index 0000000..e317322 --- /dev/null +++ b/src/Presenters/PaymentsRefundAdminPresenter.php @@ -0,0 +1,44 @@ +paymentsRepository->find($paymentId); + + $this->template->payment = $payment; + $this->template->subscription = $payment->subscription; + $this->template->translator = $this->translator; + } + + /** + * @throws DataProviderException + */ + public function createComponentPaymentRefundForm(PaymentRefundFormFactory $paymentRefundFormFactory): Form + { + $form = $paymentRefundFormFactory->create($this->getParameter('paymentId')); + + $paymentRefundFormFactory->onSave = function (int $paymentId) { + $this->flashMessage( + $this->translator->translate('payments.admin.payment_refund.form.refund_was_successful') + ); + $this->redirect(':Payments:PaymentsAdmin:Show', $paymentId); + }; + + return $form; + } +} diff --git a/src/Repositories/PaymentsRepository.php b/src/Repositories/PaymentsRepository.php index f2510a7..e30f90d 100644 --- a/src/Repositories/PaymentsRepository.php +++ b/src/Repositories/PaymentsRepository.php @@ -469,10 +469,10 @@ final public function getStatusPairs() self::STATUS_FORM => self::STATUS_FORM, self::STATUS_FAIL => self::STATUS_FAIL, self::STATUS_PAID => self::STATUS_PAID, + self::STATUS_PREPAID => self::STATUS_PREPAID, self::STATUS_TIMEOUT => self::STATUS_TIMEOUT, self::STATUS_REFUND => self::STATUS_REFUND, self::STATUS_IMPORTED => self::STATUS_IMPORTED, - self::STATUS_PREPAID => self::STATUS_PREPAID, ]; } diff --git a/src/config/config.neon b/src/config/config.neon index 72ea6a5..46c9f93 100644 --- a/src/config/config.neon +++ b/src/config/config.neon @@ -21,6 +21,7 @@ services: - Crm\PaymentsModule\Forms\PaymentFormFactory - Crm\PaymentsModule\Forms\PaymentGatewayFormFactory + - Crm\PaymentsModule\Forms\PaymentRefundFormFactory - Crm\PaymentsModule\Models\PaymentsHistogramFactory recurrentPaymentsResolver: Crm\PaymentsModule\Models\RecurrentPaymentsResolver - Crm\PaymentsModule\Forms\RecurrentPaymentFormFactory @@ -47,7 +48,9 @@ services: - Crm\PaymentsModule\Components\AddressWidget\AddressWidget - Crm\PaymentsModule\Components\ChangePaymentSubscriptionTypeWidget\ChangePaymentSubscriptionTypeWidget - Crm\PaymentsModule\Components\PaymentDonationLabelWidget\PaymentDonationLabelWidget + - Crm\PaymentsModule\Components\PaymentStatusDropdownMenuWidget\PaymentStatusDropdownMenuWidget - Crm\PaymentsModule\Components\PaymentToSubscriptionMenu\PaymentToSubscriptionMenu + - Crm\PaymentsModule\Components\RefundPaymentItemsListWidget\RefundPaymentItemsListWidget - Crm\PaymentsModule\Components\SubscriptionDetailWidget\SubscriptionDetailWidget - Crm\PaymentsModule\Commands\RecurrentPaymentsCardCheckCommand - Crm\PaymentsModule\Commands\RecurrentPaymentsChargeCommand diff --git a/src/lang/payments.cs_CZ.yml b/src/lang/payments.cs_CZ.yml index 583c885..d2001e3 100644 --- a/src/lang/payments.cs_CZ.yml +++ b/src/lang/payments.cs_CZ.yml @@ -255,6 +255,11 @@ admin: recurrent: title: ARPU - celkem všech rekurentných plateb / počet tooltip: 'Zobrazuje sumu všech rekurentne vytvořených plateb za dané období děleno počtem plateb - ARPA' + + recurrent: + duplicates: + title: Duplicitní recurrentní platby + stats: title: Statistiky plateb menu: @@ -408,7 +413,30 @@ admin: message: Zpráva no_records: "Nebyly nalezeny žádné záznamy, které by odpovídaly filtru" + payment_refund: + header: Vrácení platby + confirm_refund: Vrátit platbu + default_ends_at: Původní datum konce + form: + cancel_subscription_date: Ukončit předplatné ke dni + refund_was_successful: Vrácení platby bylo úspěšné! + stop_recurrent_charge: Zastavit automatickou obnovu + required: + subscription_ends_at: Datum konce předplatného je povinen údaj + subscription: + subscription_settings: Nastavení předplatného + payment_has_active_subscription: Platba obsahuje aktivní předplatné + automatic_renewal: Automatická obnova + user: + email: E-mail + address: Adresa + registered: Registrován + active: Aktivní + source: Zdroj + language: Jazyk + payments: + payment_info: Informace o platbě updated: Platba byla upravena created: Platba byla vytvořena send_notification: Pošli notifikaci emailem @@ -417,12 +445,16 @@ admin: variable_symbol: Variabilní symbol user: Uživatel amount: Částka + amount_without_vat: Částka bez DPH gateway: Platební brána items: Položky status: Stav created_at: Vytvořeno modified_at: Upraveno actions: Akce + note: Poznámka + referer: Referer + status_text: Platba je aktuálně ve stavu recurrent_charge: Automaticky obnoveno donation: Dar donation_recurrent: Opakovaný dar @@ -437,6 +469,7 @@ admin: item: položka item_name: Název price_with_vat: Jednotková cena s DPH + short_unit_price: Jedn. cena vat_rate: Sazba DPH enter_number_of_products: Zadejte počet kusů count: Počet kusů @@ -451,6 +484,8 @@ admin: back: zpět na uživatele subscription_id: ID předplatného payment_items: Položky platby + payment_item: Položka platby + payment_item_type: Typ položky recurrent_payment: Rekurentní platba recurrent_charge: Obnovená platba recurrent_previous: Vytvořeno rekurentní platbou @@ -652,7 +687,6 @@ frontend: success: "Přidání karty bylo úspěšné. Platba vytvořená pro potřeby ověření karty Vám bude brzy vrácena." error: "Neúspěšný pokus o přidání karty. Zkuste to prosím znovu." - config: category: Platby category_confirmation: Potvrzovací e-maily @@ -689,7 +723,11 @@ config: name: Paypal signature paypal_merchant: name: Paypal merchant - paypal_ipn_email: {} + paypal_ipn_baseurl: + name: Paypal IPN URL + paypal_ipn_email: + name: Paypal IPN email + description: '"Receiver email" pro kontrolu IPN zprávy. Nechte prázdný pro vynechání této kontroly' csob_merchant_id: name: ČSOB Merchant ID description: 'Merchant ID poskytnuté bankou nebo vygenerované přes https://iplatebnibrana.csob.cz/keygen/ (pro vývojářské účely)' diff --git a/src/lang/payments.de_DE.yml b/src/lang/payments.de_DE.yml index fdf1ea7..56db4c9 100644 --- a/src/lang/payments.de_DE.yml +++ b/src/lang/payments.de_DE.yml @@ -352,12 +352,37 @@ admin: title: Verarbeitete Zahlungs-E-Mails no_records: Keine Datensätze entsprechen den Filterbedingungen delivered_at: Erhalten am + + payment_refund: + header: Erstattung + confirm_refund: Zurück geben + default_ends_at: Ursprüngliches Enddatum + form: + cancel_subscription_date: Abonnement bis heute beenden + refund_was_successful: Die Rückerstattung war erfolgreich! + stop_recurrent_charge: Stoppen Sie die automatische Verlängerung + required: + subscription_ends_at: Das Enddatum des Abonnements ist obligatorisch + subscription: + subscription_settings: Abonnementeinstellungen + payment_has_active_subscription: Die Zahlung beinhaltet ein aktives Abonnement + automatic_renewal: Automatische Erneuerung + user: + email: Email + address: Adresse + registered: Eingetragen + active: Aktiv + source: Quelle + language: Sprache + payments: + payment_info: Zahlungsinformationen updated: Die Zahlung wurde angepasst created: Die Zahlung wurde erstellt close: Schließen title: Zahlungen amount: Summe + amount_without_vat: Betrag ohne MwSt. donation: Spende donation_recurrent: Wiederholend Spende paid_at: Bezahlt @@ -378,16 +403,37 @@ admin: label: Export modal_body: Der Export wird enthält die gefilterten Zahlungen enthalten und unter Exporten verfügbar sein. price_with_vat: Einzelpreis inkl. MwSt. + short_unit_price: Eins. der Preis send_notification: Benachrichtigung per E-Mail senden created_at: Angelegt am recurrent_charge: Wiederholende Abbuchung variable_symbol: Variables Symbol items: Artikel actions: Aktionen + note: Notiz + referer: Referent + status_text: Die Zahlung befindet sich derzeit im Status user: Nutzer gateway: Zahlungsdienstleister status: Status item_name: Titel + show: + header: Zahlung + menu_link: Zahlungsdetails + back: zurück zum Benutzer + subscription_id: Abonnement-ID + payment_items: Zahlungsposten + payment_item: Zahlungsposten + payment_item_type: Gegenstandsart + recurrent_payment: Wiederkehrende Zahlung + recurrent_charge: Erneute Zahlung + recurrent_previous: Erstellt durch wiederkehrende Zahlung + recurrent_next: Die folgende wiederkehrende Zahlung + payment_meta: + header: Meta + ip: IP Adresse + user_agent: User-Agent + report: no_recurrent_charge: label: Bislang keine wiederkehrende Abbuchung @@ -528,6 +574,7 @@ form: label: Zahlungszeitpunkt placeholder: z.B. 14.2.2016 14:21 required: Angabe ist erforderlich. + no_future_paid_at: Bezahlt um kann nicht in der Zukunft liegen. send_notification: label: Benachrichtigung senden manual_subscription: diff --git a/src/lang/payments.en_US.yml b/src/lang/payments.en_US.yml index 6c26ec1..6f9aca1 100644 --- a/src/lang/payments.en_US.yml +++ b/src/lang/payments.en_US.yml @@ -413,7 +413,30 @@ admin: message: Message no_records: No records match selected filter + payment_refund: + header: Refund + confirm_refund: Confirm refund + default_ends_at: Default end date + form: + cancel_subscription_date: End subscription to date + refund_was_successful: The refund was successful! + stop_recurrent_charge: Stop automatic renewal + required: + subscription_ends_at: The subscription end date is required + subscription: + subscription_settings: Subscription settings + payment_has_active_subscription: The payment includes an active subscription + automatic_renewal: Automatic renewal + user: + email: E-mail + address: Address + registered: Registered + active: Active + source: Source + language: Language + payments: + payment_info: Payment information updated: Payment was updated created: Payment was created send_notification: Send notification via email @@ -422,12 +445,16 @@ admin: variable_symbol: Variable symbol user: User amount: Amount + amount_without_vat: Amount without VAT gateway: Payment gateway items: Items status: Status created_at: Created at modified_at: Updated at actions: Actions + note: Note + referer: Referer + status_text: The payment is currently in status recurrent_charge: Recurrent charge donation: Donation donation_recurrent: Recurrent donation @@ -442,6 +469,7 @@ admin: item: item item_name: Name price_with_vat: Unit price with VAT + short_unit_price: Unit price vat_rate: VAT rate enter_number_of_products: Enter number of products count: Count @@ -456,6 +484,8 @@ admin: back: back to user subscription_id: ID of subscription payment_items: Payment items + payment_item: Payment item + payment_item_type: Type recurrent_payment: Recurrent payment recurrent_charge: Automatically charged payment recurrent_previous: Created by recurrent payment diff --git a/src/lang/payments.hu_HU.yml b/src/lang/payments.hu_HU.yml index 545bc66..6ab27a4 100644 --- a/src/lang/payments.hu_HU.yml +++ b/src/lang/payments.hu_HU.yml @@ -315,7 +315,30 @@ admin: message: Üzenet no_records: Nincs találat + payment_refund: + header: Visszatérítés + confirm_refund: A fizetés visszaküldése + default_ends_at: Eredeti befejezési dátum + form: + cancel_subscription_date: Az előfizetés leállítása a mai napig + refund_was_successful: A visszatérítés sikeres volt! + stop_recurrent_charge: Állítsa le az automatikus megújítást + required: + subscription_ends_at: Az előfizetés befejezési dátuma kötelező + subscription: + subscription_settings: Előfizetési beállítások + payment_has_active_subscription: A fizetés aktív előfizetést is tartalmaz + automatic_renewal: Automatikus megújítás + user: + email: E-mail + address: Cím + registered: Bejegyzett + active: Aktív + source: Forrás + language: Nyelv + payments: + payment_info: Fizetési információ updated: Fizetés frissítve created: Fizetés létrehozva send_notification: Értesítés küldése e-mailben @@ -324,11 +347,15 @@ admin: variable_symbol: Fizetés egyedi azonosítója user: Felhasználó amount: Összeg + amount_without_vat: Áfa nélküli összeg gateway: Fizetési kapu items: Tételek status: Állapot created_at: Létrehozva actions: Műveletek + note: Jegyzet + referer: Hivatalnok + status_text: A fizetés jelenleg státuszban van recurrent_charge: Ismétlődő díj donation: Adomány donation_recurrent: Ismétlődő adomány @@ -343,9 +370,31 @@ admin: item: tétel item_name: Név price_with_vat: Egységár ÁFÁ-val + short_unit_price: Egy. az ár vat_rate: ÁFA enter_number_of_products: Termékek száma count: Count + export: + label: Export + exported: 'Az exportálás hozzáadva a sorhoz, és elérhető lesz az exportálások között.' + modal_title: Exportfizetések + modal_body: 'Az exportálás szűrt fizetéseket tartalmaz majd, és az exportálás alatt lesz elérhető.' + show: + header: Fizetés + menu_link: Fizetési részletek + back: vissza a felhasználóhoz + subscription_id: Előfizetési azonosító + payment_items: Fizetési tételek + payment_item: Fizetési tétel + payment_item_type: Tárgy típus + recurrent_payment: Ismétlődő fizetés + recurrent_charge: Megújított fizetés + recurrent_previous: Ismétlődő fizetéssel létrehozva + recurrent_next: A következő ismétlődő fizetés + payment_meta: + header: Meta + ip: IP-cím + user_agent: User-Agent report: no_recurrent_charge: @@ -412,6 +461,7 @@ form: label: Fizetés időpontja placeholder: pl. 14.2.2016 14:21 required: A tétel megadása kötelező + no_future_paid_at: Fizetni nem lehet a jövőben. send_notification: label: Értesítés küldése manual_subscription: diff --git a/src/lang/payments.sk_SK.yml b/src/lang/payments.sk_SK.yml index 37db7ba..ad1b202 100644 --- a/src/lang/payments.sk_SK.yml +++ b/src/lang/payments.sk_SK.yml @@ -413,7 +413,30 @@ admin: message: Správa no_records: Nenašli sa žiadne záznamy ktoré by zodpovedali filtru + payment_refund: + header: Vrátenie platby + confirm_refund: Vrátiť platbu + default_ends_at: Pôvodný dátum konca + form: + cancel_subscription_date: Ukončiť predplatné ku dňu + refund_was_successful: Vrátenie platby bolo úspešné! + stop_recurrent_charge: Zastaviť automatickú obnovu + required: + subscription_ends_at: Dátum konca predplatného je povinný údaj + subscription: + subscription_settings: Nastavenia predplatného + payment_has_active_subscription: Platba obsahuje aktívne predplatné + automatic_renewal: Automatická obnova + user: + email: E-mail + address: Adresa + registered: Registrovaný + active: Aktívny + source: Zdroj + language: Jazyk + payments: + payment_info: Informácie o platbe updated: Platba bola upravená created: Platba bola vytvorená send_notification: Pošli notifikáciu emailom @@ -422,12 +445,16 @@ admin: variable_symbol: Variabilný symbol user: Používateľ amount: Suma + amount_without_vat: Suma bez DPH gateway: Platobná brána items: Položky status: Stav created_at: Vytvorené modified_at: Upravené actions: Akcie + note: Poznámka + referer: Referer + status_text: Platba je aktuálne v stave recurrent_charge: Automaticky obnovené donation: Dar donation_recurrent: Opakovaný dar @@ -442,6 +469,7 @@ admin: item: položka item_name: Názov price_with_vat: Jednotková cena s DPH + short_unit_price: Jedn. cena vat_rate: Sadzba DPH enter_number_of_products: Zadajte počet kusov count: Počet kusov @@ -456,6 +484,8 @@ admin: back: späť na používateľa subscription_id: ID predplatného payment_items: Položky platby + payment_item: Položka platby + payment_item_type: Typ položky recurrent_payment: Rekurentná platba recurrent_charge: Obnovená platba recurrent_previous: Vytvorené rekurentnou platbou diff --git a/src/templates/PaymentsAdmin/default.latte b/src/templates/PaymentsAdmin/default.latte index 5b95519..224529f 100644 --- a/src/templates/PaymentsAdmin/default.latte +++ b/src/templates/PaymentsAdmin/default.latte @@ -110,28 +110,7 @@ - + {control simpleWidget 'admin.payment.status.dropdown_menu', $payment} {$payment->created_at|userDate} diff --git a/src/templates/PaymentsAdmin/edit.latte b/src/templates/PaymentsAdmin/edit.latte index 0713ec5..07f23e3 100644 --- a/src/templates/PaymentsAdmin/edit.latte +++ b/src/templates/PaymentsAdmin/edit.latte @@ -10,6 +10,13 @@ {_payments.admin.payments.edit}: [{$payment->id}] {$payment->variable_symbol} + + {control simpleWidget 'admin.payment.actions.header', $payment} + {if $payment->status != Crm\PaymentsModule\Repositories\PaymentsRepository::STATUS_REFUND} + + {_payments.admin.payment_refund.confirm_refund} + + {/if} diff --git a/src/templates/PaymentsAdmin/show.latte b/src/templates/PaymentsAdmin/show.latte index de6a8e6..879d881 100644 --- a/src/templates/PaymentsAdmin/show.latte +++ b/src/templates/PaymentsAdmin/show.latte @@ -33,6 +33,13 @@ {_payments.admin.payments.show.header} VS {$payment->variable_symbol} + + {control simpleWidget 'admin.payment.actions.header', $payment} + {if $payment->status != Crm\PaymentsModule\Repositories\PaymentsRepository::STATUS_REFUND} + + {_payments.admin.payment_refund.confirm_refund} + + {/if} {_payments.admin.payments.edit} @@ -45,6 +52,9 @@
+ + {control simpleWidget 'admin.payment.show.alert', $payment} +