diff --git a/composer.json b/composer.json index 1f00660a..75c2d78d 100644 --- a/composer.json +++ b/composer.json @@ -5,10 +5,12 @@ "php": "^7.1.3", "ext-ctype": "*", "ext-iconv": "*", - "ext-mbstring": "*", "ext-intl": "*", + "ext-mbstring": "*", "doctrine/annotations": "^1.6", "friendsofsymfony/ckeditor-bundle": "^2.0", + "gerardojbaez/money": "^0.3.1", + "ocramius/proxy-manager": "2.1.*", "omines/datatables-bundle": "^0.2.2", "php-translation/symfony-bundle": "^0.8.1", "s9e/text-formatter": "^2.0", @@ -35,8 +37,7 @@ "symfony/webpack-encore-bundle": "^1.1", "symfony/yaml": "4.3.*", "twig/extensions": "^1.5", - "webmozart/assert": "^1.4", - "ocramius/proxy-manager": "2.1.*" + "webmozart/assert": "^1.4" }, "require-dev": { "roave/security-advisories": "dev-master", diff --git a/composer.lock b/composer.lock index 823e3252..7f9348d5 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "1a794cf54f952c4bf1bc00d8f952b6a3", + "content-hash": "c4b42f65037fd3b81886b8d9c98deb32", "packages": [ { "name": "doctrine/annotations", @@ -1397,6 +1397,54 @@ ], "time": "2019-04-15T16:29:43+00:00" }, + { + "name": "gerardojbaez/money", + "version": "v0.3.1", + "source": { + "type": "git", + "url": "https://github.com/gerardojbaez/money.git", + "reference": "1a29ca19899fad8ae559e9f2c982815ea21f8a6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/gerardojbaez/money/zipball/1a29ca19899fad8ae559e9f2c982815ea21f8a6c", + "reference": "1a29ca19899fad8ae559e9f2c982815ea21f8a6c", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "phpunit/phpunit": "5.4.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gerardojbaez\\Money\\": "src/" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gerardo Báez", + "email": "gerardojbaez@gmail.com" + } + ], + "description": "A simple and cross-platform alternative to PHP money_format(). 91 currencies supported, including INR.", + "keywords": [ + "currency", + "formatter", + "money", + "money_format" + ], + "time": "2018-02-24T18:59:00+00:00" + }, { "name": "jdorn/sql-formatter", "version": "v1.2.17", @@ -7486,8 +7534,8 @@ "php": "^7.1.3", "ext-ctype": "*", "ext-iconv": "*", - "ext-mbstring": "*", - "ext-intl": "*" + "ext-intl": "*", + "ext-mbstring": "*" }, "platform-dev": [] } diff --git a/config/services.yaml b/config/services.yaml index 9ab44ebd..37c19bca 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -9,6 +9,7 @@ parameters: partdb_title: 'Part-DB' # The title shown inside of Part-DB (e.g. in the navbar and on homepage) banner: '' # The info text shown in the homepage use_gravatar: true # Set to false, if no Gravatar images should be used for user profiles. + default_currency: 'EUR' # The currency that should be used services: # default configuration for services in *this* file diff --git a/src/Entity/Orderdetail.php b/src/Entity/Orderdetail.php index e9622549..06e2553d 100644 --- a/src/Entity/Orderdetail.php +++ b/src/Entity/Orderdetail.php @@ -33,6 +33,8 @@ declare(strict_types=1); namespace App\Entity; use Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\PersistentCollection; +use Exception; /** * Class Orderdetail. @@ -79,6 +81,12 @@ class Orderdetail extends DBElement */ protected $supplier_product_url; + /** + * @var \DateTime The date when this element was created. + * @ORM\Column(type="datetimetz", name="datetime_added") + */ + protected $addedDate; + /** * Returns the ID as an string, defined by the element class. * This should have a form like P000014, for a part with ID 14. @@ -142,6 +150,17 @@ class Orderdetail extends DBElement return (bool) $this->obsolete; } + /** + * Returns the date/time when the element was created. + * Returns null if the element was not yet saved to DB yet. + * + * @return \DateTime|null The creation time of the part. + */ + public function getAddedDate(): ?\DateTime + { + return $this->addedDate; + } + /** * Get the link to the website of the article on the suppliers website. * @@ -152,8 +171,8 @@ class Orderdetail extends DBElement */ public function getSupplierProductUrl(bool $no_automatic_url = false): string { - if ($no_automatic_url || '' !== $this->supplierpartnr) { - return $this->supplierpartnr; + if ($no_automatic_url || '' !== $this->supplier_product_url) { + return $this->supplier_product_url; } return $this->getSupplier()->getAutoProductUrl($this->supplierpartnr); // maybe an automatic url is available... @@ -162,12 +181,12 @@ class Orderdetail extends DBElement /** * Get all pricedetails. * - * @return Pricedetails[] all pricedetails as a one-dimensional array of Pricedetails objects, + * @return Pricedetail[] all pricedetails as a one-dimensional array of Pricedetails objects, * sorted by minimum discount quantity * * @throws Exception if there was an error */ - public function getPricedetails(): array + public function getPricedetails(): PersistentCollection { return $this->pricedetails; } diff --git a/src/Entity/Part.php b/src/Entity/Part.php index c3e57e02..42b74a8c 100644 --- a/src/Entity/Part.php +++ b/src/Entity/Part.php @@ -92,7 +92,7 @@ class Part extends AttachmentContainingDBElement protected $master_picture_attachment; /** - * @var + * @var Orderdetail[] * @ORM\OneToMany(targetEntity="Orderdetail", mappedBy="part") * * @ColumnSecurity(prefix="orderdetails", type="object") @@ -499,7 +499,7 @@ class Part extends AttachmentContainingDBElement * * @param bool $hide_obsolete If true, obsolete orderdetails will NOT be returned * - * @return Orderdetails[] * all orderdetails as a one-dimensional array of Orderdetails objects + * @return Orderdetail[] * all orderdetails as a one-dimensional array of Orderdetails objects * (empty array if there are no ones) * * the array is sorted by the suppliers names / minimum order quantity * diff --git a/src/Entity/Pricedetail.php b/src/Entity/Pricedetail.php index 76be8f43..6a8be3a9 100644 --- a/src/Entity/Pricedetail.php +++ b/src/Entity/Pricedetail.php @@ -95,31 +95,27 @@ class Pricedetail extends DBElement return $this->orderdetail; } + public function getPrice() : float + { + return (float) $this->price; + } + /** - * Get the price. + * Get the price for a single unit. * - * @param bool $as_money_string * if true, this method returns a money string incl. currency - * * if false, this method returns the price as float * @param int $multiplier The returned price (float or string) will be multiplied * with this multiplier. * * You will get the price for $multiplier parts. If you want the price which is stored * in the database, you have to pass the "price_related_quantity" count as $multiplier. * - * @return float the price as a float number (if "$as_money_string == false") - * @return string the price as a string incl. currency (if "$as_money_string == true") - * - * @see floatToMoneyString() + * @return float the price as a float number + */ - public function getPrice(bool $as_money_string = false, int $multiplier = 1) + public function getPricePerUnit(int $multiplier = 1) : float { $price = ($this->price * $multiplier) / $this->price_related_quantity; - if ($as_money_string) { - throw new \Exception('Not implemented yet...'); - //return floatToMoneyString($price); - } - return $price; } diff --git a/src/Services/MoneyFormatter.php b/src/Services/MoneyFormatter.php new file mode 100644 index 00000000..7cb984cc --- /dev/null +++ b/src/Services/MoneyFormatter.php @@ -0,0 +1,59 @@ +params = $params; + } + + public function format($amount, string $currency = "") : string + { + if ($currency === "") { + $currency = $this->params->get("default_currency"); + } + + $money = new Money($amount, $currency); + + return $money->format(); + } + +} \ No newline at end of file diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index d385e7bb..469e966d 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -32,6 +32,7 @@ namespace App\Twig; use App\Entity\Attachment; use App\Entity\DBElement; use App\Services\EntityURLGenerator; +use App\Services\MoneyFormatter; use App\Services\TreeBuilder; use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Serializer\SerializerInterface; @@ -47,22 +48,26 @@ class AppExtension extends AbstractExtension protected $cache; protected $serializer; protected $treeBuilder; + protected $moneyFormatter; public function __construct(EntityURLGenerator $entityURLGenerator, AdapterInterface $cache, - SerializerInterface $serializer, TreeBuilder $treeBuilder) + SerializerInterface $serializer, TreeBuilder $treeBuilder, + MoneyFormatter $moneyFormatter) { $this->entityURLGenerator = $entityURLGenerator; $this->cache = $cache; $this->serializer = $serializer; $this->treeBuilder = $treeBuilder; + $this->moneyFormatter = $moneyFormatter; } public function getFilters() { return [ - new TwigFilter('entityURL', [$this, 'generateEntityURL']), - new TwigFilter('bbCode', [$this, 'parseBBCode'], ['pre_escape' => 'html', 'is_safe' => ['html']]), - ]; + new TwigFilter('entityURL', [$this, 'generateEntityURL']), + new TwigFilter('bbCode', [$this, 'parseBBCode'], ['pre_escape' => 'html', 'is_safe' => ['html']]), + new TwigFilter('moneyFormat', [$this, 'formatCurrency']) + ]; } public function getTests() @@ -107,4 +112,9 @@ class AppExtension extends AbstractExtension return $item->get(); } + + public function formatCurrency($amount, $currency = "") + { + return $this->moneyFormatter->format($amount, $currency); + } } diff --git a/symfony.lock b/symfony.lock index 44dd8384..f9bc906d 100644 --- a/symfony.lock +++ b/symfony.lock @@ -108,6 +108,9 @@ "./config/packages/fos_ckeditor.yaml" ] }, + "gerardojbaez/money": { + "version": "v0.3.1" + }, "jdorn/sql-formatter": { "version": "v1.2.17" }, diff --git a/templates/Parts/_order_infos.html.twig b/templates/Parts/_order_infos.html.twig new file mode 100644 index 00000000..4d2270ee --- /dev/null +++ b/templates/Parts/_order_infos.html.twig @@ -0,0 +1,67 @@ +
+ + + + + + + + + + + {% for order in part.orderdetails %} + + + + + + + {% endfor %} + +
{% trans %}part.supplier.name{% endtrans %}{% trans %}part.supplier.partnr{% endtrans %}
{{ order.supplier.name }}{% if order.supplierProductUrl is not empty %} + {{ order.supplierPartNr }} + {% else %} + {{ order.supplierPartNr }} + {% endif %} + + {% if order.pricedetails is not empty %} + + + + + + + + + + {% for detail in order.pricedetails %} + + + + + + {% endfor %} + +
{% trans %}part.order.minamount{% endtrans %}{% trans %}part.order.price{% endtrans %}{% trans %}part.order.single_price{% endtrans %}
+ {{ detail.MinDiscountQuantity }} + + {{ detail.Price | moneyFormat }} {% trans %}part.order.price_per{% endtrans %} {{ detail.PriceRelatedQuantity }} + + {{ detail.PricePerUnit | moneyFormat}} +
+ {% endif %} +
{# Action for order information #} +
+ + +
+
+
\ No newline at end of file diff --git a/templates/Parts/show_part_info.html.twig b/templates/Parts/show_part_info.html.twig index 7a2d0513..d99fae48 100644 --- a/templates/Parts/show_part_info.html.twig +++ b/templates/Parts/show_part_info.html.twig @@ -112,9 +112,11 @@
Test
-
+
+ {% include "Parts/_order_infos.html.twig" %}
+
TODO
@@ -128,22 +130,22 @@ {% if is_granted('create', part) %} -
-
- - - {% trans %}part.clone.btn{% endtrans %} - - - {% endif %}