Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
372 changes: 0 additions & 372 deletions phpstan-baseline.php

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@
namespace AppBundle\Accounting\Invoices\Generator;

use AppBundle\Accounting\Invoices\Dto\InvoiceData;
use AppBundle\Association\Model\CompanyMember;
use AppBundle\Association\Entity\CompanyMember;
use AppBundle\Association\Model\User;

class CompanyMemberInvoiceGenerator implements InvoiceGeneration
{
public function generate(User|CompanyMember $member): InvoiceData
{
if (!$member instanceof CompanyMember) {
throw new \InvalidArgumentException('Expected a CompanyMember.');
}

return new InvoiceData(
$member->getCompanyName(),
$member->getAddress(),
$member->getZipcode(),
$member->getCity(),
$member->getCompanyName(),
$member->companyName,
$member->address,
$member->zipCode,
$member->city,
$member->companyName,
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace AppBundle\Accounting\Invoices\Generator;

use AppBundle\Accounting\Invoices\Dto\InvoiceData;
use AppBundle\Association\Model\CompanyMember;
use AppBundle\Association\Entity\CompanyMember;
use AppBundle\Association\Model\User;

interface InvoiceGeneration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
namespace AppBundle\Accounting\Invoices\Generator;

use AppBundle\Accounting\Invoices\Dto\InvoiceData;
use AppBundle\Association\Model\CompanyMember;
use AppBundle\Association\Entity\CompanyMember;
use AppBundle\Association\Model\User;

class MemberInvoiceGenerator implements InvoiceGeneration
{
public function generate(User|CompanyMember $member): InvoiceData
{
if (!$member instanceof User) {
throw new \InvalidArgumentException('Expected a User.');
}

return new InvoiceData(
$member->getFirstName() . ' ' . $member->getLastName(),
$member->getAddress(),
Expand Down
4 changes: 2 additions & 2 deletions sources/AppBundle/Accounting/Invoices/InvoiceGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use AppBundle\Accounting\Invoices\Dto\InvoiceData;
use AppBundle\Accounting\Invoices\Generator\InvoiceGeneration;
use AppBundle\Association\Model\CompanyMember;
use AppBundle\Association\Entity\CompanyMember;
use AppBundle\Association\Model\User;

class InvoiceGenerator
Expand All @@ -26,7 +26,7 @@ public function getInvoiceData(User|CompanyMember $user): InvoiceData
throw new \RuntimeException(sprintf(
'No invoice generator supports member of type %s (id: %d).',
$user::class,
$user->getId(),
$user instanceof CompanyMember ? $user->id : $user->getId(),
));
}
}
2 changes: 1 addition & 1 deletion sources/AppBundle/Accounting/SearchResultProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace AppBundle\Accounting;

use AppBundle\Association\Model\Repository\CompanyMemberRepository;
use AppBundle\Association\Entity\Repository\CompanyMemberRepository;
use AppBundle\Association\Model\Repository\SubscriptionRepository;
use AppBundle\Event\Model\Repository\InvoiceRepository;
use AppBundle\Event\Model\Repository\TicketRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace AppBundle\Association\CompanyMembership;

use AppBundle\Association\Model\CompanyMember;
use AppBundle\Association\Entity\CompanyMember;
use AppBundle\Association\Entity\CompanyMemberInvitation;
use AppBundle\Email\Mailer\Mailer;
use AppBundle\Email\Mailer\MailUser;
Expand Down Expand Up @@ -32,8 +32,8 @@ public function sendInvitation(CompanyMember $companyMember, CompanyMemberInvita
{
$text = $this->translator->trans('mail.invitationMembership.text',
[
'%firstname%' => $companyMember->getFirstName(),
'%lastname%' => $companyMember->getLastName(),
'%firstname%' => $companyMember->firstName,
'%lastname%' => $companyMember->lastName,
'%link%' => $this->router->generate(
'company_invitation',
['invitationId' => $invitation->id, 'token' => $invitation->token],
Expand All @@ -43,7 +43,7 @@ public function sendInvitation(CompanyMember $companyMember, CompanyMemberInvita
);

return $this->mailer->sendTransactional(new Message(
sprintf('%s vous invite à profiter de son compte "Membre AFUP"', $companyMember->getCompanyName()),
sprintf('%s vous invite à profiter de son compte "Membre AFUP"', $companyMember->companyName),
MailUserFactory::sponsors(),
new MailUser($invitation->email),
), $text);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use AppBundle\MembershipFee\MembershipFeeService;
use Afup\Site\Utils\Utils;
use AppBundle\Association\MemberType;
use AppBundle\Association\Model\CompanyMember;
use AppBundle\Association\Entity\CompanyMember;
use AppBundle\MembershipFee\Entity\Cotisation;

final readonly class SubscriptionManagement
Expand All @@ -20,20 +20,23 @@ public function __construct(private MembershipFeeService $membershipFeeService)

public function createInvoiceForInscription(CompanyMember $company, int $numberOfMembers): array
{
if (null === $company->id) {
throw new \LogicException('The company member must be persisted.');
}
$endSubscription = $this->membershipFeeService->getNextSubscriptionExpiration(null);

// Create the invoice
$this->membershipFeeService->ajouter(
MemberType::MemberCompany,
$company->getId(),
$company->id,
ceil($numberOfMembers / self::AFUP_PERSONNE_MORALE_SEUIL) * self::AFUP_COTISATION_PERSONNE_MORALE * (1 + Utils::MEMBERSHIP_FEE_VAT_RATE),
null,
null,
new \DateTime()->getTimestamp(),
$endSubscription->getTimestamp(),
'',
);
$subscription = $this->membershipFeeService->getLatestByUserTypeAndId(MemberType::MemberCompany, $company->getId());
$subscription = $this->membershipFeeService->getLatestByUserTypeAndId(MemberType::MemberCompany, $company->id);

if (!$subscription instanceof Cotisation) {
throw new \RuntimeException('An error occured');
Expand Down
196 changes: 196 additions & 0 deletions sources/AppBundle/Association/Entity/CompanyMember.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
<?php

declare(strict_types=1);

namespace AppBundle\Association\Entity;

use AppBundle\Association\CompanyMembership\SubscriptionManagement;
use AppBundle\Association\Entity\Repository\CompanyMemberRepository;
use AppBundle\Association\Enum\CompanyMemberStatus;
use Cocur\Slugify\Slugify;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: CompanyMemberRepository::class)]
#[ORM\Table(name: 'afup_personnes_morales')]
class CompanyMember
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'smallint', options: ['unsigned' => true])]
public ?int $id = null;

#[Assert\NotBlank]
#[ORM\Column(name: 'prenom', length: 40)]
public string $firstName = '';

#[Assert\NotBlank]
#[ORM\Column(name: 'nom', length: 40)]
public string $lastName = '';

#[Assert\NotBlank]
#[Assert\Email]
#[ORM\Column(length: 100)]
public string $email = '';

#[Assert\NotBlank(message: 'Raison sociale manquante')]
#[ORM\Column(name: 'raison_sociale', length: 100)]
public string $companyName = '';

#[Assert\NotBlank]
#[ORM\Column(length: 14)]
public string $siret = '';

#[Assert\NotBlank]
#[ORM\Column(name: 'adresse', type: 'text')]
public string $address = '';

#[Assert\NotBlank]
#[ORM\Column(name: 'code_postal', length: 10)]
public string $zipCode = '';

#[Assert\NotBlank]
#[ORM\Column(name: 'ville', length: 50)]
public string $city = '';

#[Assert\NotBlank]
#[ORM\Column(name: 'id_pays', length: 2, options: ['fixed' => true])]
public string $country = 'FR';

#[ORM\Column(name: 'telephone_fixe', length: 20, nullable: true)]
public ?string $phone = null;

#[ORM\Column(name: 'telephone_portable', length: 20, nullable: true)]
public ?string $cellphone = null;

#[ORM\Column(name: 'etat', type: 'smallint', enumType: CompanyMemberStatus::class)]
public CompanyMemberStatus $status = CompanyMemberStatus::Active;

#[ORM\Column(name: 'max_members', type: 'smallint', nullable: true, options: ['unsigned' => true])]
public ?int $maxMembers = 0;

// Colonne nullable en base (tinyint DEFAULT 0)
#[ORM\Column(name: 'public_profile_enabled', nullable: true)]
public ?bool $publicProfileEnabled = false;

#[ORM\Column(type: 'text', nullable: true)]
public ?string $description = null;

#[ORM\Column(name: 'logo_url', nullable: true)]
public ?string $logoUrl = null;

#[ORM\Column(name: 'website_url', nullable: true)]
public ?string $websiteUrl = null;

#[ORM\Column(name: 'contact_page_url', nullable: true)]
public ?string $contactPageUrl = null;

#[ORM\Column(name: 'careers_page_url', nullable: true)]
public ?string $careersPageUrl = null;

#[ORM\Column(name: 'twitter_handle', nullable: true)]
public ?string $twitterHandle = null;

#[ORM\Column(name: 'related_afup_offices', nullable: true)]
public ?string $relatedAfupOffices = null;

#[ORM\Column(name: 'membership_reason', nullable: true)]
public ?string $membershipReason = null;

/**
* Non persisté : invitations saisies dans le formulaire d'adhésion entreprise.
*
* @var array<int, CompanyMemberInvitation|null>
*/
public array $invitations = [];

/**
* Non persisté : date de fin de la dernière cotisation, renseignée par
* CompanyMemberRepository (findById, loadAll, search, findDisplayableCompanies).
*/
public ?\DateTimeImmutable $lastSubscription = null;

/**
* Invitations réellement saisies, en conservant leur position dans le formulaire
* (l'index 0 correspond toujours au gestionnaire).
*
* @return array<int, CompanyMemberInvitation>
*/
public function getValidInvitations(): array
{
return array_filter(
$this->invitations,
static fn($invitation): bool => $invitation instanceof CompanyMemberInvitation,
);
}

public function hasLogoUrl(): bool
{
return null !== $this->logoUrl;
}

public function getCleanedTwitterHandle(): ?string
{
$twitter = (string) $this->twitterHandle;
$twitter = trim($twitter, '@');
$twitter = preg_replace('!^https?://twitter.com/!', '', $twitter);

if (!is_string($twitter)) {
return null;
}

if (trim($twitter) === '') {
return null;
}

return $twitter;
}

/**
* @return list<string>
*/
public function getFormattedRelatedAfupOffices(): array
{
if (null === $this->relatedAfupOffices) {
return [];
}

return explode(',', $this->relatedAfupOffices);
}

/**
* @param array<string> $relatedAfupOffices
*/
public function setFormattedRelatedAfupOffices(array $relatedAfupOffices): void
{
if ($relatedAfupOffices === []) {
$this->relatedAfupOffices = null;

return;
}

sort($relatedAfupOffices);
$this->relatedAfupOffices = implode(',', $relatedAfupOffices);
}

public function getSlug(): string
{
return new Slugify()->slugify($this->companyName);
}

public function hasUpToDateMembershipFee(?\DateTimeInterface $now = null): bool
{
if (!$now instanceof \DateTimeInterface) {
$now = new \DateTime();
}

return $this->lastSubscription > $now;
}

public function getMembershipFee(int $default = SubscriptionManagement::AFUP_PERSONNE_MORALE_SEUIL): float
{
$max = max((int) $this->maxMembers, $default);

return ceil($max / SubscriptionManagement::AFUP_PERSONNE_MORALE_SEUIL) * SubscriptionManagement::AFUP_COTISATION_PERSONNE_MORALE;
}
}
Loading
Loading