Commit 3e2dcd6f authored by Aldo's avatar Aldo 🐛

WIP shows correct price and added price in order table

parent 898f47fd
......@@ -23,7 +23,8 @@
"symfony/webpack-encore-bundle": "^1.7",
"symfony/yaml": "5.0.*",
"twig/cssinliner-extra": "^3.0",
"twig/extra-bundle": "^3.0"
"twig/extra-bundle": "^3.0",
"twig/intl-extra": "^3.0"
},
"require-dev": {
"symfony/maker-bundle": "^1.14"
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "07f38316918f7c6f5f06646dc3d5a7ec",
"content-hash": "680e170e741cd693dfd4ea008d8cedc3",
"packages": [
{
"name": "doctrine/annotations",
......@@ -5065,6 +5065,59 @@
],
"time": "2019-10-17T07:30:08+00:00"
},
{
"name": "twig/intl-extra",
"version": "v3.0.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/intl-extra.git",
"reference": "291d79ef98891da3efe14f0771fbe03a25fe6bec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/intl-extra/zipball/291d79ef98891da3efe14f0771fbe03a25fe6bec",
"reference": "291d79ef98891da3efe14f0771fbe03a25fe6bec",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"symfony/intl": "^4.3|^5.0",
"twig/twig": "^2.4|^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^4.4|^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"Twig\\Extra\\Intl\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
}
],
"description": "A Twig extension for Intl",
"homepage": "https://twig.symfony.com",
"keywords": [
"intl",
"twig"
],
"time": "2019-12-28T07:09:27+00:00"
},
{
"name": "twig/twig",
"version": "v3.0.0",
......@@ -5180,6 +5233,7 @@
"code",
"zf"
],
"abandoned": "laminas/laminas-code",
"time": "2019-10-05T23:18:22+00:00"
},
{
......@@ -5234,6 +5288,7 @@
"events",
"zf2"
],
"abandoned": "laminas/laminas-eventmanager",
"time": "2018-04-25T15:33:34+00:00"
}
],
......
......@@ -4,7 +4,7 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
app.config.order.cutoff: 10:00:00 # cutoff time to order
app.config.order.cutoff: 16:00:00 # cutoff time to order
app.config.order.limit: false # 1 order a day if true; else unlimited orders a day
app.config.password.charters: 12 # 1 number of charters required for password
......
......@@ -56,7 +56,8 @@ class OrderController extends AbstractController
$orderStatuses = $this->getDoctrine()->getRepository(OrderStatus::class)->findBy(['id' => [2, 3, 4, 5, 6, 7, 8]]);
foreach ($orderStatuses as $orderStatus) {
$orders = $this->getDoctrine()->getRepository(Order::class)->findFullBy(['user' => $this->getUser(), 'orderStatus' => $orderStatus, 'limit' => 4]);
$orders = $this->getDoctrine()->getRepository(Order::class)->findBy(['user' => $this->getUser(), 'orderStatus' => $orderStatus], null, 4);
// $orders = $this->getDoctrine()->getRepository(Order::class)->findFullBy(['user' => $this->getUser(), 'orderStatus' => $orderStatus, 'limit' => 4]);
foreach ($orders as $order) {
$orderStatus->addOrder($order);
}
......@@ -123,6 +124,8 @@ class OrderController extends AbstractController
// get data to create Order
$order->setUser($this->getUser());
$order->setDatetime(new DateTime);
$order->setPrice(ShoppingCartController::getCartPrice($shoppingCart));
// dd($order);
// $order->setOrderStatus($this->getDoctrine()->getRepository(OrderStatus::class)->findOneBy(['id' => 3])); // Waiting for payment
$order->setOrderStatus($this->getDoctrine()->getRepository(OrderStatus::class)->findOneBy(['id' => 4])); // In progress
......
......@@ -22,29 +22,21 @@ class ShoppingCartController extends AbstractController
public function index(ShoppingCartRepository $shoppingCartRepository, $isComponent = null)
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$shoppingCart = $shoppingCartRepository->findFullCartByUser(["userId" => $this->getUser()->getId()]);
// $shoppingCart = $shoppingCartRepository->findFullCartByUser(["userId" => $this->getUser()->getId()]);
$shoppingCart = $shoppingCartRepository->findOneBy(["user" => $this->getUser()->getId()]);
// Get full price for this cart
$isComponent ?
$total = null : $total = ShoppingCartController::getCartPrice($shoppingCart);
return $this->render('front/shopping_cart/index.html.twig', [
'cart' => $shoppingCart,
'isComponent' => $isComponent
'isComponent' => $isComponent,
'total' => $total
]);
}
// /**
// * @Route("cart/order", name="show", methods={"GET"}, requirements={"id":"\d+"})
// */
// public function show(ShoppingCartRepository $shoppingCartRepository, $isComponent = null): Response
// {
// $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
// $shoppingCart = $shoppingCartRepository->findFullCartByUser(["userId" => $this->getUser()->getId()]);
// return $this->render('front/shopping_cart/show.html.twig', [
// 'shoppingCart' => $shoppingCart,
// 'isComponent' => $isComponent
// ]);
// }
/**
*
* @Route("/shopping_cart/new", name="new", methods={"POST"} )
......@@ -63,8 +55,6 @@ class ShoppingCartController extends AbstractController
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
}
$user = $this->getUser();
// Find sandwich by Id
$sandwichId = array_keys($request->request->get('submit'))[0];
$sandwich = $this->getDoctrine()->getRepository(Sandwich::class)->findOneBy(['id' => $sandwichId]);
......@@ -116,4 +106,26 @@ class ShoppingCartController extends AbstractController
return $this->redirectToRoute('sandwich_index');
}
public function getCartPrice(ShoppingCart $shoppingCart)
{
$cartTotal = 0;
foreach ($shoppingCart->getOrderLine() as $orderline) {
$orderTotal = 0;
$orderTotal += $orderline->getSandwich()->getTypeBread()->getPrice();
foreach ($orderline->getSandwich()->getTypeSpreadId() as $spread) {
$orderTotal += $spread->getPrice();
}
$multiplier = $orderline->getSandwich()->getTypeSize()->getMultiplier();
$quantity = $orderline->getQuantity();
$orderTotal = $orderTotal * ($multiplier / 100) * $quantity;
$cartTotal += $orderTotal;
}
return $cartTotal;
}
}
\ No newline at end of file
......@@ -41,6 +41,11 @@ class Order
*/
private $orderLine;
/**
* @ORM\Column(type="integer")
*/
private $price;
public function __construct()
{
$this->orderLine = new ArrayCollection();
......@@ -126,4 +131,16 @@ class Order
{
return (string) $this->id;
}
public function getPrice(): ?int
{
return $this->price;
}
public function setPrice(int $price): self
{
$this->price = $price;
return $this;
}
}
\ No newline at end of file
......@@ -28,6 +28,11 @@ class TypeSize
*/
private $sandwiches;
/**
* @ORM\Column(type="integer")
*/
private $multiplier;
public function __construct()
{
$this->sandwiches = new ArrayCollection();
......@@ -89,4 +94,16 @@ class TypeSize
{
return $this->name;
}
public function getMultiplier(): ?int
{
return $this->multiplier;
}
public function setMultiplier(int $multiplier): self
{
$this->multiplier = $multiplier;
return $this;
}
}
\ No newline at end of file
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20200103112143 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE type_size ADD multiplier INT NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE type_size DROP multiplier');
}
}
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20200103140243 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE `order` ADD price INT NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE `order` DROP price');
}
}
......@@ -412,6 +412,9 @@
"twig/extra-bundle": {
"version": "v3.0.0"
},
"twig/intl-extra": {
"version": "v3.0.1"
},
"twig/twig": {
"version": "v3.0.0"
},
......
<tr>
{# {{ dump(orderLine) }} #}
<td>{{orderLine.quantity}}</td>
<td>
{{orderLine.sandwich.name}}
</td>
<td>{{orderLine.sandwich.description}}</td>
<td>
{% set price = 0 %}
{{ orderLine.sandwich.typeBread.name }}
{% set price = price + orderLine.sandwich.typeBread.price %}
{# {{ dump(sandwich.typeBread.price ) }} #}
</td>
<td>
{{ orderLine.sandwich.typeSize }}
{# {{ dump(sandwich.typeSize ) }} #}
</td>
<td>
{% for spread in orderLine.sandwich.typeSpreadId %}
{{ spread.name|lower }}
{% set price = price + spread.price %}
{# {{ dump(spread.price ) }} #}
{% endfor %}
</td>
<td>
{% set price = price * (orderLine.sandwich.typeSize.multiplier / 100) %}
{{(price / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}
</td>
<td>
{% set price = price * orderLine.quantity %}
{{(price / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}
</td>
</tr>
......@@ -11,10 +11,38 @@
{% endblock %}
{% block body %}
{{ dump(order) }}
{# {{ dump(order) }} #}
<h1>Order nr.
{{order.id}}</h1>
<ul>
<li>{{order.datetime | date("d/m/Y H:i")}}</li>
</ul>
<p>Orderdate:
{{order.datetime | date("d/m/Y H:i")}}
</p>
<div class="card">
<div class="table-responsive">
<table class="table table-light mb-0">
<thead class="thead-light">
<tr>
<th>Quantity</th>
<th>Name</th>
<th>Description</th>
<th>Bread</th>
<th>Size</th>
<th>Spread</th>
<th>Price/sandwich</th>
<th>Price</th>
</tr>
</thead>
<tbody class="tbody-light">
{% for orderLine in order.orderLine %}
{% include 'front/order/_orderLine.html.twig' with {'orderLine': orderLine } %}
{% endfor %}
</tbody>
<tfoot class="thead-light">
<th colspan="6"></th>
<th>Total</th>
<th>{{( order.price / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}</th>
</tfoot>
</table>
</div>
</div>
{% endblock %}
......@@ -16,6 +16,8 @@
</p>
<small>
Prijs totaal
{{( order.price / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}
{% if orderStatus.id == 3 %}
| betaalactie
{% endif %}
......
......@@ -6,77 +6,72 @@
{% block body %}
<h1>Sandwich index</h1>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Bread</th>
<th>Size</th>
<th>Spread</th>
<th>Price</th>
<th>actions</th>
</tr>
</thead>
<tbody>
{% for sandwich in sandwiches %}
{% set price = 0 %}
<tr>
{# {{ dump(sandwich) }} #}
{# {{ dump(sandwich.typeBread.price) }} #}
{# {{ dump(sandwich.typeSpreadId) }} #}
<td>
{{ sandwich.id }}
</td>
<td>
{{ sandwich.name }}
</td>
<td>
{{ sandwich.description }}
</td>
<td>
{{ sandwich.typeBread.name }}
{% set price = price + sandwich.typeBread.price %}
{# {{ dump(sandwich.typeBread.price ) }} #}
</td>
<td>
{{ sandwich.typeSize }}
{# {{ dump(sandwich.typeSize ) }} #}
</td>
<td>
{% for spread in sandwich.typeSpreadId %}
{{ spread.name|lower }}
<div class="card">
<div class="table-responsive">
<table class="table table-light mb-0">
<thead class="thead-light">
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Bread</th>
<th>Size</th>
<th>Spread</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for sandwich in sandwiches %}
{% set price = 0 %}
<tr>
<td>
{{ sandwich.id }}
</td>
<td>
{{ sandwich.name }}
</td>
<td>
{{ sandwich.description }}
</td>
<td>
{{ sandwich.typeBread.name }}
{% set price = price + sandwich.typeBread.price %}
{# {{ dump(sandwich.typeBread.price ) }} #}
</td>
<td>
{{ sandwich.typeSize }}
{# {{ dump(sandwich.typeSize ) }} #}
</td>
<td>
{% for spread in sandwich.typeSpreadId %}
{{ spread.name|lower }}
{% set price = price + spread.price %}
{# {{ dump(spread.price ) }} #}
{% endfor %}
</td>
<td>
{{price}}
x price of
{{sandwich.typeSize}}
</td>
<td>
<form name="form" action="{{ path('shopping_cart_new') }}" method="post">
<input id="sandwichId" class="btn btn-primary" type="submit" name="submit[{{sandwich.id}}]" value="add to cart">
</form>
<a href="{{ path('sandwich_show', {'id': sandwich.id}) }}">show</a>
<a href="{{ path('sandwich_edit', {'id': sandwich.id}) }}">edit</a>
</td>
</tr>
{% else %}
<tr>
<td colspan="4">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% set price = price + spread.price %}
{# {{ dump(spread.price ) }} #}
{% endfor %}
</td>
<td>
{% set price = price * (sandwich.typeSize.multiplier / 100) %}
{{(price / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}
</td>
<td>
<form name="form" action="{{ path('shopping_cart_new') }}" method="post">
<input id="sandwichId" class="btn btn-primary" type="submit" name="submit[{{sandwich.id}}]" value="add to cart">
</form>
<a href="{{ path('sandwich_show', {'id': sandwich.id}) }}">show</a>
<a href="{{ path('sandwich_edit', {'id': sandwich.id}) }}">edit</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<a href="{{ path('sandwich_new') }}">Create new</a>
{# Render the ordersByStatus #}
{# {{ render(controller('App\\Controller\\Front\\SandwichController::showShoppingCart' )) }} #}
{% if is_granted('IS_AUTHENTICATED_REMEMBERED') %}
{{ render(controller('App\\Controller\\Front\\ShoppingCartController::index', {isComponent: true } )) }}
<div class="mt-3">
{{ render(controller('App\\Controller\\Front\\ShoppingCartController::index', {isComponent: true } )) }}</div>
{% endif %}
{% endblock %}
......@@ -6,4 +6,6 @@
{% block body %}
{{ dump(sandwich) }}
Work in progress...
{% endblock %}
{# {{ dump(orderLine.quantity) }}
{{ dump(orderLine.sandwich.name) }}
{{ dump(orderLine.sandwich.aLaCarte) }}
{{ dump(orderLine.sandwich.description) }}
{{ dump(orderLine.sandwich.typeBread.name) }}
{{ dump(orderLine.sandwich.typeBread.price) }} #}
<div class="col mb-4">
<div class="card h-100">
{# {{ dump(orderLine.quantity) }} #}
{# {{ dump(orderLine.sandwich) }} #}
{# {{ dump(orderLine.sandwich.aLaCarte) }} #}
{# {{ dump(orderLine.sandwich.description) }} #}
{# {{ dump(orderLine.sandwich.typeBread.name) }} #}
{# {{ dump(orderLine.sandwich.typeBread.price) }} #}
<div class="col mb-4"> <div class="card h-100">
<div class="card-body">
<h5 class="card-title">{{orderLine.sandwich.name}}</h5>
<p class="card-text">{{orderLine.sandwich.description}}</p>
{% if orderLine.sandwich.description != "Custom sandwich" %}
<p class="card-text">{{orderLine.sandwich.description}}</p>
{% endif %}
<p class="card-text">
<small class="text-muted">
name:
{{orderLine.sandwich.typeBread.name}}
price:
{{orderLine.sandwich.typeBread.price}}
quantity:
{{orderLine.quantity}}
<br>
total:
{{orderLine.quantity * orderLine.sandwich.typeBread.price}}</small>
<ul>
{% set price = 0 %}
<li>Bread:
{{orderLine.sandwich.typeBread.name}}</li>
{% set price = price + orderLine.sandwich.typeBread.price %}
<li>Spread:
{% for spread in orderLine.sandwich.typeSpreadId %}
{{spread}}
{% set price = price + spread.price %}
{% endfor %}
</li>
<li>Size:
{{orderLine.sandwich.typeSize}}</li>
{% set price = price * (orderLine.sandwich.typeSize.multiplier / 100) %}
<li>Price:
{{ (price / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}/sandwich</li>
{# <li>Quantity: {{orderLine.quantity}} </li> #}
<li>Total:
{{((orderLine.quantity * price) / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}</li>
</ul>
</small>
</p>
{{ render(controller('App\\Controller\\Front\\OrderLineController::edit', {'id': orderLine.id } )) }}
</div>
......
{# {{ dump(cart) }}
{{ dump(cart.orderLine) }}
{% for orderLine in cart.orderLine %}
{{ dump(orderLine) }}
{% endfor %} #}
{% extends isComponent ? "minimum.html.twig" : 'base.html.twig' %}
{% block title %}Sandwich index
{% endblock %}
{% block body %}
{# {{ dump(cart) }}{{ dump(cart.orderLine) }}{% for orderLine in cart.orderLine %}{{ dump(orderLine) }}{% endfor %} #}
{% if cart is not empty %}
{% set title = 'Shopping cart' %}
{% if not isComponent %}
<h1>{{title}}</h1>
{% else %}
<h4>{{title}}</h4>
{% endif %}
<div class="row row-cols-1 row-cols-md-3 mt-2">
{% for orderLine in cart.orderLine %}
{% include 'front/shopping_cart/_order_line.html.twig' with {'orderLine': orderLine} %}
{% endfor %}
</div>
{% if isComponent %}
<a href="{{path('shopping_cart_index')}}" class="btn btn-primary">Order</a>
{% else %}
{# showAllDetails #}
<div class="row row-cols-1 row-cols-md mt-2">
<div class="col mb-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">Total price
{{ (total / 100) | format_currency('EUR', {rounding_mode: 'floor'})}}</h5>
</div>
</div>
</div>
</div>
{# orderThisOrder #}
<form name="form" action="{{ path('order_new_from_shopping_cart') }}" method="post">
<input id="shoppingCartId" class="btn btn-primary" type="submit" name="submit[{{cart.id}}]" value="Order Cart">
......
# Extra assignment Symfony - Sandwiches
![Find sandwich by criteria](<.bin/img/find_custom_sandwich.PNG>)
![Find sandwich by criteria](.bin/img/find_custom_sandwich.PNG)
## Walkthrough
......@@ -40,8 +40,8 @@ php bin\console doctrine:migrations:migrate
Check database with MySQL Workbench Reverse Engineer
- [model.pdf](<.bin/db/model.pdf>)
- [model.mwb](<.bin/db/model.mwb>)
- [model.pdf](.bin/db/model.pdf)
- [model.mwb](.bin/db/model.mwb)
![make crud](<.bin/img/make crud.png>)
......@@ -75,16 +75,16 @@ lando php bin/console about
- Extra_broodjes
| [ ] User | [x] Sandwich | [x] TypeBread | [x] TypeSpread | [x] TypeSize |
| ------------ | ------------------------- | ------------------ | ---------------- | ---------------- |
| <u>id</u> | <u>id</ul> | <u>id</u> | <u>id</u> | <u>id</u> |
| email | <u>typeBread</u> (M2O) | name | name | name |
| password | <u>typeSpreadId</u> (M2M) | price (integer) | price | sandwiches (O2M) |
| roles (json) | <u>typeSize</u> (M2O) | calories (integer) | calories | |
| orders (O2M) | name | allergyId (M2M) | allergyId (M2M) | |