Commit d76cd8a9 authored by Thomas Citharel's avatar Thomas Citharel 🌲

better invoice and update deps

Signed-off-by: Thomas Citharel's avatarThomas Citharel <tcit@tcit.fr>
parent 1c801e24
......@@ -22,6 +22,7 @@ class AppKernel extends Kernel
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Knp\Bundle\SnappyBundle\KnpSnappyBundle(),
new UserBundle\UserBundle(),
new AppBundle\AppBundle(),
];
......
@import '~bootstrap/dist/css/bootstrap.css';
\ No newline at end of file
......@@ -368,13 +368,14 @@ command:
sent: En attente de paiement
responded: Paiement reçu
waiting_configuration: En attente de configuration des domaines
cancelled: Commande annulée
command_cancelled: Commande annulée
payment_cancelled: Paiement annulé
payment_issue: Souci avec le paiement
finished: Achevée
partially_finished: Partiellement achevée
unknown: Inconnu
not_payed: Non payée
label: Statut
created_at: Créée le %date%
payment_type:
bankwire: Virement bancaire
......@@ -397,11 +398,12 @@ command:
action: Action
invoice:
label: Facture
invoice_number: Facture n°
invoice_number: Facture n°%number%
order_summary: Résumé de la commande
created: Créée à
payment_method: Méthode de paiement
payment_method_card: Carte bancaire
payment_informations: Informations sur le paiement
payment_informations: Méthode de paiement
payment_method_preauth: (enregistrée)
card: Carte bancaire %type% finissant par %last4%
item: Produit
......@@ -493,6 +495,8 @@ payment:
creation_date: Date d'ajout
expiration_date: Date d'expiration
numbers: Numéro
title: Carte %brand% finissant par %last4%
title_default: Carte %brand% finissant par %last4% (carte par défaut)
id: Identifiant
created_at: Créé le
paid_at: Payé le
......@@ -782,14 +786,19 @@ user:
title: Supprimer mon compte
recap:
one: "Voici un récapitulatif des actions qui vont être entreprises :"
domains: "Les domaines suivants vont être détachés de votre compte et si vous les avez achetés via Framasite, vous allez recevoir des instructions pour en prendre le contrôle :"
sites: "Les sites et wikis suivants vont être <b>purement et simplement supprimés</b> :"
domains:
header: "Les domaines suivants vont être détachés de votre compte et si vous les avez achetés via Framasite, vous allez recevoir des instructions de la part de notre partenaire Gandi pour en prendre le contrôle :"
footer: "Note : les factures liées à l'achat de domaines ne seront plus disponibles. Pensez donc à les sauvegarder avant de supprimer votre compte"
domain_not_frama: Domaine non enregistré par Framasoft, merci de ne plus le faire pointer sur le serveur de Framasite.
sites:
header: "Les sites et wikis suivants vont être <b>purement et simplement supprimés</b>, avec tous leurs contenus :"
footer: Vous pouvez exporter vos sites et wikis en vous rendant dans leurs paramètres
password_prompt: Merci d'entrer votre mot de passe pour confirmer que vous voulez bien effectuer toutes ces actions
domain_not_frama: Domaine non enregistré par Framasoft, merci de ne plus le faire pointer sur le serveur de Framasite.
account: Votre compte %username% va être supprimé
form:
password:
label: Mot de passe
info: Vous devez entrer votre mot de passe pour confirmer la suppression de votre compte
info: Vous devez entrer votre mot de passe pour confirmer la suppression de votre compte. Si vous avez oublié votre mot de passe, vous pouvez vous déconnecter puis cliquer sur « Mot de passe oublié » sur le formulaire de connexion.
cancel: Annuler
submit: Supprimer mon compte
......@@ -801,6 +810,7 @@ breadcrumbs:
buy_new: Achat d'un nouveau domaine
attach_existing: Rattachement d'un domaine existant
price: Prix des domaines
help: Aide
email:
title: Boites email
new: Nouvelle boite
......
......@@ -19,6 +19,7 @@
</div>
</div>
<div class="uk-card-body">
<p>{{ 'command.status.label' | trans }}&nbsp;: {{ command.status | command_status | trans }}</p>
{% if command.status >= 50 %}
{{ 'command.details.stripe_id' | trans({'%stripe_id%': command.stripeId}) }}
{% endif %}
......
......@@ -5,7 +5,7 @@
<ol class="breadcrumb">
<li><a href="{{ path('homepage') }}">{{ 'breadcrumbs.home' | trans }}</a></li>
<li><a href="{{ path('settings') }}">{{ 'breadcrumbs.settings.title' | trans }}</a></li>
<li><a href="{{ path('delete-all-data') }}">{{ 'breadcrumbs.settings.delete_all_data' | trans }}</a></li>
<li><a href="{{ path('delete-all-data') }}">{{ 'breadcrumbs.settings.account.delete_all_data' | trans }}</a></li>
</ol>
......@@ -18,22 +18,23 @@
<p>{{ 'user.delete.recap.one' | trans }}</p>
{% if app.user.domains | length > 0 %}
<div class="alert alert-danger">
{{ 'user.delete.recap.domains' | trans }}
{{ 'user.delete.recap.domains.header' | trans }}
<ul>
{% for domain in app.user.domains %}
{% if domain.registeredByFrama %}
<li>{{ domain.domainName }}</li>
{% else %}
<li>{{ domain.domainName }} ({{ 'user.delete.recap.domain_not_frama' | trans }})</li>
<li>{{ domain.domainName }} ({{ 'user.delete.recap.domains.domain_not_frama' | trans }})</li>
{% endif %}
{% endfor %}
</ul>
{{ 'user.delete.recap.domains.footer' | trans }}
</div>
{% endif %}
{% if app.user.sites | length > 0 %}
<div class="alert alert-danger">
{{ 'user.delete.recap.sites' | trans | raw }}
{{ 'user.delete.recap.sites.header' | trans | raw }}
<ul>
{% for site in app.user.sites %}
<li>{{ site.subdomain }}.frama.{% spaceless %}{% if site is blog %}
......@@ -43,8 +44,12 @@
{% endif %}{% endspaceless %}</li>
{% endfor %}
</ul>
{{ 'user.delete.recap.sites.footer' | trans }}
</div>
{% endif %}
<div class="alert alert-danger">
{{ 'user.delete.recap.account' | trans({'%username%': app.user.username}) }}
</div>
<p>{{ 'user.delete.recap.password_prompt' | trans }}</p>
......@@ -58,7 +63,9 @@
</div>
<a href="{{ path('settings') }}" class="btn btn-default">{{ 'user.delete.form.cancel' | trans }}</a>
{{ form_widget(form.save) }}
<div class="pull-right">
{{ form_widget(form.save) }}
</div>
{{ form_end(form) }}
</div>
......
......@@ -2,6 +2,12 @@
{% block content %}
<ol class="breadcrumb">
<li><a href="{{ path('homepage') }}">{{ 'breadcrumbs.home' | trans }}</a></li>
<li><a href="{{ path('domain') }}">{{ 'breadcrumbs.domains.title' | trans }}</a></li>
<li><a href="{{ path('domain-help') }}">{{ 'breadcrumbs.domains.help' | trans }}</a></li>
</ol>
<div class="clearfix">
<h3>C'est quoi ?</h3>
......@@ -18,9 +24,6 @@
</div>
<div class="alert alert-warning">Dans quelques semaines, cette étape pourra être réalisée directement depuis le site Framasite, en déléguant à Framasoft l'achat du domaine et son rattachement automatique à votre Framasite. D'ici là, la procédure doit être faite manuellement.</div>
<div class="uk-flex uk-flex-center uk-flex-middle">
<a href="{{ path('domain-help') }}" class="btn btn-primary">Guide pour associer un domaine à un Framasite</a>
</div>
<h3>Comment ça marche ?</h3>
......
......@@ -3,7 +3,7 @@
{% block content %}
<div class="row progress">
{% set progress = 40 + (60 / nbDomains) * passedDomains %}
{% set progress = 60 + (40 / nbDomains) * passedDomains %}
<div class="progress-bar" role="progressbar" aria-valuenow="{{ progress }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ progress }}%;">
{{ progress }}%
</div>
......
......@@ -6,8 +6,8 @@
<div class="uk-card uk-card-default uk-width-1-2@m">
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%;">
20%
<div class="progress-bar" role="progressbar" aria-valuenow="30" aria-valuemin="0" aria-valuemax="100" style="width: 30%;">
30%
</div>
</div>
<form action="{{ path('payment-process', {'command': command.id}) }}" method="post" id="payment-form" class="form">
......@@ -31,7 +31,20 @@
<tbody>
{% for card in cards %}
<tr>
<td><label><input type="radio" id='regular' name="card" value="{{ card.id }}"> {{ card.brand }} ****-{{ card.last4 }}</label></td>
<td><label><div style="padding: 19px 0 20px 65px;border-bottom: 1px solid #DCE3E6;position: relative">
<div style="position: absolute;left: 0;top: 33px;">
<input type="radio" id='regular' name="card" value="{{ card.id }}">
<i class="fa fa-cc-{{ card.brand | lower }}" aria-hidden="true" style="font-size: 1.7em"></i></div>
<div>
{% if card.id == default_card_id and cards | length > 1 %}
{{ 'payment.card.view.title_default' | trans({'%brand%': card.brand | capitalize, '%last4%': card.last4}) }}
{% else %}
{{ 'payment.card.view.title' | trans({'%brand%': card.brand | capitalize, '%last4%': card.last4}) }}
{% endif %}</div>
<div class="details" style="color: #999">
<span>• • • • • • • • • • • • {{ card.last4 }}</span>
</div>
</div></label></td>
<td>{{ card.exp_month }} / {{ card.exp_year }}</td>
</tr>
{% endfor %}
......
......@@ -4,8 +4,8 @@
<div class="uk-flex uk-flex-center command-view">
<div class="uk-card uk-card-default uk-width-1-2@m">
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%;">
40%
<div class="progress-bar" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%;">
50%
</div>
</div>
<div class="uk-card-header">
......
......@@ -186,6 +186,13 @@ old_sound_rabbit_mq:
queue_options: {name: 'check_domain'}
callback: AppBundle\Async\Gandi\CheckDomainConsumer
knp_snappy:
process_timeout: 120
pdf:
enabled: true
binary: "%kernel.project_dir%/vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64"
options: []
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
......
This diff is collapsed.
This diff is collapsed.
......@@ -6,6 +6,8 @@ use AppBundle\Entity\Command;
use AppBundle\Entity\User;
use AppBundle\Exception\PaymentException;
use AppBundle\Helper\PaymentFactory;
use Dompdf\Dompdf;
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
......@@ -101,7 +103,26 @@ class CommandController extends Controller
{
$this->checkUserAction($command);
$framasoftAddress = $this->getParameter('app.framasoft.address');
return $this->render('default/command/invoice.html.twig', ['command' => $command, 'framasoftAddress' => $framasoftAddress]);
return $this->render('default/command/invoice.html.twig', ['command' => $command, 'framasoftAddress' => $framasoftAddress, 'pdf' => false]);
}
/**
* @Route("/command/{command}/invoice/pdf", name="command-invoice-pdf")
*
* @param Command $command
* @return Response
*/
public function generatePdfInvoiceAction(Command $command): Response
{
$this->checkUserAction($command);
$framasoftAddress = $this->getParameter('app.framasoft.address');
$html = $this->renderView('default/command/invoice.html.twig', ['command' => $command, 'framasoftAddress' => $framasoftAddress, 'pdf' => true]);
return new PdfResponse(
$this->get('knp_snappy.pdf')->getOutputFromHtml($html, ['disable-javascript' => true]),
$command->getDomainNames() . '.pdf'
);
}
......
......@@ -123,6 +123,7 @@ class DomainCommandController extends Controller
* @Route("/domain/price", name="price-domain")
*
* @return Response
* @throws APIException
*/
public function showDomainPriceAction(): Response
{
......@@ -150,6 +151,7 @@ class DomainCommandController extends Controller
*
* @param Request $request
* @return Response
* @throws APIException
*/
public function addDomainAction(Request $request): Response
{
......
......@@ -95,7 +95,7 @@ class PaymentController extends Controller
*/
$this->logger->info("This is a direct payment without saving the card");
$charge = $this->paymentFactory->charge($command->getTotal() * 100, $token,'Direct payment for ' . $command->getDomainNames());
$charge = $this->paymentFactory->charge($command->getTotal() * 100, $token, 'Direct payment for ' . $command->getDomainNames());
$command->setPaymentType(Command::PAYMENT_TYPE_DIRECT);
} else {
/**
......@@ -158,10 +158,12 @@ class PaymentController extends Controller
$this->postSuccessPayment($command);
return $this->render(':default/payment:success.html.twig',
return $this->render(
':default/payment:success.html.twig',
[
'command' => $command,
]);
]
);
}
/**
......
......@@ -144,4 +144,4 @@ class CertTask
$this->user = $user;
return $this;
}
}
\ No newline at end of file
}
......@@ -16,7 +16,7 @@ class GetDomainType extends AbstractType
'required' => true,
'label_attr' => ['class' => 'col-sm-2'],
'label' => 'domain.name.label',
'attr' => ['pattern' => '^[a-zA-Z0-9][-a-zA-Z0-9]{0,38}[a-zA-Z0-9]$'],
'attr' => ['pattern' => '^[a-zA-Z0-9][-a-zA-Z0-9\.]{0,38}[a-zA-Z0-9]$'],
])
;
}
......
......@@ -39,7 +39,8 @@ class CertTaskFactory
* @return int
* @throws \Exception
*/
public function createCertTaskForAttachment(User $user,
public function createCertTaskForAttachment(
User $user,
Domain $domain,
int $action = CertData::ACTION_CREATE,
int $status = CertTask::STATUS_TODO,
......@@ -91,4 +92,4 @@ class CertTaskFactory
return $taskId;
}
}
\ No newline at end of file
}
......@@ -41,7 +41,6 @@ class PaymentFactory
$this->logger = $logger;
$this->router = $router;
Stripe::setApiKey($stripeKeyService->getPrivateKey());
}
/**
......@@ -97,7 +96,6 @@ class PaymentFactory
{
$charge = Charge::retrieve($chargeId);
return $charge->capture();
}
/**
......
......@@ -59,6 +59,7 @@ class CommandService extends BaseService
* @param User $user
* @param float $marge
* @return Command
* @throws \AppBundle\Exception\APIException
*/
public function newCommand(Domain $domain, User $user, float $marge = 1): Command
{
......@@ -103,26 +104,20 @@ class CommandService extends BaseService
*
* @param Command $command
* @param User $user
* @throws PaymentException
*/
public function makePayment(Command $command, User $user)
{
if ($command->getPaymentType() === Command::PAYMENT_TYPE_PREAUTH) {
$this->logger->info('Payment type is preauth');
$preAuthId = $command->getMangoPayPreAuthId();
$preAuth = $this->paymentFactory->getApi()->CardPreAuthorizations->Get($preAuthId);
if ($preAuth->Status === 'SUCCEEDED' && $preAuth->PaymentStatus === 'WAITING') {
$this->logger->info('Preauth has succeeded');
$payment = $this->paymentFactory->executePrePaidPayment($command, $user->getMangoPayId());
$command->setMangoPayId($payment->Id);
$this->entityManager->persist($command);
$this->entityManager->flush();
$this->invoiceService->sendInvoice($command);
} else {
$this->logger->error('Preauth payment failed');
throw new PaymentException("Something went very very wrong");
}
}
$this->logger->info('Capturing payment charge for command n°' . $command->getId() . ' by user ' . $user->getUsername());
$paymentId = $command->getStripeId();
$this->paymentFactory->captureCharge($paymentId);
$this->logger->info('Payment charge effective');
$command->setStatus(Command::STATUS_FINISHED);
$this->entityManager->persist($command);
$this->logger->info('Command is finished');
$this->invoiceService->sendInvoice($command);
}
}
......@@ -135,6 +135,7 @@ class DetachDomainService extends BaseService
* @param Domain $domain
* @param User $user
* @return Domain
* @throws \Exception
*/
public function dissociateDomain(Domain $domain, User $user): Domain
{
......
......@@ -2,7 +2,8 @@
namespace AppBundle\Service;
class StripeKeyService {
class StripeKeyService
{
/**
* @var string
......@@ -60,4 +61,4 @@ class StripeKeyService {
$this->publicKey = $publicKey;
return $this;
}
}
\ No newline at end of file
}
This diff is collapsed.
{
"build/app.js": "/build/app.js",
"build/bootstrap.css": "/build/bootstrap.css",
"build/fonts/glyphicons-halflings-regular.eot": "/build/fonts/glyphicons-halflings-regular.eot",
"build/fonts/glyphicons-halflings-regular.ttf": "/build/fonts/glyphicons-halflings-regular.ttf",
"build/fonts/glyphicons-halflings-regular.woff": "/build/fonts/glyphicons-halflings-regular.woff",
......
......@@ -15,6 +15,7 @@ Encore
// will output as web/build/global.css
.addStyleEntry('global', './app/Resources/static/style/style.css')
.addStyleEntry('bootstrap', './app/Resources/static/style/bootstrap.css')
// allow sass/scss files to be processed
.enableSassLoader()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment