<?php | |||||
namespace backend\controllers; | |||||
use backend\controllers\BackendController; | |||||
use domain\Feature\Feature\Feature; | |||||
use yii\filters\AccessControl; | |||||
class SponsorshipController extends BackendController | |||||
{ | |||||
public function behaviors() | |||||
{ | |||||
return [ | |||||
'access' => [ | |||||
'class' => AccessControl::class, | |||||
'rules' => [ | |||||
[ | |||||
'allow' => true, | |||||
'roles' => ['@'], | |||||
'matchCallback' => function ($rule, $action) { | |||||
return | |||||
$this->getFeatureModule()->getChecker()->isEnabled(Feature::ALIAS_SPONSORSHIP) | |||||
&& $this->getUserModule() | |||||
->getAuthorizationChecker() | |||||
->isGrantedAsProducer($this->getUserCurrent()); | |||||
} | |||||
], | |||||
], | |||||
], | |||||
]; | |||||
} | |||||
public function actionIndex() | |||||
{ | |||||
$producerCurrent = $this->getProducerCurrent(); | |||||
return $this->render('index', [ | |||||
'producer' => $producerCurrent, | |||||
'producersGodsonsArray' => $this->getProducerModule()->getRepository()->findProducersSponsorshipGodsons($producerCurrent) | |||||
]); | |||||
} | |||||
} |
'template' => '<a href="{url}">{icon} {label}' . $countProducerInvoicesUnpaidLabel . '</a>' | 'template' => '<a href="{url}">{icon} {label}' . $countProducerInvoicesUnpaidLabel . '</a>' | ||||
], | ], | ||||
['label' => 'Tarifs & modules', 'icon' => 'euro', 'url' => ['/producer/billing'], 'visible' => $isUserCurrentGrantedAsProducer], | ['label' => 'Tarifs & modules', 'icon' => 'euro', 'url' => ['/producer/billing'], 'visible' => $isUserCurrentGrantedAsProducer], | ||||
[ | |||||
'label' => 'Parrainage', | |||||
'icon' => 'users', | |||||
'url' => ['/sponsorship/index'], | |||||
'visible' => $isUserCurrentGrantedAsProducer && $featureChecker->isEnabled(Feature::ALIAS_SPONSORSHIP), | |||||
'active' => Yii::$app->controller->id == 'sponsorship' | |||||
], | |||||
[ | [ | ||||
'label' => 'Développement', | 'label' => 'Développement', | ||||
'icon' => 'code', | 'icon' => 'code', |
<?php | |||||
/** | |||||
Copyright La boîte à pain (2018) | |||||
contact@souke.fr | |||||
Ce logiciel est un programme informatique servant à aider les producteurs | |||||
à distribuer leur production en circuits courts. | |||||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||||
sur le site "http://www.cecill.info". | |||||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||||
de modification et de redistribution accordés par cette licence, il n'est | |||||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||||
titulaire des droits patrimoniaux et les concédants successifs. | |||||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||||
associés au chargement, à l'utilisation, à la modification et/ou au | |||||
développement et à la reproduction du logiciel par l'utilisateur étant | |||||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||||
avertis possédant des connaissances informatiques approfondies. Les | |||||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||||
termes. | |||||
*/ | |||||
use common\helpers\Price; | |||||
use yii\helpers\Html; | |||||
$this->setTitle('Parrainage') ; | |||||
$this->addBreadcrumb($this->getTitle()) ; | |||||
$sponsorshipLink = $this->getProducerModule()->getSolver()->getSponsorshipLink($producer); | |||||
?> | |||||
<div class="alert alert-dark"> | |||||
<p> | |||||
<i class="bi bi-link"></i> | |||||
Votre lien de parrainage : <br /> | |||||
<strong> | |||||
<?= $sponsorshipLink ?> | |||||
<a class="btn btn-xs btn-default" id="sponsorship-link-copy" href="<?= $sponsorshipLink ?>" title="Copier le lien dans le presse-papier"> | |||||
<span class="glyphicon glyphicon-link"></span> | |||||
</a> | |||||
</strong> | |||||
</p> | |||||
</div> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title"> | |||||
<i class="fa fa-info"></i> | |||||
Comment ça marche ? | |||||
</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<p> | |||||
Partagez votre lien de parrainage avec les producteurs que vous souhaitez parrainer. Quand un de ces | |||||
producteurs s'inscrit en suivant ce lien, il devient votre filleul et obtenez tous les deux une récompense : | |||||
</p> | |||||
<ul> | |||||
<li>Votre filleul démarre avec <strong>3 mois offerts</strong> d'utilisation du logiciel</li> | |||||
<li>Vous obtenez <strong>30€ d'avoir</strong> sur vos prochaines factures</li> | |||||
</ul> | |||||
</div> | |||||
</div> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title"> | |||||
<i class="fa fa-users"></i> | |||||
Vos filleuls | |||||
</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<?php if($producersGodsonsArray && count($producersGodsonsArray)): ?> | |||||
<table class="table table-bordered table-striped"> | |||||
<thead> | |||||
<tr> | |||||
<th>Producteur</th> | |||||
<th>Date</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<?php foreach($producersGodsonsArray as $producerGodson): ?> | |||||
<tr> | |||||
<td><?= Html::encode($producerGodson->getName()); ?></td> | |||||
<td><?= date('d/m/Y', strtotime($producerGodson->date_creation)); ?></td> | |||||
</tr> | |||||
<?php endforeach; ?> | |||||
</tbody> | |||||
</table> | |||||
<?php else: ?> | |||||
<p>Vous n'avez encore aucun producteur parrainé.</p> | |||||
<?php endif; ?> | |||||
</div> | |||||
</div> |
opendistrib_check_all_checkboxes(); | opendistrib_check_all_checkboxes(); | ||||
opendistrib_dashboard_admin_statistics(); | opendistrib_dashboard_admin_statistics(); | ||||
opendistrib_tinymce_responsive(); | opendistrib_tinymce_responsive(); | ||||
opendistrib_sponsorship(); | |||||
}); | }); | ||||
function opendistrib_sponsorship() { | |||||
$('#sponsorship-link-copy').click(function() { | |||||
navigator.clipboard.writeText($(this).attr('href')); | |||||
appAlerts.alert('success', 'Lien de parrainage copié'); | |||||
return false; | |||||
}); | |||||
} | |||||
function saveData (data, fileName) { | function saveData (data, fileName) { | ||||
var a = document.createElement("a"); | var a = document.createElement("a"); | ||||
document.body.appendChild(a); | document.body.appendChild(a); |
<?php | |||||
use common\helpers\Password; | |||||
use domain\Producer\Producer\ProducerBuilder; | |||||
use domain\Producer\Producer\ProducerRepository; | |||||
use yii\db\Migration; | |||||
use yii\db\Schema; | |||||
/** | |||||
* Class m240613_070747_add_columns_producer_sponsorship | |||||
*/ | |||||
class m240613_070747_add_columns_producer_sponsorship extends Migration | |||||
{ | |||||
/** | |||||
* {@inheritdoc} | |||||
*/ | |||||
public function safeUp() | |||||
{ | |||||
$this->addColumn('producer', 'sponsorship_code', Schema::TYPE_STRING); | |||||
$this->addColumn('producer', 'sponsored_by', Schema::TYPE_INTEGER); | |||||
$this->addColumn('producer', 'sponsorship_sponsor_reward', Schema::TYPE_BOOLEAN); | |||||
$this->addColumn('producer', 'sponsorship_godson_reward', Schema::TYPE_BOOLEAN); | |||||
$producersArray = ProducerRepository::getInstance()->findAll(); | |||||
foreach($producersArray as $producer) { | |||||
ProducerBuilder::getInstance()->initSponsorshipCode($producer); | |||||
$producer->save(); | |||||
} | |||||
} | |||||
/** | |||||
* {@inheritdoc} | |||||
*/ | |||||
public function safeDown() | |||||
{ | |||||
$this->dropColumn('producer', 'sponsorship_code'); | |||||
$this->dropColumn('producer', 'sponsored_by'); | |||||
$this->dropColumn('producer', 'sponsorship_sponsor_reward'); | |||||
$this->dropColumn('producer', 'sponsorship_godson_reward'); | |||||
} | |||||
} |
const ALIAS_SHOP_SUPPORT = 'shop_support'; | const ALIAS_SHOP_SUPPORT = 'shop_support'; | ||||
const ALIAS_SHARED_POINT_SALE = 'shared_point_sale'; | const ALIAS_SHARED_POINT_SALE = 'shared_point_sale'; | ||||
const ALIAS_SUMUP_SYNCHRONIZATION = 'sumup_synchronization'; | const ALIAS_SUMUP_SYNCHRONIZATION = 'sumup_synchronization'; | ||||
const ALIAS_SPONSORSHIP = 'sponsorship'; | |||||
/** | /** | ||||
* @inheritdoc | * @inheritdoc |
Feature::ALIAS_SETTINGS => 'Système de paramètres', | Feature::ALIAS_SETTINGS => 'Système de paramètres', | ||||
Feature::ALIAS_SHOP_SUPPORT => 'Support boutique', | Feature::ALIAS_SHOP_SUPPORT => 'Support boutique', | ||||
Feature::ALIAS_SHARED_POINT_SALE => 'Points de vente partagés', | Feature::ALIAS_SHARED_POINT_SALE => 'Points de vente partagés', | ||||
Feature::ALIAS_SUMUP_SYNCHRONIZATION => "Synchronisation de commandes avec Sumup / Tiller" | |||||
Feature::ALIAS_SUMUP_SYNCHRONIZATION => "Synchronisation de commandes avec Sumup / Tiller", | |||||
Feature::ALIAS_SPONSORSHIP => "Parrainage producteurs" | |||||
]; | ]; | ||||
} | } | ||||
} | } |
'option_weeks_distributions_activated_in_advance', | 'option_weeks_distributions_activated_in_advance', | ||||
'option_document_width_logo', | 'option_document_width_logo', | ||||
'export_shopping_cart_labels_number_per_column', | 'export_shopping_cart_labels_number_per_column', | ||||
'id_user_group_default' | |||||
'id_user_group_default', | |||||
'sponsored_by' | |||||
], | ], | ||||
'integer' | 'integer' | ||||
], | ], | ||||
'option_leave_period_message_title', | 'option_leave_period_message_title', | ||||
'option_leave_period_message', | 'option_leave_period_message', | ||||
'option_credit_description', | 'option_credit_description', | ||||
'sponsorship_code' | |||||
], | ], | ||||
'string' | 'string' | ||||
], | ], | ||||
'delivery_note_automatic_validation', | 'delivery_note_automatic_validation', | ||||
'is_new', | 'is_new', | ||||
'agree_contact_about_software_development', | 'agree_contact_about_software_development', | ||||
'option_leave_period_message_display' | |||||
'option_leave_period_message_display', | |||||
'sponsorship_sponsor_reward', | |||||
'sponsorship_godson_reward', | |||||
], | ], | ||||
'boolean' | 'boolean' | ||||
], | ], | ||||
return $this->name; | return $this->name; | ||||
} | } | ||||
public function getSponsorshipCode(): string | |||||
{ | |||||
return $this->sponsorship_code; | |||||
} | |||||
public function setSponsorshipCode(string $sponsorshipCode): self | |||||
{ | |||||
$this->sponsorship_code = $sponsorshipCode; | |||||
return $this; | |||||
} | |||||
public function getSponsoredBy(): ?User | |||||
{ | |||||
return $this->sponsoredByRelation; | |||||
} | |||||
public function setSponsoredBy(User $user): self | |||||
{ | |||||
$this->populateFieldObject('sponsored_by', 'sponsoredByRelation', $user); | |||||
return $this; | |||||
} | |||||
public function getSponsorshipSponsorReward(): ?bool | |||||
{ | |||||
return $this->sponsorship_sponsor_reward; | |||||
} | |||||
public function setSponsorshipSponsorReward(bool $sponsorshipSponsorReward = null): self | |||||
{ | |||||
$this->sponsorship_sponsor_reward = $sponsorshipSponsorReward; | |||||
return $this; | |||||
} | |||||
public function getSponsorshipGodsonReward(): ?bool | |||||
{ | |||||
return $this->sponsorship_godson_reward; | |||||
} | |||||
public function setSponsorshipGodsonReward(bool $sponsorshipGodsonReward = null): self | |||||
{ | |||||
$this->sponsorship_godson_reward = $sponsorshipGodsonReward; | |||||
return $this; | |||||
} | |||||
/* | /* | ||||
* Relations | * Relations | ||||
*/ | */ |
public function instanciateProducer(): Producer | public function instanciateProducer(): Producer | ||||
{ | { | ||||
$producer = new Producer(); | $producer = new Producer(); | ||||
$producer->order_deadline = Producer::ORDER_DEADLINE_DEFAULT; | $producer->order_deadline = Producer::ORDER_DEADLINE_DEFAULT; | ||||
$producer->order_delay = Producer::ORDER_DELAY_DEFAULT; | $producer->order_delay = Producer::ORDER_DELAY_DEFAULT; | ||||
$this->initSponsorshipCode($producer); | |||||
return $producer; | return $producer; | ||||
} | } | ||||
$producer->save(); | $producer->save(); | ||||
} | } | ||||
} | } | ||||
public function initSponsorshipCode(Producer $producer): self | |||||
{ | |||||
$producer->setSponsorshipCode(Password::generate()); | |||||
return $this; | |||||
} | |||||
} | } |
return 0; | return 0; | ||||
} | } | ||||
public function findOneProducerBySponsorshipCode(string $sponsorshipCode): ?Producer | |||||
{ | |||||
return $this->createQuery() | |||||
->filterBySponsorshipCode($sponsorshipCode) | |||||
->findOne(); | |||||
} | |||||
public function findProducersSponsorshipGodsons(Producer $producer): array | |||||
{ | |||||
return $this->createQuery() | |||||
->filterBySponsoredBy($producer) | |||||
->find(); | |||||
} | |||||
} | } |
$this->andWhere('producer.option_time_saved > 0'); | $this->andWhere('producer.option_time_saved > 0'); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterBySponsorshipCode(string $sponsorshipCode): self | |||||
{ | |||||
$this->andWhere('producer.sponsorship_code LIKE :sponsorship_code') | |||||
->addParams(['sponsorship_code' => $sponsorshipCode]); | |||||
return $this; | |||||
} | |||||
public function filterBySponsoredBy(Producer $producer): self | |||||
{ | |||||
$this->andWhere(['producer.sponsored_by' => $producer->id]); | |||||
return $this; | |||||
} | |||||
} | } |
return false; | return false; | ||||
} | } | ||||
public function getSponsorshipLink(Producer $producer): string | |||||
{ | |||||
return \Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/signup', 'from' => $producer->getSponsorshipCode()]); | |||||
} | |||||
} | } |
[ | [ | ||||
'actions' => ['signup-producer'], | 'actions' => ['signup-producer'], | ||||
'allow' => true, | 'allow' => true, | ||||
'roles' => ['@'], | |||||
], | ], | ||||
[ | [ | ||||
'actions' => ['logout'], | 'actions' => ['logout'], | ||||
public function actionSignupProducer() | public function actionSignupProducer() | ||||
{ | { | ||||
$userCurrent = $this->getUserCurrent(); | |||||
if(!$userCurrent) { | |||||
// Lien parrainage | |||||
if(Yii::$app->request->get('from')) { | |||||
$this->redirect(['site/signup', 'from' => Yii::$app->request->get('from')]); | |||||
} | |||||
else { | |||||
$this->redirect(['site/signup']); | |||||
} | |||||
} | |||||
$model = new SignupForm(); | $model = new SignupForm(); | ||||
$model->signup_producer_only = 'producer'; | $model->signup_producer_only = 'producer'; | ||||
$model->option_user_producer = 'producer'; | $model->option_user_producer = 'producer'; | ||||
if ($model->load(Yii::$app->request->post())) { | if ($model->load(Yii::$app->request->post())) { | ||||
$user = $model->signup($this->getUserCurrent()); | |||||
$user = $model->signup($userCurrent); | |||||
if($user) { | if($user) { | ||||
$this->redirect(['site/signup-confirm']); | $this->redirect(['site/signup-confirm']); | ||||
} | } |