✨ feat(AvisPaymentState): Ajoute les champs year et month pour le suivi.
🌐 i18n(messages.fr.yaml): Ajoute la traduction pour l'hébergement de site. ✨ feat(templates/price.twig): Ajoute les prix pour les offres d'hébergement. ✨ feat(AutoCreatedAvisPaymentCommand): Génère les avis de paiement pour l'hébergement. ♻️ refactor(PriceController): Gère la sauvegarde des prix d'hébergement. 📧 feat(avis-payment-wait.twig): Améliore le formatage du mail d'avis de paiement.
This commit is contained in:
34
migrations/Version20251112173808.php
Normal file
34
migrations/Version20251112173808.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251112173808 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE avis_payment_state ADD year VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE avis_payment_state ADD month VARCHAR(255) DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE avis_payment_state DROP year');
|
||||
$this->addSql('ALTER TABLE avis_payment_state DROP month');
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,13 @@ use App\Entity\AvisPaymentState;
|
||||
use App\Entity\CustomerAdvertPayment;
|
||||
use App\Entity\CustomerAdvertPaymentLine;
|
||||
use App\Entity\CustomerDns;
|
||||
use App\Entity\EsyWeb\WebsiteDates;
|
||||
use App\Repository\AvisPaymentStateRepository;
|
||||
use App\Repository\CustomerAdvertPaymentRepository;
|
||||
use App\Repository\CustomerDnsRepository;
|
||||
use App\Repository\CustomerPriceRepository;
|
||||
use App\Repository\EsyWeb\WebsiteDatesRepository;
|
||||
use App\Repository\EsyWeb\WebsiteRepository;
|
||||
use App\Service\Customer\CreateAvisEvent;
|
||||
use App\Service\Ovh\Client;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
@@ -29,6 +32,8 @@ class AutoCreatedAvisPaymentCommand extends Command
|
||||
private CustomerAdvertPaymentRepository $customerAdvertPaymentRepository,
|
||||
private AvisPaymentStateRepository $avisPaymentStateRepository,
|
||||
private EntityManagerInterface $entityManager,
|
||||
private WebsiteDatesRepository $websiteDatesRepository,
|
||||
private WebsiteRepository $websiteRepository,
|
||||
private CustomerPriceRepository $customerPriceRepository,
|
||||
private EventDispatcherInterface $eventDispatcher,
|
||||
?string $name = null)
|
||||
@@ -42,9 +47,10 @@ class AutoCreatedAvisPaymentCommand extends Command
|
||||
$io->title("Auto Generated Avis Payment");
|
||||
$nddRenouvellement = $this->customerPriceRepository->findOneBy(['type'=>'renouvellement_ndd']);
|
||||
$nddGestion = $this->customerPriceRepository->findOneBy(['type'=>'gestion_ndd']);
|
||||
$t = new \DateTime();
|
||||
/** @var CustomerDns $value */
|
||||
foreach ($this->customerDnsRepository->expitedSoon() as $value) {
|
||||
$searchCurrentStat = $this->avisPaymentStateRepository->findOneBy(['type'=>'ndd','target'=>$value->getNdd()]);
|
||||
$searchCurrentStat = $this->avisPaymentStateRepository->findOneBy(['type'=>'ndd','target'=>$value->getNdd(),'year'=>$t->format('Y')]);
|
||||
if(!$searchCurrentStat){
|
||||
$t = new \DateTimeImmutable();
|
||||
$num = "A-".$t->format('Y/m')."/".sprintf('%05d',$this->customerAdvertPaymentRepository->count()+1);
|
||||
@@ -107,9 +113,10 @@ class AutoCreatedAvisPaymentCommand extends Command
|
||||
$tThird = $tThird->modify("+2 week");
|
||||
$tFinal = new \DateTimeImmutable();
|
||||
$tFinal = $tFinal->modify("+1 month");
|
||||
$tThird = $tFinal->modify("+2 week");
|
||||
$tFinal = $tFinal->modify("+2 week");
|
||||
$tFinal = $tFinal->modify("+4 week");
|
||||
$avisState = new AvisPaymentState();
|
||||
$avisState->setYear($t->format('Y'));
|
||||
$avisState->setAvisPayment($avisPayment);
|
||||
$avisState->setFirstSendAt($tFirst);
|
||||
$avisState->setSecondSendAt($tSecond);
|
||||
@@ -134,6 +141,93 @@ class AutoCreatedAvisPaymentCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$hosting1 = $this->customerPriceRepository->findOneBy(['type'=>'hosting_1']);
|
||||
$hosting2 = $this->customerPriceRepository->findOneBy(['type'=>'hosting_2']);
|
||||
$hostingRestore = $this->customerPriceRepository->findOneBy(['type'=>'hosting_restore']);
|
||||
foreach ($this->websiteRepository->findBy(['state' =>'deploy']) as $value) {
|
||||
if($value->getOffert() == "Esy-Premium" || $value->getOffert() == "E-COMMERCE - PREMIUM") {
|
||||
$dates = $value->getWebsiteDates()->getNextHosting();
|
||||
$t = new \DateTimeImmutable();
|
||||
$diff = $t->diff($dates);
|
||||
if($diff->days <= 60) {
|
||||
$searchCurrentStat = $this->avisPaymentStateRepository->findOneBy(['type'=>'hosting','target'=>$value->getUuid(),'year'=>$t->format('Y')]);
|
||||
if(!$searchCurrentStat) {
|
||||
$t = new \DateTimeImmutable();
|
||||
$num = "A-" . $t->format('Y/m') . "/" . sprintf('%05d', $this->customerAdvertPaymentRepository->count() + 1);
|
||||
$io->info("Generate avis payment - Hosting " . $value->getTitle()." - EsyPremium");
|
||||
|
||||
$avisPayment = new CustomerAdvertPayment();
|
||||
$avisPayment->setState("created");
|
||||
$avisPayment->setCustomer($value->getCustomer());
|
||||
$avisPayment->setCreateAt(new \DateTimeImmutable('now'));
|
||||
$avisPayment->setUpdateAt(new \DateTimeImmutable('now'));
|
||||
$avisPayment->setNumAvis($num);
|
||||
$this->entityManager->persist($avisPayment);
|
||||
|
||||
$expiredAt = $value->getWebsiteDates()->getNextHosting();
|
||||
$expiredAt = $expiredAt->modify("-1 year");
|
||||
$newLimitAt = clone $value->getWebsiteDates()->getNextHosting();
|
||||
if($value->getType() =="vitrine") {
|
||||
$desciption = $hosting1->getDescription();
|
||||
$price = $hosting1->getAmmount();
|
||||
} else {
|
||||
$desciption = $hosting2->getDescription();
|
||||
$price = $hosting2->getAmmount();
|
||||
}
|
||||
$content = explode("\n", $desciption);
|
||||
$title = str_replace("{website_name}",$value->getMainDns(), $content[0]);
|
||||
unset($content[0]);
|
||||
$desciption = implode("\n", $content);
|
||||
$desciption = str_replace("{date_start}",$expiredAt->format('d M Y'),$desciption);
|
||||
$desciption = str_replace("{date_stop}",$newLimitAt->format('d M Y'),$desciption);
|
||||
|
||||
$avisLine = new CustomerAdvertPaymentLine();
|
||||
$avisLine->setPos(0);
|
||||
$avisLine->setName($title);
|
||||
$avisLine->setPriceHT($price);
|
||||
$avisLine->setContent($desciption);
|
||||
$avisLine->setTva(1.20);
|
||||
$this->entityManager->persist($avisLine);
|
||||
$avisPayment->addCustomerAdvertPaymentLine($avisLine);
|
||||
$this->entityManager->persist($avisPayment);
|
||||
$tFirst = new \DateTimeImmutable();
|
||||
$tSecond = new \DateTimeImmutable();
|
||||
$tSecond = $tSecond->modify("+1 month");
|
||||
$tThird = new \DateTimeImmutable();
|
||||
$tThird = $tThird->modify("+1 month");
|
||||
$tThird = $tThird->modify("+2 week");
|
||||
$tFinal = new \DateTimeImmutable();
|
||||
$tFinal = $tFinal->modify("+1 month");
|
||||
$tFinal = $tFinal->modify("+2 week");
|
||||
$tFinal = $tFinal->modify("+4 week");
|
||||
$avisState = new AvisPaymentState();
|
||||
$avisState->setYear($t->format('Y'));
|
||||
$avisState->setAvisPayment($avisPayment);
|
||||
$avisState->setFirstSendAt($tFirst);
|
||||
$avisState->setSecondSendAt($tSecond);
|
||||
$avisState->setThirdSendAt($tThird);
|
||||
$avisState->setFinalSendAt($tFinal);
|
||||
$avisState->setType("hosting");
|
||||
$avisState->setYear($t->format('Y'));
|
||||
$avisState->setTarget($value->getUuid());
|
||||
$avisState->setIsGenerated(true);
|
||||
$avisState->setIsValidated(false);
|
||||
$avisState->setIsFirstSend(false);
|
||||
$avisState->setIsSecondSend(false);
|
||||
$avisState->setIsThirdSend(false);
|
||||
$avisState->setIsFinalSend(false);
|
||||
$this->entityManager->persist($avisState);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$event = new CreateAvisEvent($avisPayment, false);
|
||||
$this->eventDispatcher->dispatch($event);
|
||||
$io->info("Completed avis payement generated");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -107,6 +107,42 @@ class PriceController extends AbstractController
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('artemis_intranet_price');
|
||||
}
|
||||
if(isset($data['price_hosting_1'])) {
|
||||
$customPrice = $customerPriceRepository->findOneBy(['type'=>'hosting_1']);
|
||||
if(!$customPrice) {
|
||||
$customPrice = new CustomerPrice();
|
||||
$customPrice->setType('hosting_1');
|
||||
}
|
||||
$customPrice->setDescription($data['description_hosting_1']);
|
||||
$customPrice->setAmmount(floatval($data['price_hosting_1']));
|
||||
$entityManager->persist($customPrice);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('artemis_intranet_price');
|
||||
}
|
||||
if(isset($data['price_hosting_2'])) {
|
||||
$customPrice = $customerPriceRepository->findOneBy(['type'=>'hosting_2']);
|
||||
if(!$customPrice) {
|
||||
$customPrice = new CustomerPrice();
|
||||
$customPrice->setType('hosting_2');
|
||||
}
|
||||
$customPrice->setDescription($data['description_hosting_2']);
|
||||
$customPrice->setAmmount(floatval($data['price_hosting_2']));
|
||||
$entityManager->persist($customPrice);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('artemis_intranet_price');
|
||||
}
|
||||
if(isset($data['price_hosting_restore'])) {
|
||||
$customPrice = $customerPriceRepository->findOneBy(['type'=>'hosting_restore']);
|
||||
if(!$customPrice) {
|
||||
$customPrice = new CustomerPrice();
|
||||
$customPrice->setType('hosting_restore');
|
||||
}
|
||||
$customPrice->setDescription($data['description_hosting_restore']);
|
||||
$customPrice->setAmmount(floatval($data['price_hosting_restore']));
|
||||
$entityManager->persist($customPrice);
|
||||
$entityManager->flush();
|
||||
return $this->redirectToRoute('artemis_intranet_price');
|
||||
}
|
||||
if(isset($data['price_ndd_gestion'])) {
|
||||
$customPrice = $customerPriceRepository->findOneBy(['type'=>'gestion_ndd']);
|
||||
if(!$customPrice) {
|
||||
@@ -127,6 +163,9 @@ class PriceController extends AbstractController
|
||||
'renouvellement_ndd' => $customerPriceRepository->findOneBy(['type'=>'renouvellement_ndd']),
|
||||
'restore_ndd' => $customerPriceRepository->findOneBy(['type'=>'restore_ndd']),
|
||||
'gestion_ndd' => $customerPriceRepository->findOneBy(['type'=>'gestion_ndd']),
|
||||
'hosting_1' => $customerPriceRepository->findOneBy(['type'=>'hosting_1']),
|
||||
'hosting_2' => $customerPriceRepository->findOneBy(['type'=>'hosting_2']),
|
||||
'hosting_restore' => $customerPriceRepository->findOneBy(['type'=>'hosting_restore']),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,12 @@ class AvisPaymentState
|
||||
#[ORM\Column]
|
||||
private ?\DateTimeImmutable $finalSendAt = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $year = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $month = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@@ -212,4 +218,28 @@ class AvisPaymentState
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getYear(): ?string
|
||||
{
|
||||
return $this->year;
|
||||
}
|
||||
|
||||
public function setYear(?string $year): static
|
||||
{
|
||||
$this->year = $year;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMonth(): ?string
|
||||
{
|
||||
return $this->month;
|
||||
}
|
||||
|
||||
public function setMonth(?string $month): static
|
||||
{
|
||||
$this->month = $month;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +158,123 @@
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-gray-800 p-6 md:p-8 rounded-xl shadow-2xl transition duration-300">
|
||||
<h2 class="text-1xl font-bold text-indigo-700 dark:text-indigo-400 mb-4">Hébergement 5 Go</h2>
|
||||
|
||||
<form action="#" method="POST" class="space-y-6">
|
||||
|
||||
<!-- Champ Prix -->
|
||||
<div>
|
||||
<label for="price_hosting_1" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Prix (€)</label>
|
||||
<div class="relative mt-1 rounded-md shadow-sm">
|
||||
<input type="number" name="price_hosting_1" id="price_hosting_1" value="{% if hosting_1 is not null %}{{ hosting_1.ammount }}{% endif %}" step="0.01" required
|
||||
class="block w-full rounded-lg border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 pl-7 pr-12 py-2 text-gray-900 dark:text-white placeholder-gray-400 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
placeholder="0.00">
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
||||
<span class="text-gray-500 dark:text-gray-400 sm:text-sm">€</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Champ Description -->
|
||||
<div>
|
||||
<label for="description_hosting_1" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label>
|
||||
<textarea id="description_hosting_1" name="description_hosting_1" rows="3" required
|
||||
class="block w-full rounded-lg border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 shadow-sm p-3 text-gray-900 dark:text-white focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
placeholder="">{% if hosting_1 is not null %}{{ hosting_1.description }}{% endif %}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="badge bg-indigo-500 rounded p-1">{website_name}</span>
|
||||
<span class="badge bg-indigo-500 rounded p-1">{date_start}</span>
|
||||
<span class="badge bg-indigo-500 rounded p-1">{date_stop}</span>
|
||||
</div>
|
||||
|
||||
<!-- Bouton d'action -->
|
||||
<button type="submit"
|
||||
class="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-150 ease-in-out">
|
||||
Sauvegarder
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-gray-800 p-6 md:p-8 rounded-xl shadow-2xl transition duration-300">
|
||||
<h2 class="text-1xl font-bold text-indigo-700 dark:text-indigo-400 mb-4">Hébergement 10 Go</h2>
|
||||
|
||||
<form action="#" method="POST" class="space-y-6">
|
||||
|
||||
<!-- Champ Prix -->
|
||||
<div>
|
||||
<label for="price_hosting_2" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Prix (€)</label>
|
||||
<div class="relative mt-1 rounded-md shadow-sm">
|
||||
<input type="number" name="price_hosting_2" id="price_hosting_2" value="{% if hosting_2 is not null %}{{ hosting_2.ammount }}{% endif %}" step="0.01" required
|
||||
class="block w-full rounded-lg border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 pl-7 pr-12 py-2 text-gray-900 dark:text-white placeholder-gray-400 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
placeholder="0.00">
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
||||
<span class="text-gray-500 dark:text-gray-400 sm:text-sm">€</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Champ Description -->
|
||||
<div>
|
||||
<label for="description_hosting_2" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label>
|
||||
<textarea id="description_hosting_2" name="description_hosting_2" rows="3" required
|
||||
class="block w-full rounded-lg border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 shadow-sm p-3 text-gray-900 dark:text-white focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
placeholder="">{% if hosting_2 is not null %}{{ hosting_2.description }}{% endif %}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="badge bg-indigo-500 rounded p-1">{website_name}</span>
|
||||
<span class="badge bg-indigo-500 rounded p-1">{date_start}</span>
|
||||
<span class="badge bg-indigo-500 rounded p-1">{date_stop}</span>
|
||||
</div>
|
||||
|
||||
<!-- Bouton d'action -->
|
||||
<button type="submit"
|
||||
class="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-150 ease-in-out">
|
||||
Sauvegarder
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-gray-800 p-6 md:p-8 rounded-xl shadow-2xl transition duration-300">
|
||||
<h2 class="text-1xl font-bold text-indigo-700 dark:text-indigo-400 mb-4">Restauration Hébergement</h2>
|
||||
|
||||
<form action="#" method="POST" class="space-y-6">
|
||||
|
||||
<!-- Champ Prix -->
|
||||
<div>
|
||||
<label for="price_hosting_restore" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Prix (€)</label>
|
||||
<div class="relative mt-1 rounded-md shadow-sm">
|
||||
<input type="number" name="price_hosting_restore" id="price_hosting_restore" value="{% if hosting_restore is not null %}{{ hosting_restore.ammount }}{% endif %}" step="0.01" required
|
||||
class="block w-full rounded-lg border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 pl-7 pr-12 py-2 text-gray-900 dark:text-white placeholder-gray-400 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
placeholder="0.00">
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
||||
<span class="text-gray-500 dark:text-gray-400 sm:text-sm">€</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Champ Description -->
|
||||
<div>
|
||||
<label for="description_hosting_restore" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Description</label>
|
||||
<textarea id="description_hosting_restore" name="description_hosting_restore" rows="3" required
|
||||
class="block w-full rounded-lg border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 shadow-sm p-3 text-gray-900 dark:text-white focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
placeholder="">{% if hosting_restore is not null %}{{ hosting_restore.description }}{% endif %}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="badge bg-indigo-500 rounded p-1">{website_name}</span>
|
||||
<span class="badge bg-indigo-500 rounded p-1">{date_start}</span>
|
||||
<span class="badge bg-indigo-500 rounded p-1">{date_stop}</span>
|
||||
</div>
|
||||
|
||||
<!-- Bouton d'action -->
|
||||
<button type="submit"
|
||||
class="w-full flex justify-center py-3 px-4 border border-transparent rounded-lg shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition duration-150 ease-in-out">
|
||||
Sauvegarder
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Bonjour,
|
||||
</mj-text>
|
||||
<mj-text>
|
||||
Nous vous informons qu'un nouvel avis de paiement numéro **{{ datas.paymentNotice.number }}** d'un montant de **{{ datas.paymentNotice.amount | number_format(2, ',', ' ') }} € TTC ** est disponible.
|
||||
Nous vous informons qu'un nouvel avis de paiement numéro <strong>{{ datas.paymentNotice.number }}</strong> d'un montant de <strong>{{ datas.paymentNotice.amount | number_format(2, ',', ' ') }} € TTC</strong> est disponible.
|
||||
Vous pouvez le consulter et procéder au paiement en cliquant sur le bouton ci-dessous.
|
||||
</mj-text>
|
||||
<mj-button href="{{ datas.url }}" background-color="#4CAF50" color="white" font-family="Helvetica, Arial, sans-serif" font-size="16px" font-weight="bold" inner-padding="10px 25px" border-radius="3px">
|
||||
|
||||
@@ -84,5 +84,6 @@ esyWeb_created: Créer en attends de validation
|
||||
esyWeb_validate: Validation - En Attends de déploiement
|
||||
esyWeb_deploy: En ligne
|
||||
vadvert-ndd : Renouvellement nom de domaine
|
||||
vadvert-hosting : Hébergement de votre site internet
|
||||
f-created: Facture Crée
|
||||
f-send: Facture envoyée
|
||||
|
||||
Reference in New Issue
Block a user