This commit is contained in:
Dennis Eichhorn 2024-02-28 05:09:12 +00:00
parent 544758631d
commit da8369376e
48 changed files with 873 additions and 2114 deletions

View File

@ -1,35 +0,0 @@
---
name: Dev Bug Report
about: Create a report to help us improve
title: ''
labels: stat_backlog, type_bug
assignees: ''
---
# Bug Description
A clear and concise description of what the bug is.
# How to Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Minimal Code Example
```
// your code ...
```
# Expected Behavior
A clear and concise description of what you expected to happen.
# Screenshots
If applicable, add screenshots to help explain your problem.
# Additional Information
Add any other context about the problem here.

View File

@ -1,18 +0,0 @@
---
name: Dev Feature Request
about: Suggest an idea for this project
title: ''
labels: stat_backlog, type_feature
assignees: ''
---
# What is the feature you request
* A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
* A clear and concise description of what you want to happen.
# Alternatives
A clear and concise description of any alternative solutions or features you've considered.
# Additional Information
Add any other context or screenshots about the feature request here.

View File

@ -55,42 +55,42 @@
"type": "DATETIME",
"null": false
},
"purchase_order_suggestion_suggestion": {
"name": "purchase_order_suggestion_suggestion",
"purchase_order_suggestion_element_suggestion": {
"name": "purchase_order_suggestion_element_suggestion",
"type": "INT(11)",
"null": false,
"foreignTable": "purchase_order_suggestion",
"foreignKey": "purchase_order_suggestion_id"
},
"purchase_order_suggestion_item": {
"name": "purchase_order_suggestion_item",
"purchase_order_suggestion_element_item": {
"name": "purchase_order_suggestion_element_item",
"type": "INT(11)",
"null": false,
"foreignTable": "itemmgmt_item",
"foreignKey": "itemmgmt_item_id"
},
"purchase_order_suggestion_bill": {
"name": "purchase_order_suggestion_bill",
"purchase_order_suggestion_element_bill": {
"name": "purchase_order_suggestion_element_bill",
"type": "INT(11)",
"null": true,
"default": null,
"foreignTable": "billing_bill",
"foreignKey": "billing_bill_id"
},
"purchase_order_suggestion_supplier": {
"name": "purchase_order_suggestion_supplier",
"purchase_order_suggestion_element_supplier": {
"name": "purchase_order_suggestion_element_supplier",
"type": "INT(11)",
"null": false,
"foreignTable": "suppliermgmt_supplier",
"foreignKey": "suppliermgmt_supplier_id"
},
"purchase_order_suggestion_quantity": {
"name": "purchase_order_suggestion_quantity",
"purchase_order_suggestion_element_quantity": {
"name": "purchase_order_suggestion_element_quantity",
"type": "BIGINT",
"null": false
},
"purchase_order_suggestion_costs": {
"name": "purchase_order_suggestion_costs",
"purchase_order_suggestion_element_costs": {
"name": "purchase_order_suggestion_element_costs",
"type": "BIGINT",
"null": false
}

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
use phpOMS\Router\RouteVerb;
return [
'^/purchase/order/suggestion/create(\?.*$|$)' => [
'^/purchase/order/suggestion/create( .*$|$)' => [
[
'dest' => '\Modules\Purchase\Controller\CliController:cliGenerateOrderSuggestion',
'verb' => RouteVerb::ANY,

61
Admin/Routes/Web/Api.php Normal file
View File

@ -0,0 +1,61 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use Modules\Purchase\Controller\ApiController;
use Modules\Purchase\Models\PermissionCategory;
use phpOMS\Account\PermissionType;
use phpOMS\Router\RouteVerb;
return [
'^.*/purchase/order/suggestion(\?.*|$)' => [
[
'dest' => '\Modules\Purchase\Controller\ApiController:apiOrderSuggestionCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::CREATE,
'state' => PermissionCategory::ORDER,
],
],
[
'dest' => '\Modules\Purchase\Controller\ApiController:apiOrderSuggestionUpdate',
'verb' => RouteVerb::SET,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::MODIFY,
'state' => PermissionCategory::ORDER,
],
],
[
'dest' => '\Modules\Purchase\Controller\ApiController:apiOrderSuggestionDelete',
'verb' => RouteVerb::DELETE,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::MODIFY,
'state' => PermissionCategory::ORDER,
],
],
],
'^.*/purchase/order/suggestion/bill(\?.*|$)' => [
[
'dest' => '\Modules\Purchase\Controller\ApiController:apiOrderSuggestionBillCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::CREATE,
'state' => PermissionCategory::ORDER,
],
],
]
];

View File

@ -4,7 +4,7 @@
*
* PHP Version 8.1
*
* @package Modules\HumanResourceManagement
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
@ -12,20 +12,28 @@
*/
declare(strict_types=1);
namespace Modules\HumanResourceManagement\Controller;
namespace Modules\Purchase\Controller;
use Modules\Billing\Models\Price\PriceType;
use Modules\Billing\Models\SalesBillMapper;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionElement;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionElementMapper;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionMapper;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionStatus;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\NotificationLevel;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Stdlib\Base\FloatInt;
use phpOMS\Stdlib\Base\SmartDateTime;
use phpOMS\System\OperatingSystem;
use phpOMS\System\SystemType;
use phpOMS\System\SystemUtils;
/**
* HumanResourceManagement controller class.
* Purchase controller class.
*
* @package Modules\HumanResourceManagement
* @package Modules\Purchase
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
@ -45,7 +53,7 @@ final class ApiController extends Controller
*
* @since 1.0.0
*/
public function apiOrderSuggestionSimulate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
public function apiOrderSuggestionCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
// Offload bill parsing to cli
$cliPath = \realpath(__DIR__ . '/../../../cli.php');
@ -60,17 +68,251 @@ final class ApiController extends Controller
try {
SystemUtils::runProc(
OperatingSystem::getSystem() === SystemType::WIN ? 'php.exe' : 'php',
\escapeshellarg($cliPath)
\escapeshellarg($cliPath)
. ' /purchase/order/suggestion/create'
. ($supplier === null ? '' : ' -supplier ' . \escapeshellarg($supplier))
. ($productGroup === null ? '' : ' -pgroup ' . \escapeshellarg((string) $productGroup))
. ($showIrrelevant === null ? '' : ' -irrelevant ' . \escapeshellarg((string) $showIrrelevant))
. ' -user ' . ((int) $request->header->account),
$request->getDataBool('async') ?? true
true
);
} catch (\Throwable $t) {
$response->header->status = RequestStatusCode::R_400;
$this->app->logger->error($t->getMessage());
}
$this->createStandardBackgroundResponse($request, $response, []);
}
public function getOrderSuggestionElementData(array $elements) : array
{
if (empty($elements)) {
return [];
}
$data = [];
$itemIds = \array_map(function(OrderSuggestionElement $element) {
return $element->item->id;
}, $elements);
$start = SmartDateTime::startOfMonth();
$start->smartModify(0, -12);
$end = SmartDateTime::endOfMonth();
$end->smartModify(0, -1);
$salesHistory = SalesBillMapper::getItemMonthlySalesQuantity($itemIds, $start, $end);
$distributions = \Modules\WarehouseManagement\Models\StockMapper::getStockDistribution($itemIds);
$historyStart = (int) $start->format('m');
$historyEnd = (int) $end->format('m');
// @todo A lot of the code below is mirrored in the CliController for ALL items.
// Pull out some of the code so we only need to maintain one version
foreach ($elements as $element) {
$maxHistoryDuration = $element->item->getAttribute('order_suggestion_history_duration')->value->getValue() ?? 12;
$salesForecast = [];
// If item is new, the history start is shifted
$tempHistoryStart = ((int) $element->item->createdAt->format('Y')) >= ((int) $start->format('Y'))
&& ((int) $element->item->createdAt->format('m')) >= ((int) $start->format('m'))
? (int) $element->item->createdAt->format('m') // @todo Bad if created at end of month (+1 also not possible because of year change)
: $historyStart;
$actualHistoricDuration = \min(
$maxHistoryDuration,
SmartDateTime::calculateMonthIndex($historyEnd, $tempHistoryStart)
);
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// get historic sales
// use order_suggestion_history_duration
// Or 12 month
// If less than 12 month use what we have
///////////////////////////////////////////////////////////////////////////////////////////////////////////
foreach ($salesHistory as $month) {
$currentMonthIndex = SmartDateTime::calculateMonthIndex($month['month'], $tempHistoryStart);
// @bug Doesn't work if maxHistoryDuration > 12 months
if ($month['item'] !== $element->item->id
|| 12 - SmartDateTime::calculateMonthIndex($month['month'], $tempHistoryStart) >= $maxHistoryDuration
) {
continue;
}
$salesForecast[$currentMonthIndex] = $month['quantity'];
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Range based calculation
// calculate current range using historic sales
// above calculation provides array as forecast which allows to easily impl. seasonal data
// get minimum range
// Either directly from attribute minimum_stock_range
// Or from minimum_stock_quantity
// calculate quantity needed incl. lead_time and admin_time for minimum range
// make sure that the quantity is rounded to the next closest quantity step
// make sure that at least the minimum order quantity is fulfilled
// make sure that the maximum order quantity is not exceeded
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Calculate current range using historic sales + other current stats
$totalHistoricSales = \array_sum($salesForecast);
$avgMonthlySales = (int) \round($totalHistoricSales / $actualHistoricDuration);
$totalStockQuantity = 0;
foreach ($distributions['dists'][$element->item->id] ?? [] as $dist) {
$totalStockQuantity += $dist->quantity;
}
$totalReservedQuantity = $distributions['reserved'][$element->item->id] ?? 0;
$totalOrderedQuantity = $distributions['ordered'][$element->item->id] ?? 0;
$currentRangeStock = $avgMonthlySales == 0 ? \PHP_INT_MAX : ($totalStockQuantity + $totalOrderedQuantity) / $avgMonthlySales;
$currentRangeReserved = $avgMonthlySales == 0 ? \PHP_INT_MAX : ($totalStockQuantity + $totalOrderedQuantity - $totalReservedQuantity) / $avgMonthlySales;
// @todo Sometimes the reserved range is misleading since the company may not be able to deliver that fast anyway
// -> the reserved quantity is always a constant (even if we have stock, we wouldn't ship)
// -> see SD HTS (depending on other shipments -> not delivered even if available)
// -> maybe it's possible to consider the expected delivery time?
$minimumStockQuantity = $element->item->getAttribute('minimum_stock_quantity')->value->getValue() ?? 0;
$minimumStockQuantity = (int) \round($minimumStockQuantity * 1000);
$minimumStockRange = $avgMonthlySales === 0 ? 0 : $minimumStockQuantity / $avgMonthlySales;
$minimumStockQuantity = (int) \round($minimumStockRange * $avgMonthlySales);
$minimumOrderQuantity = $element->item->getAttribute('minimum_order_quantity')->value->getValue() ?? 0;
$minimumOrderQuantity = (int) \round($minimumOrderQuantity * FloatInt::DIVISOR);
$orderQuantityStep = $element->item->getAttribute('order_quantity_steps')->value->getValue() ?? 1;
$orderQuantityStep = (int) \round($orderQuantityStep * FloatInt::DIVISOR);
$orderQuantity = $element->quantity->value;
$orderRange = $avgMonthlySales === 0 ? \PHP_INT_MAX : $element->quantity->value / $avgMonthlySales;
$internalRequest = new HttpRequest();
$internalRequest->setData('price_quantity', $orderQuantity);
$internalRequest->setData('price_type', PriceType::PURCHASE);
$price = $this->app->moduleManager->get('Billing', 'ApiPrice')->findBestPrice($internalRequest, $element->item);
// @question Consider to add gross price
$data[$element->item->id] = [
'singlePrice' => $price['bestActualPrice'],
'totalPrice' => new FloatInt((int) ($price['bestActualPrice']->value * $orderQuantity / FloatInt::DIVISOR)),
'stock' => new FloatInt($totalStockQuantity),
'reserved' => new FloatInt($totalReservedQuantity),
'ordered' => new FloatInt($totalOrderedQuantity),
'minquantity' => new FloatInt($minimumOrderQuantity),
'minstock' => new FloatInt($minimumStockQuantity),
'quantitystep' => new FloatInt($orderQuantityStep),
'avgsales' => new FloatInt($avgMonthlySales),
'range_stock' => $currentRangeStock, // range only considering stock + ordered
'range_reserved' => $currentRangeReserved, // range considering stock - reserved + ordered
'range_ordered' => $orderRange, // range ADDED with suggested new order quantity
];
}
return $data;
}
/**
* Api method to delete a suggestion from an existing account
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiOrderSuggestionDelete(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
$old = OrderSuggestionMapper::get()
->where('id', (int) $request->getData('id'))
->execute();
$new = clone $old;
$new->status = OrderSuggestionStatus::DELETED;
$this->updateModel($request->header->account, $old, $new, OrderSuggestionMapper::class, 'order_suggestion', $request->getOrigin());
$this->createStandardDeleteResponse($request, $response, $new);
}
/**
* Api method to update a suggestion from an existing account
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiOrderSuggestionUpdate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
$old = OrderSuggestionMapper::get()
->with('elements')
->where('id', (int) $request->getData('id'))
->execute();
// Only drafts can get updated
if ($old->status !== OrderSuggestionStatus::DRAFT) {
$response->header->status = RequestStatusCode::R_423;
$this->createInvalidUpdateResponse($request, $response, []);
return;
}
$elements = $request->getDataJson('element');
$quantities = $request->getDataJson('quantity');
// Missmatch -> data corrupted
if (\count($elements) !== \count($quantities)) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidUpdateResponse($request, $response, []);
return;
}
foreach ($elements as $idx => $e) {
$e = (int) $e;
$temp = new FloatInt($quantities[$idx]);
foreach ($old->elements as $element) {
if ($element->id !== $e) {
continue;
}
if ($element->quantity->value === $temp->value) {
break;
}
$new = clone $element;
$new->quantity = $temp;
$internalRequest = new HttpRequest();
$internalRequest->setData('price_quantity', $new->quantity->value);
$internalRequest->setData('price_type', PriceType::PURCHASE);
$price = $this->app->moduleManager->get('Billing', 'ApiPrice')->findBestPrice($internalRequest, $element->item);
$new->costs = new FloatInt((int) ($price['bestActualPrice']->value * $new->quantity->value / FloatInt::DIVISOR));
$this->updateModel($request->header->account, $element, $new, OrderSuggestionElementMapper::class, 'order_suggestion_element', $request->getOrigin());
}
}
$this->createStandardUpdateResponse($request, $response, $old);
}
}

View File

@ -14,7 +14,7 @@ declare(strict_types=1);
namespace Modules\Purchase\Controller;
use Modules\Purchase\Models\OrderSuggestionMapper;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionMapper;
use phpOMS\Contract\RenderableInterface;
use phpOMS\DataStorage\Database\Query\OrderType;
use phpOMS\Message\RequestAbstract;
@ -152,23 +152,36 @@ final class BackendController extends Controller
public function viewPurchaseOrderSuggestion(RequestAbstract $request, ResponseAbstract $response, array $data = []) : RenderableInterface
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/Purchase/Theme/Backend/article-order-suggestion');
$view->setTemplate('/Modules/Purchase/Theme/Backend/order-suggestion');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1002105001, $request, $response);
$view->data['suggestions'] = OrderSuggestionMapper::get()
$view->data['suggestion'] = OrderSuggestionMapper::get()
->with('createdBy')
->with('elements')
->with('elements/supplier')
->with('elements/supplier/account')
->with('elements/item')
->with('elements/bill')
->with('elements/item/container')
->with('elements/item/l11n')
->with('elements/item/l11n/type')
->with('elements/item/attributes')
->with('elements/item/attributes/type')
->with('elements/bill')
->where('id', (int) $request->getData('id'))
->where('elements/item/l11n/language', $response->header->l11n->language)
->where('elements/item/l11n/type/title', ['name1', 'name2'], 'IN')
->where('elements/item/attributes/type/name', [
'minimum_stock_quantity',
'minimum_order_quantity',
'order_quantity_steps',
'order_suggestion_history_duration',
'segment', 'section', 'sales_group', 'product_group', 'product_type',], 'IN')
->sort('elements/supplier', OrderType::ASC)
->execute();
$view->data['suggestion_data'] = $this->app->moduleManager->get('Purchase', 'Api')
->getOrderSuggestionElementData($view->data['suggestion']->elements);
return $view;
}
@ -211,8 +224,11 @@ final class BackendController extends Controller
$view->setTemplate('/Modules/Purchase/Theme/Backend/order-suggestion-list');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1002105001, $request, $response);
$view->data['suggestions'] = $this->app->moduleManager->get('Purchase', 'Cli')
->calculateSuggestions($response->header->l11n->language);
$view->data['suggestions'] = OrderSuggestionMapper::getAll()
->with('createdBy')
->with('elements')
->sort('createdAt', OrderType::DESC)
->execute();
return $view;
}

View File

@ -23,6 +23,9 @@ use Modules\ItemManagement\Models\ItemStatus;
use Modules\ItemManagement\Models\StockIdentifierType;
use Modules\Organization\Models\Attribute\UnitAttributeMapper;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestion;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionElement;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionElementStatus;
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionMapper;
use Modules\SupplierManagement\Models\SupplierMapper;
use phpOMS\Contract\RenderableInterface;
use phpOMS\Math\Functions\Functions;
@ -76,11 +79,12 @@ final class CliController extends Controller
}
$orderSuggestion = $this->createSuggestionFromRequest($request);
$this->createModel($request->header->account, $orderSuggestion, OrderSuggestionMapper::class, 'order_suggestion', $request->getOrigin());
return $view;
}
public function createSuggestionFromRequest(RequestAbstract $request) : array
public function createSuggestionFromRequest(RequestAbstract $request) : OrderSuggestion
{
$showIrrelevant = $request->getDataBool('-irrelevant') ?? false;
$now = new \DateTime('now');
@ -115,6 +119,9 @@ final class CliController extends Controller
], 'IN')
->execute();
// @todo check for supplier of item if set
// @todo check for product type of item if set
// @todo Implement item dependencies (i.e. for production)
// @todo Consider production requests
// Exclude items only created through production (finished + semi-finished)
@ -148,7 +155,6 @@ final class CliController extends Controller
$historyStart = (int) $start->format('m');
$historyEnd = (int) $end->format('m');
$suggestions = [];
foreach ($items as $item) {
$maxHistoryDuration = $item->getAttribute('order_suggestion_history_duration')->value->getValue() ?? 12;
@ -222,24 +228,24 @@ final class CliController extends Controller
$wantedStockRange = $item->getAttribute('minimum_stock_range')->value->getValue() ?? 1;
$minimumStockQuantity = $item->getAttribute('minimum_stock_quantity')->value->getValue() ?? 0;
$minimumStockQuantity = (int) \round($minimumStockQuantity * 1000);
$minimumStockQuantity = (int) \round($minimumStockQuantity * FloatInt::DIVISOR);
$minimumStockRange = $avgMonthlySales === 0 ? 0 : $minimumStockQuantity / $avgMonthlySales;
$minimumStockQuantity = (int) \round($minimumStockRange * $avgMonthlySales);
$minimumOrderQuantity = $item->getAttribute('minimum_order_quantity')->value->getValue() ?? 0;
$minimumOrderQuantity = (int) \round($minimumOrderQuantity * 10000);
$minimumOrderQuantity = (int) \round($minimumOrderQuantity * FloatInt::DIVISOR);
$orderQuantityStep = $item->getAttribute('order_quantity_steps')->value->getValue() ?? 1;
$orderQuantityStep = (int) \round($orderQuantityStep * 10000);
$orderQuantityStep = (int) \round($orderQuantityStep * FloatInt::DIVISOR);
$leadTime = $item->getAttribute('lead_time')->value->getValue() ?? 3; // in days
// @todo Business hours don't have to be 8 hours
// we assume 10 seconds per item if nothing is defined for (invoice handling, stock handling)
$adminTime = ($item->getAttribute('admin_time')->value->getValue() ?? 10) / (8 * 60 * 60); // from minutes -> days
$adminTime = ($item->getAttribute('admin_time')->value->getValue() ?? 10) / (8 * 60 * 60); // from seconds -> days
// Overhead time in days by estimating at least 1 week worth of order quantity
$estimatedOverheadTime = $leadTime + $adminTime * \max($minimumOrderQuantity, $avgMonthlySales / 4) / 10000;
$estimatedOverheadTime = $leadTime + $adminTime * \max($minimumOrderQuantity, $avgMonthlySales / 4) / FloatInt::DIVISOR;
$orderQuantity = 0;
$orderRange = 0;
@ -262,7 +268,7 @@ final class CliController extends Controller
$orderQuantity = $orderQuantity - $mod + ($orderQuantityStep - $mod < $mod ? $orderQuantityStep : 0) + $minimumOrderQuantity;
}
$estimatedOverheadTime = $leadTime + $adminTime * $orderQuantity / 10000;
$estimatedOverheadTime = $leadTime + $adminTime * $orderQuantity / FloatInt::DIVISOR;
}
}
@ -290,26 +296,17 @@ final class CliController extends Controller
->where('id', (int) $price['supplier'])
->execute();
// @question Consider to add gross price
$suggestions[$item->id] = [
'item' => $item,
'supplier' => $supplier,
'quantity' => new FloatInt($orderQuantity),
'singlePrice' => $price['bestActualPrice'],
'totalPrice' => new FloatInt((int) ($price['bestActualPrice']->value * $orderQuantity / 10000)),
'stock' => new FloatInt($totalStockQuantity),
'reserved' => new FloatInt($totalReservedQuantity),
'ordered' => new FloatInt($totalOrderedQuantity),
'minquantity' => new FloatInt($minimumOrderQuantity),
'minstock' => new FloatInt($minimumStockQuantity),
'quantitystep' => new FloatInt($orderQuantityStep),
'avgsales' => new FloatInt($avgMonthlySales),
'range_stock' => $currentRangeStock, // range only considering stock + ordered
'range_reserved' => $currentRangeReserved, // range considering stock - reserved + ordered
'range_ordered' => $orderRange, // range ADDED with suggested new order quantity
];
$element = new OrderSuggestionElement();
$element->status = OrderSuggestionElementStatus::CALCULATED;
$element->modifiedBy = $suggestion->createdBy;
$element->quantity->value = $orderQuantity;
$element->item = $item;
$element->supplier = $supplier;
$element->costs = new FloatInt((int) ($price['bestActualPrice']->value * $orderQuantity / FloatInt::DIVISOR));
$suggestion->elements[] = $element;
}
return $suggestions;
return $suggestion;
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase\Models\OrderSuggestion
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Purchase\Models\OrderSuggestion;
/**
* Null model
*
* @package Modules\Purchase\Models\OrderSuggestion
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
final class NullOrderSuggestion extends OrderSuggestion
{
/**
* Constructor
*
* @param int $id Model id
*
* @since 1.0.0
*/
public function __construct(int $id = 0)
{
$this->id = $id;
parent::__construct();
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() : mixed
{
return ['id' => $this->id];
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase\Models\OrderSuggestion
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\Purchase\Models\OrderSuggestion;
/**
* Null model
*
* @package Modules\Purchase\Models\OrderSuggestion
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
final class NullOrderSuggestionElement extends OrderSuggestionElement
{
/**
* Constructor
*
* @param int $id Model id
*
* @since 1.0.0
*/
public function __construct(int $id = 0)
{
$this->id = $id;
parent::__construct();
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() : mixed
{
return ['id' => $this->id];
}
}

View File

@ -16,6 +16,7 @@ namespace Modules\Purchase\Models\OrderSuggestion;
use Modules\Admin\Models\Account;
use Modules\Admin\Models\NullAccount;
use phpOMS\Stdlib\Base\FloatInt;
/**
* OrderSuggestion class.
@ -42,4 +43,14 @@ class OrderSuggestion
$this->createdBy = new NullAccount();
$this->createdAt = new \DateTimeImmutable('now');
}
public function getTotalCosts() : FloatInt
{
$total = new FloatInt();
foreach ($this->elements as $element) {
$total->add($element->costs);
}
return $total;
}
}

View File

@ -4,7 +4,7 @@
*
* PHP Version 8.1
*
* @package Modules\Purchase\Models
* @package Modules\Purchase\Models\OrderSuggestion
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
@ -12,7 +12,7 @@
*/
declare(strict_types=1);
namespace Modules\Purchase\Models;
namespace Modules\Purchase\Models\OrderSuggestion;
use Modules\Admin\Models\AccountMapper;
use Modules\Billing\Models\BillMapper;
@ -23,7 +23,7 @@ use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Client mapper class.
*
* @package Modules\Purchase\Models
* @package Modules\Purchase\Models\OrderSuggestion
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
@ -42,14 +42,14 @@ final class OrderSuggestionElementMapper extends DataMapperFactory
public const COLUMNS = [
'purchase_order_suggestion_element_id' => ['name' => 'purchase_order_suggestion_element_id', 'type' => 'int', 'internal' => 'id'],
'purchase_order_suggestion_element_status' => ['name' => 'purchase_order_suggestion_element_status', 'type' => 'int', 'internal' => 'status'],
'purchase_order_suggestion_element_modified_by' => ['name' => 'purchase_order_suggestion_element_modified_by', 'type' => 'int', 'internal' => 'modifiedBy'],
'purchase_order_suggestion_element_modified_at' => ['name' => 'purchase_order_suggestion_element_modified_at', 'type' => 'DateTimeImmutable', 'internal' => 'modifiedAt'],
'purchase_order_suggestion_element_updated_by' => ['name' => 'purchase_order_suggestion_element_updated_by', 'type' => 'int', 'internal' => 'modifiedBy'],
'purchase_order_suggestion_element_updated_at' => ['name' => 'purchase_order_suggestion_element_updated_at', 'type' => 'DateTimeImmutable', 'internal' => 'modifiedAt'],
'purchase_order_suggestion_element_suggestion' => ['name' => 'purchase_order_suggestion_element_suggestion', 'type' => 'int', 'internal' => 'suggestion'],
'purchase_order_suggestion_element_item' => ['name' => 'purchase_order_suggestion_element_item', 'type' => 'int', 'internal' => 'item'],
'purchase_order_suggestion_element_bill' => ['name' => 'purchase_order_suggestion_element_bill', 'type' => 'int', 'internal' => 'bill'],
'purchase_order_suggestion_element_supplier' => ['name' => 'purchase_order_suggestion_element_supplier', 'type' => 'int', 'internal' => 'supplier'],
'purchase_order_suggestion_element_quantity' => ['name' => 'purchase_order_suggestion_element_quantity', 'type' => 'int', 'internal' => 'quantity'],
'purchase_order_suggestion_element_costs' => ['name' => 'purchase_order_suggestion_element_costs', 'type' => 'int', 'internal' => 'costs'],
'purchase_order_suggestion_element_quantity' => ['name' => 'purchase_order_suggestion_element_quantity', 'type' => 'Serializable', 'internal' => 'quantity'],
'purchase_order_suggestion_element_costs' => ['name' => 'purchase_order_suggestion_element_costs', 'type' => 'Serializable', 'internal' => 'costs'],
];
/**

View File

@ -4,7 +4,7 @@
*
* PHP Version 8.1
*
* @package Modules\Purchase\Models
* @package Modules\Purchase\Models\OrderSuggestion
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
@ -12,22 +12,15 @@
*/
declare(strict_types=1);
namespace Modules\Purchase\Models;
namespace Modules\Purchase\Models\OrderSuggestion;
use Modules\Admin\Models\AccountMapper;
use Modules\Admin\Models\AddressMapper;
use Modules\Purchase\Models\Attribute\ClientAttributeMapper;
use Modules\Editor\Models\EditorDocMapper;
use Modules\ItemManagement\Models\ItemMapper;
use Modules\Media\Models\MediaMapper;
use Modules\Payment\Models\PaymentMapper;
use Modules\SupplierManagement\Models\SupplierMapper;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Client mapper class.
*
* @package Modules\Purchase\Models
* @package Modules\Purchase\Models\OrderSuggestion
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
@ -47,7 +40,7 @@ final class OrderSuggestionMapper extends DataMapperFactory
'purchase_order_suggestion_id' => ['name' => 'purchase_order_suggestion_id', 'type' => 'int', 'internal' => 'id'],
'purchase_order_suggestion_status' => ['name' => 'purchase_order_suggestion_status', 'type' => 'int', 'internal' => 'status'],
'purchase_order_suggestion_created_by' => ['name' => 'purchase_order_suggestion_created_by', 'type' => 'int', 'internal' => 'createdBy'],
'purchase_order_suggestion_created_at' => ['name' => 'purchase_order_suggestion_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'modifiedAt'],
'purchase_order_suggestion_created_at' => ['name' => 'purchase_order_suggestion_created_at', 'type' => 'DateTimeImmutable', 'internal' => 'createdAt'],
];
/**

View File

@ -26,9 +26,12 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class OrderSuggestionOptimizationType extends Enum
{
public const COST = 1; // Suggestion focuses on creating better prices if volume discounts exist.
public const ITEM_SPECIFIC = 0; // Suggestion focuses on an availability for X days, days need to be specified in the algorithm.
public const JUST_IN_TIME = 2; // Suggestion focuses on calculating minimum stock quantities.
public const AVAILABILITY = 1; // Suggestion focuses on an availability for X days, days need to be specified in the algorithm.
public const COST = 2; // Suggestion focuses on creating better prices if volume discounts exist.
public const JUST_IN_TIME = 3; // Suggestion focuses on calculating minimum stock quantities.
public const AVAILABILITY = 3; // Suggestion focuses on an availability for X days, days need to be specified in the algorithm.
}

View File

@ -19,7 +19,7 @@ return ['Navigation' => [
'Invoice' => 'Rechnung',
'Invoices' => 'Rechnungen',
'List' => 'Liste',
'OrderSuggestions' => 'Vorschläge auf Bestellung',
'OrderSuggestions' => 'Bestellvorschläg',
'PendingOrders' => 'Ausstehende Bestellungen',
'Profile' => 'Profil',
'Purchase' => 'Kaufen',

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'الحساب',
'Active' => 'نشيط',
'Activity' => 'نشاط',
'Address' => 'تبوك',
'All' => 'الجميع',
'Amount' => 'مقدار',
'Analysis' => 'التحليلات',
'Area' => 'مساحة',
'Article' => 'مقالة - سلعة',
'Articles' => 'مقالات',
'Available' => 'متوفرة',
'Calculate' => 'حساب',
'City' => 'مدينة',
'Class' => 'فصل',
'Confirmation' => 'تأكيد',
'CoreData' => 'البيانات الأساسية',
'Country' => 'دولة',
'Created' => 'خلقت',
'Creator' => 'المنشئ',
'CreditNote' => 'اشعار دائن',
'DSO' => 'DSO.',
'Date' => 'تاريخ',
'DefaultInternational' => 'افتراضي الدولية',
'DefaultNational' => 'الوضع الوطني الافتراضي',
'Delivery' => 'توصيل',
'DeliveryNote' => 'مذكرة تسليم',
'Description' => 'وصف',
'Discount' => 'خصم',
'DiscountP' => 'خصم في٪',
'Documentation' => 'توثيق',
'Employee' => 'موظف',
'FAO' => 'الفاو',
'From' => 'من',
'Group' => 'مجموعة',
'Groups' => 'مجموعات',
'Highest' => 'أعلى',
'Inactive' => 'غير نشط',
'Interval' => 'فترة',
'Invoice' => 'فاتورة',
'Invoices' => 'الفواتير',
'IsDefault' => 'افتراضي؟',
'Language' => 'لغة',
'Last' => 'الاخير',
'Localization' => 'الموقع',
'Loginname' => 'اسم الدخول',
'Matchcode' => 'رمز مطابق',
'Media' => 'وسائط',
'MinPrice' => 'سعر دقيقة',
'Name' => 'اسم',
'Name1' => 'الاسم 1.',
'Name2' => 'الاسم 2.',
'Name3' => 'الاسم 3.',
'Offer' => 'عرض',
'Order' => 'طلب',
'Ordered' => 'أمر',
'OrderedBy' => 'أمر من قبل',
'OrderedDate' => 'تاريخ الطلب',
'Orders' => 'الطلب #٪ s',
'Payment' => 'دفع',
'Price' => 'السعر',
'Priority' => 'أفضلية',
'Purchases' => 'المشتريات',
'Quantity' => 'كمية',
'Receipt' => 'إيصال',
'Reference' => 'المرجعي',
'Sales' => 'مبيعات',
'Settings' => 'إعدادات',
'Single' => 'غير مرتبطة',
'State' => 'ولاية',
'Statistics' => 'إحصائيات',
'Status' => 'حالة',
'Stock' => 'المخزون',
'Street' => 'شارع',
'Subgroup' => 'مجموعة فرعية',
'Supplier' => 'المورد',
'SupplierID' => 'واسم المورد',
'SupplierName' => 'اسم المورد',
'Suppliers' => 'الموردون',
'Tax' => 'ضريبة',
'Terms' => 'شروط',
'To' => 'ل',
'TopArticles' => 'أفضل المقالات',
'Trend' => 'اتجاه',
'Turnover' => 'دوران',
'Type' => 'نوع',
'ZipCode' => 'رمز بريدي',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Účet',
'Active' => 'Aktivní',
'Activity' => 'Aktivita',
'Address' => 'Adresa',
'All' => 'Všechno',
'Amount' => 'Množství',
'Analysis' => 'Analýza',
'Area' => 'Plocha',
'Article' => 'Článek',
'Articles' => 'Články',
'Available' => 'Dostupný',
'Calculate' => 'Vypočítat',
'City' => 'Město',
'Class' => 'Třída',
'Confirmation' => 'potvrzení',
'CoreData' => 'Základní data',
'Country' => 'Země',
'Created' => 'Vytvořený',
'Creator' => 'Tvůrce',
'CreditNote' => 'Dobropis',
'DSO' => 'DSO.',
'Date' => 'datum',
'DefaultInternational' => 'Výchozí mezinárodní',
'DefaultNational' => 'Výchozí státní příslušník',
'Delivery' => 'dodávka',
'DeliveryNote' => 'Dodací list',
'Description' => 'Popis',
'Discount' => 'Sleva',
'DiscountP' => 'Sleva v%',
'Documentation' => 'Dokumentace',
'Employee' => 'Zaměstnanec',
'FAO' => 'Fao.',
'From' => 'Z',
'Group' => 'Skupina',
'Groups' => 'Skupiny',
'Highest' => 'Nejvyšší',
'Inactive' => 'Neaktivní',
'Interval' => 'Interval',
'Invoice' => 'Faktura',
'Invoices' => 'Faktury',
'IsDefault' => 'Je výchozí?',
'Language' => 'Jazyk',
'Last' => 'Poslední',
'Localization' => 'Lokalizace',
'Loginname' => 'Přihlašovací jméno',
'Matchcode' => 'MatchCode.',
'Media' => 'Mediální',
'MinPrice' => 'Min',
'Name' => 'název',
'Name1' => 'Jméno 1.',
'Name2' => 'Jméno 2.',
'Name3' => 'Jméno 3.',
'Offer' => 'Nabídka',
'Order' => 'Objednat',
'Ordered' => 'Objednaný',
'OrderedBy' => 'Objednáno někým',
'OrderedDate' => 'Objednané datum',
'Orders' => 'Objednávky',
'Payment' => 'Způsob platby',
'Price' => 'Cena',
'Priority' => 'Přednost',
'Purchases' => 'Nákupy',
'Quantity' => 'Množství',
'Receipt' => 'Účtenka',
'Reference' => 'Odkaz',
'Sales' => 'Odbyt',
'Settings' => 'Nastavení',
'Single' => 'Singl',
'State' => 'Stát',
'Statistics' => 'Statistika',
'Status' => 'Postavení',
'Stock' => 'Skladem',
'Street' => 'ulice',
'Subgroup' => 'Podskupina',
'Supplier' => 'Dodavatel',
'SupplierID' => 'ID dodavatele',
'SupplierName' => 'Jméno dodavatele',
'Suppliers' => 'Dodavatelé',
'Tax' => 'Daň',
'Terms' => 'Podmínky',
'To' => 'Na',
'TopArticles' => 'Nejlepší články',
'Trend' => 'Trend',
'Turnover' => 'Obrat',
'Type' => 'Typ',
'ZipCode' => 'PSČ',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Konto',
'Active' => 'Aktiv',
'Activity' => 'Aktivitet',
'Address' => 'Adresse',
'All' => 'Alle',
'Amount' => 'Beløb',
'Analysis' => 'Analyse',
'Area' => 'Areal',
'Article' => 'Artikel',
'Articles' => 'Artikler',
'Available' => 'Ledig',
'Calculate' => 'Beregn',
'City' => 'City.',
'Class' => 'Klasse',
'Confirmation' => 'Bekræftelse',
'CoreData' => 'Kernedata.',
'Country' => 'Land',
'Created' => 'Oprettet',
'Creator' => 'Skaber.',
'CreditNote' => 'Kreditnota',
'DSO' => 'DSO.',
'Date' => 'Dato',
'DefaultInternational' => 'Standard International',
'DefaultNational' => 'Standard National',
'Delivery' => 'Levering',
'DeliveryNote' => 'Levering note',
'Description' => 'Beskrivelse',
'Discount' => 'Rabat',
'DiscountP' => 'Rabat i%',
'Documentation' => 'Dokumentation',
'Employee' => 'Medarbejder',
'FAO' => 'FAO.',
'From' => 'Fra',
'Group' => 'Gruppe',
'Groups' => 'Grupper.',
'Highest' => 'Højeste',
'Inactive' => 'Inaktiv.',
'Interval' => 'Interval',
'Invoice' => 'Faktura',
'Invoices' => 'Fakturaer.',
'IsDefault' => 'Er standard?',
'Language' => 'Sprog',
'Last' => 'Sidst',
'Localization' => 'Lokalisering',
'Loginname' => 'Login-navn',
'Matchcode' => 'MatchCode.',
'Media' => 'Medier',
'MinPrice' => 'Min',
'Name' => 'Navn',
'Name1' => 'Navn 1',
'Name2' => 'Navn 2.',
'Name3' => 'Navn 3.',
'Offer' => 'Tilbud',
'Order' => 'Bestille',
'Ordered' => 'Bestilt.',
'OrderedBy' => 'Bestilt af',
'OrderedDate' => 'Bestilte Dato',
'Orders' => 'Ordre:% s',
'Payment' => 'Betaling',
'Price' => 'Pris',
'Priority' => 'Prioritet',
'Purchases' => 'Køb',
'Quantity' => 'Antal',
'Receipt' => 'Kvittering',
'Reference' => 'Reference',
'Sales' => 'SALG',
'Settings' => 'Indstillinger.',
'Single' => 'Enkelt',
'State' => 'Stat',
'Statistics' => 'Statistikker',
'Status' => 'Status.',
'Stock' => 'Lager',
'Street' => 'Gade',
'Subgroup' => 'Undergruppe',
'Supplier' => 'Leverandør',
'SupplierID' => 'Leverandør ID.',
'SupplierName' => 'Leverandør Navn',
'Suppliers' => 'Leverandører.',
'Tax' => 'Skat',
'Terms' => 'Vilkår',
'To' => 'Til',
'TopArticles' => 'Top artikler',
'Trend' => 'Trend.',
'Turnover' => 'Omsætning',
'Type' => 'Type',
'ZipCode' => 'Postnummer',
]];

View File

@ -13,90 +13,48 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Konto',
'Active' => 'Aktiv',
'Activity' => 'Aktivität',
'Address' => 'Adresse',
'All' => 'Alle',
'Amount' => 'Höhe',
'Analysis' => 'Analyse',
'Area' => 'Bereich',
'Article' => 'Artikel',
'Articles' => 'Artikel',
'Available' => 'Erhältlich',
'Calculate' => 'Berechnung',
'City' => 'Stadt',
'Class' => 'Klasse',
'Confirmation' => 'Bestätigung',
'CoreData' => 'Kerndatei',
'Country' => 'Land',
'Created' => 'Erstellt',
'Creator' => 'Ersteller',
'CreditNote' => 'Gutschrift',
'DSO' => 'DSO.',
'Date' => 'Datum',
'DefaultInternational' => 'Standard-Internationale',
'DefaultNational' => 'Standardnationalstaat',
'Delivery' => 'Die Zustellung',
'DeliveryNote' => 'Lieferschein',
'Description' => 'Beschreibung',
'Discount' => 'Rabatt',
'DiscountP' => 'Rabatt in%',
'Documentation' => 'Dokumentation',
'Employee' => 'Mitarbeiter',
'FAO' => 'Fao',
'From' => 'Von',
'Group' => 'Gruppe',
'Groups' => 'Gruppen',
'Highest' => 'Höchste',
'Inactive' => 'Inaktiv',
'Interval' => 'Intervall',
'Invoice' => 'Rechnung',
'Invoices' => 'Rechnungen',
'IsDefault' => 'Ist standardmäßig?',
'Language' => 'Sprache',
'Last' => 'Zuletzt',
'Localization' => 'Lokalisierung',
'Loginname' => 'Benutzername',
'Matchcode' => 'Matchcode',
'Media' => 'Medien',
'MinPrice' => 'Minster Preis',
'Name' => 'Name',
'Name1' => 'Name 1',
'Name2' => 'Name 2',
'Name3' => 'Name 3',
'Offer' => 'Angebot',
'Order' => 'Befehl',
'Ordered' => 'Bestellt',
'OrderedBy' => 'Bestellt durch',
'OrderedDate' => 'Bestelldatum',
'Orders' => 'Aufträge',
'Payment' => 'Zahlung',
'Price' => 'Preis',
'Priority' => 'Priorität',
'Purchases' => 'Käufe',
'Quantity' => 'Menge',
'Receipt' => 'Kassenbon',
'Reference' => 'Bezug',
'Sales' => 'Umsatz',
'Settings' => 'Einstellungen',
'Single' => 'Single',
'State' => 'Zustand',
'Statistics' => 'Statistiken',
'Status' => 'Status',
'Stock' => 'Aktie',
'Street' => 'Straße',
'Subgroup' => 'Untergruppe',
'Supplier' => 'Anbieter',
'SupplierID' => 'Lieferanten ID',
'SupplierName' => 'Name des Anbieters',
'Suppliers' => 'Lieferanten',
'Tax' => 'Steuer',
'Terms' => 'Bedingungen',
'To' => 'Zu',
'TopArticles' => 'Top-Artikeln',
'Trend' => 'Trend',
'Turnover' => 'Umsatz',
'Type' => 'Typ',
'ZipCode' => 'Postleitzahl',
'Order' => 'Bestellen',
'Item' => 'Artikel',
'Supplier' => 'Lieferant',
'Stock' => 'Lager',
'Reserved' => 'Reserviert',
'Ordered' => 'Bestellt',
'AvgConsumption' => 'Ø Verbrauch',
'Range1' => 'Reichw. 1',
'Range2' => 'Reichw. 2',
'MinStock' => 'Min. Lager',
'MinOrder' => 'Min. Bestellmenge',
'MinRange' => 'Min. Reichw.',
'Steps' => 'Schritte',
'Ordering' => 'Bestellen',
'NewRange' => 'Neue Reichw.',
'Price' => 'Preis',
'Total' => 'Gesamt',
'Costs' => 'Kosten',
':SuggestionStatus-1' => 'Entwurf',
':SuggestionStatus-2' => 'Gelöscht',
':SuggestionStatus-3' => 'Bestellt',
':OptimizationAlgorithm-0' => 'Artikel specifisch',
':OptimizationAlgorithm-1' => 'Verfügbarkeit',
':OptimizationAlgorithm-2' => 'Kosten',
':OptimizationAlgorithm-3' => 'Just in time',
'Elements' => 'Elemente',
'Algorithm' => 'Algorithmus',
'Analyze' => 'Analysiere',
'Segment' => 'Segment',
'HideIrrelevant' => 'Nur relevante',
'Section' => 'Sparte',
'SalesGroup' => 'Umsatzgruppe',
'ProductGroup' => 'Produktgruppe',
'MinRange' => 'Min.-Reichweite',
'OrderSuggestions' => 'Bestellvorschläge',
'OrderSuggestion' => 'Bestellvorschlag',
'Suggestions' => 'Vorschläge',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'λογαριασμός',
'Active' => 'Ενεργός',
'Activity' => 'Δραστηριότητα',
'Address' => 'Διεύθυνση',
'All' => 'Ολα',
'Amount' => 'Ποσό',
'Analysis' => 'Ανάλυση',
'Area' => 'Περιοχή',
'Article' => 'Αρθρο',
'Articles' => 'Είδη',
'Available' => 'Διαθέσιμος',
'Calculate' => 'Υπολογίζω',
'City' => 'Πόλη',
'Class' => 'Τάξη',
'Confirmation' => 'Επιβεβαίωση',
'CoreData' => 'Βασικά δεδομένα',
'Country' => 'Χώρα',
'Created' => 'Δημιουργήθηκε',
'Creator' => 'Δημιουργός',
'CreditNote' => 'Πιστωτικό σημείωμα',
'DSO' => 'ΔΣΟ',
'Date' => 'Ημερομηνία',
'DefaultInternational' => 'Προεπιλογή Διεθνής',
'DefaultNational' => 'Προεπιλεγμένος Εθνικός',
'Delivery' => 'Διανομή',
'DeliveryNote' => 'Δελτίο παράδοσης',
'Description' => 'Περιγραφή',
'Discount' => 'Εκπτωση',
'DiscountP' => 'Έκπτωση σε%',
'Documentation' => 'Τεκμηρίωση',
'Employee' => 'Υπάλληλος',
'FAO' => 'Φλυαρία',
'From' => 'Από',
'Group' => 'Ομάδα',
'Groups' => 'Ομάδες',
'Highest' => 'Υψιστος',
'Inactive' => 'Αδρανής',
'Interval' => 'Διάστημα',
'Invoice' => 'Τιμολόγιο',
'Invoices' => 'Τιμολόγια',
'IsDefault' => 'Είναι προεπιλογή;',
'Language' => 'Γλώσσα',
'Last' => 'τελευταίος',
'Localization' => 'Εντοπισμός',
'Loginname' => 'Ονομα σύνδεσης',
'Matchcode' => 'Matchcode',
'Media' => 'Μεσο ΜΑΖΙΚΗΣ ΕΝΗΜΕΡΩΣΗΣ',
'MinPrice' => 'Ελάχιστη τιμή',
'Name' => 'Ονομα',
'Name1' => 'Όνομα 1',
'Name2' => 'Όνομα 2',
'Name3' => 'Όνομα 3',
'Offer' => 'Προσφορά',
'Order' => 'Σειρά',
'Ordered' => 'Διέταξε',
'OrderedBy' => 'Παραγγέλθηκε από',
'OrderedDate' => 'Παραγγελία',
'Orders' => 'Εντολές',
'Payment' => 'Πληρωμή',
'Price' => 'Τιμή',
'Priority' => 'Προτεραιότητα',
'Purchases' => 'Ψώνια',
'Quantity' => 'Ποσότητα',
'Receipt' => 'Παραλαβή',
'Reference' => 'Αναφορά',
'Sales' => 'Εκπτώσεις',
'Settings' => 'Ρυθμίσεις',
'Single' => 'Μονόκλινο',
'State' => 'κατάσταση',
'Statistics' => 'Στατιστική',
'Status' => 'Κατάσταση',
'Stock' => 'Στοκ',
'Street' => 'Δρόμος',
'Subgroup' => 'Υποομάδα',
'Supplier' => 'Προμηθευτής',
'SupplierID' => 'Προμηθευτή',
'SupplierName' => 'Όνομα προμηθευτή',
'Suppliers' => 'Προμηθευτές',
'Tax' => 'Φόρος',
'Terms' => 'Οροι',
'To' => 'Προς το',
'TopArticles' => 'Κορυφαία άρθρα',
'Trend' => 'Τάση',
'Turnover' => 'Τζίρος',
'Type' => 'Τύπος',
'ZipCode' => 'Ταχυδρομικός κώδικας',
]];

View File

@ -13,90 +13,48 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Account',
'Active' => 'Active',
'Activity' => 'Activity',
'Address' => 'Address',
'All' => 'All',
'Amount' => 'Amount',
'Analysis' => 'Analysis',
'Area' => 'Area',
'Article' => 'Article',
'Articles' => 'Articles',
'Available' => 'Available',
'Calculate' => 'Calculate',
'City' => 'City',
'Class' => 'Class',
'Confirmation' => 'Confirmation',
'CoreData' => 'Core data',
'Country' => 'Country',
'Created' => 'Created',
'Creator' => 'Creator',
'CreditNote' => 'Credit Note',
'DSO' => 'DSO',
'Date' => 'Date',
'DefaultInternational' => 'Default International',
'DefaultNational' => 'Default National',
'Delivery' => 'Delivery',
'DeliveryNote' => 'Delivery Note',
'Description' => 'Description',
'Discount' => 'Discount',
'DiscountP' => 'Discount in %',
'Documentation' => 'Documentation',
'Employee' => 'Employee',
'FAO' => 'FAO',
'From' => 'From',
'Group' => 'Group',
'Groups' => 'Groups',
'Highest' => 'Highest',
'Inactive' => 'Inactive',
'Interval' => 'Interval',
'Invoice' => 'Invoice',
'Invoices' => 'Invoices',
'IsDefault' => 'Is default?',
'Language' => 'Language',
'Last' => 'Last',
'Localization' => 'Localization',
'Loginname' => 'Loginname',
'Matchcode' => 'Matchcode',
'Media' => 'Media',
'MinPrice' => 'Min Price',
'Name' => 'Name',
'Name1' => 'Name 1',
'Name2' => 'Name 2',
'Name3' => 'Name 3',
'Offer' => 'Offer',
'Order' => 'Order',
'Ordered' => 'Ordered',
'OrderedBy' => 'Ordered By',
'OrderedDate' => 'Ordered Date',
'Orders' => 'Orders',
'Payment' => 'Payment',
'Price' => 'Price',
'Priority' => 'Priority',
'Purchases' => 'Purchases',
'Quantity' => 'Quantity',
'Receipt' => 'Receipt',
'Reference' => 'Reference',
'Sales' => 'Sales',
'Settings' => 'Settings',
'Single' => 'Single',
'State' => 'State',
'Statistics' => 'Statistics',
'Status' => 'Status',
'Stock' => 'Stock',
'Street' => 'Street',
'Subgroup' => 'Subgroup',
'Supplier' => 'Supplier',
'SupplierID' => 'Supplier ID',
'SupplierName' => 'Supplier Name',
'Suppliers' => 'Suppliers',
'Tax' => 'Tax',
'Terms' => 'Terms',
'To' => 'To',
'TopArticles' => 'Top Articles',
'Trend' => 'Trend',
'Turnover' => 'Turnover',
'Type' => 'Type',
'ZipCode' => 'ZipCode',
'Order' => 'Order',
'Item' => 'Item',
'Supplier' => 'Supplier',
'Stock' => 'Stock',
'Reserved' => 'Reserved',
'Ordered' => 'Ordered',
'AvgConsumption' => 'Ø Cons.',
'Range1' => 'Range 1',
'Range2' => 'Range 2',
'MinStock' => 'Min. Stock',
'MinOrder' => 'Min. Order',
'MinRange' => 'Min. Range',
'Steps' => 'Steps',
'Ordering' => 'Ordering',
'NewRange' => 'New Range',
'Price' => 'Price',
'Total' => 'Total',
'Costs' => 'Costs',
':SuggestionStatus-1' => 'Draft',
':SuggestionStatus-2' => 'DELETED',
':SuggestionStatus-3' => 'ORDERED',
':OptimizationAlgorithm-0' => 'Item specific',
':OptimizationAlgorithm-1' => 'Availability optimization',
':OptimizationAlgorithm-2' => 'Cost optimization',
':OptimizationAlgorithm-3' => 'Just in time',
'Elements' => 'Elements',
'Algorithm' => 'Algorithm',
'Analyze' => 'Analyze',
'Segment' => 'Segment',
'HideIrrelevant' => 'Hide irrelevant',
'Section' => 'Section',
'SalesGroup' => 'Sales Group',
'ProductGroup' => 'Product Group',
'MinRange' => 'Min. Range',
'OrderSuggestions' => 'Order Suggestions',
'Suggestions' => 'Suggestions',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Cuenta',
'Active' => 'Activo',
'Activity' => 'Actividad',
'Address' => 'Habla a',
'All' => 'Todo',
'Amount' => 'Monto',
'Analysis' => 'Análisis',
'Area' => 'Área',
'Article' => 'Artículo',
'Articles' => 'Artículos',
'Available' => 'Disponible',
'Calculate' => 'Calcular',
'City' => 'Ciudad',
'Class' => 'Clase',
'Confirmation' => 'Confirmación',
'CoreData' => 'Datos principales',
'Country' => 'País',
'Created' => 'Creado',
'Creator' => 'Creador',
'CreditNote' => 'Nota de crédito',
'DSO' => 'DSO',
'Date' => 'Fecha',
'DefaultInternational' => 'Internacional predeterminado',
'DefaultNational' => 'Nacional predeterminado',
'Delivery' => 'Entrega',
'DeliveryNote' => 'Nota de entrega',
'Description' => 'Descripción',
'Discount' => 'Descuento',
'DiscountP' => 'Descuento en%',
'Documentation' => 'Documentación',
'Employee' => 'Empleado',
'FAO' => 'Fao',
'From' => 'Desde',
'Group' => 'Grupo',
'Groups' => 'Grupo',
'Highest' => 'Más alto',
'Inactive' => 'Inactivo',
'Interval' => 'Intervalo',
'Invoice' => 'Factura',
'Invoices' => 'Facturas',
'IsDefault' => 'Es por defecto?',
'Language' => 'Idioma',
'Last' => 'Ultimo',
'Localization' => 'Localización',
'Loginname' => 'Nombre de inicio de sesión',
'Matchcode' => 'Código de asociación',
'Media' => 'Medios de comunicación',
'MinPrice' => 'Precio mínimo',
'Name' => 'Nombre',
'Name1' => 'Nombre 1',
'Name2' => 'Nombre 2',
'Name3' => 'Nombre 3',
'Offer' => 'Oferta',
'Order' => 'Pedido',
'Ordered' => 'Ordenado',
'OrderedBy' => 'Ordenado por',
'OrderedDate' => 'Fecha ordenada',
'Orders' => 'Pedidos',
'Payment' => 'Pago',
'Price' => 'Precio',
'Priority' => 'Prioridad',
'Purchases' => 'Compras',
'Quantity' => 'Cantidad',
'Receipt' => 'Recibo',
'Reference' => 'Referencia',
'Sales' => 'Ventas',
'Settings' => 'Ajustes',
'Single' => 'Único',
'State' => 'Expresar',
'Statistics' => 'Estadísticas',
'Status' => 'Estado',
'Stock' => 'Valores',
'Street' => 'calle',
'Subgroup' => 'Subgrupo',
'Supplier' => 'Proveedor',
'SupplierID' => 'Identificación del proveedor',
'SupplierName' => 'Nombre del proveedor',
'Suppliers' => 'Proveedores',
'Tax' => 'Impuesto',
'Terms' => 'Condiciones',
'To' => 'A',
'TopArticles' => 'Artículos principales',
'Trend' => 'Tendencia',
'Turnover' => 'Rotación',
'Type' => 'Escribe',
'ZipCode' => 'Código postal',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Tili',
'Active' => 'Aktiivinen',
'Activity' => 'Toiminta',
'Address' => 'Osoite',
'All' => 'Kaikki',
'Amount' => 'Määrä',
'Analysis' => 'Analyysi',
'Area' => 'Alue',
'Article' => 'Artikla',
'Articles' => 'Artikkelit',
'Available' => 'Saatavilla',
'Calculate' => 'Laskea',
'City' => 'Kaupunki',
'Class' => 'Luokka',
'Confirmation' => 'Vahvistus',
'CoreData' => 'Keskeiset tiedot',
'Country' => 'Maa',
'Created' => 'Luotu',
'Creator' => 'Luoja',
'CreditNote' => 'Luottoluotto',
'DSO' => 'Dso',
'Date' => 'Päivämäärä',
'DefaultInternational' => 'Oletus kansainvälinen',
'DefaultNational' => 'Oletusarvoinen kansallinen',
'Delivery' => 'Toimitus',
'DeliveryNote' => 'Saapumisilmoitus',
'Description' => 'Kuvaus',
'Discount' => 'Alennus',
'DiscountP' => 'Alennus%',
'Documentation' => 'Dokumentointi',
'Employee' => 'Työntekijä',
'FAO' => 'Fao',
'From' => 'Peräkkäin',
'Group' => 'Ryhmä',
'Groups' => 'Ryhmät',
'Highest' => 'Korkein',
'Inactive' => 'Epäaktiivinen',
'Interval' => 'Aikaväli',
'Invoice' => 'Lasku',
'Invoices' => 'Laskut',
'IsDefault' => 'On oletusarvo?',
'Language' => 'Kieli',
'Last' => 'Kestää',
'Localization' => 'Lokalisointi',
'Loginname' => 'Kirjautumisnimi',
'Matchcode' => 'Matchcode',
'Media' => 'Media',
'MinPrice' => 'Min hinta',
'Name' => 'Nimi',
'Name1' => 'Nimi 1',
'Name2' => 'Nimi 2',
'Name3' => 'Nimi 3',
'Offer' => 'Tarjous',
'Order' => 'Tilaus',
'Ordered' => 'Tilattu',
'OrderedBy' => 'Tilaama',
'OrderedDate' => 'Tilattu päivämäärä',
'Orders' => 'Tilaus',
'Payment' => 'Maksu',
'Price' => 'Hinta',
'Priority' => 'Etusija',
'Purchases' => 'Ostokset',
'Quantity' => 'Määrä',
'Receipt' => 'Kuitti',
'Reference' => 'Viite',
'Sales' => 'Myynti',
'Settings' => 'asetukset',
'Single' => 'Yksittäinen',
'State' => 'Osavaltio',
'Statistics' => 'Tilastot',
'Status' => 'Tila',
'Stock' => 'Varasto',
'Street' => 'Katu',
'Subgroup' => 'Alaryhmä',
'Supplier' => 'Toimittaja',
'SupplierID' => 'Toimittajan tunnus',
'SupplierName' => 'Toimittajan nimi',
'Suppliers' => 'Toimittajat',
'Tax' => 'Verottaa',
'Terms' => 'Ehdot',
'To' => 'Jllek',
'TopArticles' => 'Top artikkelit',
'Trend' => 'Trendi',
'Turnover' => 'Liikevaihto',
'Type' => 'Tyyppi',
'ZipCode' => 'Postinumero',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Compte',
'Active' => 'actif',
'Activity' => 'Activité',
'Address' => 'Adresse',
'All' => 'Tout',
'Amount' => 'Quantité',
'Analysis' => 'Analyse',
'Area' => 'Zone',
'Article' => 'Article',
'Articles' => 'Des articles',
'Available' => 'Disponible',
'Calculate' => 'Calculer',
'City' => 'Ville',
'Class' => 'Classer',
'Confirmation' => 'Confirmation',
'CoreData' => 'Données de base',
'Country' => 'Pays',
'Created' => 'Établi',
'Creator' => 'Créateur',
'CreditNote' => 'Note de crédit',
'DSO' => 'Dso',
'Date' => 'Date',
'DefaultInternational' => 'International par défaut',
'DefaultNational' => 'National par défaut',
'Delivery' => 'Livraison',
'DeliveryNote' => 'Bon de livraison',
'Description' => 'La description',
'Discount' => 'Remise',
'DiscountP' => 'Rabais en%',
'Documentation' => 'Documentation',
'Employee' => 'Employé',
'FAO' => 'Fao',
'From' => 'À partir de',
'Group' => 'Grouper',
'Groups' => 'Groupes',
'Highest' => 'Plus haut',
'Inactive' => 'Inactif',
'Interval' => 'Intervalle',
'Invoice' => 'Facture d\'achat',
'Invoices' => 'Factures',
'IsDefault' => 'Est par défaut?',
'Language' => 'Langue',
'Last' => 'Dernier',
'Localization' => 'Localisation',
'Loginname' => 'Identifiant',
'Matchcode' => 'Encadrement',
'Media' => 'Médias',
'MinPrice' => "Prix \u{200b}\u{200b}min",
'Name' => 'Nom',
'Name1' => 'Nom 1',
'Name2' => 'Nom 2',
'Name3' => 'Nom 3',
'Offer' => 'Offrir',
'Order' => 'Commander',
'Ordered' => 'Commandé',
'OrderedBy' => 'Commander par',
'OrderedDate' => 'Date ordonnée',
'Orders' => 'Ordres',
'Payment' => 'Paiement',
'Price' => 'Prix',
'Priority' => 'Priorité',
'Purchases' => 'Achats',
'Quantity' => 'Quantité',
'Receipt' => 'Reçu',
'Reference' => 'Référence',
'Sales' => 'Ventes',
'Settings' => 'Réglages',
'Single' => 'Seul',
'State' => 'État',
'Statistics' => 'Statistiques',
'Status' => 'Statut',
'Stock' => 'Stocker',
'Street' => 'rue',
'Subgroup' => 'Sous-groupe',
'Supplier' => 'Fournisseur',
'SupplierID' => 'ID du fournisseur',
'SupplierName' => 'Nom du fournisseur',
'Suppliers' => 'Fournisseurs',
'Tax' => 'Impôt',
'Terms' => 'termes',
'To' => 'À',
'TopArticles' => 'Top articles',
'Trend' => 'Tendance',
'Turnover' => 'Chiffre d\'affaires',
'Type' => 'Taper',
'ZipCode' => 'Code postal',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Számla',
'Active' => 'Aktív',
'Activity' => 'Tevékenység',
'Address' => 'Cím',
'All' => 'Minden',
'Amount' => 'Összeg',
'Analysis' => 'Elemzés',
'Area' => 'Terület',
'Article' => 'Cikk',
'Articles' => 'Árucikkek',
'Available' => 'Elérhető',
'Calculate' => 'Kiszámítja',
'City' => 'Város',
'Class' => 'Osztály',
'Confirmation' => 'Megerősítés',
'CoreData' => 'Alapvető adatok',
'Country' => 'Ország',
'Created' => 'Létrehozott',
'Creator' => 'Teremtő',
'CreditNote' => 'Jóváírás',
'DSO' => 'DSO',
'Date' => 'Dátum',
'DefaultInternational' => 'Alapértelmezett nemzetközi',
'DefaultNational' => 'Alapértelmezett nemzeti',
'Delivery' => 'Szállítás',
'DeliveryNote' => 'Fuvarlevél',
'Description' => 'Leírás',
'Discount' => 'Kedvezmény',
'DiscountP' => 'Kedvezmény%',
'Documentation' => 'Dokumentáció',
'Employee' => 'Munkavállaló',
'FAO' => 'FAO',
'From' => 'Tól től',
'Group' => 'Csoport',
'Groups' => 'Csoportok',
'Highest' => 'Legmagasabb',
'Inactive' => 'Inaktív',
'Interval' => 'Intervallum',
'Invoice' => 'Számla',
'Invoices' => 'Számlák',
'IsDefault' => 'Alapértelmezett?',
'Language' => 'Nyelv',
'Last' => 'Utolsó',
'Localization' => 'Lokalizáció',
'Loginname' => 'Bejelentkezési név',
'Matchcode' => 'Matchcode',
'Media' => 'Média',
'MinPrice' => 'Min Ár',
'Name' => 'Név',
'Name1' => 'NAME 1',
'Name2' => 'NAME 2',
'Name3' => 'Név 3',
'Offer' => 'Ajánlat',
'Order' => 'Rendelés',
'Ordered' => 'Elrendelt',
'OrderedBy' => 'Megrendelő',
'OrderedDate' => 'Rendezett dátum',
'Orders' => 'Megrendelések',
'Payment' => 'Fizetés',
'Price' => 'Ár',
'Priority' => 'Kiemelten fontos',
'Purchases' => 'Vásárlások',
'Quantity' => 'Mennyiség',
'Receipt' => 'Nyugta',
'Reference' => 'Referencia',
'Sales' => 'Értékesítés',
'Settings' => 'Beállítások',
'Single' => 'Egyetlen',
'State' => 'Állapot',
'Statistics' => 'Statisztika',
'Status' => 'Állapot',
'Stock' => 'Készlet',
'Street' => 'utca',
'Subgroup' => 'Alcsoport',
'Supplier' => 'Támogató',
'SupplierID' => 'Szállítóazonosító',
'SupplierName' => 'Szállító neve',
'Suppliers' => 'Beszállítók',
'Tax' => 'Adó',
'Terms' => 'Feltételek',
'To' => 'Nak nek',
'TopArticles' => 'Top cikkek',
'Trend' => 'Irányzat',
'Turnover' => 'Forgalom',
'Type' => 'típus',
'ZipCode' => 'Irányítószám',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Account',
'Active' => 'Attivo',
'Activity' => 'Attività',
'Address' => 'Indirizzo',
'All' => 'Tutto',
'Amount' => 'Quantità',
'Analysis' => 'Analisi',
'Area' => 'La zona',
'Article' => 'Articolo',
'Articles' => 'Artificio',
'Available' => 'A disposizione',
'Calculate' => 'Calcolare',
'City' => 'Città',
'Class' => 'Classe',
'Confirmation' => 'Conferma',
'CoreData' => 'Dati principali',
'Country' => 'Nazione',
'Created' => 'Creato',
'Creator' => 'Creatore',
'CreditNote' => 'Nota di credito',
'DSO' => 'DSO.',
'Date' => 'Data',
'DefaultInternational' => 'Default International.',
'DefaultNational' => 'National default.',
'Delivery' => 'Consegna',
'DeliveryNote' => 'Bolla d\'accompagnamento',
'Description' => 'Descrizione',
'Discount' => 'Sconto',
'DiscountP' => 'Sconto in%',
'Documentation' => 'Documentazione',
'Employee' => 'Dipendente',
'FAO' => 'FAO.',
'From' => 'A partire dal',
'Group' => 'Gruppo',
'Groups' => 'Gruppi',
'Highest' => 'Massimo',
'Inactive' => 'Non attivo',
'Interval' => 'Intervallo',
'Invoice' => 'Fattura',
'Invoices' => 'Fatture',
'IsDefault' => 'È predefinito?',
'Language' => 'Lingua',
'Last' => 'Scorso',
'Localization' => 'Localizzazione',
'Loginname' => 'Nome di login',
'Matchcode' => 'Matchcode.',
'Media' => 'Media',
'MinPrice' => 'Prezzo minimo',
'Name' => 'Nome',
'Name1' => 'Nome 1.',
'Name2' => 'Nome 2.',
'Name3' => 'Nome 3.',
'Offer' => 'Offerta',
'Order' => 'Ordine',
'Ordered' => 'Ordinato',
'OrderedBy' => 'Ordinato da',
'OrderedDate' => 'Data ordinata',
'Orders' => 'Ordini',
'Payment' => 'Pagamento',
'Price' => 'Prezzo',
'Priority' => 'Priorità',
'Purchases' => 'Acquisti',
'Quantity' => 'Quantità',
'Receipt' => 'Ricevuta',
'Reference' => 'Riferimento',
'Sales' => 'Saldi',
'Settings' => 'Impostazioni',
'Single' => 'Separare',
'State' => 'Stato',
'Statistics' => 'Statistiche',
'Status' => 'Stato',
'Stock' => 'Azione',
'Street' => 'strada',
'Subgroup' => 'Sottogruppo',
'Supplier' => 'Fornitore',
'SupplierID' => 'ID fornitore',
'SupplierName' => 'Nome del fornitore',
'Suppliers' => 'Fornitori',
'Tax' => 'Imposta',
'Terms' => 'Termini',
'To' => 'a',
'TopArticles' => 'Articoli migliori',
'Trend' => 'Tendenza',
'Turnover' => 'Turnover',
'Type' => 'Tipo',
'ZipCode' => 'Cap',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'アカウント',
'Active' => 'アクティブ',
'Activity' => 'アクティビティ',
'Address' => '住所',
'All' => '全て',
'Amount' => '額',
'Analysis' => '分析',
'Area' => '領域',
'Article' => '記事',
'Articles' => 'articles',
'Available' => '利用可能',
'Calculate' => '計算する',
'City' => '市',
'Class' => 'クラス',
'Confirmation' => '確認',
'CoreData' => 'コアデータ',
'Country' => '国',
'Created' => '作成した',
'Creator' => 'クリエーター',
'CreditNote' => 'クレジットノート',
'DSO' => 'DSO',
'Date' => '日にち',
'DefaultInternational' => 'デフォルトの国際',
'DefaultNational' => 'デフォルトの国',
'Delivery' => '配達',
'DeliveryNote' => '配達メモ',
'Description' => '説明',
'Discount' => '割引',
'DiscountP' => '割引%',
'Documentation' => 'ドキュメンテーション',
'Employee' => '従業員',
'FAO' => 'fa fa',
'From' => 'から',
'Group' => 'グループ',
'Groups' => '団体',
'Highest' => '最高',
'Inactive' => '非活性',
'Interval' => '間隔',
'Invoice' => '請求書',
'Invoices' => '請求書',
'IsDefault' => 'デフォルトですか?',
'Language' => '言語',
'Last' => '最後',
'Localization' => 'ローカライズ',
'Loginname' => 'ログイン名',
'Matchcode' => 'マッチコード',
'Media' => 'メディア',
'MinPrice' => '最小価格',
'Name' => '名前',
'Name1' => '名前1',
'Name2' => '名前2',
'Name3' => '名前3',
'Offer' => 'オファー',
'Order' => '注文',
'Ordered' => '順序付けられました',
'OrderedBy' => 'によって順序付け',
'OrderedDate' => '注文日',
'Orders' => '命令',
'Payment' => '支払い',
'Price' => '価格',
'Priority' => '優先度',
'Purchases' => '購入する',
'Quantity' => '量',
'Receipt' => 'レシート',
'Reference' => 'リファレンス',
'Sales' => '売り返り',
'Settings' => '設定',
'Single' => '独身',
'State' => '州',
'Statistics' => '統計学',
'Status' => '状態',
'Stock' => 'ストック',
'Street' => '街',
'Subgroup' => 'サブグループ',
'Supplier' => 'サプライヤー',
'SupplierID' => 'サプライヤID',
'SupplierName' => 'サプライヤ名',
'Suppliers' => 'サプライヤー',
'Tax' => '税',
'Terms' => '条項',
'To' => 'に',
'TopArticles' => 'トップ記事',
'Trend' => '傾向',
'Turnover' => 'ひっくり返す',
'Type' => 'タイプ',
'ZipCode' => '郵便番号',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => '계정',
'Active' => '활동적인',
'Activity' => '활동',
'Address' => '주소',
'All' => '모두',
'Amount' => '양',
'Analysis' => '분석',
'Area' => '지역',
'Article' => '기사',
'Articles' => '조항',
'Available' => '사용 가능',
'Calculate' => '계산하다',
'City' => '도시',
'Class' => '등급',
'Confirmation' => '확인',
'CoreData' => '핵심 데이터',
'Country' => '국가',
'Created' => '만들어진',
'Creator' => '창조자',
'CreditNote' => '신용 노트',
'DSO' => 'DSO.',
'Date' => '날짜',
'DefaultInternational' => '기본 국제',
'DefaultNational' => '기본 내셔널',
'Delivery' => '배달',
'DeliveryNote' => '배달 메모',
'Description' => '설명',
'Discount' => '할인',
'DiscountP' => '할인 %',
'Documentation' => '선적 서류 비치',
'Employee' => '직원',
'FAO' => '조금',
'From' => '에서',
'Group' => '그룹',
'Groups' => '여러 떼',
'Highest' => '제일 높은',
'Inactive' => '비활성으로',
'Interval' => '간격',
'Invoice' => '송장',
'Invoices' => '송장',
'IsDefault' => '기본값은 무엇입니까?',
'Language' => '언어',
'Last' => '마지막',
'Localization' => '현지화',
'Loginname' => '로그인 이름',
'Matchcode' => '매치 코드',
'Media' => '미디어',
'MinPrice' => '최소 가격',
'Name' => '이름',
'Name1' => '이름 1',
'Name2' => '이름 2',
'Name3' => '이름 3.',
'Offer' => '권하다',
'Order' => '주문하다',
'Ordered' => '주문했다',
'OrderedBy' => '명령을 받았다',
'OrderedDate' => '날짜 주문',
'Orders' => '명령',
'Payment' => '지불',
'Price' => '가격',
'Priority' => '우선 사항',
'Purchases' => '구매',
'Quantity' => '수량',
'Receipt' => '영수증',
'Reference' => '참조',
'Sales' => '매상',
'Settings' => '설정',
'Single' => '하나의',
'State' => '상태',
'Statistics' => '통계',
'Status' => '상태',
'Stock' => '재고',
'Street' => '거리',
'Subgroup' => '하급 집단',
'Supplier' => '공급자',
'SupplierID' => '공급자 ID.',
'SupplierName' => '공급 업체 이름',
'Suppliers' => '공급자',
'Tax' => '세',
'Terms' => '자귀',
'To' => '에게',
'TopArticles' => '최고 기사',
'Trend' => '경향',
'Turnover' => '회전율',
'Type' => '유형',
'ZipCode' => '우편 번호',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Regnskap',
'Active' => 'Aktiv',
'Activity' => 'Aktivitet',
'Address' => 'Adresse',
'All' => 'Alle',
'Amount' => 'Beløp',
'Analysis' => 'Analyse',
'Area' => 'Område',
'Article' => 'Artikkel',
'Articles' => 'Artikler',
'Available' => 'Tilgjengelig',
'Calculate' => 'Regne ut',
'City' => 'By',
'Class' => 'Klasse',
'Confirmation' => 'Bekreftelse',
'CoreData' => 'Kjernedata',
'Country' => 'Land',
'Created' => 'Opprettet',
'Creator' => 'Skaperen.',
'CreditNote' => 'Kredittnota',
'DSO' => 'DSO',
'Date' => 'Dato',
'DefaultInternational' => 'Standard internasjonal',
'DefaultNational' => 'Standard nasjonal',
'Delivery' => 'Leveranse',
'DeliveryNote' => 'Leveringsnotat',
'Description' => 'Beskrivelse',
'Discount' => 'Rabatt',
'DiscountP' => 'Rabatt i%',
'Documentation' => 'Dokumentasjon',
'Employee' => 'Ansatt',
'FAO' => 'FAO.',
'From' => 'Fra',
'Group' => 'Gruppe',
'Groups' => 'Grupper',
'Highest' => 'Høyeste',
'Inactive' => 'Inaktiv',
'Interval' => 'Intervall',
'Invoice' => 'Faktura',
'Invoices' => 'Fakturaer',
'IsDefault' => 'Er standard?',
'Language' => 'Språk',
'Last' => 'Siste',
'Localization' => 'Lokalisering',
'Loginname' => 'Påloggingsnavn',
'Matchcode' => 'MatchCode.',
'Media' => 'Media',
'MinPrice' => 'Min pris',
'Name' => 'Navn',
'Name1' => 'Navn 1',
'Name2' => 'Navn 2.',
'Name3' => 'Navn 3.',
'Offer' => 'By på',
'Order' => 'Rekkefølge',
'Ordered' => 'Bestilt',
'OrderedBy' => 'Bestilt av.',
'OrderedDate' => 'Bestilt dato',
'Orders' => 'Bestillinger',
'Payment' => 'innbetaling',
'Price' => 'Pris',
'Priority' => 'Prioritet',
'Purchases' => 'Kjøp',
'Quantity' => 'Mengde',
'Receipt' => 'Kvittering',
'Reference' => 'Referanse',
'Sales' => 'Salg',
'Settings' => 'Innstillinger',
'Single' => 'Enkelt',
'State' => 'Stat',
'Statistics' => 'Statistikk',
'Status' => 'Status',
'Stock' => 'Lager',
'Street' => 'gate',
'Subgroup' => 'Undergruppe',
'Supplier' => 'Leverandør',
'SupplierID' => 'Leverandør ID.',
'SupplierName' => 'Leverandørnavn',
'Suppliers' => 'Leverandører',
'Tax' => 'Avgift',
'Terms' => 'Vilkårene',
'To' => 'Til',
'TopArticles' => 'Toppartikler',
'Trend' => 'Trend',
'Turnover' => 'Omsetning',
'Type' => 'Type',
'ZipCode' => 'Post kode',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Rachunek',
'Active' => 'Aktywny',
'Activity' => 'Czynność',
'Address' => 'Adres',
'All' => 'Wszystkie',
'Amount' => 'Kwota',
'Analysis' => 'Analiza',
'Area' => 'Powierzchnia',
'Article' => 'Artykuł',
'Articles' => 'Artykuły',
'Available' => 'Dostępny',
'Calculate' => 'Oblicz',
'City' => 'Miasto',
'Class' => 'Klasa',
'Confirmation' => 'Potwierdzenie',
'CoreData' => 'Podstawowe dane',
'Country' => 'Kraj',
'Created' => 'Utworzony',
'Creator' => 'Twórca',
'CreditNote' => 'Uwaga kredytowa',
'DSO' => 'DSO.',
'Date' => 'Data',
'DefaultInternational' => 'Domyślny międzynarodowy',
'DefaultNational' => 'Domyślny National.',
'Delivery' => 'Dostawa',
'DeliveryNote' => 'Dowód dostawy',
'Description' => 'Opis',
'Discount' => 'Zniżka',
'DiscountP' => 'Zniżka w%',
'Documentation' => 'Dokumentacja',
'Employee' => 'Pracownik',
'FAO' => 'Fao.',
'From' => 'Z',
'Group' => 'Grupa',
'Groups' => 'Grupy',
'Highest' => 'Najwyższy',
'Inactive' => 'Nieaktywny',
'Interval' => 'Interwał',
'Invoice' => 'Faktura',
'Invoices' => 'Faktury',
'IsDefault' => 'Jest domyślnie?',
'Language' => 'Język',
'Last' => 'Ostatni, ubiegły, zeszły',
'Localization' => 'Lokalizacja',
'Loginname' => 'Nazwa użytkownika',
'Matchcode' => 'MatchCode.',
'Media' => 'Głoska bezdźwięczna',
'MinPrice' => 'Cena min',
'Name' => 'Nazwa',
'Name1' => 'Nazwa 1.',
'Name2' => 'Nazwa 2.',
'Name3' => 'Nazwa 3.',
'Offer' => 'Oferta',
'Order' => 'Zamówienie',
'Ordered' => 'Uporządkowany',
'OrderedBy' => 'Zamówiony przez',
'OrderedDate' => 'Uporządkowana data',
'Orders' => 'Zamówienia',
'Payment' => 'Zapłata',
'Price' => 'Cena £',
'Priority' => 'Priorytet',
'Purchases' => 'Zakupy',
'Quantity' => 'Ilość',
'Receipt' => 'Paragon fiskalny',
'Reference' => 'Odniesienie',
'Sales' => 'Obroty',
'Settings' => 'Ustawienia',
'Single' => 'Pojedynczy',
'State' => 'Państwo',
'Statistics' => 'Statystyka',
'Status' => 'Status',
'Stock' => 'Magazyn',
'Street' => 'Ulica',
'Subgroup' => 'Podgrupa',
'Supplier' => 'Dostawca',
'SupplierID' => 'identyfikator dostawcy',
'SupplierName' => 'Nazwa Dostawcy',
'Suppliers' => 'Dostawcy',
'Tax' => 'Podatek',
'Terms' => 'Semestry',
'To' => 'Do',
'TopArticles' => 'Najlepsze artykuły',
'Trend' => 'Tendencja',
'Turnover' => 'Obrót',
'Type' => 'Rodzaj',
'ZipCode' => 'Kod pocztowy',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Conta',
'Active' => 'Ativo',
'Activity' => 'Atividade',
'Address' => 'Endereço',
'All' => 'Tudo',
'Amount' => 'Montante',
'Analysis' => 'Análise',
'Area' => 'Área',
'Article' => 'Artigo',
'Articles' => 'Artigos',
'Available' => 'Disponível',
'Calculate' => 'Calcular',
'City' => 'Cidade',
'Class' => 'Classe',
'Confirmation' => 'Confirmação',
'CoreData' => 'Dados principais',
'Country' => 'País',
'Created' => 'Criado',
'Creator' => 'O Criador',
'CreditNote' => 'Nota de crédito',
'DSO' => 'Dso.',
'Date' => 'Encontro',
'DefaultInternational' => 'Padrão Internacional',
'DefaultNational' => 'Nacional padrão',
'Delivery' => 'Entrega',
'DeliveryNote' => 'Nota de entrega',
'Description' => 'Descrição',
'Discount' => 'Desconto',
'DiscountP' => 'Desconto em%',
'Documentation' => 'Documentação',
'Employee' => 'Funcionário',
'FAO' => 'FAO.',
'From' => 'A partir de',
'Group' => 'Grupo',
'Groups' => 'Grupos',
'Highest' => 'Altíssima',
'Inactive' => 'Inativo',
'Interval' => 'Intervalo',
'Invoice' => 'Fatura',
'Invoices' => 'Faturas',
'IsDefault' => 'É padrão?',
'Language' => 'Língua',
'Last' => 'Durar',
'Localization' => 'Localização',
'Loginname' => 'Nome de acesso',
'Matchcode' => 'Código de combinação',
'Media' => 'meios de comunicação',
'MinPrice' => 'Preço mínimo',
'Name' => 'Nome',
'Name1' => 'Nome 1.',
'Name2' => 'Nome 2.',
'Name3' => 'Nome 3.',
'Offer' => 'Oferta',
'Order' => 'Pedido',
'Ordered' => 'Encomendado',
'OrderedBy' => 'Ordenado por',
'OrderedDate' => 'Data ordenada',
'Orders' => 'Pedidos',
'Payment' => 'Pagamento',
'Price' => 'Preço',
'Priority' => 'Prioridade',
'Purchases' => 'Compras',
'Quantity' => 'Quantidade',
'Receipt' => 'Recibo',
'Reference' => 'Referência',
'Sales' => 'Vendas',
'Settings' => 'Configurações',
'Single' => 'Solteiro',
'State' => 'Estado',
'Statistics' => 'Estatisticas',
'Status' => 'Status',
'Stock' => 'Estoque',
'Street' => 'rua',
'Subgroup' => 'Subgrupo',
'Supplier' => 'Fornecedor',
'SupplierID' => 'Identificação do Fornecedor',
'SupplierName' => 'Nome do Fornecedor',
'Suppliers' => 'Fornecedores',
'Tax' => 'Imposto',
'Terms' => 'Termos.',
'To' => 'Para',
'TopArticles' => 'Artigos de topo',
'Trend' => 'Tendência',
'Turnover' => 'Volume de negócios',
'Type' => 'Modelo',
'ZipCode' => 'CEP',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Счет',
'Active' => 'Активный',
'Activity' => 'Мероприятия',
'Address' => 'Адрес',
'All' => 'Все',
'Amount' => 'Количество',
'Analysis' => 'Анализ',
'Area' => 'Площадь',
'Article' => 'Статья',
'Articles' => 'Статьи',
'Available' => 'Доступный',
'Calculate' => 'Рассчитать',
'City' => 'Город',
'Class' => 'Класс',
'Confirmation' => 'Подтверждение',
'CoreData' => 'Основные данные',
'Country' => 'Страна',
'Created' => 'Созданный',
'Creator' => 'Создатель',
'CreditNote' => 'Кредитная нота',
'DSO' => 'DSO',
'Date' => 'Дата',
'DefaultInternational' => 'Default International',
'DefaultNational' => 'Национальный по умолчанию',
'Delivery' => 'Доставка',
'DeliveryNote' => 'Накладная',
'Description' => 'Описание',
'Discount' => 'Скидка',
'DiscountP' => 'Скидка в%',
'Documentation' => 'Документация',
'Employee' => 'Наемный рабочий',
'FAO' => 'ФАО',
'From' => 'От',
'Group' => 'Группа',
'Groups' => 'Группы',
'Highest' => 'Наибольший',
'Inactive' => 'Неактивный',
'Interval' => 'Интервал',
'Invoice' => 'Счет',
'Invoices' => 'Счета',
'IsDefault' => 'По умолчанию?',
'Language' => 'Язык',
'Last' => 'Последний',
'Localization' => 'Локализация',
'Loginname' => 'Логин',
'Matchcode' => 'MatchCode.',
'Media' => 'Средства массовой информации',
'MinPrice' => 'Мин цена',
'Name' => 'Имя',
'Name1' => 'Имя 1.',
'Name2' => 'Имя 2.',
'Name3' => 'Имя 3.',
'Offer' => 'Предложение',
'Order' => 'Заказ',
'Ordered' => 'Заказал',
'OrderedBy' => 'Заказан',
'OrderedDate' => 'Заказанная дата',
'Orders' => 'Заказывает',
'Payment' => 'Оплата',
'Price' => 'Цена',
'Priority' => 'Приоритет',
'Purchases' => 'Покупки',
'Quantity' => 'Количество',
'Receipt' => 'Квитанция',
'Reference' => 'Ссылка',
'Sales' => 'Продажи',
'Settings' => 'Настройки',
'Single' => 'Одинокий',
'State' => 'Состояние',
'Statistics' => 'Статистика',
'Status' => 'Статус',
'Stock' => 'Склад',
'Street' => 'улица',
'Subgroup' => 'Подгруппа',
'Supplier' => 'Поставщик',
'SupplierID' => 'ID поставщик',
'SupplierName' => 'наименование поставщика',
'Suppliers' => 'Поставщики',
'Tax' => 'Налог',
'Terms' => 'Условия',
'To' => 'К',
'TopArticles' => 'Лучшие статьи',
'Trend' => 'Тренд',
'Turnover' => 'Оборот',
'Type' => 'Тип',
'ZipCode' => 'Почтовый Индекс',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'konto',
'Active' => 'Aktiva',
'Activity' => 'Aktivitet',
'Address' => 'Adress',
'All' => 'Allt',
'Amount' => 'Belopp',
'Analysis' => 'Analys',
'Area' => 'Område',
'Article' => 'Artikel',
'Articles' => 'Artiklar',
'Available' => 'Tillgängligt',
'Calculate' => 'Beräkna',
'City' => 'Stad',
'Class' => 'Klass',
'Confirmation' => 'Bekräftelse',
'CoreData' => 'Kärndata',
'Country' => 'Land',
'Created' => 'Skapad',
'Creator' => 'Skapare',
'CreditNote' => 'Kreditanteckning',
'DSO' => 'Do',
'Date' => 'Datum',
'DefaultInternational' => 'Standard International',
'DefaultNational' => 'Standard nationell',
'Delivery' => 'Leverans',
'DeliveryNote' => 'Leveransanteckning',
'Description' => 'Beskrivning',
'Discount' => 'Rabatt',
'DiscountP' => 'Rabatt i%',
'Documentation' => 'Dokumentation',
'Employee' => 'Anställd',
'FAO' => 'Fao',
'From' => 'Från',
'Group' => 'Grupp',
'Groups' => 'Grupp',
'Highest' => 'Högsta',
'Inactive' => 'Inaktiv',
'Interval' => 'Intervall',
'Invoice' => 'Faktura',
'Invoices' => 'Fakturor',
'IsDefault' => 'Är standard?',
'Language' => 'Språk',
'Last' => 'Sista',
'Localization' => 'Lokalisering',
'Loginname' => 'Inloggningsnamn',
'Matchcode' => 'Matchcode',
'Media' => 'Media',
'MinPrice' => 'Min pris',
'Name' => 'namn',
'Name1' => 'Namn 1',
'Name2' => 'Namn 2',
'Name3' => 'Namn 3',
'Offer' => 'Erbjudande',
'Order' => 'Beställa',
'Ordered' => 'Beställde',
'OrderedBy' => 'Beställd av',
'OrderedDate' => 'Beställt datum',
'Orders' => 'Order',
'Payment' => 'Betalning',
'Price' => 'Pris',
'Priority' => 'Prioritet',
'Purchases' => 'Inköp',
'Quantity' => 'Kvantitet',
'Receipt' => 'Mottagande',
'Reference' => 'Referens',
'Sales' => 'Försäljning',
'Settings' => 'inställningar',
'Single' => 'Enda',
'State' => 'stat',
'Statistics' => 'Statistik',
'Status' => 'Status',
'Stock' => 'Stock',
'Street' => 'Gata',
'Subgroup' => 'Undergrupp',
'Supplier' => 'Leverantör',
'SupplierID' => 'Leverantörs-ID',
'SupplierName' => 'Leverantörsnamn',
'Suppliers' => 'Leverantörer',
'Tax' => 'Beskatta',
'Terms' => 'Villkor',
'To' => 'Till',
'TopArticles' => 'Toppartiklar',
'Trend' => 'Trend',
'Turnover' => 'Omsättning',
'Type' => 'Typ',
'ZipCode' => 'Postnummer',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'บัญชี',
'Active' => 'คล่องแคล่ว',
'Activity' => 'กิจกรรม',
'Address' => 'ที่อยู่',
'All' => 'ทั้งหมด',
'Amount' => 'จำนวน',
'Analysis' => 'การวิเคราะห์',
'Area' => 'พื้นที่',
'Article' => 'บทความ',
'Articles' => 'บทความ',
'Available' => 'มีอยู่',
'Calculate' => 'คำนวณ',
'City' => 'เมือง',
'Class' => 'ระดับ',
'Confirmation' => 'การยืนยัน',
'CoreData' => 'ข้อมูลหลัก',
'Country' => 'ประเทศ',
'Created' => 'สร้าง',
'Creator' => 'ผู้สร้าง',
'CreditNote' => 'ใบลดหนี้',
'DSO' => 'DSO',
'Date' => 'วันที่',
'DefaultInternational' => 'เริ่มต้นระหว่างประเทศ',
'DefaultNational' => 'เริ่มต้นชาติ',
'Delivery' => 'จัดส่ง',
'DeliveryNote' => 'บันทึกการส่งมอบ',
'Description' => 'คำอธิบาย',
'Discount' => 'การลดราคา',
'DiscountP' => 'ส่วนลดใน%',
'Documentation' => 'เอกสาร',
'Employee' => 'พนักงาน',
'FAO' => 'คน',
'From' => 'จาก',
'Group' => 'กลุ่ม',
'Groups' => 'กลุ่ม',
'Highest' => 'สูงที่สุด',
'Inactive' => 'ไม่ใช้งาน',
'Interval' => 'ช่วงเวลา',
'Invoice' => 'ใบแจ้งหนี้',
'Invoices' => 'ใบแจ้งหนี้',
'IsDefault' => 'เป็นค่าเริ่มต้น?',
'Language' => 'ภาษา',
'Last' => 'ล่าสุด',
'Localization' => 'การแปล',
'Loginname' => 'ชื่อเข้าสู่ระบบ',
'Matchcode' => 'การจับคู่',
'Media' => 'สื่อ',
'MinPrice' => 'นาทีราคา',
'Name' => 'ชื่อ',
'Name1' => 'ชื่อ 1',
'Name2' => 'ชื่อ 2',
'Name3' => 'ชื่อ 3',
'Offer' => 'เสนอ',
'Order' => 'คำสั่ง',
'Ordered' => 'ที่ได้รับคำสั่ง',
'OrderedBy' => 'ได้รับคำสั่งจาก',
'OrderedDate' => 'วันที่สั่งซื้อ',
'Orders' => 'คำสั่งซื้อ',
'Payment' => 'การชำระเงิน',
'Price' => 'ราคา',
'Priority' => 'ลำดับความสำคัญ',
'Purchases' => 'การซื้อ',
'Quantity' => 'ปริมาณ',
'Receipt' => 'ใบเสร็จ',
'Reference' => 'อ้างอิง',
'Sales' => 'ฝ่ายขาย',
'Settings' => 'การตั้งค่า',
'Single' => 'เดี่ยว',
'State' => 'สถานะ',
'Statistics' => 'สถิติ',
'Status' => 'สถานะ',
'Stock' => 'คลังสินค้า',
'Street' => 'ถนน',
'Subgroup' => 'กลุ่มย่อย',
'Supplier' => 'ผู้ผลิต',
'SupplierID' => 'ID ผู้จัดหา',
'SupplierName' => 'ชื่อผู้ผลิต',
'Suppliers' => 'ซัพพลายเออร์',
'Tax' => 'ภาษี',
'Terms' => 'เงื่อนไข',
'To' => 'ถึง',
'TopArticles' => 'บทความยอดนิยม',
'Trend' => 'แนวโน้ม',
'Turnover' => 'การหมุนเวียน',
'Type' => 'พิมพ์',
'ZipCode' => 'รหัสไปรษณีย์',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Hesap',
'Active' => 'Aktif',
'Activity' => 'Aktivite',
'Address' => 'Adres',
'All' => 'Herşey',
'Amount' => 'Miktar',
'Analysis' => 'Analiz',
'Area' => 'Alan',
'Article' => 'Madde',
'Articles' => 'Nesne',
'Available' => 'Mevcut',
'Calculate' => 'Hesaplamak',
'City' => 'Şehir',
'Class' => 'Sınıf',
'Confirmation' => 'Onayla',
'CoreData' => 'Temel veri',
'Country' => 'Ülke',
'Created' => 'Yaratılmış',
'Creator' => 'Yaratıcı',
'CreditNote' => 'Kredi notu',
'DSO' => 'Dso',
'Date' => 'Tarih',
'DefaultInternational' => 'Varsayılan Uluslararası',
'DefaultNational' => 'Varsayılan ulusal',
'Delivery' => 'Teslimat',
'DeliveryNote' => 'Teslimat notu',
'Description' => 'Açıklama',
'Discount' => 'İndirim',
'DiscountP' => '% İndirim',
'Documentation' => 'Belgeler',
'Employee' => 'Çalışan',
'FAO' => 'FAO',
'From' => 'İtibaren',
'Group' => 'Grup',
'Groups' => 'Gruplar',
'Highest' => 'En yüksek',
'Inactive' => 'Aktif olmayan',
'Interval' => 'Aralık',
'Invoice' => 'Fatura',
'Invoices' => 'Faturalar',
'IsDefault' => 'Varsayılan mı?',
'Language' => 'Dilim',
'Last' => 'Geçen',
'Localization' => 'Yerelleştirme',
'Loginname' => 'Kullanıcı adı',
'Matchcode' => 'Maç Kodu',
'Media' => 'Medya',
'MinPrice' => 'Minik fiyat',
'Name' => 'İsim',
'Name1' => 'İsim 1',
'Name2' => 'İsim 2',
'Name3' => 'ADI 3',
'Offer' => 'Teklif',
'Order' => 'Emir',
'Ordered' => 'Emir',
'OrderedBy' => 'Tarafından sipariş edildi',
'OrderedDate' => 'Sipariş edilen tarih',
'Orders' => 'Emirler',
'Payment' => 'Ödeme',
'Price' => 'Fiyat',
'Priority' => 'Öncelik',
'Purchases' => 'Alımlar',
'Quantity' => 'Miktar',
'Receipt' => 'Fiş',
'Reference' => 'Referans',
'Sales' => 'Satış',
'Settings' => 'Ayarlar',
'Single' => 'Bekar',
'State' => 'Belirtmek, bildirmek',
'Statistics' => 'İstatistik',
'Status' => 'Durum',
'Stock' => 'Stoklamak',
'Street' => 'sokak',
'Subgroup' => 'Alt grup',
'Supplier' => 'Tedarikçi',
'SupplierID' => 'tedarikçi kimliği',
'SupplierName' => 'sağlayıcı adı',
'Suppliers' => 'Tedarikçiler',
'Tax' => 'Vergi',
'Terms' => 'Terimler',
'To' => 'İle',
'TopArticles' => 'En iyi makaleler',
'Trend' => 'Akım',
'Turnover' => 'Devir',
'Type' => 'Tip',
'ZipCode' => 'Posta kodu',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => 'Обліковий запис',
'Active' => 'Активний',
'Activity' => 'Діяльність',
'Address' => 'Адреса',
'All' => 'Все',
'Amount' => 'Сума',
'Analysis' => 'Аналіз',
'Area' => 'Площа',
'Article' => 'Стаття',
'Articles' => 'Статті',
'Available' => 'Доступний',
'Calculate' => 'Розраховувати',
'City' => 'Місто',
'Class' => 'Клас',
'Confirmation' => 'Підтвердження',
'CoreData' => 'Основні дані',
'Country' => 'Країна',
'Created' => 'Створений',
'Creator' => 'Творець',
'CreditNote' => 'Кредитове авізо',
'DSO' => 'Дз',
'Date' => 'Дата',
'DefaultInternational' => 'Міжнародний за замовчуванням',
'DefaultNational' => 'Національний за замовчуванням',
'Delivery' => 'Доставка',
'DeliveryNote' => 'Накладна',
'Description' => 'Опис',
'Discount' => 'Знижка',
'DiscountP' => 'Знижка у%',
'Documentation' => 'Документація',
'Employee' => 'Співробітник',
'FAO' => 'Фах',
'From' => 'Від',
'Group' => 'Група',
'Groups' => 'Групи',
'Highest' => 'Найвищий',
'Inactive' => 'Неактивний',
'Interval' => 'Інтервал',
'Invoice' => 'Рахунок-фактура',
'Invoices' => 'Рахунки-фактури',
'IsDefault' => 'Чи є за замовчуванням?',
'Language' => 'Мову',
'Last' => 'Остання',
'Localization' => 'Локалізація',
'Loginname' => 'Логін',
'Matchcode' => 'Матч',
'Media' => 'Медіа',
'MinPrice' => 'Ціна',
'Name' => 'Назва',
'Name1' => 'Ім\'я 1',
'Name2' => 'Ім\'я 2',
'Name3' => 'Назва 3',
'Offer' => 'Пропозиція',
'Order' => 'Порядок',
'Ordered' => 'Упорядкований',
'OrderedBy' => 'Замовлений',
'OrderedDate' => 'Упорядкована дата',
'Orders' => 'Накази',
'Payment' => 'Платіж',
'Price' => 'Ціна',
'Priority' => 'Пріоритет',
'Purchases' => 'Покупок',
'Quantity' => 'Кількість',
'Receipt' => 'Квитанція',
'Reference' => 'Довідник',
'Sales' => 'Продаж',
'Settings' => 'Налаштування',
'Single' => 'Одиночний',
'State' => 'Держава',
'Statistics' => 'Статистика',
'Status' => 'Статус',
'Stock' => 'Запас',
'Street' => 'Вулиця',
'Subgroup' => 'Підгруп',
'Supplier' => 'Постачальник',
'SupplierID' => 'Ідентифікатор постачальника',
'SupplierName' => 'Ім\'я постачальника',
'Suppliers' => 'Постачальники',
'Tax' => 'Оподаткування',
'Terms' => 'Умови',
'To' => 'До',
'TopArticles' => 'Топці',
'Trend' => 'Тенденція',
'Turnover' => 'Оборот',
'Type' => 'Тип',
'ZipCode' => 'ЗІП код',
]];

View File

@ -13,90 +13,12 @@
declare(strict_types=1);
return ['Purchase' => [
'Account' => '帐户',
'Active' => '积极的',
'Activity' => '活动',
'Address' => '地址',
'All' => '全部',
'Amount' => '数量',
'Analysis' => '分析',
'Area' => '区域',
'Article' => '文章',
'Articles' => '文章',
'Available' => '可用的',
'Calculate' => '计算',
'City' => '城市',
'Class' => '班级',
'Confirmation' => '确认',
'CoreData' => '核心数据',
'Country' => '国家',
'Created' => '创造了',
'Creator' => '创造者',
'CreditNote' => '信用票据',
'DSO' => 'DSO',
'Date' => '日期',
'DefaultInternational' => '违约国际',
'DefaultNational' => '违约国家',
'Delivery' => '交货',
'DeliveryNote' => '送货单',
'Description' => '描述',
'Discount' => '折扣',
'DiscountP' => '折扣%%',
'Documentation' => '文件',
'Employee' => '员工',
'FAO' => '粮农组织',
'From' => '从',
'Group' => '团体',
'Groups' => '团体',
'Highest' => '最高',
'Inactive' => '不活跃',
'Interval' => '间隔',
'Invoice' => '发票',
'Invoices' => '发票',
'IsDefault' => '默认为默认情况下?',
'Language' => '语',
'Last' => '最后的',
'Localization' => '本土化',
'Loginname' => '登录名',
'Matchcode' => '匹配码',
'Media' => '媒体',
'MinPrice' => '最终价格',
'Name' => '名称',
'Name1' => '名称1',
'Name2' => '名称2',
'Name3' => '名称3.',
'Offer' => '提供',
'Order' => '命令',
'Ordered' => '订购',
'OrderedBy' => '订购',
'OrderedDate' => '订购日期',
'Orders' => '命令',
'Payment' => '支付',
'Price' => '价格',
'Priority' => '优先事项',
'Purchases' => '购买',
'Quantity' => '数量',
'Receipt' => '收据',
'Reference' => '参考',
'Sales' => '销售量',
'Settings' => '设置',
'Single' => '单身的',
'State' => '状态',
'Statistics' => '统计数据',
'Status' => '地位',
'Stock' => '库存',
'Street' => '街道',
'Subgroup' => '亚组',
'Supplier' => '供应商',
'SupplierID' => '供应商ID',
'SupplierName' => '供应商名称',
'Suppliers' => '供应商',
'Tax' => '税',
'Terms' => '条款',
'To' => '到',
'TopArticles' => '顶级文章',
'Trend' => '趋势',
'Turnover' => '周转',
'Type' => '类型',
'ZipCode' => '邮政编码',
]];

View File

@ -1,18 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();

View File

@ -1,18 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();

View File

@ -1,18 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();

View File

@ -1,18 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();

View File

@ -1,18 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();

View File

@ -1,18 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();

View File

@ -1,18 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();

View File

@ -1,19 +0,0 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();
?>

View File

@ -0,0 +1,94 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionOptimizationType;
use phpOMS\Uri\UriFactory;
$optimizationAlgorithms = OrderSuggestionOptimizationType::getConstants();
// @feature Allow to specify a supplier
// @feature Allow to specify a item segmentation. Ideally segment->section->sales_group->product_group
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();
?>
<div class="row">
<div class="col-xs-12 col-sm-6">
<div class="portlet">
<form id="orderSuggestionCreate" action="<?= UriFactory::build('{/api}purchase/order/suggestion'); ?>" method="put">
<div class="portlet-body">
<!--
<div class="form-group">
<label for="iOptimizationAlgorithm"><?= $this->getHtml('Algorithm'); ?></label>
<select id="iOptimizationAlgorithm" name="optimization">
<?php foreach ($optimizationAlgorithms as $alg) : ?>
<option value="<?= $alg; ?>"><?= $this->getHtml(':OptimizationAlgorithm-' . $alg); ?>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="portlet-separator"></div>
<div class="portlet-body">
<div class="form-group">
<label for="iSupplier"><?= $this->getHtml('Supplier'); ?></label>
<input id="iSupplier" name="supplier" type="text">
</div>
</div>
<div class="portlet-separator"></div>
<div class="portlet-body">
<div class="form-group">
<label for="iItemSegment"><?= $this->getHtml('Segment'); ?></label>
<input id="iItemSegment" name="item_segment" type="text">
</div>
<div class="form-group">
<label for="iItemSection"><?= $this->getHtml('Section'); ?></label>
<input id="iItemSection" name="item_section" type="text">
</div>
<div class="form-group">
<label for="iItemSalesGroup"><?= $this->getHtml('SalesGroup'); ?></label>
<input id="iItemSalesGroup" name="item_salesgroup" type="text">
</div>
<div class="form-group">
<label for="iItemProductGroup"><?= $this->getHtml('ProductGroup'); ?></label>
<input id="iItemProductGroup" name="item_productgroup" type="text">
</div>
</div>
<div class="portlet-separator"></div>
<div class="portlet-body">
<div class="form-group">
<label for="iMinRange"><?= $this->getHtml('MinRange'); ?></label>
<input id="iMinRange" name="minrange" type="text">
</div>
-->
<div class="form-group">
<label class="checkbox" for="iIrrelevantItems">
<input id="iIrrelevantItems" name="hide_irrelevant" type="checkbox" value="1" checked>
<span class="checkmark"></span>
<?= $this->getHtml('HideIrrelevant'); ?>
</label>
</div>
</div>
<div class="portlet-foot">
<input type="submit" value="<?= $this->getHtml('Analyze'); ?>">
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,133 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Purchase
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
use phpOMS\Uri\UriFactory;
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();
?>
<div class="row">
<div class="col-xs-12">
<div class="portlet">
<div class="portlet-head"><?= $this->getHtml('OrderSuggestions'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table id="suggestionList" class="default sticky">
<thead>
<tr>
<td><?= $this->getHtml('ID', '0', '0'); ?>
<label for="suggestionList-sort-1">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-1">
<i class="sort-asc g-icon">expand_less</i>
</label>
<label for="suggestionList-sort-2">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-2">
<i class="sort-desc g-icon">expand_more</i>
</label>
<label>
<i class="filter g-icon">filter_alt</i>
</label>
<td><?= $this->getHtml('Status'); ?>
<label for="suggestionList-sort-9">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-9">
<i class="sort-asc g-icon">expand_less</i>
</label>
<label for="suggestionList-sort-10">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-10">
<i class="sort-desc g-icon">expand_more</i>
</label>
<label>
<i class="filter g-icon">filter_alt</i>
</label>
<td><?= $this->getHtml('Created'); ?>
<label for="suggestionList-sort-5">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-5">
<i class="sort-asc g-icon">expand_less</i>
</label>
<label for="suggestionList-sort-6">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-6">
<i class="sort-desc g-icon">expand_more</i>
</label>
<label>
<i class="filter g-icon">filter_alt</i>
</label>
<td class="wf-100"><?= $this->getHtml('Creator'); ?>
<label for="suggestionList-sort-3">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-3">
<i class="sort-asc g-icon">expand_less</i>
</label>
<label for="suggestionList-sort-4">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-4">
<i class="sort-desc g-icon">expand_more</i>
</label>
<label>
<i class="filter g-icon">filter_alt</i>
</label>
<td><?= $this->getHtml('Costs'); ?>
<label for="suggestionList-sort-5">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-5">
<i class="sort-asc g-icon">expand_less</i>
</label>
<label for="suggestionList-sort-6">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-6">
<i class="sort-desc g-icon">expand_more</i>
</label>
<label>
<i class="filter g-icon">filter_alt</i>
</label>
<td class="wf-100"><?= $this->getHtml('Elements'); ?>
<label for="suggestionList-sort-7">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-7">
<i class="sort-asc g-icon">expand_less</i>
</label>
<label for="suggestionList-sort-8">
<input type="radio" name="suggestionList-sort" id="suggestionList-sort-8">
<i class="sort-desc g-icon">expand_more</i>
</label>
<label>
<i class="filter g-icon">filter_alt</i>
</label>
<tbody>
<?php $count = 0; foreach ($this->data['suggestions'] as $key => $value) :
++$count;
$url = UriFactory::build('{/base}/purchase/order/suggestion/view?{?}&id=' . $value->id);
?>
<tr data-href="<?= $url; ?>">
<td><a href="<?= $url; ?>"><?= $value->id; ?></a>
<td><a href="<?= $url; ?>"><?= $this->getHtml(':SuggestionStatus-' . $value->status); ?></a>
<td><a href="<?= $url; ?>"><?= $value->createdAt->format('Y-m-d'); ?></a>
<td><a class="content" href="<?= UriFactory::build('{/base}/profile/view?{?}&for=' . $value->createdBy->id); ?>">
<?= $this->printHtml($this->renderUserName(
'%3$s %2$s %1$s',
[
$value->createdBy->name1,
$value->createdBy->name2,
$value->createdBy->name3,
$value->createdBy->login ?? '',
])
); ?>
</a>
<td><a href="<?= $url; ?>"><?= $value->getTotalCosts()->getAmount(); ?></a>
<td><a href="<?= $url; ?>"><?= \count($value->elements); ?></a>
<?php endforeach; ?>
<?php if ($count === 0) : ?>
<tr><td colspan="12" class="empty"><?= $this->getHtml('Empty', '0', '0'); ?>
<?php endif; ?>
</table>
</div>
</div>
</div>
</div>

View File

@ -12,100 +12,57 @@
*/
declare(strict_types=1);
use Modules\Purchase\Models\OrderSuggestion\OrderSuggestionStatus;
use phpOMS\Stdlib\Base\FloatInt;
use phpOMS\Stdlib\Base\SmartDateTime;
use phpOMS\Uri\UriFactory;
/**
* @var \phpOMS\Views\View $this
*/
echo $this->data['nav']->render();
?>
<?php if ($this->data['suggestion']->status === OrderSuggestionStatus::DRAFT) : ?>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
<div class="col-xs-12 col-sm-7 col-md-5 col-lg-4">
<div class="portlet">
<div class="portlet-body">
<div class="form-group">
<label>Supplier</label>
<input type="text">
</div>
<div class="form-group">
<label>Product Group</label>
<input type="text">
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
<div class="portlet">
<div class="portlet-body">
<div class="form-group">
<label>Algorithm</label>
<select>
<option>Availability Optimization
<option>Cost Optimization
</select>
</div>
<div class="form-group">
<label>Min. range</label>
<input type="text">
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
<div class="portlet">
<div class="portlet-body">
<div class="form-group">
<label class="checkbox" for="iIrrelevantItems">
<input id="iIrrelevantItems" name="hide_irrelevant" type="checkbox" value="1" checked>
<span class="checkmark"></span>
Hide irrelevant
</label>
</div>
</div>
<div class="portlet-foot">
<!-- @todo Adjust button visibility -->
<!-- Save if not created ?> -->
<!-- Order if saved ?> -->
<!-- None if already order created -->
<input type="submit" value="Save">
<input type="submit" value="Order">
<input type="hidden" name="id" form="suggestionList" value="<?= $this->data['suggestion']->id; ?>">
<input name="save" type="submit" form="suggestionList" value="<?= $this->getHtml('Save', '0', '0'); ?>">
<!--<input name="order" type="submit" form="suggestionList" formaction="<?= UriFactory::build('{/api}purchase/order/suggestion/bill'); ?>" formmethod="put" value="<?= $this->getHtml('Order'); ?>">-->
<input name="delete" class="cancel" type="submit" form="suggestionList" formmethod="delete" value="<?= $this->getHtml('Delete', '0', '0'); ?>">
</div>
</div>
</div>
</div>
<?php endif; ?>
<div class="row">
<div class="col-xs-12">
<div class="portlet">
<div class="portlet-head">Suggestions<i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table id="billList" class="default sticky">
<div class="portlet-head"><?= $this->getHtml('Suggestions'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class=""><!-- @todo Re-implement slider once we figured out how to combine slider+sticky -->
<table id="suggestionList" class="default sticky" data-tag="form"
data-uri="<?= UriFactory::build('{/api}purchase/order/suggestion'); ?>" data-method="post"
data-redirect="<?= UriFactory::build('{/base}/purchase/order/suggestion/view?id=' . $this->data['suggestion']->id); ?>">
<thead>
<tr>
<td>Item
<td><?= $this->getHtml('Item'); ?>
<td class="wf-100">
<td>Supplier
<td>Stock
<td>Reserved
<td>Ordered
<td>Ø Sales
<td>Range 1
<td>Range 2
<td>Min. stock
<td>Min. order
<td>Steps
<td>Ordering
<td>Adding
<td>New range
<td>Price
<td>Costs
<td><?= $this->getHtml('Supplier'); ?>
<td><?= $this->getHtml('Stock'); ?>
<td><?= $this->getHtml('Reserved'); ?>
<td><?= $this->getHtml('Ordered'); ?>
<td><?= $this->getHtml('AvgConsumption'); ?>
<td><?= $this->getHtml('Range1'); ?>
<td><?= $this->getHtml('Range2'); ?>
<td><?= $this->getHtml('MinStock'); ?>
<td><?= $this->getHtml('MinOrder'); ?>
<td><?= $this->getHtml('Steps'); ?>
<td style="min-width: 75px;"><?= $this->getHtml('Ordering'); ?>
<td><?= $this->getHtml('NewRange'); ?>
<td><?= $this->getHtml('Price'); ?>
<td><?= $this->getHtml('Costs'); ?>
<tbody>
<?php
$now = new SmartDateTime('now');
@ -118,72 +75,72 @@ echo $this->data['nav']->render();
$isFirst = true;
foreach ($this->data['suggestions'] as $item => $suggestion) :
$isNew = $now->getTimestamp() - $suggestion['item']->createdAt->getTimestamp() < 60 * 60 * 24 * 60;
foreach ($this->data['suggestion']->elements as $element) :
$isNew = $now->getTimestamp() - $element->item->createdAt->getTimestamp() < 60 * 60 * 24 * 60;
// Skip irrelevant items
// No purchase suggestion
// Not new (new = item created in the last 60 days)
// At least 1 month in stock
// At least 20% above min. stock
if ($suggestion['quantity']->value === 0
&& !$isNew
&& ($suggestion['range_reserved'] > 1.0 || $suggestion['avgsales']->value === 0)
&& $suggestion['minquantity']->value * 1.2 <= $suggestion['range_reserved'] * $suggestion['avgsales']->value
) {
continue;
}
$total->add($suggestion['totalPrice']);
$subtotal->add($suggestion['totalPrice']);
$container = \reset($suggestion['item']->container);
$total->add($element->costs);
$container = \reset($element->item->container);
$class = '';
if ($suggestion['quantity']->value !== 0) {
$class = ' class="highlight-2"';
if ($element->quantity->value !== 0) {
$class = ' class="hl-2"';
}
?>
<?php
if (empty($supplier) && $lastSupplier !== $suggestion['supplier']->id && !$isFirst) :
if (empty($supplier) && $lastSupplier !== $element->supplier->id && !$isFirst) :
$hasSupplierSwitch = true;
$lastSupplier = $suggestion['supplier']->id;
$lastSupplier = $element->supplier->id;
?>
<tr class="highlight-7">
<td colspan="16"><?= $this->printHtml($suggestion['supplier']->account->name1); ?> <?= $this->printHtml($suggestion['supplier']->account->name2); ?>
<td><?= $total->getAmount(); ?>
<tr class="hl-7">
<td colspan="15"><?= $this->printHtml($element->supplier->account->name1); ?> <?= $this->printHtml($element->supplier->account->name2); ?>
<td><?= $subtotal->getAmount(); ?>
<?php
$subtotal = new FloatInt();
endif;
$subtotal->add($element->costs);
$isFirst = false;
?>
<tr>
<td><?= $this->printHtml($suggestion['item']->number); ?>
<td><?= $this->printHtml($suggestion['item']->getL11n('name1')->content); ?> <?= $this->printHtml($suggestion['item']->getL11n('name1')->content); ?>
<td><?= $this->printHtml($suggestion['supplier']->number); ?>
<td><?= $suggestion['stock']->getAmount($container->quantityDecimals); ?>
<td><?= $suggestion['reserved']->getAmount($container->quantityDecimals); ?>
<td><?= $suggestion['ordered']->getAmount($container->quantityDecimals); ?>
<td><?= $suggestion['avgsales']->getAmount(1); ?>
<td><?= $suggestion['range_stock'] === \PHP_INT_MAX ? '' : \number_format($suggestion['range_stock'], 1); ?>
<td><?= $suggestion['range_reserved'] === \PHP_INT_MAX ? '' : \number_format($suggestion['range_reserved'], 1); ?>
<td><?= $suggestion['minstock']->getAmount($container->quantityDecimals); ?>
<td><?= $suggestion['minquantity']->getAmount($container->quantityDecimals); ?>
<td><?= $suggestion['quantitystep']->getAmount($container->quantityDecimals); ?>
<td<?= $class; ?>><input step="<?= $suggestion['quantitystep']->getAmount($container->quantityDecimals); ?>" type="number" value="<?= $suggestion['quantity']->getFloat($container->quantityDecimals); ?>">
<td><?= \number_format($suggestion['range_ordered'], 1); ?>
<td><?= $suggestion['range_reserved'] === \PHP_INT_MAX ? '' : $now->createModify(0, (int) \ceil($suggestion['range_ordered'] + $suggestion['range_reserved']))->format('Y-m-d') ?>
<td><?= $suggestion['singlePrice']->getAmount(); ?>
<td><?= $suggestion['totalPrice']->getAmount(); ?>
<tr data-name="element" data-value="<?= $element->id; ?>">
<td><?= $this->printHtml($element->item->number); ?>
<td><?= $this->printHtml($element->item->getL11n('name1')->content); ?> <?= $this->printHtml($element->item->getL11n('name2')->content); ?>
<td><?= $this->printHtml($element->supplier->number); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['stock']->getAmount($container->quantityDecimals); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['reserved']->getAmount($container->quantityDecimals); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['ordered']->getAmount($container->quantityDecimals); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['avgsales']->getAmount(1); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['range_stock'] === \PHP_INT_MAX ? '' : \number_format($this->data['suggestion_data'][$element->item->id]['range_stock'], 1); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['range_reserved'] === \PHP_INT_MAX ? '' : \number_format($this->data['suggestion_data'][$element->item->id]['range_reserved'], 1); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['minstock']->getAmount($container->quantityDecimals); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['minquantity']->getAmount($container->quantityDecimals); ?>
<td><?= $this->data['suggestion_data'][$element->item->id]['quantitystep']->getAmount($container->quantityDecimals); ?>
<td<?= $class; ?>><input name="quantity"
step="<?= $this->data['suggestion_data'][$element->item->id]['quantitystep']->getAmount($container->quantityDecimals); ?>"
type="number"
value="<?= $element->quantity->getFloat($container->quantityDecimals); ?>">
<td><?= $this->data['suggestion_data'][$element->item->id]['range_reserved'] === \PHP_INT_MAX
? ''
: $now->createModify(
0,
(int) ($months = ($this->data['suggestion_data'][$element->item->id]['range_ordered']
+ $this->data['suggestion_data'][$element->item->id]['range_reserved'])),
(int) (($months - ((int) $months)) * 30))
->format('Y-m-d')
?>
<td><?= $this->data['suggestion_data'][$element->item->id]['singlePrice']->getAmount(); ?>
<td><?= $element->costs->getAmount(); ?>
<?php endforeach; ?>
<?php if ($hasSupplierSwitch) : ?>
<tr class="highlight-7">
<td colspan="16"><?= $this->printHtml($suggestion['supplier']->account->name1); ?> <?= $this->printHtml($suggestion['supplier']->account->name2); ?>
<?php if (empty($supplier)) : ?>
<tr class="hl-7">
<td colspan="15"><?= $this->printHtml($element->supplier->account->name1); ?> <?= $this->printHtml($element->supplier->account->name2); ?>
<td><?= $subtotal->getAmount(); ?>
<?php endif; ?>
<?php
$subtotal = new FloatInt();
endif;
?>
<tfoot>
<tr class="highlight-3">
<td colspan="16">Total
<tr class="hl-3">
<td colspan="15"><?= $this->getHtml('Total'); ?>
<td><?= $total->getAmount(); ?>
</table>
</div>
@ -193,8 +150,8 @@ echo $this->data['nav']->render();
<div class="row">
<div class="col-xs-12 col-sm-4 col-md-3 col-lg-2">
<div class="portlet highlight-2">
<div class="portlet-body">Ordering</div>
<div class="portlet hl-2">
<div class="portlet-body"><?= $this->getHtml('Ordering'); ?></div>
</div>
</div>
</div>