up to sf 7

This commit is contained in:
Tykayn 2025-02-09 16:45:35 +01:00 committed by tykayn
parent a39b6239b0
commit 501795a8fa
16586 changed files with 19384005 additions and 0 deletions

View file

@ -0,0 +1,5 @@
{% extends "@FOSUser/layout.html.twig" %}
{% block fos_user_content %}
TODO changer le pass
{% endblock fos_user_content %}

View file

@ -0,0 +1,3 @@
formulaire de changement de pass

View file

@ -0,0 +1,6 @@
{% extends "@FOSUser/layout.html.twig" %}
{% block fos_user_content %}
<p>check mail</p>
{% endblock fos_user_content %}

View file

@ -0,0 +1,11 @@
{% extends "@FOSUser/layout.html.twig" %}
{% block fos_user_content %}
<p>enregistrement confirmé</p>
{% if targetUrl %}
<p>
retour enregistrement
</p>
{% endif %}
{% endblock fos_user_content %}

View file

@ -0,0 +1,12 @@
{% block subject %}
{%- autoescape false -%}
{{ 'registration.email.subject'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }}
{%- endautoescape -%}
{% endblock %}
{% block body_text %}
{% autoescape false %}
{{ 'registration.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }}
{% endautoescape %}
{% endblock %}
{% block body_html %}{% endblock %}

View file

@ -0,0 +1,22 @@
{% extends "@FOSUser/layout.html.twig" %}
{% block fos_user_content %}
<div class="row">
<div class="col-xs-6">
<h1>Enregistrer un nouveau compte</h1>
TODO
</div>
<div class="col-xs-6">
ou bien,
{#<a class="btn btn-info" href="{{ path('fos_user_security_login') }}">se connecter.</a>#}
<a class="btn btn-info" href="#">
Mot de passe oublié?
</a>
</div>
</div>
{% endblock fos_user_content %}

View file

@ -0,0 +1,4 @@
enregistrer un compte
<br>
envoyer

View file

@ -0,0 +1,14 @@
{% extends "@FOSUser/layout.html.twig" %}
{% block fos_user_content %}
<div class="row">
<div class="col-xs-6">
<h1>Mot de passe oublié</h1>
reset TODO
</div>
<div class="col-xs-6">
ou bien,
{#<a class="btn btn-info" href="{{ path('fos_user_security_login') }}">se connecter.</a>#}
</div>
</div>
{% endblock fos_user_content %}

View file

@ -0,0 +1,73 @@
{% extends "@FOSUser/layout.html.twig" %}
{% block fos_user_content %}
<div class="row">
<div class="col-xs-12 col-sm-6">
<div class="padded">
<h1>
<i class="fa fa-key"></i>
Se connecter
</h1>
</div>
</div>
<div class="col-xs-12 col-sm-6">
<div class="visible-xs">
<hr>
</div>
<div class="padded">
<p>
<a class="btn btn-info btn-block" href="#">
Créer un compte
</a>
<a class="btn btn-warning btn-block" href="#">
Mot de passe oublié?
</a>
<a href="#" id="demo_login_btn" class="btn btn-block btn-primary">
<i class="fa fa-arrow-circle-right"></i>
Se connecter à la démo</a>
</p>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-xs-12">
<div class="padded">
{% if error %}
<div class="alert alert-info">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="#" method="post">
{% if csrf_token %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
{% endif %}
<div>
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" class="input-lg" name="_username" value="{{ last_username }}"
required="required"
autocomplete="username"/>
</div>
<div>
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" class="input-lg" name="_password" required="required"
autocomplete="current-password"/>
</div>
<div class="padded-v">
<input type="checkbox" id="remember_me" name="_remember_me" value="on"/>
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
</div>
<input class="btn btn-success btn-block btn-lg" type="submit" id="_submit" name="_submit"
value="{{ 'security.login.submit'|trans }}"/>
</form>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,22 @@
{% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="#" method="post">
{% if csrf_token %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
{% endif %}
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" required="required"
autocomplete="username"/>
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password" required="required" autocomplete="current-password"/>
<br>
<input type="checkbox" id="remember_me" name="_remember_me" value="on"/>
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
<br>
<input class="btn btn-primary btn-block" type="submit" id="_submit" name="_submit"
value="{{ 'security.login.submit'|trans }}"/>
</form>

View file

@ -0,0 +1,19 @@
{% extends 'base.html.twig' %}
{% block title %}Caisse{% endblock %}
{% block bigMain %}
{% include 'default/header.html.twig' %}
<section class="bg-girl padded login-fosub">
<div class="container">
<div class="row justify-content-md-center align-items-center">
<div class="col-md-auto">
<fieldset class="bg-shader pull-left form-group padded">
{% block fos_user_content %}{% endblock %}
</fieldset>
</div>
</div>
</div>
</section>
{% include 'default/footer.html.twig' %}
{% endblock %}

View file

@ -0,0 +1,498 @@
<?php
/*
* This file is part of the HWIOAuthBundle package.
*
* (c) Hardware.Info <opensource@hardware.info>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace HWI\Bundle\OAuthBundle\Controller;
use HWI\Bundle\OAuthBundle\Event\FilterUserResponseEvent;
use HWI\Bundle\OAuthBundle\Event\FormEvent;
use HWI\Bundle\OAuthBundle\Event\GetResponseUserEvent;
use HWI\Bundle\OAuthBundle\HWIOAuthEvents;
use HWI\Bundle\OAuthBundle\OAuth\ResourceOwnerInterface;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\Authentication\Token\OAuthToken;
use HWI\Bundle\OAuthBundle\Security\Core\Exception\AccountNotLinkedException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Csrf\CsrfTokenManager;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
/**
* @author Alexander <iam.asm89@gmail.com>
*/
class ConnectController extends Controller {
private $tokenManager;
public function __construct( CsrfTokenManagerInterface $tokenManager = null ) {
$this->tokenManager = new CsrfTokenManager();
}
/**
* Action that handles the login 'form'. If connecting is enabled the
* user will be redirected to the appropriate login urls or registration forms.
*
* @param Request $request
*
* @throws \LogicException
*
* @return Response
*/
public function connectAction( Request $request ) {
// var_dump( "override" );
// var_dump( $this->tokenManager );
// die();
$csrf_token = $this->tokenManager
? $this->tokenManager->getToken( 'authenticate' )->getValue()
: null;
$connect = $this->container->getParameter( 'hwi_oauth.connect' );
$hasUser = $this->getUser() ? $this->isGranted( $this->container->getParameter( 'hwi_oauth.grant_rule' ) ) : false;
$error = $this->getErrorForRequest( $request );
// if connecting is enabled and there is no user, redirect to the registration form
if ( $connect && ! $hasUser && $error instanceof AccountNotLinkedException ) {
$key = time();
$session = $request->getSession();
$session->set( '_hwi_oauth.registration_error.' . $key, $error );
return $this->redirectToRoute( 'hwi_oauth_connect_registration', [ 'key' => $key ] );
}
if ( $error ) {
if ( $error instanceof AuthenticationException ) {
$error = $error->getMessageKey();
} else {
$error = $error->getMessage();
}
}
$csrf_token = '';
return $this->render( '@HWIOAuth/Connect/login.html.twig',
[
'csrf_token' => $csrf_token,
'error' => $error,
] );
}
/**
* Shows a registration form if there is no user logged in and connecting
* is enabled.
*
* @param Request $request a request
* @param string $key key used for retrieving the right information for the registration form
*
* @return Response
*
* @throws NotFoundHttpException if `connect` functionality was not enabled
* @throws AccessDeniedException if any user is authenticated
* @throws \RuntimeException
*/
public function registrationAction( Request $request, $key ) {
$connect = $this->container->getParameter( 'hwi_oauth.connect' );
if ( ! $connect ) {
throw new NotFoundHttpException();
}
$hasUser = $this->isGranted( $this->container->getParameter( 'hwi_oauth.grant_rule' ) );
if ( $hasUser ) {
throw new AccessDeniedException( 'Cannot connect already registered account.' );
}
$session = $request->getSession();
$error = $session->get( '_hwi_oauth.registration_error.' . $key );
$session->remove( '_hwi_oauth.registration_error.' . $key );
if ( ! $error instanceof AccountNotLinkedException ) {
throw new \RuntimeException( 'Cannot register an account.',
0,
$error instanceof \Exception ? $error : null );
}
$userInformation = $this
->getResourceOwnerByName( $error->getResourceOwnerName() )
->getUserInformation( $error->getRawToken() );
/* @var $form FormInterface */
if ( $this->container->getParameter( 'hwi_oauth.fosub_enabled' ) ) {
// enable compatibility with FOSUserBundle 1.3.x and 2.x
if ( interface_exists( 'FOS\UserBundle\Form\Factory\FactoryInterface' ) ) {
$form = $this->container->get( 'hwi_oauth.registration.form.factory' )->createForm();
} else {
$form = $this->container->get( 'hwi_oauth.registration.form' );
}
} else {
$form = $this->container->get( 'hwi_oauth.registration.form' );
}
$formHandler = $this->container->get( 'hwi_oauth.registration.form.handler' );
if ( $formHandler->process( $request, $form, $userInformation ) ) {
$event = new FormEvent( $form, $request );
$this->get( 'event_dispatcher' )->dispatch( HWIOAuthEvents::REGISTRATION_SUCCESS, $event );
$this->container->get( 'hwi_oauth.account.connector' )->connect( $form->getData(), $userInformation );
// Authenticate the user
$this->authenticateUser( $request,
$form->getData(),
$error->getResourceOwnerName(),
$error->getAccessToken() );
if ( null === $response = $event->getResponse() ) {
if ( $targetPath = $this->getTargetPath( $session ) ) {
$response = $this->redirect( $targetPath );
} else {
$response = $this->render( '@HWIOAuth/Connect/registration_success.html.twig',
[
'userInformation' => $userInformation,
] );
}
}
$event = new FilterUserResponseEvent( $form->getData(), $request, $response );
$this->get( 'event_dispatcher' )->dispatch( HWIOAuthEvents::REGISTRATION_COMPLETED, $event );
return $response;
}
// reset the error in the session
$session->set( '_hwi_oauth.registration_error.' . $key, $error );
$event = new GetResponseUserEvent( $form->getData(), $request );
$this->get( 'event_dispatcher' )->dispatch( HWIOAuthEvents::REGISTRATION_INITIALIZE, $event );
if ( $response = $event->getResponse() ) {
return $response;
}
return $this->render( '@HWIOAuth/Connect/registration.html.twig',
[
'key' => $key,
'form' => $form->createView(),
'userInformation' => $userInformation,
] );
}
/**
* Connects a user to a given account if the user is logged in and connect is enabled.
*
* @param Request $request the active request
* @param string $service name of the resource owner to connect to
*
* @throws \Exception
*
* @return Response
*
* @throws NotFoundHttpException if `connect` functionality was not enabled
* @throws AccessDeniedException if no user is authenticated
*/
public function connectServiceAction( Request $request, $service ) {
$connect = $this->container->getParameter( 'hwi_oauth.connect' );
if ( ! $connect ) {
throw new NotFoundHttpException();
}
$hasUser = $this->isGranted( $this->container->getParameter( 'hwi_oauth.grant_rule' ) );
if ( ! $hasUser ) {
throw new AccessDeniedException( 'Cannot connect an account.' );
}
// Get the data from the resource owner
$resourceOwner = $this->getResourceOwnerByName( $service );
$session = $request->getSession();
$key = $request->query->get( 'key', time() );
if ( $resourceOwner->handles( $request ) ) {
$accessToken = $resourceOwner->getAccessToken(
$request,
$this->container->get( 'hwi_oauth.security.oauth_utils' )->getServiceAuthUrl( $request, $resourceOwner )
);
// save in session
$session->set( '_hwi_oauth.connect_confirmation.' . $key, $accessToken );
} else {
$accessToken = $session->get( '_hwi_oauth.connect_confirmation.' . $key );
}
// Redirect to the login path if the token is empty (Eg. User cancelled auth)
if ( null === $accessToken ) {
if ( $this->container->getParameter( 'hwi_oauth.failed_use_referer' ) && $targetPath = $this->getTargetPath( $session,
'failed_target_path' ) ) {
return $this->redirect( $targetPath );
}
return $this->redirectToRoute( $this->container->getParameter( 'hwi_oauth.failed_auth_path' ) );
}
// Show confirmation page?
if ( ! $this->container->getParameter( 'hwi_oauth.connect.confirmation' ) ) {
return $this->getConfirmationResponse( $request, $accessToken, $service );
}
// Symfony <3.0 BC
/** @var $form FormInterface */
$form = method_exists( 'Symfony\Component\Form\AbstractType', 'getBlockPrefix' )
? $this->createForm( FormType::class )
: $this->createForm( 'form' );
// Handle the form
$form->handleRequest( $request );
if ( $form->isSubmitted() && $form->isValid() ) {
return $this->getConfirmationResponse( $request, $accessToken, $service );
}
$event = new GetResponseUserEvent( $this->getUser(), $request );
$this->get( 'event_dispatcher' )->dispatch( HWIOAuthEvents::CONNECT_INITIALIZE, $event );
if ( $response = $event->getResponse() ) {
return $response;
}
return $this->render( '@HWIOAuth/Connect/connect_confirm.html.twig',
[
'key' => $key,
'service' => $service,
'form' => $form->createView(),
'userInformation' => $resourceOwner->getUserInformation( $accessToken ),
] );
}
/**
* @param Request $request
* @param string $service
*
* @throws NotFoundHttpException
*
* @return RedirectResponse
*/
public function redirectToServiceAction( Request $request, $service ) {
try {
$authorizationUrl = $this->container->get( 'hwi_oauth.security.oauth_utils' )->getAuthorizationUrl( $request,
$service );
} catch ( \RuntimeException $e ) {
throw new NotFoundHttpException( $e->getMessage(), $e );
}
// Check for a return path and store it before redirect
if ( $request->hasSession() ) {
// initialize the session for preventing SessionUnavailableException
$session = $request->getSession();
$session->start();
foreach ( $this->container->getParameter( 'hwi_oauth.firewall_names' ) as $providerKey ) {
$sessionKey = '_security.' . $providerKey . '.target_path';
$sessionKeyFailure = '_security.' . $providerKey . '.failed_target_path';
$param = $this->container->getParameter( 'hwi_oauth.target_path_parameter' );
if ( ! empty( $param ) && $targetUrl = $request->get( $param ) ) {
$session->set( $sessionKey, $targetUrl );
}
if ( $this->container->getParameter( 'hwi_oauth.failed_use_referer' ) && ! $session->has( $sessionKeyFailure ) && ( $targetUrl = $request->headers->get( 'Referer' ) ) && $targetUrl !== $authorizationUrl ) {
$session->set( $sessionKeyFailure, $targetUrl );
}
if ( $this->container->getParameter( 'hwi_oauth.use_referer' ) && ! $session->has( $sessionKey ) && ( $targetUrl = $request->headers->get( 'Referer' ) ) && $targetUrl !== $authorizationUrl ) {
$session->set( $sessionKey, $targetUrl );
}
}
}
return $this->redirect( $authorizationUrl );
}
/**
* Get the security error for a given request.
*
* @param Request $request
*
* @return string|\Exception
*/
protected function getErrorForRequest( Request $request ) {
$authenticationErrorKey = Security::AUTHENTICATION_ERROR;
$session = $request->getSession();
if ( $request->attributes->has( $authenticationErrorKey ) ) {
$error = $request->attributes->get( $authenticationErrorKey );
} elseif ( null !== $session && $session->has( $authenticationErrorKey ) ) {
$error = $session->get( $authenticationErrorKey );
$session->remove( $authenticationErrorKey );
} else {
$error = '';
}
return $error;
}
/**
* Get a resource owner by name.
*
* @param string $name
*
* @return ResourceOwnerInterface
*
* @throws NotFoundHttpException if there is no resource owner with the given name
*/
protected function getResourceOwnerByName( $name ) {
foreach ( $this->container->getParameter( 'hwi_oauth.firewall_names' ) as $firewall ) {
$id = 'hwi_oauth.resource_ownermap.' . $firewall;
if ( ! $this->container->has( $id ) ) {
continue;
}
$ownerMap = $this->container->get( $id );
if ( $resourceOwner = $ownerMap->getResourceOwnerByName( $name ) ) {
return $resourceOwner;
}
}
throw new NotFoundHttpException( sprintf( "No resource owner with name '%s'.", $name ) );
}
/**
* Generates a route.
*
* @deprecated since version 0.4. Will be removed in 1.0.
*
* @param string $route Route name
* @param array $params Route parameters
* @param bool $absolute absolute url or note
*
* @return string
*/
protected function generate( $route, array $params = [], $absolute = false ) {
@trigger_error( 'The ' . __METHOD__ . ' method is deprecated since version 0.4 and will be removed in 1.0. Use Symfony\Bundle\FrameworkBundle\Controller\Controller::generateUrl instead.',
E_USER_DEPRECATED );
return $this->container->get( 'router' )->generate( $route, $params, $absolute );
}
/**
* Authenticate a user with Symfony Security.
*
* @param Request $request
* @param UserInterface $user
* @param string $resourceOwnerName
* @param string $accessToken
* @param bool $fakeLogin
*/
protected function authenticateUser(
Request $request,
UserInterface $user,
$resourceOwnerName,
$accessToken,
$fakeLogin = true
) {
try {
$this->container->get( 'hwi_oauth.user_checker' )->checkPreAuth( $user );
$this->container->get( 'hwi_oauth.user_checker' )->checkPostAuth( $user );
} catch ( AccountStatusException $e ) {
// Don't authenticate locked, disabled or expired users
return;
}
$token = new OAuthToken( $accessToken, $user->getRoles() );
$token->setResourceOwnerName( $resourceOwnerName );
$token->setUser( $user );
$token->setAuthenticated( true );
$this->get( 'security.token_storage' )->setToken( $token );
if ( $fakeLogin ) {
// Since we're "faking" normal login, we need to throw our INTERACTIVE_LOGIN event manually
$this->container->get( 'event_dispatcher' )->dispatch(
SecurityEvents::INTERACTIVE_LOGIN,
new InteractiveLoginEvent( $request, $token )
);
}
}
/**
* @param SessionInterface $session
*
* @return string|null
*/
private function getTargetPath( SessionInterface $session ) {
foreach ( $this->container->getParameter( 'hwi_oauth.firewall_names' ) as $providerKey ) {
$sessionKey = '_security.' . $providerKey . '.target_path';
if ( $session->has( $sessionKey ) ) {
return $session->get( $sessionKey );
}
}
return null;
}
/**
* @param Request $request The active request
* @param array $accessToken The access token
* @param string $service Name of the resource owner to connect to
*
* @return Response
*
* @throws NotFoundHttpException if there is no resource owner with the given name
*/
private function getConfirmationResponse( Request $request, array $accessToken, $service ) {
/** @var $currentToken OAuthToken */
$currentToken = $this->container->get( 'security.token_storage' )->getToken();
/** @var $currentUser UserInterface */
$currentUser = $currentToken->getUser();
/** @var $resourceOwner ResourceOwnerInterface */
$resourceOwner = $this->getResourceOwnerByName( $service );
/** @var $userInformation UserResponseInterface */
$userInformation = $resourceOwner->getUserInformation( $accessToken );
$event = new GetResponseUserEvent( $currentUser, $request );
$this->get( 'event_dispatcher' )->dispatch( HWIOAuthEvents::CONNECT_CONFIRMED, $event );
$this->container->get( 'hwi_oauth.account.connector' )->connect( $currentUser, $userInformation );
if ( $currentToken instanceof OAuthToken ) {
// Update user token with new details
$newToken =
is_array( $accessToken ) &&
( isset( $accessToken[ 'access_token' ] ) || isset( $accessToken[ 'oauth_token' ] ) ) ?
$accessToken : $currentToken->getRawToken();
$this->authenticateUser( $request, $currentUser, $service, $newToken, false );
}
if ( null === $response = $event->getResponse() ) {
if ( $targetPath = $this->getTargetPath( $request->getSession() ) ) {
$response = $this->redirect( $targetPath );
} else {
$response = $this->render( '@HWIOAuth/Connect/connect_success.html.twig',
[
'userInformation' => $userInformation,
'service' => $service,
] );
}
}
$event = new FilterUserResponseEvent( $currentUser, $request, $response );
$this->get( 'event_dispatcher' )->dispatch( HWIOAuthEvents::CONNECT_COMPLETED, $event );
return $response;
}
}

View file

@ -0,0 +1,94 @@
{% extends '@HWIOAuth/layout.html.twig' %}
{% block bigMain %}
{% include 'default/header.html.twig' %}
<section class="bg-girl padded login-hwioauth">
<div class="container">
<div class="row justify-content-md-center align-items-center">
<div class="col-md-auto">
<fieldset class="bg-shader pull-left form-group padded">
<div class="row">
<div class="col-xs-12 col-sm-6">
<div class="row">
<div class="col-xs-12 col-sm-6">
<h1>
<i class="fa fa-key"></i>
Se connecter
</h1>
{#<div class="alert alert-info">#}
{#En raison de maintenance technique, seul le login via twitter fonctionne#}
{#actuellement.#}
{#</div>#}
{% if error %}
<div class="alert alert-danger">
{{ error|trans }}
</div>
{% endif %}
<form action="#" method="post">
{% if csrf_token is defined %}
csrf_token : {{ csrf_token }}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
{% else %}
<div class="alert alert-danger">
PAS DE TOKEN
</div>
{% endif %}
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username"
value="" required="required"
autocomplete="username"/>
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password"
required="required"
autocomplete="current-password"/>
<input type="checkbox" id="remember_me" name="_remember_me" value="on"/>
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
<input type="submit" id="_submit" name="_submit"
value="{{ 'security.login.submit'|trans }}"/>
</form>
</div>
<div class="col-xs-12 col-sm-6">
{#<p>#}
{#<a class="btn btn-info" href="{{ path('fos_user_resetting_request') }}">#}
{#Mot de passe oublié?#}
{#</a>#}
{#</p>#}
<p>
<a class="btn btn-info btn-block"
href="#">
Créer un compte
</a>
</p>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6">
{#{% block hwi_oauth_content %}#}
{#<h1>oauth login</h1>#}
{#{% if error is defined and error %}#}
{#<div class="alert alert-danger pull-left">{{ error|trans }}</div>#}
{#{% endif %}#}
{#<a class="btn btn-default btn-{{ "twitter" }}"#}
{#href="{{ hwi_oauth_login_url("twitter") }}">#}
{#<i class="fa fa-{{ "twitter" }}"></i>#}
{#{{ "twitter" | trans({}, 'HWIOAuthBundle') }}#}
{#</a>#}
{#{% endblock hwi_oauth_content %}#}
</div>
</div>
</fieldset>
</div>
</div>
</div>
</section>
{% include 'default/footer.html.twig' %}
{% endblock %}

View file

@ -0,0 +1,41 @@
{% extends '::default/index.html.twig' %}
{% block title %}Login{% endblock %}
{% block body %}
<h2>Le login</h2>
<div class="row">
<div class="col-xs-6">
{% if error %}
<div>{{ error|trans }}</div>
{% endif %}
<form action="#" method="post">
{% if csrf_token is defined %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
{% else %}
PAS DE TOKEN CSRF
{% endif %}
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="" required="required"
autocomplete="username"/>
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password" required="required"
autocomplete="current-password"/>
<input type="checkbox" id="remember_me" name="_remember_me" value="on"/>
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
<input type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}"/>
</form>
</div>
<div class="col-xs-6">
{#{% block hwi_oauth_content %}#}
{#{% endblock %}#}
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,57 @@
{% trans_default_domain 'messages' %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="google-signin-client_id"
content="938689189350-frtrg93bnva4b3p7c1al880mi3ts5i35.apps.googleusercontent.com">
<title>{% block title %} {% trans %}menu.title{% endtrans %} - Fiche de compte dynamique{% endblock %}</title>
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/app.css') }}">
{% endblock %}
</head>
<body>
{% block navigation %}
{% endblock %}
<div id="bodyland">
{% block bigMain %}
{% include 'default/header.html.twig' %}
<div class="row">
<div class="col-xs-12 col-sm-9 col-sm-offset-3 col-md-9 col-md-offset-3">
{% block body %}
{% endblock %}
</div>
</div>
{% include 'default/footer.html.twig' %}
{% endblock %}
</div>
{% block javascripts %}
<script src="{{ asset('build/app.js') }}"></script>
<!-- Matomo -->
<script type="text/javascript">
var _paq = _paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = "https://piwik.cipherbliss.com/";
_paq.push(['setTrackerUrl', u + 'piwik.php']);
_paq.push(['setSiteId', '1']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.type = 'text/javascript';
g.async = true;
g.defer = true;
g.src = u + 'piwik.js';
s.parentNode.insertBefore(g, s);
})();
</script>
<!-- End Matomo Code -->
{% endblock %}
</body>
</html>

View file

@ -0,0 +1,48 @@
<div class="product-values marged-v">
<div class="row">
<div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-check-circle fa-3x"></i>
<h2 class="text-center">{% trans %}home.specs.free{% endtrans %}</h2>
<p>{% trans %}home.specs.free_text{% endtrans %}</p>
</div>
<div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-random fa-3x"></i>
<h2>{% trans %}home.specs.flex{% endtrans %}</h2>
<p>{% trans %}home.specs.flex_text{% endtrans %}</p>
</div>
<div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-truck fa-3x"></i>
<h2>{% trans %}home.specs.portable{% endtrans %}</h2>
<p>{% trans %}home.specs.portable_text{% endtrans %}</p>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-rotate-left fa-3x"></i>
<h2>{% trans %}home.specs.open{% endtrans %}</h2>
<p>{% trans %}home.specs.open_text{% endtrans %}
<ul>
<li>
<a href="https://framagit.org/tykayn/caisse-bliss">gitlab.</a>
</li>
<li>
<a href="https://www.cipherbliss.com">CipherBliss</a>
</li>
</ul>
</p>
</div>
<div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-pie-chart fa-3x"></i>
<h2>{% trans %}home.specs.stats{% endtrans %}</h2>
<p>
{% trans %}home.specs.stats_text{% endtrans %}
</p>
</div>
<div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-heart-o fa-3x"></i>
<h2>{% trans %}home.specs.data{% endtrans %}</h2>
<p>{% trans %}home.specs.data_text{% endtrans %}</p>
</div>
</div>
</div>

View file

@ -0,0 +1,27 @@
<footer class="big-footer text-center navbar-inverse navbar-footer ">
<sub class="footer-note text-center">
{% trans %}global.made_by{% endtrans %}
<a href="https://mastodon.cipherbliss.com/@tykayn">
<i class="fa fa-share-alt"></i>
Tykayn -
</a>
<a href="https://www.cipherbliss.com">
<i class="fa fa-world"></i>
Cipher Bliss
</a>
<a href="https://framagit.org/tykayn/caisse-bliss">
<i class="fa fa-gitlab"></i>
sources de la Caisse Bliss
</a>
-
<a href="https://framagit.org/tykayn/caisse-bliss/blob/master/LICENSE">
<i class="fa fa-file-text"></i>
Licence AGPL v3
</a>
-
<a href="mailto:contact@cipherbliss.com">
<i class="fa fa-envelope-o"></i>
contact
</a>
</sub>
</footer>

View file

@ -0,0 +1,27 @@
<div class="header-block">
<div class="nav padded">
<div class="row">
<div class="col-xs-12">
{% include 'default/login-choices.html.twig' %}
</div>
</div>
<div class="nav-elements">
{% if app.request.hasPreviousSession %}
{% for type, messages in app.session.flashBag.all %}
{% for message in messages %}
<div class="{{ type }}">
{{ message|trans({}, 'FOSUserBundle') }}
</div>
{% endfor %}
{% endfor %}
{% endif %}
<div>
{% block fos_user_content %}
{% endblock fos_user_content %}
</div>
</div>
</div>
</div>

View file

@ -0,0 +1,6 @@
{% extends 'base.html.twig' %}
{% block bigMain %}
{% include 'default/main-screen.html.twig' %}
{% endblock %}

View file

@ -0,0 +1,181 @@
{% block loginchoices %}
<div class="loginland ">
<div class="login-choices">
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
<div class="row">
<div class="col-xs-12 col-sm-9">
<div id="menu-dashboard">
<ul class="nav">
<li>
<a href="{{ path('homepage') }}" class="btn btn-default logo-home">
<i class="fa fa-home"></i>
{% trans %}menu.title{% endtrans %}
</a>
</li>
<li>
<a class="btn {% if app.request.attributes.get('_route') == 'dashboard' %}
btn-success
{% else %}
btn-default
{% endif %}" href="{{ path('dashboard') }}">
<i class="fa fa-list"></i>
{% trans %}menu.dashboard{% endtrans %}
</a>
</li>
<li>
<a class="btn {% if app.request.attributes.get('_route') == 'productcategory_index' %}
btn-success
{% else %}
btn-default
{% endif %} "
href="{{ path('productcategory_index') }}">
<i class="fa fa-file-archive-o"></i>
{% trans %}menu.categories{% endtrans %}
<span class="badge">
{{ app.user.categories|length }}
</span>
</a>
</li>
<li>
<a class="btn {% if app.request.attributes.get('_route') == 'product_index' %}
btn-success
{% else %}
btn-default
{% endif %} "
href="{{ path('product_index') }}"
>
<i class="fa fa-gears"></i>
{% trans %}menu.products{% endtrans %}
<span class="badge">
{{ app.user.products|length }}
</span>
</a>
</li>
<li>
<a id="menu_festivals" class="btn {% if app.request.attributes.get('_route') == 'festival_index' %}
btn-success
{% else %}
btn-default
{% endif %}
" href='{{ path('festival_index') }}'
>
<i class="fa fa-th-large"></i>
{% trans %}menu.festivals{% endtrans %}
<span class="badge">
{{ app.user.festivals|length }}
</span>
</a>
</li>
<li>
<a id="menu_series" class="btn {% if app.request.attributes.get('_route') == 'seriefestival_index' %}
btn-success
{% else %}
btn-default
{% endif %}
" href='{{ path('seriefestival_index') }}'
>
<i class="fa fa-th-large"></i>
{% trans %}menu.series{% endtrans %}
<span class="badge">
{{ app.user.seriesFestivals|length }}
</span>
</a>
</li>
<li>
<a class="btn {% if app.request.attributes.get('_route') == 'history' %}
btn-success
{% else %}
btn-default
{% endif %}" href="{{ path('history') }}"
>
<i class="fa fa-clock-o"></i>
{% trans %}menu.history{% endtrans %}
</a>
</li>
<li>
<a class="btn {% if app.request.attributes.get('_route') == 'import' %}
btn-success
{% else %}
btn-default
{% endif %}" href="{{ path('import') }}"
>
<i class="fa fa-arrow-circle-o-up"></i>
{% trans %}menu.import{% endtrans %}
</a>
</li>
<li>
<a id="menu_previsionnel" class="btn {% if app.request.attributes.get('_route') == 'previsionnel' %}
btn-success
{% else %}
btn-default
{% endif %}" href="{{ path('previsionnel') }}"
>
<i class="fa fa-forward"></i>
{% trans %}menu.future{% endtrans %}
</a>
</li>
<li>
<a href="#" id="introjs_start">
<i class="fa fa-play"></i>
{# {% trans %}menu.introjs{% endtrans %}#}
Visite guidée
</a>
{% if app.user.username == 'demo' %}
<div class="text-warning alert-sm marged ">
<i class="fa fa-info-circle"></i>
<sub> Ceci est un compte de démonstration. Créez votre compte personnel dès
maintenant. </sub>
</div>
{% endif %}
</li>
</ul>
</div>
</div>
<div class="col-xs-12 col-sm-3 text-sm-left text-md-right user-info-part">
<button class="btn btn-default visible-xs pull-right" id="menu_button">
<i class="fa fa-bars"></i>
Menu
</button>
{% trans %}user.greet{% endtrans %}
<a href="#" class="user-info-link">
<i class="fa fa-user"></i>
{{ app.user.username }}
</a>
|
<a class="btn btn-default" href="#">
{% trans %}layout.logout{% endtrans %}
</a>
</div>
</div>
{% else %}
<div class="text-right pull-right">
<a class="btn btn-primary"
href="#">
<i class="fa fa-key"></i>
{{ 'layout.login'|trans }}</a>
<a class="btn btn-default"
href="#">Inscription
</a>
</div>
{% endif %}
</div>
</div>
{% endblock loginchoices %}

View file

@ -0,0 +1,100 @@
{% block bigMain %}
{% include 'default/header.html.twig' %}
{% block body %}
<div class="main-screen" id="homepage">
<div id="welcome">
<section class="bg-accessories">
<div class="bg-shader">
<div class="container main-section">
<div class="row">
<div class="col-xs-12 padded-v">
<h1 class="text-center">
{#<i class="fa fa-circle-o-notch logo-main"></i>#}
{% trans %}menu.title{% endtrans %}
</h1>
</div>
<div class="col-xs-12 col-md-6 padded-v">
<div class="description">
{% trans %}home.main_description{% endtrans %}
</div>
</div>
<div class="try col-xs-12 col-md-6">
<br>
<div class="row">
<div class=" padded text-right">
<a class="btn btn-primary"
href="#"
class="btn btn-primary">
{% trans %}home.try{% endtrans %}
</a>
</div>
<div class="hint padded">
<sub>{% trans %}home.demo_hint{% endtrans %}</sub>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
<section class="bg-girl">
<div class="bg-shader">
<div class="container">
{% include 'default/description-app.html.twig' %}
<div class="try">
<fieldset class="bg-dark padded">
<div class="row">
<div class="col-xs-12 col-sm-6">
<a class="btn btn-primary" href="{{ path('dashboard') }}"
class="btn btn-success">
{% trans %}home.try{% endtrans %}
</a>
<p>
{% trans %}home.demo_hint{% endtrans %}
</p>
</div>
<div class="col-xs-12 col-sm-6">
<a class="btn btn-primary" href="#">
<i class="fa fa-user"></i>
{% trans %}layout.register{% endtrans %}
</a>
</div>
</div>
</fieldset>
</div>
</div>
</div>
</section>
<section class="bg-color">
<div id="contact" class="text-center">
<i class="fa fa-envelope-open-o"></i>
contactez-moi pour tout renseignement:
<a href="mailto:contact@cipherbliss.com"> par email</a>
, Telegram
<a href="https://t.me/tykayn">
@tykayn
</a>
, ou sur Mastodon
<a href="https://mastodon.cipherbliss.com/@tykayn">
<img src="https://en.gravatar.com/userimage/53061325/811d383aa2ebb8d2d83baab7da5f4a7b.jpeg"
alt="avatar Mastodon" width="50" height="50"> @tykayn
</a>
</div>
</section>
</div>
{% endblock %}
{% include 'default/footer.html.twig' %}
{% endblock %}

View file

@ -0,0 +1,15 @@
{% extends 'base.html.twig' %}
{% block bigMain %}
<div style="padding:2rem;">
<h1>tadam test de mail</h1>
<p>
le contenu Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus doloremque exercitationem
provident quae quod soluta sunt velit. Architecto, assumenda deserunt expedita laudantium nemo voluptatem.
Atque commodi est iste itaque mollitia. Consequatur cumque cupiditate eveniet facilis illo illum impedit
itaque omnis placeat quaerat, quia quidem ratione saepe similique sunt veniam veritatis.
</p>
</div>
{% endblock %}

View file

@ -0,0 +1,25 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Festival edit</h1>
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type=submit value=" Envoyer
"/>
{{ form_end(edit_form) }}
<ul>
<li>
<a class="btn btn-primary" href="{{ path('festival_index') }}">
<i class="fa fa-arrow-left"></i>
Retour à la liste
</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,95 @@
{% extends 'base.html.twig' %}
{% block body %}
<div class="row heading-of-list">
<div class="col-xs-6">
<h1>Festivals</h1></div>
<div class="col-xs-6">
<a class="btn btn-primary" href="{{ path('festival_new') }}">Nouveau festival</a>
</div>
</div>
<table class="table-responsive table-striped table table-bordered table-light">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Datecreation</th>
<th>Tous Frais</th>
<th>Clients</th>
<th>fond caisse avant</th>
<th>fond caisse apres</th>
<th>chiffre affaire</th>
<th>fond caisse + CA</th>
<th>diff</th>
<th>bénefices CA - frais</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for festival in festivals %}
<tr
{% if app.user.activeFestival and (app.user.activeFestival.id == festival.id) %}
class="bg-success"
{% endif %}
>
<td>
<a class="btn btn-primary"
href="{{ path('festival_show', { 'id': festival.id }) }}">{{ festival.id }}</a>
</td>
<td>{{ festival.name }}</td>
<td>{% if festival.dateCreation %}{{ festival.dateCreation|date('Y-m-d H:i:s') }}{% endif %}</td>
<td>{{ festival.fraisInscription + festival.fraisTransport + festival.fraisRepas + festival.fraisHebergement }}
 €
</td>
<td>{{ festival.sellRecords|length }}</td>
<td>{{ festival.fondDeCaisseAvant }}€</td>
<td>{{ festival.fondDeCaisseApres }}€</td>
<td>{{ festival.chiffreAffaire }}€</td>
<td>{{ festival.fondDeCaisseAvant + festival.chiffreAffaire }}€</td>
<td
class="{% if (festival.chiffreAffaire - festival.fondDeCaisseApres) != 0 %}
bg-warning
{% else %}
bg-success
{% endif %}"
>{{ festival.chiffreAffaire - festival.fondDeCaisseApres }}
</td>
<td>{{ festival.chiffreAffaire - (festival.fraisInscription + festival.fraisTransport + festival.fraisRepas + festival.fraisHebergement ) }}</td>
<td>
{% if app.user.activeFestival and (app.user.activeFestival.id == festival.id) %}
<span class="badge badge-success">
Actuel
</span>
{% else %}
<a class="btn btn-success" href="{{ path('set_active_festival', { 'id': festival.id }) }}">
choisir comme actuel
</a>
{% endif %}
{% if festival.user|length %}
{% for u in festival.user %}
<span class="badge badge-info">{{ u.username }}</span>
{% endfor %}
{% else %}
<div class="alert alert-info">
pas d'owner.
</div>
{% endif %}
<a class="btn btn-primary" href="{{ path('festival_edit', { 'id': festival.id }) }}">
<i class="fa fa-pencil"></i>
Modifier
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a class="btn btn-primary" href="{{ path('festival_new') }}">Nouveau festival</a>
{% endblock %}

View file

@ -0,0 +1,16 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Festival creation</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<input class="btn btn-primary btn-block" type="submit" value="Créer" />
{{ form_end(form) }}
<ul>
<li>
<a class="btn btn-primary" href="{{ path('festival_index') }}"> <i class="fa fa-arrow-left"></i>Retour à la liste</a>
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,39 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Festival</h1>
<table class="table-responsive table-striped table table-bordered table-light">
<tbody>
<tr>
<th>Id</th>
<td>{{ festival.id }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ festival.name }}</td>
</tr>
<tr>
<th>Datecreation</th>
<td>{% if festival.dateCreation %}{{ festival.dateCreation|date('Y-m-d H:i:s') }}{% endif %}</td>
</tr>
</tbody>
</table>
<ul>
<li>
<a class="btn btn-primary" href="{{ path('festival_index') }}">
<i class="fa fa-arrow-left"></i>
Retour à la liste
</a>
</li>
<li>
<a class="btn btn-primary" href="{{ path('festival_edit', { 'id': festival.id }) }}">edit</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1 @@
<h1>Privacy</h1>

View file

@ -0,0 +1 @@
<h1>Terms of service</h1>

View file

@ -0,0 +1,26 @@
{% verbatim %}
<div id="choice-categories" class="choice-categories well" ng-if="categories.length">
<h2>
<i class="fa-eye fa"></i>
Visibilité des
{{ categories.length - categoriesVisibleCount() }} /
{{ categories.length }} catégories
</h2>
<div ng-repeat="c in categories">
<div class="btn btn-block"
ng-class="{'btn-success': !c.hidden}"
ng-click="c.hidden = !c.hidden">
{{ c.name }}
<span ng-if="c.hidden">(caché)</span>
</div>
</div>
</div>
<div class="well" ng-if="!categories.length">
<i class="fa fa-info"></i>
Aucune catégorie enregistrée
</div>
{% endverbatim %}

View file

@ -0,0 +1,64 @@
{% verbatim %}
<div class="current-selling">
<hr>
<form>
<div class="new-display">
<div class="row">
</div>
<div class="row">
<div class="col-xs-12 col-sm-6">
<button class="btn btn-warning btn-remove-all marged-v" ng-click="removeAll()" ng-disable="!CurrentSellingTotal()">
<i class="fa fa-trash"></i> enlever tout
</button>
</div>
</div>
<div ng-repeat="group in activeSellingFiltered track by $index">
<div class="row">
<div class="col-xs-2">
<span class="btn btn-warning remove-item"
ng-click="removeGroupeProducts(group.groupId)">
<i class="fa fa-trash"></i>
</span>
</div>
<div class="col-xs-10">
<input class="group-name" type="text" ng-model="group.name">
</div>
</div>
<div class="row">
<div class="col-xs-7 col-xs-offset-2 ">
<span ng-if="group.count > 1">
<strong>
{{group.unitPrice}}
€ </strong>
</span>
<span class="badge badge-default" ng-if="group.count">
<i class="fa fa-times"></i> {{group.count}}
</span>
</div>
<div class="col-xs-3 text-right">
<strong>
{{group.totalPrice}}
€ </strong>
</div>
</div>
</div>
</div>
<hr>
{% endverbatim %}
{% include 'logged/angular/totals.html.twig' %}
{% include 'logged/angular/validate-button.html.twig' %}
{% include 'logged/angular/pause-selling.html.twig' %}
</form>
</div>
</div>

View file

@ -0,0 +1,40 @@
{% verbatim %}
<div class="horizontal-land">
<div class="super-large" style="min-width: {{(1+categories.length) * 400}}px">
<div class="category-listing one-category col-xs-12 col-sm-4 " ng-repeat="c in categories"
ng-if="! c.hidden">
<h2 ng-class="{'hidden':c.hidden}" class="title">
{{ c.name }}
</h2>
<div class="product-listing" >
<span ng-repeat="p in c.products track by p.id"
class="product-box"
>
<button class="product-button text-left" ng-class="{ 'active' : p.enabled}" ng-click="addProduct( p )">
<img class="product-image" src="{{p.image}}" alt="image" ng-if="p.image.length">
<span class="product-name">
{{ p.name }}
</span>
<span class="badge">
{{ p.price }}
</span>
<span class="badge badge-default" ng-if="show_config.stock_count">
{{ p.stockCount }}
</span>
<span class="badge badge-success" ng-if="show_config.sold">
<i class="fa fa-tick"></i>
{{ countProductsSoldForActiveFestival[p.id] }}
</span>
</button>
<button class="express-button" ng-if="show_config.expressSelling" ng-click="expressSell(p)" title="achat express sans compléter les infos du client">
<i class="fa fa-shopping-cart"></i>
</button>
</span>
</div>
</div>
</div>
</div>
{% endverbatim %}

View file

@ -0,0 +1,30 @@
<!--ok loading done-->
<div id="loaded" ng-if="initLoadDone">
<!--caisse IHM-->
<div id="load_ok">
<div id="listing-products" class="listing-products col-xs-12 col-md-8">
{% include 'logged/angular/messages.html.twig' %}
{% include 'logged/angular/listing-products.html.twig' %}
</div>
<div id="sellings" class="sellings col-xs-12 col-md-4">
<div class="list-sell" ng-class="{'bg-success text-success': sellingOk }">
{% include 'logged/angular/validate-button.html.twig' %}
{% if app.user.products |length %}
{% include 'logged/angular/current.html.twig' %}
{% endif %}
{#{% include 'logged/angular/paused.html.twig' %}#}
</div>
</div>
</div>
<div id="other_time">
{% include 'logged/angular/recent.html.twig' %}
</div>
<div class="col-xs-12 col-md-4 col-md-offset-8">
{% include 'logged/angular/categ-options.html.twig' %}
</div>
</div>

View file

@ -0,0 +1,42 @@
{% verbatim %}
<div id="messages">
<div id="no-categories" class="alert alert-info" ng-if="!categories.length">
<i class="fa fa-info"></i>
Vous n'avez pas encore enregistré de <strong>catégorie de produit</strong>, ajoutez-en donc.
</div>
<div id="no-products" class="alert alert-info" ng-if="!productsFromDB.length">
<i class="fa fa-info"></i>
Vous n'avez pas encore enregistré de <strong>produit</strong>, ajoutez-en donc.
</div>
{% endverbatim %}
<div>
{% if app.user.activeFestival is null %}
<div id="no-products" class="alert alert-info" ng-if="!productsFromDB.length">
<i class="fa fa-info"></i>
Sélectionnez un <strong>festival</strong> pour grouper vos ventes clients par évènement.
</div>
{% endif %}
</div>
{% if not (app.user.products |length) %}
<div class="alert alert-info" ng-if="!productsFromDB.length && initLoadDone">
<i class="fa fa-info"></i>
Créez facilement vos catégories de produits et vos produits juste en écrivant un nom par ligne dans
<a class="link" href="{{ path('import') }}">
<button>
l'interface d'importation simplifiée
</button>
</a>
</div>
<hr>
{% endif %}
{% verbatim %}
<!--end messages warning-->
</div>
{% endverbatim %}

View file

@ -0,0 +1,8 @@
{% verbatim %}
<!--<div class="col">-->
<!--<button class="btn btn-default" id="pause_selling" ng-click="pauseSelling()">-->
<!--<i class="fa fa-clock"></i>-->
<!--Pause-->
<!--</button>-->
<!--</div>-->
{% endverbatim %}

View file

@ -0,0 +1,15 @@
{% verbatim %}
<div class="selling-on-hold">
<h4>
Ventes en pause
</h4>
<ul>
<li ng-repeat="list in pausedSellings track by $index"
ng-click="setBackPausedSelling(list, $index)">
{{ $index }}) {{ list.products.length }} produits, <strong>
{{ sumOfList(list) }}€ </strong>
</li>
</ul>
<hr>
</div>
{% endverbatim %}

View file

@ -0,0 +1,8 @@
<div class="selling-history">
{% verbatim %}
<div ng-repeat="s in recentSelling track by $index">
{{s.id}} )
{{s.amount}}
</div>
{% endverbatim %}
</div>

View file

@ -0,0 +1,33 @@
{% verbatim %}
<div class="">
<div class="row clickable" >
<div class="col-xs-12 col-sm-6 text-right">
<h3 ng-click="setRightAmountPaid()">Total: </h3>
</div>
<div class="col-xs-12 col-sm-6 text-right">
<h3 ng-click="setRightAmountPaid()">
<strong>
{{ CurrentSellingTotal() }}
</strong>€
</h3>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div >
Le client paie:
</div>
<div >
<input class="text-right" type="number" id="paid_amount" ng-model="paidAmount">
</div>
</div>
</div>
<div class="alert alert-success" ng-if="paidAmount && CurrentSellingTotal() - paidAmount <=0">
<h3>Rendu: {{ -1*(CurrentSellingTotal() - paidAmount) }} €</h3>
</div>
<div class="alert alert-warning" ng-if="paidAmount && CurrentSellingTotal() - paidAmount >0">
<h3>il manque: {{ CurrentSellingTotal() - paidAmount }} €</h3>
</div>
</div>
{% endverbatim %}

View file

@ -0,0 +1,13 @@
{% verbatim %}
<button class="btn btn-primary btn-block validate_selling" ng-click="sendForm(event)"
ng-disabled="!paidAmount">
<i class="fa fa-check"></i>
<span ng-if="paidAmount && CurrentSellingTotal() - paidAmount <=0">
Valider
</span>
<span ng-if="paidAmount && CurrentSellingTotal() - paidAmount >0">
<i class="fa fa-warning"></i>
</span>
</button>
{% endverbatim %}

View file

@ -0,0 +1,11 @@
<div class="caisse-main-box">
{% verbatim %}
<div id="not_loaded" ng-if="!initLoadDone">
<div class="well text-center">
<i class="fa fa-refresh fa-spin fa-3x"></i> Chargement en cours de vos produits
</div>
</div>
{% endverbatim %}
{% include 'logged/angular/loaded-caisse.html.twig' %}
</div>

View file

@ -0,0 +1,25 @@
{% verbatim %}
<!-- client actuel infos-->
<div id="client-now" class="client-now padded">
<i class="fa fa-user"></i>
<label for="sellingComment">
Client actuel: {{ activeSelling.length }} produit<span ng-if="activeSelling.length!=1">s</span>
</label>
<button type="button" class="deleter pull-right" ng-click="sellingComment = ''">
<i class="fa fa-times"></i>
</button>
<input type="text"
class="form-control"
aria-label="Note about the client"
id="sellingComment"
aria-describedby="selling-comment"
ng-model="sellingComment"
ng-model-options="{ updateOn: 'keyup' , allowInvalid: true}"
name="sellingComment"
autofocus="autofocus"
placeholder="nom ou commentaire">
</div>
{% endverbatim %}

View file

@ -0,0 +1,38 @@
{% extends 'base.html.twig' %}
{% block body %}
{% verbatim %}
<div id="caisse-now" class=""
ng-app="caisse"
ng-controller="CaisseCtrl as MainCtrl">
<div class="caisse-main row-fluid" >
<div class="col-xs-12 ">
<!-- ligne d'informations-->
{% endverbatim %}
{% include 'logged/listing-options.html.twig' %}
{% include 'logged/festival-infos.html.twig' %}
{# </div>#}
<div class="col-xs-12">
{% include 'logged/customer.html.twig' %}
{% verbatim %}
</div>
<!--états de sauvegarde-->
<div class="selling-ok alert-success alert block" ng-if="sellingOk" ng-click="sellingOk = false">
<i class="fa fa-save"></i>
Sauvegardé! WOHOOOOOO +{{recentSellings[recentSellings.length -1].amount}}
</div>
<div class="selling-ok alert-error alert block" ng-if="sellingError" ng-click="sellingError = false">
<i class="fa fa-warning"></i>
Problème de sauvegarde (pas de réseau ?)
</div>
{% endverbatim %}
{% include 'logged/caisse-main.html.twig' %}
{% verbatim %}
{% endverbatim %}
</div>
{% endblock %}

View file

@ -0,0 +1,25 @@
<div id="festival-current_info">
<a class="btn " href=" {{ path('festival_index') }}">
<i class="fa fa-th-large"></i>
Festival:
{% verbatim %}
{{activeFestival.name}}
</a>
<!-- <input type="text" ng-model="activeFestival.name" placeholder="nom du festival">-->
<!-- <input class="pull-right" type="text" ng-model="activeFestival.commentaire" placeholder="commentaire">-->
<span class="badge" title="fond de caisse + chiffre d'affaire. veillez à vider votre fond de caisse ailleurs lorsqu'il devient trop important, par exemple au dela de 200€" ng-class="{'badge-warning': activeFestival.fondDeCaisseAvant + activeFestival.chiffreAffaire > 200}">
<i class="fa fa-archive"></i>
{{ activeFestival.fondDeCaisseAvant + activeFestival.chiffreAffaire}} €
</span>
<span class="badge badge-success">
CA {{ activeFestival.chiffreAffaire }}
<span ng-if="sellingOk">
<i class="fa fa-check-circle-o"></i>
</span>
</span>
<span class="badge badge-success">
{{ activeFestival.clientsCount }} <i class="fa fa-user"></i>
</span>
{% endverbatim %}
</div>

View file

@ -0,0 +1,75 @@
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script>
var dataPoints = [
{% for pair in statisticsSoldProducts %}
{
label: "{{ pair.name }}",
x: {{ pair.count }},
y: {{ pair.count }}
},
{% endfor %}
];
var dataPointsChiffreAffaire = [
{% for pair in statisticsSoldProducts %}
{
label: "{{ pair.name }}",
x: {{ pair.value }},
y: {{ pair.value }}
},
{% endfor %}
];
var dataPointsFestivals = [
{% for pair in statisticsFestivals %}
{
label: "{{ pair.name }} {{ pair.date|date('Y-m-d') }} , {{ pair.chiffreAffaire }} €",
y: {{ pair.chiffreAffaire }} ,
countClients : "{{ pair.clients_count }} clients"
},
{% endfor %}
];
console.log(dataPointsFestivals);
var chartFestival = new CanvasJS.Chart("chartContainerstatisticsFestivals", {
title:{
text: "Chiffre d'affaire par festival"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "column",
dataPoints: dataPointsFestivals
}
]
});
console.log('dataPointsFestivals', dataPointsFestivals);
chartFestival.render();
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "Volume de produits vendus"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
dataPoints: dataPoints
}
]
});
chart.render();
var chartContainerChiffreAffaire = new CanvasJS.Chart("chartContainerChiffreAffaire", {
title:{
text: "Valeur en euros des produits vendus"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
dataPoints: dataPointsChiffreAffaire
}
]
});
chartContainerChiffreAffaire.render();
</script>

View file

@ -0,0 +1,156 @@
{% extends 'base.html.twig' %}
{% block body %}
<div id="wrapper">
<div id="container" class="container">
<div class="row">
<h1>Historique</h1>
</div>
<div class="row">
<div class="col-xs-12">
<div class="sells">
<div class="row">
<div class="col-xs-12 col-sm-4">
<h2>
<i class="fa fa-users"></i>
<span class="chiffre key-figure">
{{ allSellings }}
</span>
Clients
</h2>
</div>
<div class="col-xs-12 col-sm-4">
<h2>
<i class="fa fa-euro"></i>
<span class="chiffre key-figure">
{{ chiffreAffaires }}
</span>
Chiffre d'affaires
</h2>
</div>
<div class="col-xs-12 col-sm-4">
<h2>
<i class="fa fa-shopping-cart"></i>
<span class="chiffre key-figure">
{% if allSellings %}
{{ (chiffreAffaires / (allSellings))|round }}
{% else %}
?
{% endif %}
</span>
€ panier moyen
</h2>
</div>
</div>
<div>
</div>
</div>
</div>
<div class="col-xs-12 ">
<h2>Exporter toutes vos données</h2>
<a class="btn btn-success" href="{{ path('export_all') }}">
<i class="fa fa-file-excel-o fa-3x"></i>
en format csv
</a
><a class="btn btn-success" href="{{ path('export_all_json') }}">
<i class="fa fa-file-code-o fa-3x"></i>
en JSON
</a>
</div>
</div>
<hr>
<h2 class="text-center">Statistiques de ventes </h2>
<div id="chartContainer" style="display: inline-block; height: 300px; width: 49%;"></div>
<div id="chartContainerChiffreAffaire" style="display: inline-block; height: 300px; width: 49%;"></div>
<h2> {{ statisticsFestivals |length }} Festival
{% if statisticsFestivals |length >1 %}
s
{% endif %}</h2>
<div id="chartContainerstatisticsFestivals"
style="display: inline-block; height: 300px; width: 100%;"></div>
</div>
<hr>
<div id="last-sellings">
<div class="row">
<div class="col-xs-12">
<div class="table">
<div class="row-fluid">
<div class="col-xs-12">
<h2>
{{ recentSells |length }} Dernières ventes
</h2>
</div>
</div>
<table class="table table-striped">
<thead>
<tr>
<td>n°</td>
<td>date</td>
<td>commentaire</td>
<td>produits</td>
<td>montant</td>
<td>Actions</td>
</tr>
</thead>
<tbody>
{% for vente in recentSells %}
<tr>
<td> {{ vente.id }}</td>
<td> {{ vente.date |date('Y-m-d H:i:s') }}</td>
<td>{{ vente.comment }}</td>
<td class="text-right">
{% if vente.productsSold |length >1 %}
<strong>
{{ vente.productsSold |length }}
</strong> produits
{% else %}
{% if vente.productsSold and vente.productsSold.0 is defined %}
{{ vente.productsSold.0.name }}
{% endif %}
{% endif %}
</td>
<td class="text-right">
{{ vente.amount }}
</td>
<td>
<a href="{{ path('sellrecord_delete',{id: vente.id }) }}"
class="btn btn-warning pull-right">
<i class="fa fa-trash"></i>
</a>
</td>
</tr> {% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% include ':logged:history-script.html.twig' %}
</div>
{% endblock %}

View file

@ -0,0 +1,39 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Importation, création en masse</h1>
<div class="row">
<div class="col-xs-12 ">
{% include 'logged/mass-register.html.twig' %}
</div>
<div class="col-xs-12">
<h2>
Importer votre historique de ventes
</h2>
<div class="alert alert-warning">
<i class="fa fa-warning"></i>
Fonctionnalité en cours de création
</div>
{# 1)#}
{# <a class="btn btn-success" href="{{ asset('modele_import_caisse.csv') }}">#}
{# <i class="fa fa-file-o fa-3x"></i>#}
{# Télécharger le fichier de modèle#}
{# </a>#}
{# <hr>#}
{# 2) Remplir votre modèle avec vos ventes#}
{# <hr>#}
{# 3) à faire#}
{#<form action="{{ path('import') }}" method="post">#}
{#<fieldset>#}
{#Importer votre modèle rempli#}
{#<input disabled type="file" name="fichier_import">#}
{#<input disabled class="btn btn-primary btn-block" type="submit" value="importer votre historique">#}
{#</fieldset>#}
</form>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,48 @@
<div id="festival-listing-options">
{% verbatim %}
<!-- options-->
<div class="row marged-v" ng-if="simpleDisplay">
<button class="btn btn-success" ng-click="toggleSimpleDisplay()">
<i class="fa fa-bars"></i> Affichage simple <i class="fa fa-check-circle"></i>
</button>
</div>
<div class="row marged-v" ng-if="! simpleDisplay">
<div class="col-xs-12 col-md-6" id="main_options">
<button class="btn btn-disabled" ng-click="toggleSimpleDisplay()">
<i class="fa fa-bars"></i> Affichage simple
</button>
<button
title="la vente express vous permet d'enregistrer une vente pour un seul article sans remplir le formulaire de détail"
class="btn"
ng-class="{'btn-success': show_config.expressSelling, 'btn-disabled':! show_config.expressSelling}"
ng-click="show_config.expressSelling = !show_config.expressSelling">
<i class="fa fa-shopping-cart"></i>
vente express
<span ng-if=show_config.show_config.expressSelling>
<i class="fa fa-check-circle"></i></span>
</button>
<button
title="montrer le nombre d'objets restants dans les stocks"
class="btn"
ng-class="{'btn-success': show_config.stock_count, 'btn-disabled':!show_config.stock_count}"
ng-click="show_config.stock_count = !show_config.stock_count">
<i class="fa fa-shopping-cart"></i>
stocks
<span ng-if=show_config.stock_count>
<i class="fa fa-check-circle"></i></span>
</button>
<button
title="montrer le nombre d'objets restants dans les stocks"
class="btn"
ng-class="{'btn-success': show_config.sold, 'btn-disabled':!show_config.sold}"
ng-click="show_config.sold = !show_config.sold">
<i class="fa fa-shopping-cart"></i>
vendus
<span ng-if=show_config.sold>
<i class="fa fa-check-circle"></i>
</span>
</button>
</div>
</div>
{% endverbatim %}
</div>

View file

@ -0,0 +1,49 @@
<div id="mass-register">
<form action="{{ path('mass_create') }}" method="post">
<div class="row">
<div class="col-xs-12 col-sm-6">
<blockquote>
<strong>Vous pouvez copier et adapter cet exemple: </strong>
<pre id="example_mass_import">
catégorie: livre
les moutaines;5€
la laine des moutons;6€
star wars spécial noël;7€
catégorie: poster
super bannière A2;10€
Sébastien Chabal sexy;10€
catégorie: dessin à la demande
dessin A4 crayon;20€
dessin A4 aquarelle;150€
</pre>
<a href="#filling_zone" id="use_example">
<i class="fa fa-arrow-down"></i>
Utiliser l'exemple
</a>
</blockquote>
</div>
<div class="col-xs-12 col-sm-6">
<div class="well" id="filling_zone">
<label for="produits">
<h3>
Créez vos produits et leur catégorie en masse, un par ligne.
</h3>
Séparez le nom du produit de son prix avec un point virgule. vous n'êtes pas obligé de préciser
le symbole € pour le prix. Utilisez une virgule ou un point pour faire des prix à virgule. Si le
nom de catégorie existe déjà, le produit sera associé avec celle-ci.
</label>
<textarea style="width: 100%;" name="produits" id="produits" cols="30" rows="10"
placeholder="catégorie et produits">
catégorie: livre
mon livre ; 5€
</textarea>
<input class="btn btn-primary btn-block" type="submit" value="créer en masse">
</div>
</div>
</div>
</form>
</div>

View file

@ -0,0 +1,8 @@
{% extends 'base.html.twig' %}
{% block body %}
<div id="wrapper">
<h1>Appli angular embarquée</h1>
<script href="{{ asset('/assets/js/build-frontend-submodule/main.js') }}"></script>
<div ng-app="tktest"></div>
</div>
{% endblock %}

View file

@ -0,0 +1,281 @@
{% extends 'base.html.twig' %}
{% block body %}
{% verbatim %}
<div id="wrapper">
<div class="previsionnel"
ng-app="caisse"
ng-controller="previsionnelCtrl as pCtrl"
>
<div class="row">
<div class="col-xs-12 col-lg-6">
<h1>Prévisionnel</h1>
</div>
<div class="col-xs-12 col-lg-6">
<div ng-if="config.initialLoadingDone && config.loading">
<i class="fa fa-spin fa-refresh"></i>
Chargement
</div>
<div ng-if="config.initialLoadingDone && !config.loading">
Modifications sauvegardées
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="config well">
<h2>
Configuration
</h2>
<div class="row">
<div class="col-xs-12 col-sm-6">
<p >
<label for="dispo">
Euros disponibles au départ:
</label>
<input
id="dispo"
class="big-number"
type="number"
ng-model="config.disponibility"
ng-change="save()"
ng-model-options="{ debounce: config.debounceTime }">
<br>
<label for="gains">
Gains moyen par mois:
</label>
<input type="number"
class="big-number"
id="gains"
ng-model="config.averageMonthlyEarnings"
ng-change="save()"
ng-model-options="{ debounce: config.debounceTime }">
</p>
<p>
Gérer délais de paiement
<input type="checkbox" ng-model="config.showDelays">
Gérer répétitions
<input type="checkbox" ng-model="config.showRepeats">
</p>
</div>
<div class="col-xs-12 col-sm-6">
<p>
<strong>
Dépenses mensuelles:
<span class="big-number">
{{ sumMonthlyExpenses() }}
</span>
</strong>
</p>
<p>
<strong>
Bénef mensuel: <span class="big-number">{{ config.averageMonthlyEarnings - sumMonthlyExpenses() }} €</span>
</strong>
</p>
<p>
Crédit mensuel réalisable (33% des gains moyens par mois): {{ config.averageMonthlyEarnings * 0.33 |number }}
</p>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-lg-7 postes">
<h2>
{{expenses.length}} Postes de dépenses mensuelles
<button ng-click="addExpense()">+</button>
</h2>
<p class="desc">
Indiquez les catégories de dépenses mensuelles que vous faites pour faire évoluer la
simulation de budget restant dans plusieurs mois.
</p>
<table class="exepanse-table">
<thead>
<tr>
<td class="padded" >
Nom
</td>
<td class="padded" ng-if="config.showDelays">
débute dans X mois
</td>
<td class="padded" ng-if="config.showRepeats">
mois répétitions
</td>
<td class="padded" ng-if="config.showRepeats">
prix répétitions
</td>
<td class="padded" >
prix mensuel
</td>
<td class="padded" >
prix annuel
</td>
<td class="padded" >
activé
</td>
</tr>
</thead>
<tbody>
</tbody>
<tr ng-repeat="e in expenses ">
<td>
<input type="text" ng-model="e.name" ng-change="save()" ng-model-options="{ debounce: config.debounceTime }">
</td>
<td ng-if="config.showDelays">
<input type="number" ng-model="e.delay" ng-change="save()" ng-model-options="{ debounce: config.debounceTime }">
</td>
<td ng-if="config.showRepeats">
<input type="number" ng-model="e.repeat" ng-change="save()" ng-model-options="{ debounce: config.debounceTime }">
</td>
<td ng-if="config.showRepeats" class="text-right padded">
{{ e.repeat * e.amount }}
</td>
<td>
<input type="number" ng-model="e.amount" ng-change="save()" ng-model-options="{ debounce: config.debounceTime }">
</td>
<td class="text-right padded">
<strong>
{{ e.amount * 12 }}
</strong>
</td>
<td class="padded">
<input type="checkbox" ng-model="e.enabled" ng-change="save()" ng-model-options="{ debounce: config.debounceTime }">
</td>
</tr>
</table>
<div class="well examples-depenses">
<strong>
Exemples de postes de dépenses à ajouter:
</strong>
{% endverbatim %}
{{ "
appartement
mutuelle
transport en commun
assurance voiture
assurance moto
trucs de loisirs divers
gaz
elec
internet
épargne
impots
cottisation URSSAF
resto au boulot
courses
serveur wouaibe
abonnement protonmail VPN
abonnement service audio, vidéo
carburant véhicule
donations
médecin
chat
chien
licorne"|nl2br }}
{% verbatim %}
</div>
</div>
<div class="col-sm-12 col-lg-5">
<h2>Simulation sur {{config.lines}} mois</h2>
<div class="" id="simulationPrevision" style="display: inline-block; height: 300px; width: 90%;">(graphique)</div>
<!--block to insert the graph-->
<div class="well big-number" ng-if="config.monthsBeforeNoMoney && config.monthsBeforeNoMoney <= config.lines">
<i class="fa fa-warning"></i>
Ce sera la dèche dans {{config.monthsBeforeNoMoney}} mois
</div>
<div ng-if=" ! config.monthsBeforeNoMoney" class="bg-success padded">
cool ! votre plan est supportable dans le temps
</div>
<table>
<thead>
<tr >
<td class="padded" >
Month in the future
</td>
<td class="padded" >
date
</td>
<td class="padded" >
Dépenses
</td>
<td class="padded" >
Disponibilité
</td>
</trclass>
</thead>
<tbody>
<tr ng-repeat="line in previsionTable" >
<td>
<div ng-if="line.available > config.warningThershold"
class=" bgsuccess padded ">
{{ $index }}
</div>
<div ng-if="line.available > 0 && line.available < config.warningThershold"
class="bgwarning padded ">
{{ $index }} bientôt la dèche
</div>
<div ng-if="line.available < 0"
class="bgdanger padded ">
{{ $index }} DAMNED pu de pognon!
</div>
</td>
<td>
-
</td>
<td class="text-right ">
{{ line.expense }}
</td>
<td class="text-right"
ngClass="{'bgdanger' : line.available < 0 }">
<strong>
{{ line.available}}
</strong>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!--<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>-->
<script>
var dataPoints = {{graphPointsPrevision}} ;
var chartContainerChiffreAffaire = new CanvasJS.Chart("simulationPrevision", {
title:{
text: "Euros disponibles dans le temps"
},
animationEnabled: true,
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "splineArea",
dataPoints: dataPoints
}
]
});
chartContainerChiffreAffaire.render();
</script>
{% endverbatim %}
{% endblock %}

View file

@ -0,0 +1,24 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Product edit</h1>
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Edit"/>
{{ form_end(edit_form) }}
<ul>
<li>
<a class="btn btn-primary" href="{{ path('product_index') }}">
<i class="fa fa-arrow-left"></i>
Retour à la liste
</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,74 @@
{% extends 'base.html.twig' %}
{% block body %}
<div class="row heading-of-list">
<div class="col-xs-6">
<h1>Produits</h1></div>
<div class="col-xs-6">
<a class="btn btn-primary pull-right" href="{{ path('product_new') }}">Nouveau produit</a>
<span class="hint alert alert-info pull-right">
astuce: Utilisez
<strong>
<a href="{{ path('import') }}">
l'import de masse
</a>
</strong>
pour créer plusieurs produits et catégories à la fois
</span>
</div>
</div>
<table class="table-responsive table-striped table table-bordered table-light">
<thead class="bg-dark">
<tr>
<th>Id</th>
<th>Category</th>
<th>Name</th>
<th>Image</th>
<th>Price</th>
<th>Stocks</th>
<th>Vendus</th>
<th>Comment</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr>
<td>
<a class="btn btn-primary btn-block"
href="{{ path('product_show', { 'id': product.id }) }}">{{ product.id }}</a>
</td>
<td>
<a class="btn btn-primary btn-block"
href="{{ path('productcategory_edit', { 'id': product.category.id }) }}">
{{ product.category.name }}
</a>
</td>
<td>
<a class="btn btn-default btn-block" href="{{ path('product_edit', { 'id': product.id }) }}">
{{ product.name }}
</a>
</td>
<td>{{ product.image }}</td>
<td>{{ product.price }}</td>
<td>{{ product.stockCount }}</td>
<td>{{ product.productsSold | length }}</td>
<td>{{ product.comment }}</td>
<td>
<a class="btn btn-default" href="{{ path('product_edit', { 'id': product.id }) }}">
<i class="fa fa-pencil"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a class="btn btn-primary" href="{{ path('product_new') }}">Nouveau produit</a>
{% endblock %}

View file

@ -0,0 +1,19 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Product creation</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" class="btn btn-primary btn-block" value="Créer"/>
{{ form_end(form) }}
<ul>
<li>
<a class="btn btn-primary" href="{{ path('product_index') }}">
<i class="fa fa-arrow-left"></i>
Retour à la liste
</a>
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,47 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Product</h1>
<table class="table-responsive table-striped table table-bordered table-light">
<tbody>
<tr>
<th>Id</th>
<td>{{ product.id }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ product.name }}</td>
</tr>
<tr>
<th>Image</th>
<td>{{ product.image }}</td>
</tr>
<tr>
<th>Price</th>
<td>{{ product.price }}</td>
</tr>
<tr>
<th>Comment</th>
<td>{{ product.comment }}</td>
</tr>
</tbody>
</table>
<ul>
<li>
<a class="btn btn-primary" href="{{ path('product_index') }}">
<i class="fa fa-arrow-left"></i>
Retour à la liste
</a>
</li>
<li>
<a class="btn btn-primary" href="{{ path('product_edit', { 'id': product.id }) }}">edit</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1 @@
essai qui marche

View file

@ -0,0 +1,41 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Catégorie <strong> {{ productCategory.name }} </strong></h1>
<div class="row">
<div class="col-xs-12 col-sm-6">
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Edit"/>
{{ form_end(edit_form) }}
<div class="padded">
<ul>
<li>
<a class="btn btn-primary btn-block" href="{{ path('productcategory_index') }}"> <i
class="fa fa-arrow-left"></i> Retour à la liste</a>
</li>
<li>
{{ form_start(delete_form) }}
<input class="btn btn-warning btn-block" type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
</div>
</div>
<div class="col-xs-12 col-sm-6">
<h2>{{ productCategory.products|length }} Produits associés</h2>
<div class="listing">
{% for p in productCategory.products %}
<a class="btn btn-default btn-block" href="{{ path('product_edit', { 'id': p.id }) }}">
{{ p.name }}
</a>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,49 @@
{% extends 'base.html.twig' %}
{% block body %}
<div class="row heading-of-list">
<div class="col-xs-6">
<h1>Catégorie de produit</h1></div>
<div class="col-xs-6">
<a class="btn btn-primary" href="{{ path('productcategory_new') }}">Nouvelle catégorie</a>
</div>
</div>
<table class="table-responsive table-striped table table-bordered table-light">
<thead>
<tr>
<th>Id</th>
<th>Nom</th>
<th>Produits</th>
<th>Vendus</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for productCategory in productCategories %}
<tr>
<td>
<a class="btn btn-primary"
href="{{ path('productcategory_show', { 'id': productCategory.id }) }}">{{ productCategory.id }}</a>
</td>
<td><a class="btn btn-default btn-block"
href="{{ path('productcategory_edit', { 'id': productCategory.id }) }}">
{{ productCategory.name }}
</a></td>
<td>{{ productCategory.products|length }}</td>
<td>{{ productCategory.productsSold|length }}</td>
<td>
<a class="btn btn-primary"
href="{{ path('productcategory_edit', { 'id': productCategory.id }) }}">
<i class="fa fa-pencil"></i>
edit
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a class="btn btn-primary" href="{{ path('productcategory_new') }}">Nouvelle catégorie</a>
{% endblock %}

View file

@ -0,0 +1,16 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Création de catégorie de produit</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" class="btn btn-primary btn-block" value="Créer" />
{{ form_end(form) }}
<ul>
<li>
<a class="btn btn-primary" href="{{ path('productcategory_index') }}"> <i class="fa fa-arrow-left"></i>Retour à la liste</a>
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,32 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Productcategory</h1>
<table class="table-responsive table-striped table table-bordered table-light">
<tbody>
<tr>
<th>Id</th>
<td>{{ productCategory.id }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ productCategory.name }}</td>
</tr>
</tbody>
</table>
<ul>
<li>
<a class="btn btn-primary" href="{{ path('productcategory_index') }}"> <i class="fa fa-arrow-left"></i>Retour à la liste</a>
</li>
<li>
<a class="btn btn-primary" href="{{ path('productcategory_edit', { 'id': productCategory.id }) }}">edit</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,21 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Sellrecord edit</h1>
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Edit" />
{{ form_end(edit_form) }}
<ul>
<li>
<a class="btn btn-primary" href="{{ path('sellrecord_index') }}"> <i class="fa fa-arrow-left"></i>Retour à la liste</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,54 @@
{% extends 'base.html.twig' %}
{% block body %}
<div class="row heading-of-list">
<div class="col-xs-6">
<h1>Enregistrements de ventes</h1>
</div>
<div class="col-xs-6">
<a class="btn btn-primary" href="{{ path('sellrecord_new') }}">Nouvel enregistrement</a>
</div>
</div>
<table class="table-responsive table-striped table table-bordered table-light">
<thead>
<tr>
<th>Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for sellRecord in sellRecords %}
<tr>
<td>
<a class="btn btn-primary"
href="{{ path('sellrecord_show', { 'date': sellRecord.date }) }}">{{ sellRecord.date }}</a>
</td>
<td>
<ul>
<li>
<a class="btn btn-primary"
href="{{ path('sellrecord_show', { 'date': sellRecord.date }) }}">voir
</a>
</li>
<li>
<a class="btn btn-primary"
href="{{ path('sellrecord_edit', { 'date': sellRecord.date }) }}">
<i class="fa fa-pencil"></i>
</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a class="btn btn-primary" href="{{ path('sellrecord_new') }}">Nouveau sellRecord</a>
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,19 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Sellrecord creation</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" class="btn btn-primary btn-block" value="Créer"/>
{{ form_end(form) }}
<ul>
<li>
<a class="btn btn-primary" href="{{ path('sellrecord_index') }}">
<i class="fa fa-arrow-left"></i>
Retour à la liste
</a>
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,31 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Sellrecord</h1>
<table class="table-responsive table-striped table table-bordered table-light">
<tbody>
<tr>
<th>Date</th>
<td>{% if sellRecord.date %}{{ sellRecord.date|date('Y-m-d H:i:s') }}{% endif %}</td>
</tr>
</tbody>
</table>
<ul>
<li>
<a class="btn btn-primary" href="{{ path('sellrecord_index') }}">
<i class="fa fa-arrow-left"></i>
Retour à la liste
</a>
</li>
<li>
<a class="btn btn-primary" href="{{ path('sellrecord_edit', { 'date': sellRecord.date }) }}">edit</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,21 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Seriefestival edit</h1>
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Edit" />
{{ form_end(edit_form) }}
<ul>
<li>
<a href="{{ path('seriefestival_index') }}">Back to the list</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,55 @@
{% extends 'base.html.twig' %}
{% block body %}
<div class="row heading-of-list">
<div class="col-xs-6">
<h1>Série de Festivals</h1>
<div class="well">
une série de festival vous permet d'obtenir des statistiques sur plusieurs évènements à la fois. et de comparer
des coûts et bénéfices d'une édition à une autre.
</div>
</div>
<div class="col-xs-6">
<a class="btn btn-primary" href="{{ path('seriefestival_new') }}">Nouvelle série</a>
</div>
</div>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Datecreation</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for serieFestival in serieFestivals %}
<tr>
<td>
<a href="{{ path('seriefestival_show', { 'id': serieFestival.id }) }}">{{ serieFestival.id }}</a>
</td>
<td>{{ serieFestival.name }}</td>
<td>{% if serieFestival.dateCreation %}{{ serieFestival.dateCreation|date('Y-m-d H:i:s') }}{% endif %}</td>
<td>
<ul>
<li>
<a href="{{ path('seriefestival_show', { 'id': serieFestival.id }) }}">show</a>
</li>
<li>
<a href="{{ path('seriefestival_edit', { 'id': serieFestival.id }) }}">edit</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a class="btn btn-primary" href="{{ path('seriefestival_new') }}">Nouvelle série</a>
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,16 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Création de série de festival</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" value="Create"/>
{{ form_end(form) }}
<ul>
<li>
<a href="{{ path('seriefestival_index') }}">Retour à la liste</a>
</li>
</ul>
{% endblock %}

View file

@ -0,0 +1,36 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Seriefestival</h1>
<table>
<tbody>
<tr>
<th>Id</th>
<td>{{ serieFestival.id }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ serieFestival.name }}</td>
</tr>
<tr>
<th>Datecreation</th>
<td>{% if serieFestival.dateCreation %}{{ serieFestival.dateCreation|date('Y-m-d H:i:s') }}{% endif %}</td>
</tr>
</tbody>
</table>
<ul>
<li>
<a href="{{ path('seriefestival_index') }}">Back to the list</a>
</li>
<li>
<a href="{{ path('seriefestival_edit', { 'id': serieFestival.id }) }}">Edit</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}