Merge branch 'develop'

This commit is contained in:
Dennis Eichhorn 2024-03-15 22:52:08 +00:00
commit fc2398fb39
69 changed files with 1282 additions and 1137 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

@ -1,40 +0,0 @@
---
name: User 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
# Expected Behavior
A clear and concise description of what you expected to happen.
# Screenshots
If applicable, add screenshots to help explain your problem.
# System Information
- System: [e.g. PC or iPhone11, ...]
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- KarakaVersion [e.g. 22]
# Additional Information
Add any other context about the problem here.

View File

@ -1,21 +0,0 @@
---
name: User 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

@ -0,0 +1,43 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\WarehouseManagement\Admin\Install
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\Admin\Install;
use phpOMS\Application\ApplicationAbstract;
/**
* ClientManagement class.
*
* @package Modules\WarehouseManagement\Admin\Install
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class ClientManagement
{
/**
* Install navigation providing
*
* @param ApplicationAbstract $app Application
* @param string $path Module path
*
* @return void
*
* @since 1.0.0
*/
public static function install(ApplicationAbstract $app, string $path) : void
{
\Modules\WarehouseManagement\Admin\Installer::personalStock($app, 'client');
}
}

View File

@ -7,7 +7,7 @@
"name": "Warehousing",
"uri": null,
"target": "self",
"icon": "fa fa-cube",
"icon": "deployed_code",
"order": 50,
"from": "WarehouseManagement",
"permission": { "permission": 2, "category": null, "element": null },
@ -19,7 +19,7 @@
"type": 2,
"subtype": 1,
"name": "Stock",
"uri": "{/base}/warehouse/stock/list",
"uri": "{/base}/warehouse/stock/list?{?}",
"target": "self",
"icon": null,
"order": 1,
@ -33,7 +33,7 @@
"type": 3,
"subtype": 1,
"name": "Stocks",
"uri": "{/base}/warehouse/stock/list",
"uri": "{/base}/warehouse/stock/list?{?}",
"target": "self",
"icon": null,
"order": 1,
@ -48,7 +48,7 @@
"type": 3,
"subtype": 1,
"name": "Locations",
"uri": "{/base}/warehouse/stock/location/list",
"uri": "{/base}/warehouse/stock/location/list?{?}",
"target": "self",
"icon": null,
"order": 5,
@ -63,7 +63,7 @@
"type": 3,
"subtype": 1,
"name": "Types",
"uri": "{/base}/warehouse/stock/type/list",
"uri": "{/base}/warehouse/stock/type/list?{?}",
"target": "self",
"icon": null,
"order": 10,

View File

@ -0,0 +1,43 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\WarehouseManagement\Admin\Install
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\Admin\Install;
use phpOMS\Application\ApplicationAbstract;
/**
* SupplierManagement class.
*
* @package Modules\WarehouseManagement\Admin\Install
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class SupplierManagement
{
/**
* Install navigation providing
*
* @param ApplicationAbstract $app Application
* @param string $path Module path
*
* @return void
*
* @since 1.0.0
*/
public static function install(ApplicationAbstract $app, string $path) : void
{
\Modules\WarehouseManagement\Admin\Installer::personalStock($app, 'supplier');
}
}

View File

@ -1,43 +1,4 @@
{
"warehousemgmt_item": {
"name": "warehousemgmt_item",
"fields": {
"warehousemgmt_item_id": {
"name": "warehousemgmt_item_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"warehousemgmt_item_item": {
"name": "warehousemgmt_item_item",
"type": "INT",
"null": false,
"foreignTable": "itemmgmt_item",
"foreignKey": "itemmgmt_item_id"
},
"warehousemgmt_item_hassn": {
"name": "warehousemgmt_item_hassn",
"type": "TINYINT(1)",
"null": false
},
"warehousemgmt_item_haslot": {
"name": "warehousemgmt_item_haslot",
"type": "TINYINT(1)",
"null": false
},
"warehousemgmt_item_hasstock": {
"name": "warehousemgmt_item_hasstock",
"type": "TINYINT(1)",
"null": false
},
"warehousemgmt_item_negative": {
"name": "warehousemgmt_item_negative",
"type": "TINYINT",
"null": false
}
}
},
"warehousemgmt_stock": {
"name": "warehousemgmt_stock",
"fields": {
@ -53,6 +14,11 @@
"type": "VARCHAR(255)",
"null": false
},
"warehousemgmt_stock_inventory": {
"name": "warehousemgmt_stock_inventory",
"type": "TINYINT(1)",
"null": false
},
"warehousemgmt_stock_unit": {
"name": "warehousemgmt_stock_unit",
"type": "INT",
@ -60,6 +26,20 @@
"foreignTable": "itemmgmt_item",
"foreignKey": "itemmgmt_item_id"
},
"warehousemgmt_stock_client": {
"name": "warehousemgmt_stock_client",
"type": "INT",
"null": false,
"foreignTable": "clientmgmt_client",
"foreignKey": "clientmgmt_client_id"
},
"warehousemgmt_stock_supplier": {
"name": "warehousemgmt_stock_supplier",
"type": "INT",
"null": false,
"foreignTable": "suppliermgmt_supplier",
"foreignKey": "suppliermgmt_supplier_id"
},
"warehousemgmt_stock_address": {
"name": "warehousemgmt_stock_address",
"type": "INT",
@ -307,6 +287,16 @@
"type": "TINYINT(1)",
"null": false
},
"warehousemgmt_attr_type_repeatable": {
"name": "warehousemgmt_attr_type_repeatable",
"type": "TINYINT(1)",
"null": false
},
"warehousemgmt_attr_type_internal": {
"name": "warehousemgmt_attr_type_internal",
"type": "TINYINT(1)",
"null": false
},
"warehousemgmt_attr_type_required": {
"description": "Every item must have this attribute type if set to true.",
"name": "warehousemgmt_attr_type_required",
@ -551,16 +541,17 @@
"warehousemgmt_stock_distribution_lot": {
"name": "warehousemgmt_stock_distribution_lot",
"type": "INT",
"null": false,
"null": true,
"default": null,
"foreignTable": "warehousemgmt_lot",
"foreignKey": "warehousemgmt_lot_id"
},
"warehousemgmt_stock_distribution_shelf": {
"name": "warehousemgmt_stock_distribution_shelf",
"warehousemgmt_stock_distribution_stock": {
"name": "warehousemgmt_stock_distribution_stock",
"type": "INT",
"null": false,
"foreignTable": "warehousemgmt_stockshelf",
"foreignKey": "warehousemgmt_stockshelf_id"
"foreignTable": "warehousemgmt_stock",
"foreignKey": "warehousemgmt_stock_id"
},
"warehousemgmt_stock_distribution_stocktype": {
"name": "warehousemgmt_stock_distribution_stocktype",
@ -606,12 +597,12 @@
"foreignTable": "warehousemgmt_lot",
"foreignKey": "warehousemgmt_lot_id"
},
"warehousemgmt_stock_distribution_history_shelf": {
"name": "warehousemgmt_stock_distribution_history_shelf",
"warehousemgmt_stock_distribution_history_stock": {
"name": "warehousemgmt_stock_distribution_history_stock",
"type": "INT",
"null": false,
"foreignTable": "warehousemgmt_stockshelf",
"foreignKey": "warehousemgmt_stockshelf_id"
"foreignTable": "warehousemgmt_stock",
"foreignKey": "warehousemgmt_stock_id"
},
"warehousemgmt_stock_distribution_history_stocktype": {
"name": "warehousemgmt_stock_distribution_history_stocktype",
@ -653,11 +644,6 @@
"type": "BIGINT",
"null": false
},
"warehousemgmt_stock_transaction_pprice": {
"name": "warehousemgmt_stock_transaction_pprice",
"type": "BIGINT",
"null": false
},
"warehousemgmt_stock_transaction_type": {
"name": "warehousemgmt_stock_transaction_type",
"type": "INT",
@ -673,42 +659,48 @@
"warehousemgmt_stock_transaction_from_lot": {
"name": "warehousemgmt_stock_transaction_from_lot",
"type": "INT",
"null": false,
"null": true,
"default": null,
"foreignTable": "warehousemgmt_lot",
"foreignKey": "warehousemgmt_lot_id"
},
"warehousemgmt_stock_transaction_from_shelf": {
"name": "warehousemgmt_stock_transaction_from_shelf",
"warehousemgmt_stock_transaction_from_stock": {
"name": "warehousemgmt_stock_transaction_from_stock",
"type": "INT",
"null": false,
"foreignTable": "warehousemgmt_stockshelf",
"foreignKey": "warehousemgmt_stockshelf_id"
"null": true,
"default": null,
"foreignTable": "warehousemgmt_stock",
"foreignKey": "warehousemgmt_stock_id"
},
"warehousemgmt_stock_transaction_from_stocktype": {
"name": "warehousemgmt_stock_transaction_from_stocktype",
"type": "INT",
"null": false,
"null": true,
"default": null,
"foreignTable": "warehousemgmt_stock_type",
"foreignKey": "warehousemgmt_stock_type_id"
},
"warehousemgmt_stock_transaction_to_lot": {
"name": "warehousemgmt_stock_transaction_to_lot",
"type": "INT",
"null": false,
"null": true,
"default": null,
"foreignTable": "warehousemgmt_lot",
"foreignKey": "warehousemgmt_lot_id"
},
"warehousemgmt_stock_transaction_to_shelf": {
"name": "warehousemgmt_stock_transaction_to_shelf",
"warehousemgmt_stock_transaction_to_stock": {
"name": "warehousemgmt_stock_transaction_to_stock",
"type": "INT",
"null": false,
"foreignTable": "warehousemgmt_stockshelf",
"foreignKey": "warehousemgmt_stockshelf_id"
"null": true,
"default": null,
"foreignTable": "warehousemgmt_stock",
"foreignKey": "warehousemgmt_stock_id"
},
"warehousemgmt_stock_transaction_to_stocktype": {
"name": "warehousemgmt_stock_transaction_to_stocktype",
"type": "INT",
"null": false,
"null": true,
"default": null,
"foreignTable": "warehousemgmt_stock_type",
"foreignKey": "warehousemgmt_stock_type_id"
},

View File

@ -14,17 +14,12 @@ declare(strict_types=1);
namespace Modules\WarehouseManagement\Admin;
use Modules\WarehouseManagement\Models\Stock;
use Modules\WarehouseManagement\Models\StockLocation;
use Modules\WarehouseManagement\Models\StockLocationMapper;
use Modules\WarehouseManagement\Models\StockMapper;
use phpOMS\Application\ApplicationAbstract;
use phpOMS\Config\SettingsInterface;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\HttpResponse;
use phpOMS\Module\InstallerAbstract;
use phpOMS\Module\ModuleInfo;
use phpOMS\Uri\HttpUri;
/**
* Installer class.
@ -51,7 +46,7 @@ final class Installer extends InstallerAbstract
{
parent::install($app, $info, $cfgHandler);
self::createDefaultStock();
self::createDefaultStock($app);
/* Stock types */
$fileContent = \file_get_contents(__DIR__ . '/Install/types.json');
@ -75,15 +70,19 @@ final class Installer extends InstallerAbstract
*
* @since 1.0.0
*/
private static function createDefaultStock() : void
private static function createDefaultStock(ApplicationAbstract $app) : void
{
$stock = new Stock('Default');
$stock->unit = 1;
StockMapper::create()->execute($stock);
/** @var \Modules\WarehouseManagement\Controller\ApiController $module */
$module = $app->moduleManager->get('WarehouseManagement', 'Api');
$stockLocation = new StockLocation((string) ($stock->id . '-1'));
$stockLocation->stock = $stock;
StockLocationMapper::create()->execute($stockLocation);
$response = new HttpResponse();
$request = new HttpRequest();
$request->header->account = 1;
$request->setData('name', 'Default');
$request->setData('unit', 1);
$request->setData('inventory', true);
$module->apiStockCreate($request, $response);
}
/**
@ -101,14 +100,11 @@ final class Installer extends InstallerAbstract
$stockTypes = [];
/** @var \Modules\WarehouseManagement\Controller\ApiStockTypeController $module */
$module = $app->moduleManager->getModuleInstance('WarehouseManagement', 'ApiStockType');
// @todo: allow multiple alternative stock templates
// @todo: implement ordering of templates
$module = $app->moduleManager->get('WarehouseManagement', 'ApiStockType');
foreach ($types as $type) {
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request = new HttpRequest();
$request->header->account = 1;
$request->setData('name', $type['name'] ?? '');
@ -136,7 +132,7 @@ final class Installer extends InstallerAbstract
}
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request = new HttpRequest();
$request->header->account = 1;
$request->setData('title', $l11n);
@ -149,4 +145,35 @@ final class Installer extends InstallerAbstract
return $stockTypes;
}
/**
* Import accounts
*
* @param ApplicationAbstract $app Application
* @param string $type Personal account type
*
* @return void
*
* @since 1.0.0
*/
public static function personalStock(ApplicationAbstract $app, string $type) : void
{
/** @var \Modules\WarehouseManagement\Controller\ApiController $module */
$module = $app->moduleManager->get('WarehouseManagement', 'Api');
$mapper = $type === 'client'
? \Modules\ClientManagement\Models\ClientMapper::class
: \Modules\SupplierManagement\Models\SupplierMapper::class;
/** @var \Modules\ClientManagement\Models\Client|\Modules\SupplierManagement\Models\Supplier $person */
foreach ($mapper::yield()->executeYield() as $person) {
$response = new HttpResponse();
$request = new HttpRequest();
$request->header->account = 1;
$request->setData('name', $person->number);
$request->setData($type, $person->id);
$module->apiStockCreate($request, $response);
}
}
}

View File

@ -18,7 +18,7 @@ use phpOMS\Account\PermissionType;
use phpOMS\Router\RouteVerb;
return [
'^.*/warehouse/stock/list.*$' => [
'^.*/warehouse/stock/list(\?.*$|$)' => [
[
'dest' => '\Modules\WarehouseManagement\Controller\BackendController:viewStockList',
'verb' => RouteVerb::GET,
@ -40,7 +40,7 @@ return [
],
],
],
'^.*/warehouse/stock/type/list.*$' => [
'^.*/warehouse/stock/type/list(\?.*$|$)' => [
[
'dest' => '\Modules\WarehouseManagement\Controller\BackendController:viewStockTypeList',
'verb' => RouteVerb::GET,
@ -62,7 +62,7 @@ return [
],
],
],
'^.*/warehouse/stock/location/list.*$' => [
'^.*/warehouse/stock/location/list(\?.*$|$)' => [
[
'dest' => '\Modules\WarehouseManagement\Controller\BackendController:viewStockLocationList',
'verb' => RouteVerb::GET,

View File

@ -17,6 +17,7 @@ namespace Modules\WarehouseManagement\Controller;
use Modules\Attribute\Models\Attribute;
use Modules\Attribute\Models\AttributeType;
use Modules\Attribute\Models\AttributeValue;
use Modules\Attribute\Models\AttributeValueType;
use Modules\Attribute\Models\NullAttributeType;
use Modules\Attribute\Models\NullAttributeValue;
use Modules\WarehouseManagement\Models\Attribute\LotAttributeMapper;
@ -156,12 +157,10 @@ final class ApiAttributeController extends Controller
*/
private function createLotAttributeTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n
{
$attrL11n = new BaseStringL11n();
$attrL11n->ref = $request->getDataInt('type') ?? 0;
$attrL11n->setLanguage(
$request->getDataString('language') ?? $request->header->l11n->language
);
$attrL11n->content = $request->getDataString('title') ?? '';
$attrL11n = new BaseStringL11n();
$attrL11n->ref = $request->getDataInt('type') ?? 0;
$attrL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language;
$attrL11n->content = $request->getDataString('title') ?? '';
return $attrL11n;
}
@ -226,11 +225,14 @@ final class ApiAttributeController extends Controller
private function createLotAttributeTypeFromRequest(RequestAbstract $request) : AttributeType
{
$attrType = new AttributeType($request->getDataString('name') ?? '');
$attrType->datatype = $request->getDataInt('datatype') ?? 0;
$attrType->datatype = AttributeValueType::tryFromValue($request->getDataInt('datatype')) ?? AttributeValueType::_STRING;
$attrType->custom = $request->getDataBool('custom') ?? false;
$attrType->isRequired = $request->getDataBool('is_required') ?? false;
$attrType->validationPattern = $request->getDataString('validation_pattern') ?? '';
$attrType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN);
$attrType->setL11n(
$request->getDataString('title') ?? '',
ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? ISO639x1Enum::_EN
);
$attrType->setFields($request->getDataInt('fields') ?? 0);
return $attrType;
@ -315,7 +317,10 @@ final class ApiAttributeController extends Controller
$attrValue->setValue($request->getDataString('value'), $type->datatype);
if ($request->hasData('title')) {
$attrValue->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN);
$attrValue->setL11n(
$request->getDataString('title') ?? '',
ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? ISO639x1Enum::_EN
);
}
return $attrValue;
@ -380,12 +385,10 @@ final class ApiAttributeController extends Controller
*/
private function createLotAttributeValueL11nFromRequest(RequestAbstract $request) : BaseStringL11n
{
$attrL11n = new BaseStringL11n();
$attrL11n->ref = $request->getDataInt('value') ?? 0;
$attrL11n->setLanguage(
$request->getDataString('language') ?? $request->header->l11n->language
);
$attrL11n->content = $request->getDataString('title') ?? '';
$attrL11n = new BaseStringL11n();
$attrL11n->ref = $request->getDataInt('value') ?? 0;
$attrL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language;
$attrL11n->content = $request->getDataString('title') ?? '';
return $attrL11n;
}

View File

@ -18,16 +18,24 @@ use Modules\Billing\Models\BillElement;
use Modules\Billing\Models\BillMapper;
use Modules\Billing\Models\BillStatus;
use Modules\Billing\Models\BillTransferType;
use Modules\ClientManagement\Models\NullClient;
use Modules\ItemManagement\Models\StockIdentifierType;
use Modules\SupplierManagement\Models\NullSupplier;
use Modules\WarehouseManagement\Models\Stock;
use Modules\WarehouseManagement\Models\StockDistribution;
use Modules\WarehouseManagement\Models\StockDistributionMapper;
use Modules\WarehouseManagement\Models\StockLocation;
use Modules\WarehouseManagement\Models\StockLocationMapper;
use Modules\WarehouseManagement\Models\StockMapper;
use Modules\WarehouseManagement\Models\StockMovement;
use Modules\WarehouseManagement\Models\StockMovementMapper;
use Modules\WarehouseManagement\Models\StockMovementState;
use Modules\WarehouseManagement\Models\StockMovementType;
use Modules\WarehouseManagement\Models\StockShelf;
use Modules\WarehouseManagement\Models\StockShelfMapper;
use Modules\WarehouseManagement\Models\StockTransaction;
use Modules\WarehouseManagement\Models\StockTransactionMapper;
use Modules\WarehouseManagement\Models\StockTransactionState;
use Modules\WarehouseManagement\Models\StockTransactionType;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
/**
* WarehouseManagement api controller class.
@ -39,6 +47,148 @@ use Modules\WarehouseManagement\Models\StockShelfMapper;
*/
final class ApiController extends Controller
{
/**
* Api method to create stock
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiStockCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateStockCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
$stock = $this->createStockFromRequest($request);
$this->createModel($request->header->account, $stock, StockMapper::class, 'stock', $request->getOrigin());
$request->setData('name', $request->getDataString('name') . '-1', true);
$request->setData('stock', $stock->id, true);
$stock = $this->createStockLocationFromRequest($request);
$this->createModel($request->header->account, $stock, StockLocationMapper::class, 'stocklocation', $request->getOrigin());
$this->createStandardCreateResponse($request, $response, $stock);
}
/**
* Validate stock create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateStockCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['name'] = !$request->hasData('name'))
) {
return $val;
}
return [];
}
/**
* Method to create stock from request.
*
* @param RequestAbstract $request Request
*
* @return Stock
*
* @since 1.0.0
*/
private function createStockFromRequest(RequestAbstract $request) : Stock
{
$stock = new Stock();
$stock->name = $request->getDataString('name') ?? '';
$stock->unit = $request->getDataInt('unit') ?? 1;
$stock->inventory = $request->getDataBool('inventory') ?? false;
$stock->client = $request->hasData('client') ? new NullClient((int) $request->getData('client')) : null;
$stock->supplier = $request->hasData('supplier') ? new NullSupplier((int) $request->getData('supplier')) : null;
return $stock;
}
/**
* Api method to create stock
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param array $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiStockLocationCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (!empty($val = $this->validateStockLocationCreate($request))) {
$response->header->status = RequestStatusCode::R_400;
$this->createInvalidCreateResponse($request, $response, $val);
return;
}
$stock = $this->createStockLocationFromRequest($request);
$this->createModel($request->header->account, $stock, StockLocationMapper::class, 'stocklocation', $request->getOrigin());
$this->createStandardCreateResponse($request, $response, $stock);
}
/**
* Validate stock create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateStockLocationCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['name'] = !$request->hasData('name'))
|| ($val['stock'] = !$request->hasData('stock'))
) {
return $val;
}
return [];
}
/**
* Method to create stock from request.
*
* @param RequestAbstract $request Request
*
* @return StockLocation
*
* @since 1.0.0
*/
private function createStockLocationFromRequest(RequestAbstract $request) : StockLocation
{
$location = new StockLocation();
$location->name = $request->getDataString('name') ?? '';
$location->stock = $request->getDataInt('stock') ?? 1;
return $location;
}
/**
* Event after creating a stock
*
@ -60,12 +210,12 @@ final class ApiController extends Controller
int $account,
mixed $old,
mixed $new,
int $type = null,
?int $type = null,
string $trigger = '',
string $module = null,
string $ref = null,
string $content = null,
string $ip = null
?string $module = null,
?string $ref = null,
?string $content = null,
?string $ip = null
) : void
{
/** @var \Modules\ClientManagement\Models\Client|\Modules\SupplierManagement\Models\Supplier $new */
@ -97,195 +247,260 @@ final class ApiController extends Controller
* @return void
*
* @since 1.0.0
*
* @todo Cleanup/restructure so this function works with database transactions and exceptions. This function is very critical!
* Maybe do the transaction outside wherever the updateModel/createModel/... functions are called.
*/
public function eventBillUpdateInternal(
int $account,
mixed $old,
mixed $new,
int $type = null,
?int $type = null,
string $trigger = '',
string $module = null,
string $ref = null,
string $content = null,
string $ip = null
?string $module = null,
?string $ref = null,
?string $content = null,
?string $ip = null
) : void
{
// Directly/manually creating a transaction is handled in the API Create/Update functions.
$isBillElement = $new instanceof BillElement;
/** @var \Modules\Billing\Models\Bill|\Modules\Billing\Models\BillElement $new */
/** @var \Modules\Billing\Models\Bill $bill */
$bill = BillMapper::get()
->with('type')
->with('elements')
->with('elements/container')
->with('elements/item')
->with('supplier')
->with('client')
->where('id', $new instanceof BillElement ? $new->bill->id : $new->id)
->where('id', $isBillElement ? $new->bill->id : $new->id)
->where('type/transferStock', true)
->execute();
// Has stock movement?
if ($bill->id !== 0 && !$bill->type->transferStock) {
if ($bill->id === 0 || !$bill->type->transferStock) {
return;
}
// @todo: check if old element existed -> removed/changed item
// @todo: we cannot have transaction->to and transaction->from be the id of client/supplier because the IDs can overlap
/*
Only necessary if actual client/supplier stock
$externalStock = 1;
if ($bill->client !== null) {
$externalStock = StockMapper::get()
->where('client', $bill->client->id)
->limit(1)
->execute();
} elseif ($bill->supplier !== null) {
$externalStock = StockMapper::get()
->where('supplier', $bill->supplier->id)
->limit(1)
->execute();
}
*/
$transaction = new StockMovement();
// @todo check if old element existed -> removed/changed item
// @todo we cannot have transaction->to and transaction->from be the id of client/supplier because the IDs can overlap
if ($trigger === 'POST:Module:Billing-bill_element-create') {
/** @var \Modules\Billing\Models\BillElement $new */
$transaction->billElement = $new->id;
$transaction->state = StockMovementState::DRAFT;
// @todo: load default stock movement for bill type/organization settings (default stock location, default lot order e.g. FIFO/LIFO)
// @todo: find stock candidates
$transaction->type = StockMovementType::TRANSFER; // @todo: depends on bill type
$transaction->quantity = $new->getQuantity(); // @todo may require split quantity if not sufficient available from one lost
// @todo: allow consignment bills
// @todo: allow to pass stocklocation for entire bill to avoid re-defining it
// @todo: allow custom stock location
if ($bill->type->sign > 0) {
// Handle from
// @todo: find possible candidate based on defined default stock for bill type/org/location
// Handle to
if (($bill->client?->id ?? 0) !== 0) {
// @todo: remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->to = $bill->client->id;
} elseif (($bill->supplier?->id ?? 0) !== 0) {
// @todo: remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->to = $bill->supplier->id;
}
if ($bill->type->transferType === BillTransferType::SALES) {
$transaction->subtype = StockMovementType::SALE;
} elseif ($bill->type->transferType === BillTransferType::PURCHASE) {
$transaction->subtype = StockMovementType::PURCHASE;
}
} else {
// Handle from
if (($bill->client?->id ?? 0) !== 0) {
// @todo: remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->from = $bill->client->id;
} elseif (($bill->supplier?->id ?? 0) !== 0) {
// @todo: remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->from = $bill->supplier->id;
}
// Handle to
// @todo: find possible candidate based on defined default stock for bill type/org/location
if ($bill->type->transferType === BillTransferType::SALES
|| $bill->type->transferType === BillTransferType::PURCHASE
) {
$transaction->subtype = StockMovementType::RETURN;
}
// @todo How to differentiate between stock movement
// invoice with prior delivery note(s),
// invoice with partly delivery note(s),
// invoice with no delivery note
// @todo Handle bill drafts (now only finalization moves stock, how do we reserve stock?)
foreach ($bill->elements as $element) {
if ($element->item === 0 || $element->item === null
|| $element->item->stockIdentifier === StockIdentifierType::NONE
) {
continue;
}
return;
} elseif ($trigger === 'POST:Module:Billing-bill_element-update') {
/** @var \Modules\Billing\Models\BillElement $new */
/** @var \Modules\Billing\Models\BillElement $old */
/** @var \Modules\WarehouseManagement\Models\StockMovement[] $transactions */
$transactions = StockMovementMapper::getAll()
->where('billElement', $new->id)
$dist = StockDistributionMapper::get()
->where('item', $element->item->id)
->where('stock', 1) // @todo fix
->where('stockType', 1) // @todo fix
->where('lot', $element->item->stockIdentifier === StockIdentifierType::NUMBER ? null : '')
->limit(1)
->execute();
/*
if ($new->item === $old->item) {
// quantity change
// lot changes
// stock changes
// all other changes ignore!
// check availability again, if not available abort bill
// maybe from an algorithmic point of view first set quantity to zero
// and then do normal algorithm like for a new element
}
*/
if ($new->item !== $old->item) {
StockMovementMapper::delete()->execute($transactions);
// @todo how to handle only reserving items for drafted bills (not yet shipped)
$this->eventBillUpdateInternal(
$account, $old, $new,
$type, 'POST:Module:Billing-bill_element-create', $module, $ref, $content, $ip
);
}
if ($trigger === 'Billing-bill_element-create') {
// Check stock availability
if ($bill->type->sign > 0 && $dist->quantity < $element->quantity->getInt()) {
continue;
}
return;
} elseif ($trigger === 'POST:Module:Billing-bill_element-delete') {
/** @var \Modules\Billing\Models\BillElement $new */
/** @var \Modules\WarehouseManagement\Models\StockMovement[] $transactions */
$transactions = StockMovementMapper::getAll()
->where('billElement', $new->id)
->execute();
/** @var \Modules\Billing\Models\BillElement $new */
StockMovementMapper::delete()->execute($transactions);
// Handle stock quantity
/////////////////////////////////////////////////////////////////
return;
} elseif ($trigger === 'POST:Module:Billing-bill-delete') {
/** @var \Modules\Billing\Models\Bill $new */
/** @var \Modules\Billing\Models\Bill $bill */
$bill = BillMapper::get()
->with('type')
->with('elements')
->with('supplier')
->with('client')
->where('id', $new->id)
->execute();
// @todo handle stock returns!!!
if ($bill->type->sign > 0) {
$dist->quantity -= $element->quantity->getInt();
foreach ($bill->elements as $element) {
/** @var \Modules\WarehouseManagement\Models\StockMovement[] $transactions */
$transactions = StockMovementMapper::getAll()
->where('billElement', $element->id)
StockDistributionMapper::update()->execute($dist);
} elseif ($dist->id === 0) {
$dist = new StockDistribution();
$dist->item = $element->item->id;
$dist->quantity = $element->quantity->getInt();
$dist->lot = null; // @todo handle correct
$dist->stock = 1; // @todo handle correct
$dist->stockType = 1; // @todo handle correct
StockDistributionMapper::create()->execute($dist);
} else {
$dist->quantity += $element->quantity->getInt();
StockDistributionMapper::update()->execute($dist);
}
// Handle transfer protocol
/////////////////////////////////////////////////////////////////
$transaction = new StockTransaction();
$transaction->billElement = $new->id;
$transaction->state = StockTransactionState::DRAFT;
// @todo load default stock movement for bill type/organization settings (default stock location, default lot order e.g. FIFO/LIFO)
// @todo find stock candidates
$transaction->type = StockTransactionType::TRANSFER; // @todo depends on bill type
$transaction->quantity = $new->quantity->getInt(); // @todo may require split quantity if not sufficient available from one lost
$transaction->item = $element->item->id;
// @todo allow consignment bills
// @todo allow to pass stocklocation for entire bill to avoid re-defining it
// @todo allow custom stock location
if ($bill->type->sign > 0) {
// Handle from
// @todo find possible candidate based on defined default stock for bill type/org/location
$transaction->fromStock = 1; // @todo requires update
$transaction->fromStockType = 1; // @todo requires update
// Handle to
$transaction->toStock = null; // @todo requires update
$transaction->toStockType = null; // @todo requires update
if (($bill->client?->id ?? 0) !== 0) {
// @todo remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->to = $bill->client->id;
} elseif (($bill->supplier?->id ?? 0) !== 0) {
// @todo remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->to = $bill->supplier->id;
}
if ($bill->type->transferType === BillTransferType::SALES) {
$transaction->subtype = StockTransactionType::SALE;
} elseif ($bill->type->transferType === BillTransferType::PURCHASE) {
$transaction->subtype = StockTransactionType::RETURN;
}
} else {
// Handle from
$transaction->fromStock = null; // @todo requires update
$transaction->fromStockType = null; // @todo requires update
if (($bill->client?->id ?? 0) !== 0) {
// @todo remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->from = $bill->client->id;
} elseif (($bill->supplier?->id ?? 0) !== 0) {
// @todo remove phpstan this is just a bug fix until phpstan fixes this bug
/** @phpstan-ignore-next-line */
$transaction->from = $bill->supplier->id;
}
// Handle to
// @todo find possible candidate based on defined default stock for bill type/org/location
$transaction->toStock = 1; // @todo requires update
$transaction->toStockType = 1; // @todo requires update
if ($bill->type->transferType === BillTransferType::SALES) {
$transaction->subtype = StockTransactionType::RETURN;
} elseif ($bill->type->transferType === BillTransferType::PURCHASE) {
$transaction->subtype = StockTransactionType::PURCHASE;
}
}
StockTransactionMapper::create()->execute($transaction);
} elseif ($trigger === 'Billing-bill_element-update') {
/** @var \Modules\Billing\Models\BillElement $new */
/** @var \Modules\Billing\Models\BillElement $old */
/** @var \Modules\WarehouseManagement\Models\StockTransaction[] $transactions */
$transactions = StockTransactionMapper::getAll()
->where('billElement', $new->id)
->execute();
StockMovementMapper::delete()->execute($transactions);
// @todo: consider not to delete but mark as deleted?
}
/*
if ($new->item === $old->item) {
// quantity change
// lot changes
// stock changes
// all other changes ignore!
// check availability again, if not available abort bill
// maybe from an algorithmic point of view first set quantity to zero
// and then do normal algorithm like for a new element
}
*/
if ($new->item?->id !== $old->item?->id) {
// @todo: also undo stock amount in stock distribution
StockTransactionMapper::delete()->execute($transactions);
return;
} elseif ($trigger === 'POST:Module:Billing-bill-update') {
// is receiver update -> change all movements
// is status update -> change all movements (delete = delete)
$this->eventBillUpdateInternal(
$account, $old, $new,
$type, 'Billing-bill_element-create', $module, $ref, $content, $ip
);
}
/** @var \Modules\Billing\Models\Bill $new */
if ($new->status === BillStatus::DELETED) {
$this->eventBillUpdateInternal(
$account, $old, $new,
$type, 'POST:Module:Billing-bill-delete', $module, $ref, $content, $ip
);
} elseif ($new->status === BillStatus::ARCHIVED) {
/** @var \Modules\Billing\Models\Bill $bill */
$bill = BillMapper::get()
->with('type')
->with('elements')
->with('supplier')
->with('client')
->where('id', $new->id)
// @todo handle same item but quantity update
} elseif ($trigger === 'Billing-bill_element-delete') {
/** @var \Modules\Billing\Models\BillElement $new */
/** @var \Modules\WarehouseManagement\Models\StockTransaction[] $transactions */
$transactions = StockTransactionMapper::getAll()
->where('billElement', $new->id)
->execute();
StockTransactionMapper::delete()->execute($transactions);
} elseif ($trigger === 'Billing-bill-delete') {
foreach ($bill->elements as $element) {
/** @var \Modules\WarehouseManagement\Models\StockMovement[] $transactions */
$transactions = StockMovementMapper::getAll()
/** @var \Modules\WarehouseManagement\Models\StockTransaction[] $transactions */
$transactions = StockTransactionMapper::getAll()
->where('billElement', $element->id)
->execute();
foreach ($transactions as $transaction) {
$transaction->state = StockMovementState::TRANSIT; // @todo: change to more specific
StockTransactionMapper::delete()->execute($transactions);
// @todo consider not to delete but mark as deleted?
}
} elseif ($trigger === 'Billing-bill-update') {
// is receiver update -> change all movements
// is status update -> change all movements (delete = delete)
StockMovementMapper::update()->execute($transaction);
/** @var \Modules\Billing\Models\Bill $new */
if ($new->status === BillStatus::DELETED) {
$this->eventBillUpdateInternal(
$account, $old, $new,
$type, 'Billing-bill-delete', $module, $ref, $content, $ip
);
} elseif ($new->status === BillStatus::ARCHIVED) {
foreach ($bill->elements as $element) {
/** @var \Modules\WarehouseManagement\Models\StockTransaction[] $transactions */
$transactions = StockTransactionMapper::getAll()
->where('billElement', $element->id)
->execute();
foreach ($transactions as $transaction) {
$transaction->state = StockTransactionState::TRANSIT; // @todo change to more specific
StockTransactionMapper::update()->execute($transaction);
}
}
}
}
return;
}
}
}

View File

@ -74,7 +74,10 @@ final class ApiStockTypeController extends Controller
{
$stockType = new StockType();
$stockType->name = $request->getDataString('name') ?? '';
$stockType->setL11n($request->getDataString('title') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN);
$stockType->setL11n(
$request->getDataString('title') ?? '',
ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? ISO639x1Enum::_EN
);
return $stockType;
}
@ -138,12 +141,10 @@ final class ApiStockTypeController extends Controller
*/
private function createStockTypeL11nFromRequest(RequestAbstract $request) : BaseStringL11n
{
$stockTypeL11n = new BaseStringL11n();
$stockTypeL11n->ref = $request->getDataInt('type') ?? 0;
$stockTypeL11n->setLanguage(
$request->getDataString('language') ?? $request->header->l11n->language
);
$stockTypeL11n->content = $request->getDataString('title') ?? '';
$stockTypeL11n = new BaseStringL11n();
$stockTypeL11n->ref = $request->getDataInt('type') ?? 0;
$stockTypeL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language;
$stockTypeL11n->content = $request->getDataString('title') ?? '';
return $stockTypeL11n;
}

View File

@ -35,7 +35,7 @@ use phpOMS\Views\View;
final class BackendController extends Controller
{
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -77,7 +77,7 @@ final class BackendController extends Controller
}
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -113,7 +113,7 @@ final class BackendController extends Controller
}
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -137,7 +137,7 @@ final class BackendController extends Controller
}
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -152,7 +152,7 @@ final class BackendController extends Controller
{
$view = new View($this->app->l11nManager, $request, $response);
$view->setTemplate('/Modules/WarehouseManagement/Theme/Backend/stock-type-profile');
$view->setTemplate('/Modules/WarehouseManagement/Theme/Backend/stock-type-view');
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1001302001, $request, $response);
$view->data['type'] = StockMapper::get()->where('id', (int) $request->getData('id'))->execute();
@ -168,7 +168,7 @@ final class BackendController extends Controller
}
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
@ -207,7 +207,7 @@ final class BackendController extends Controller
}
/**
* Routing end-point for application behaviour.
* Routing end-point for application behavior.
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response

View File

@ -1,6 +1,6 @@
# Individual Contributor License Agreement ("CLA") 1.0
Thank you for your interest in Karaka-Management (the "Company"). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Company must provide a Contributor License Agreement ("CLA") on file that has been made available to each Contributor. This license is for your protection as a Contributor as well as the protection of the Company and its users; it does not change your rights to use your own Contributions for any other purpose.
Thank you for your interest in Jingga e. K. (the "Company"). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Company must provide a Contributor License Agreement ("CLA") on file that has been made available to each Contributor. This license is for your protection as a Contributor as well as the protection of the Company and its users; it does not change your rights to use your own Contributions for any other purpose.
By contributing to the Company You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Company. In return, the Company shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its bylaws in effect at the time of the Contribution. Except for the license granted herein to the Company and recipients of software distributed by the Company, You reserve all right, title, and interest in and to Your Contributions.

View File

@ -37,13 +37,13 @@ final class LotAttributeTypeMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_attr_type_id' => ['name' => 'warehousemgmt_attr_type_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_attr_type_name' => ['name' => 'warehousemgmt_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true],
'warehousemgmt_attr_type_datatype' => ['name' => 'warehousemgmt_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'],
'warehousemgmt_attr_type_fields' => ['name' => 'warehousemgmt_attr_type_fields', 'type' => 'int', 'internal' => 'fields'],
'warehousemgmt_attr_type_custom' => ['name' => 'warehousemgmt_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'],
'warehousemgmt_attr_type_pattern' => ['name' => 'warehousemgmt_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'],
'warehousemgmt_attr_type_required' => ['name' => 'warehousemgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'],
'warehousemgmt_attr_type_id' => ['name' => 'warehousemgmt_attr_type_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_attr_type_name' => ['name' => 'warehousemgmt_attr_type_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true],
'warehousemgmt_attr_type_datatype' => ['name' => 'warehousemgmt_attr_type_datatype', 'type' => 'int', 'internal' => 'datatype'],
'warehousemgmt_attr_type_fields' => ['name' => 'warehousemgmt_attr_type_fields', 'type' => 'int', 'internal' => 'fields'],
'warehousemgmt_attr_type_custom' => ['name' => 'warehousemgmt_attr_type_custom', 'type' => 'bool', 'internal' => 'custom'],
'warehousemgmt_attr_type_pattern' => ['name' => 'warehousemgmt_attr_type_pattern', 'type' => 'string', 'internal' => 'validationPattern'],
'warehousemgmt_attr_type_required' => ['name' => 'warehousemgmt_attr_type_required', 'type' => 'bool', 'internal' => 'isRequired'],
];
/**

View File

@ -37,10 +37,10 @@ final class LotAttributeValueL11nMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_attr_value_l11n_id' => ['name' => 'warehousemgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_attr_value_l11n_title' => ['name' => 'warehousemgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true],
'warehousemgmt_attr_value_l11n_value' => ['name' => 'warehousemgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'],
'warehousemgmt_attr_value_l11n_lang' => ['name' => 'warehousemgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'],
'warehousemgmt_attr_value_l11n_id' => ['name' => 'warehousemgmt_attr_value_l11n_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_attr_value_l11n_title' => ['name' => 'warehousemgmt_attr_value_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true],
'warehousemgmt_attr_value_l11n_value' => ['name' => 'warehousemgmt_attr_value_l11n_value', 'type' => 'int', 'internal' => 'ref'],
'warehousemgmt_attr_value_l11n_lang' => ['name' => 'warehousemgmt_attr_value_l11n_lang', 'type' => 'string', 'internal' => 'language'],
];
/**

View File

@ -37,15 +37,15 @@ final class LotAttributeValueMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_attr_value_id' => ['name' => 'warehousemgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_attr_value_default' => ['name' => 'warehousemgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'],
'warehousemgmt_attr_value_valueStr' => ['name' => 'warehousemgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'],
'warehousemgmt_attr_value_valueInt' => ['name' => 'warehousemgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'],
'warehousemgmt_attr_value_valueDec' => ['name' => 'warehousemgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'],
'warehousemgmt_attr_value_valueDat' => ['name' => 'warehousemgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'],
'warehousemgmt_attr_value_unit' => ['name' => 'warehousemgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'],
'warehousemgmt_attr_value_deptype' => ['name' => 'warehousemgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'],
'warehousemgmt_attr_value_depvalue' => ['name' => 'warehousemgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'],
'warehousemgmt_attr_value_id' => ['name' => 'warehousemgmt_attr_value_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_attr_value_default' => ['name' => 'warehousemgmt_attr_value_default', 'type' => 'bool', 'internal' => 'isDefault'],
'warehousemgmt_attr_value_valueStr' => ['name' => 'warehousemgmt_attr_value_valueStr', 'type' => 'string', 'internal' => 'valueStr'],
'warehousemgmt_attr_value_valueInt' => ['name' => 'warehousemgmt_attr_value_valueInt', 'type' => 'int', 'internal' => 'valueInt'],
'warehousemgmt_attr_value_valueDec' => ['name' => 'warehousemgmt_attr_value_valueDec', 'type' => 'float', 'internal' => 'valueDec'],
'warehousemgmt_attr_value_valueDat' => ['name' => 'warehousemgmt_attr_value_valueDat', 'type' => 'DateTime', 'internal' => 'valueDat'],
'warehousemgmt_attr_value_unit' => ['name' => 'warehousemgmt_attr_value_unit', 'type' => 'string', 'internal' => 'unit'],
'warehousemgmt_attr_value_deptype' => ['name' => 'warehousemgmt_attr_value_deptype', 'type' => 'int', 'internal' => 'dependingAttributeType'],
'warehousemgmt_attr_value_depvalue' => ['name' => 'warehousemgmt_attr_value_depvalue', 'type' => 'int', 'internal' => 'dependingAttributeValue'],
];
/**
@ -59,6 +59,7 @@ final class LotAttributeValueMapper extends DataMapperFactory
'mapper' => LotAttributeValueL11nMapper::class,
'table' => 'warehousemgmt_attr_value_l11n',
'self' => 'warehousemgmt_attr_value_l11n_value',
'column' => 'content',
'external' => null,
],
];

View File

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

View File

@ -14,19 +14,33 @@ declare(strict_types=1);
namespace Modules\WarehouseManagement\Models;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* WarehouseManagement mapper class.
* Null model
*
* @package Modules\WarehouseManagement\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of StockMovement
* @extends DataMapperFactory<T>
*/
final class StockMovementMapper extends DataMapperFactory
final class NullStockTransaction extends StockTransaction
{
/**
* Constructor
*
* @param int $id Model id
*
* @since 1.0.0
*/
public function __construct(int $id = 0)
{
$this->id = $id;
}
/**
* {@inheritdoc}
*/
public function jsonSerialize() : mixed
{
return ['id' => $this->id];
}
}

View File

@ -17,7 +17,7 @@ namespace Modules\WarehouseManagement\Models;
use phpOMS\Stdlib\Base\Enum;
/**
* Permision state enum.
* Permission category enum.
*
* @package Modules\WarehouseManagement\Models
* @license OMS License 2.0

View File

@ -14,7 +14,9 @@ declare(strict_types=1);
namespace Modules\WarehouseManagement\Models;
use Modules\Admin\Models\Address;
use Modules\ClientManagement\Models\Client;
use Modules\SupplierManagement\Models\Supplier;
use phpOMS\Stdlib\Base\Address;
/**
* Warehouse class.
@ -23,6 +25,11 @@ use Modules\Admin\Models\Address;
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @todo Add attributes for stock
* This is important for things like warehousing cost ratio (Lagerkostensatz)
* HR + energy + insurance + interest rate + machinery (e.g. depreciation) + leasing + cleaning
* + security + maintenance + ...
*/
class Stock
{
@ -44,8 +51,14 @@ class Stock
public int $unit = 0;
public ?Client $client = null;
public ?Supplier $supplier = null;
public ?Address $address = null;
public bool $inventory = false;
/**
* Constructor.
*
@ -57,16 +70,4 @@ class Stock
{
$this->name = $name;
}
/**
* Get id.
*
* @return int
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->id;
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\Warehousing\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\Models;
/**
* Warehouse class.
*
* @package Modules\Warehousing\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class StockDistribution
{
/**
* ID.
*
* @var int
* @since 1.0.0
*/
public int $id = 0;
public int $quantity = 0;
public ?int $lot = null;
public int $item = 0;
public int $stock = 0;
public int $stockType = 0;
}

View File

@ -0,0 +1,70 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\WarehouseManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\Models;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* WarehouseManagement mapper class.
*
* @package Modules\WarehouseManagement\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of StockDistribution
* @extends DataMapperFactory<T>
*/
final class StockDistributionMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_stock_distribution_id' => ['name' => 'warehousemgmt_stock_distribution_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_distribution_item' => ['name' => 'warehousemgmt_stock_distribution_item', 'type' => 'int', 'internal' => 'item'],
'warehousemgmt_stock_distribution_lot' => ['name' => 'warehousemgmt_stock_distribution_lot', 'type' => 'int', 'internal' => 'lot'],
'warehousemgmt_stock_distribution_stock' => ['name' => 'warehousemgmt_stock_distribution_stock', 'type' => 'int', 'internal' => 'stock'],
'warehousemgmt_stock_distribution_stocktype' => ['name' => 'warehousemgmt_stock_distribution_stocktype', 'type' => 'int', 'internal' => 'stockType'],
'warehousemgmt_stock_distribution_quantity' => ['name' => 'warehousemgmt_stock_distribution_quantity', 'type' => 'int', 'internal' => 'quantity'],
];
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = StockDistribution::class;
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'warehousemgmt_stock_distribution';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'warehousemgmt_stock_distribution_id';
}

View File

@ -55,16 +55,4 @@ class StockLocation
{
$this->name = $name;
}
/**
* Get id.
*
* @return int
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->id;
}
}

View File

@ -36,13 +36,13 @@ final class StockLocationMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_stocklocation_id' => ['name' => 'warehousemgmt_stocklocation_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stocklocation_name' => ['name' => 'warehousemgmt_stocklocation_name', 'type' => 'string', 'internal' => 'name'],
'warehousemgmt_stocklocation_stock' => ['name' => 'warehousemgmt_stocklocation_stock', 'type' => 'int', 'internal' => 'stock'],
'warehousemgmt_stocklocation_type' => ['name' => 'warehousemgmt_stocklocation_type', 'type' => 'int', 'internal' => 'type'],
'warehousemgmt_stocklocation_x' => ['name' => 'warehousemgmt_stocklocation_x', 'type' => 'int', 'internal' => 'x'],
'warehousemgmt_stocklocation_y' => ['name' => 'warehousemgmt_stocklocation_y', 'type' => 'int', 'internal' => 'y'],
'warehousemgmt_stocklocation_z' => ['name' => 'warehousemgmt_stocklocation_z', 'type' => 'int', 'internal' => 'z'],
'warehousemgmt_stocklocation_id' => ['name' => 'warehousemgmt_stocklocation_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stocklocation_name' => ['name' => 'warehousemgmt_stocklocation_name', 'type' => 'string', 'internal' => 'name'],
'warehousemgmt_stocklocation_stock' => ['name' => 'warehousemgmt_stocklocation_stock', 'type' => 'int', 'internal' => 'stock'],
'warehousemgmt_stocklocation_type' => ['name' => 'warehousemgmt_stocklocation_type', 'type' => 'int', 'internal' => 'type'],
'warehousemgmt_stocklocation_x' => ['name' => 'warehousemgmt_stocklocation_x', 'type' => 'int', 'internal' => 'x'],
'warehousemgmt_stocklocation_y' => ['name' => 'warehousemgmt_stocklocation_y', 'type' => 'int', 'internal' => 'y'],
'warehousemgmt_stocklocation_z' => ['name' => 'warehousemgmt_stocklocation_z', 'type' => 'int', 'internal' => 'z'],
];
/**
@ -53,8 +53,8 @@ final class StockLocationMapper extends DataMapperFactory
*/
public const BELONGS_TO = [
'stock' => [
'mapper' => StockMapper::class,
'external' => 'warehousemgmt_stocklocation_stock',
'mapper' => StockMapper::class,
'external' => 'warehousemgmt_stocklocation_stock',
],
];

View File

@ -15,7 +15,11 @@ declare(strict_types=1);
namespace Modules\WarehouseManagement\Models;
use Modules\Admin\Models\AddressMapper;
use Modules\ClientManagement\Models\ClientMapper;
use Modules\ItemManagement\Models\StockIdentifierType;
use Modules\SupplierManagement\Models\SupplierMapper;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
use phpOMS\DataStorage\Database\Query\Builder;
/**
* WarehouseManagement mapper class.
@ -37,10 +41,13 @@ final class StockMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_stock_id' => ['name' => 'warehousemgmt_stock_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_name' => ['name' => 'warehousemgmt_stock_name', 'type' => 'string', 'internal' => 'name'],
'warehousemgmt_stock_unit' => ['name' => 'warehousemgmt_stock_unit', 'type' => 'int', 'internal' => 'unit'],
'warehousemgmt_stock_address' => ['name' => 'warehousemgmt_stock_address', 'type' => 'int', 'internal' => 'address'],
'warehousemgmt_stock_id' => ['name' => 'warehousemgmt_stock_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_name' => ['name' => 'warehousemgmt_stock_name', 'type' => 'string', 'internal' => 'name'],
'warehousemgmt_stock_unit' => ['name' => 'warehousemgmt_stock_unit', 'type' => 'int', 'internal' => 'unit'],
'warehousemgmt_stock_client' => ['name' => 'warehousemgmt_stock_client', 'type' => 'int', 'internal' => 'client'],
'warehousemgmt_stock_supplier' => ['name' => 'warehousemgmt_stock_supplier', 'type' => 'int', 'internal' => 'supplier'],
'warehousemgmt_stock_inventory' => ['name' => 'warehousemgmt_stock_inventory', 'type' => 'bool', 'internal' => 'inventory'],
'warehousemgmt_stock_address' => ['name' => 'warehousemgmt_stock_address', 'type' => 'int', 'internal' => 'address'],
];
/**
@ -56,6 +63,23 @@ final class StockMapper extends DataMapperFactory
],
];
/**
* Belongs to.
*
* @var array<string, array{mapper:class-string, external:string, column?:string, by?:string}>
* @since 1.0.0
*/
public const BELONGS_TO = [
'client' => [
'mapper' => ClientMapper::class,
'external' => 'warehousemgmt_stock_client',
],
'supplier' => [
'mapper' => SupplierMapper::class,
'external' => 'warehousemgmt_stock_supplier',
],
];
/**
* Primary table.
*
@ -71,4 +95,90 @@ final class StockMapper extends DataMapperFactory
* @since 1.0.0
*/
public const PRIMARYFIELD = 'warehousemgmt_stock_id';
/**
* Get stock distributions
*
* @param int[] $items Items
*
* @return array{dists:array, reserved:array, ordered:array}
*
* @since 1.0.0
*/
public static function getStockDistribution(array $items) : array
{
$dists = [];
$reserved = [];
$ordered = [];
if (empty($items)) {
return [
'dists' => $dists,
'reserved' => $reserved,
'ordered' => $ordered,
];
}
$itemIdsString = \implode(',', $items);
// @todo only select sales stock. Therefore we need a place to define the sales stock(s)
/** @var \Modules\WarehouseManagement\Models\StockDistribution[] $temp */
$temp = StockDistributionMapper::getAll()
->where('item', $items, 'IN')
->execute();
foreach ($temp as $t) {
if (!isset($dists[$t->item])) {
$dists[$t->item] = [];
}
// @todo These numbers might need adjustments for delivery notes/invoices depending on
// how we implement them in the warehouse management (maybe flag them in the transaction protocol as reserved?)
// also remember the SD issue where delivery notes can be technically still in stock -> stock value still belongs to company
// solution: "just" do a soft adjust of the available numbers?! but don't change the actual stock in the db
// the SD solution where actually delivered delivery notes can be adjusted after "archiving" will not be allowed
// to allow them to see what happened with such a delivery note maybe we can implement a view shows how many of the items are
// actually still outstanding. This shouldn't be anything special since we need importing of delivery notes anyways and marking
// old delivery note elements in a way to show which line items or even sub-line items got invoiced/returned etc.
$dists[$t->item][] = $t;
}
$stockIdentifier = StockIdentifierType::NONE;
$sql = <<<SQL
SELECT billing_bill_element.billing_bill_element_item,
billing_type.billing_type_name,
SUM(billing_bill_element.billing_bill_element_quantity) AS quantity
FROM billing_bill_element
LEFT JOIN itemmgmt_item ON billing_bill_element.billing_bill_element_item = itemmgmt_item.itemmgmt_item_id
LEFT JOIN billing_bill ON billing_bill_element.billing_bill_element_bill = billing_bill.billing_bill_id
LEFT JOIN billing_type ON billing_bill.billing_bill_type = billing_type.billing_type_id
WHERE billing_bill_element.billing_bill_element_item IN ({$itemIdsString})
AND itemmgmt_item.itemmgmt_item_stockidentifier != {$stockIdentifier}
AND billing_type.billing_type_name IN ('sales_order_confirmation', 'purchase_order')
GROUP BY billing_bill_element.billing_bill_element_item, billing_type.billing_type_name;
SQL;
$query = new Builder(self::$db);
$results = $query->raw($sql)->execute()?->fetchAll(\PDO::FETCH_ASSOC) ?? [];
foreach ($results as $result) {
if (!isset($reserved[(int) $result['billing_bill_element_item']])) {
$reserved[(int) $result['billing_bill_element_item']] = 0;
$ordered[(int) $result['billing_bill_element_item']] = 0;
}
if ($result['billing_type_name'] === 'sales_order_confirmation') {
$reserved[(int) $result['billing_bill_element_item']] += (int) $result['quantity'];
} else {
$ordered[(int) $result['billing_bill_element_item']] += (int) $result['quantity'];
}
}
return [
'dists' => $dists,
'reserved' => $reserved,
'ordered' => $ordered,
];
}
}

View File

@ -55,16 +55,4 @@ class StockShelf
{
$this->name = $name;
}
/**
* Get id.
*
* @return int
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->id;
}
}

View File

@ -36,13 +36,13 @@ final class StockShelfMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_stockshelf_id' => ['name' => 'warehousemgmt_stockshelf_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stockshelf_name' => ['name' => 'warehousemgmt_stockshelf_name', 'type' => 'string', 'internal' => 'name'],
'warehousemgmt_stockshelf_location' => ['name' => 'warehousemgmt_stockshelf_location', 'type' => 'int', 'internal' => 'location'],
'warehousemgmt_stockshelf_type' => ['name' => 'warehousemgmt_stockshelf_type', 'type' => 'int', 'internal' => 'type'],
'warehousemgmt_stockshelf_x' => ['name' => 'warehousemgmt_stockshelf_x', 'type' => 'int', 'internal' => 'x'],
'warehousemgmt_stockshelf_y' => ['name' => 'warehousemgmt_stockshelf_y', 'type' => 'int', 'internal' => 'y'],
'warehousemgmt_stockshelf_z' => ['name' => 'warehousemgmt_stockshelf_z', 'type' => 'int', 'internal' => 'z'],
'warehousemgmt_stockshelf_id' => ['name' => 'warehousemgmt_stockshelf_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stockshelf_name' => ['name' => 'warehousemgmt_stockshelf_name', 'type' => 'string', 'internal' => 'name'],
'warehousemgmt_stockshelf_location' => ['name' => 'warehousemgmt_stockshelf_location', 'type' => 'int', 'internal' => 'location'],
'warehousemgmt_stockshelf_type' => ['name' => 'warehousemgmt_stockshelf_type', 'type' => 'int', 'internal' => 'type'],
'warehousemgmt_stockshelf_x' => ['name' => 'warehousemgmt_stockshelf_x', 'type' => 'int', 'internal' => 'x'],
'warehousemgmt_stockshelf_y' => ['name' => 'warehousemgmt_stockshelf_y', 'type' => 'int', 'internal' => 'y'],
'warehousemgmt_stockshelf_z' => ['name' => 'warehousemgmt_stockshelf_z', 'type' => 'int', 'internal' => 'z'],
];
/**
@ -53,8 +53,8 @@ final class StockShelfMapper extends DataMapperFactory
*/
public const BELONGS_TO = [
'location' => [
'mapper' => StockMapper::class,
'external' => 'warehousemgmt_stockshelf_location',
'mapper' => StockMapper::class,
'external' => 'warehousemgmt_stockshelf_location',
],
];

View File

@ -25,7 +25,7 @@ use Modules\Admin\Models\NullAccount;
* @link https://jingga.app
* @since 1.0.0
*/
class StockMovement
class StockTransaction
{
/**
* ID.
@ -43,7 +43,7 @@ class StockMovement
public int $to = 0;
public int $type = StockMovementType::TRANSFER;
public int $type = StockTransactionType::TRANSFER;
public int $subtype = 0;
@ -51,7 +51,21 @@ class StockMovement
public int $billElement = 0;
public int $state = StockMovementState::DRAFT;
public int $state = StockTransactionState::DRAFT;
public int $item = 0;
public ?int $fromLot = null;
public ?int $fromStock = null;
public ?int $fromStockType = null;
public ?int $toLot = null;
public ?int $toStock = null;
public ?int $toStockType = null;
/**
* Creator.
@ -79,16 +93,4 @@ class StockMovement
$this->createdBy = new NullAccount();
$this->createdAt = new \DateTimeImmutable('now');
}
/**
* Get ID.
*
* @return int
*
* @since 1.0.0
*/
public function getId()
{
return $this->id;
}
}

View File

@ -0,0 +1,76 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\WarehouseManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\Models;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* WarehouseManagement mapper class.
*
* @package Modules\WarehouseManagement\Models
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*
* @template T of StockTransaction
* @extends DataMapperFactory<T>
*/
final class StockTransactionMapper extends DataMapperFactory
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_stock_transaction_id' => ['name' => 'warehousemgmt_stock_transaction_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_transaction_state' => ['name' => 'warehousemgmt_stock_transaction_state', 'type' => 'int', 'internal' => 'state'],
'warehousemgmt_stock_transaction_quantity' => ['name' => 'warehousemgmt_stock_transaction_quantity', 'type' => 'int', 'internal' => 'quantity'],
'warehousemgmt_stock_transaction_type' => ['name' => 'warehousemgmt_stock_transaction_type', 'type' => 'int', 'internal' => 'type'],
'warehousemgmt_stock_transaction_item' => ['name' => 'warehousemgmt_stock_transaction_item', 'type' => 'int', 'internal' => 'item'],
'warehousemgmt_stock_transaction_from_lot' => ['name' => 'warehousemgmt_stock_transaction_from_lot', 'type' => 'int', 'internal' => 'fromLot'],
'warehousemgmt_stock_transaction_from_stock' => ['name' => 'warehousemgmt_stock_transaction_from_stock', 'type' => 'int', 'internal' => 'fromStock'],
'warehousemgmt_stock_transaction_from_stocktype' => ['name' => 'warehousemgmt_stock_transaction_from_stocktype', 'type' => 'int', 'internal' => 'fromStockType'],
'warehousemgmt_stock_transaction_to_lot' => ['name' => 'warehousemgmt_stock_transaction_to_lot', 'type' => 'int', 'internal' => 'toLot'],
'warehousemgmt_stock_transaction_to_stock' => ['name' => 'warehousemgmt_stock_transaction_to_stock', 'type' => 'int', 'internal' => 'toStock'],
'warehousemgmt_stock_transaction_to_stocktype' => ['name' => 'warehousemgmt_stock_transaction_to_stocktype', 'type' => 'int', 'internal' => 'toStockType'],
'warehousemgmt_stock_transaction_bill_element' => ['name' => 'warehousemgmt_stock_transaction_bill_element', 'type' => 'int', 'internal' => 'billElement'],
];
/**
* Model to use by the mapper.
*
* @var class-string<T>
* @since 1.0.0
*/
public const MODEL = StockTransaction::class;
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
public const TABLE = 'warehousemgmt_stock_transaction';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
public const PRIMARYFIELD = 'warehousemgmt_stock_transaction_id';
}

View File

@ -24,7 +24,7 @@ use phpOMS\Stdlib\Base\Enum;
* @link https://jingga.app
* @since 1.0.0
*/
abstract class StockMovementState extends Enum
abstract class StockTransactionState extends Enum
{
public const DRAFT = 1;

View File

@ -24,7 +24,7 @@ use phpOMS\Stdlib\Base\Enum;
* @link https://jingga.app
* @since 1.0.0
*/
abstract class StockMovementType extends Enum
abstract class StockTransactionType extends Enum
{
public const MERGE = 1;
@ -36,7 +36,7 @@ abstract class StockMovementType extends Enum
public const TRANSFER = 16;
// @todo: subtypes, maybe creates as database subtypes during install.
// @todo subtypes, maybe creates as database subtypes during install.
public const DESTROY = 101;
public const RETURN = 102;

View File

@ -65,13 +65,13 @@ class StockType
if ($l11n instanceof BaseStringL11n) {
$this->l11n = $l11n;
} elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) {
$this->l11n->content = $l11n;
$this->l11n->setLanguage($lang);
$this->l11n->content = $l11n;
$this->l11n->language = $lang;
} else {
$this->l11n = new BaseStringL11n();
$this->l11n->content = $l11n;
$this->l11n->ref = $this->id;
$this->l11n->setLanguage($lang);
$this->l11n = new BaseStringL11n();
$this->l11n->content = $l11n;
$this->l11n->ref = $this->id;
$this->l11n->language = $lang;
}
}
@ -95,7 +95,7 @@ class StockType
public function toArray() : array
{
return [
'id' => $this->id,
'id' => $this->id,
];
}

View File

@ -37,10 +37,10 @@ final class StockTypeL11nMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_stock_type_l11n_id' => ['name' => 'warehousemgmt_stock_type_l11n_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_type_l11n_name' => ['name' => 'warehousemgmt_stock_type_l11n_name', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true],
'warehousemgmt_stock_type_l11n_type' => ['name' => 'warehousemgmt_stock_type_l11n_type', 'type' => 'int', 'internal' => 'ref'],
'warehousemgmt_stock_type_l11n_language' => ['name' => 'warehousemgmt_stock_type_l11n_language', 'type' => 'string', 'internal' => 'language'],
'warehousemgmt_stock_type_l11n_id' => ['name' => 'warehousemgmt_stock_type_l11n_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_type_l11n_name' => ['name' => 'warehousemgmt_stock_type_l11n_name', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true],
'warehousemgmt_stock_type_l11n_type' => ['name' => 'warehousemgmt_stock_type_l11n_type', 'type' => 'int', 'internal' => 'ref'],
'warehousemgmt_stock_type_l11n_language' => ['name' => 'warehousemgmt_stock_type_l11n_language', 'type' => 'string', 'internal' => 'language'],
];
/**

View File

@ -36,8 +36,8 @@ final class StockTypeMapper extends DataMapperFactory
* @since 1.0.0
*/
public const COLUMNS = [
'warehousemgmt_stock_type_id' => ['name' => 'warehousemgmt_stock_type_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_type_name' => ['name' => 'warehousemgmt_stock_type_name', 'type' => 'string', 'internal' => 'name'],
'warehousemgmt_stock_type_id' => ['name' => 'warehousemgmt_stock_type_id', 'type' => 'int', 'internal' => 'id'],
'warehousemgmt_stock_type_name' => ['name' => 'warehousemgmt_stock_type_name', 'type' => 'string', 'internal' => 'name'],
];
/**
@ -48,11 +48,11 @@ final class StockTypeMapper extends DataMapperFactory
*/
public const HAS_MANY = [
'l11n' => [
'mapper' => StockTypeL11nMapper::class,
'table' => 'warehousemgmt_stock_type_l11n',
'self' => 'warehousemgmt_stock_type_l11n_type',
'column' => 'content',
'external' => null,
'mapper' => StockTypeL11nMapper::class,
'table' => 'warehousemgmt_stock_type_l11n',
'self' => 'warehousemgmt_stock_type_l11n_type',
'column' => 'content',
'external' => null,
],
];

View File

@ -51,7 +51,7 @@ Currently Karaka is still developing the first Alpha version. As soon as we have
General updates can be found in our info section at https://jingga.app/info and developer updates can be found in our developer section at https://jingga.app/dev. In our developer section you can also check out the automatically generated reports such as code coverage, code style, static analysis etc. as well as our code style guide lines and developer documentation.
* [Project Status](https://github.com/Karaka-Management/Organization-Guide/blob/master/Project/PROJECT.md)
* [Project Status](https://github.com/orgs/Karaka-Management/projects/10)
## Tech stack
@ -62,7 +62,7 @@ General updates can be found in our info section at https://jingga.app/info and
## Become a contributor
Karaka has a very open culture and we always welcome new people who share our philosophy in providing create solutions which just work. You can find the development process description which also describes how to become a contributer in the [Organization documentation](https://github.com/Karaka-Management/Organization-Guide/blob/master/Processes/Development.md).
Karaka has a very open culture and we always welcome new people who share our philosophy in providing create solutions which just work. You can find the development process description which also describes how to become a contributer in the [Organization documentation](https://github.com/Karaka-Management/Organization-Guide/blob/master/Processes/01_Development.md).
## Misc

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'الجميع',
'Amount' => 'مقدار',
'Arrivals' => 'الوصول',
'Article' => 'مقالة - سلعة',
'Articles' => 'مقالات',
'City' => 'مدينة',
'Consignee' => 'المرسل إليه',
'Consignor' => 'المرسل',
'Country' => 'دولة',
'Date' => 'تاريخ',
'Description' => 'وصف',
'Interval' => 'فترة',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'موقع',
'Locations' => '',
'Matchcode' => 'رمز مطابق',
'Month' => 'شهر',
'Name' => 'اسم',
'Order' => 'طلب',
'Quantity' => 'كمية',
'Reference' => 'المرجعي',
'Shipping' => 'شحن',
'Statistics' => 'إحصائيات',
'Stock' => 'المخزون',
'Stocks' => '',
'Street' => 'شارع',
'Today' => 'اليوم',
'Type' => 'نوع',
'Types' => '',
'Week' => 'أسبوع',
'Year' => 'عام',
'Zip' => 'أزيز',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Všechno',
'Amount' => 'Množství',
'Arrivals' => 'Přílety',
'Article' => 'Článek',
'Articles' => 'Články',
'City' => 'Město',
'Consignee' => 'Příjemce',
'Consignor' => 'Odesílatel',
'Country' => 'Země',
'Date' => 'datum',
'Description' => 'Popis',
'Interval' => 'Interval',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Umístění',
'Locations' => '',
'Matchcode' => 'MatchCode.',
'Month' => 'Měsíc',
'Name' => 'název',
'Order' => 'Objednat',
'Quantity' => 'Množství',
'Reference' => 'Odkaz',
'Shipping' => 'Lodní doprava',
'Statistics' => 'Statistika',
'Stock' => 'Skladem',
'Stocks' => '',
'Street' => 'ulice',
'Today' => 'Dnes',
'Type' => 'Typ',
'Types' => '',
'Week' => 'Týden',
'Year' => 'Rok',
'Zip' => 'Zip',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Alle',
'Amount' => 'Beløb',
'Arrivals' => 'Ankomster.',
'Article' => 'Artikel',
'Articles' => 'Artikler',
'City' => 'City.',
'Consignee' => 'Modtageren.',
'Consignor' => 'Afsender.',
'Country' => 'Land',
'Date' => 'Dato',
'Description' => 'Beskrivelse',
'Interval' => 'Interval',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Beliggenhed',
'Locations' => '',
'Matchcode' => 'MatchCode.',
'Month' => 'Måned',
'Name' => 'Navn',
'Order' => 'Bestille',
'Quantity' => 'Antal',
'Reference' => 'Reference',
'Shipping' => 'Forsendelse',
'Statistics' => 'Statistikker',
'Stock' => 'Lager',
'Stocks' => '',
'Street' => 'Gade',
'Today' => 'I dag',
'Type' => 'Type',
'Types' => '',
'Week' => 'Uge',
'Year' => 'År',
'Zip' => 'Zip.',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Alle',
'Amount' => 'Höhe',
'Arrivals' => 'Ankunft',
'Article' => 'Artikel',
'Articles' => 'Artikel',
'City' => 'Stadt',
'Consignee' => 'Empfänger',
'Consignor' => 'Versender',
'Country' => 'Land',
'Date' => 'Datum',
'Description' => 'Beschreibung',
'Interval' => 'Intervall',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Ort',
'Locations' => '',
'Matchcode' => 'Matchcode',
'Month' => 'Monat',
'Name' => 'Name',
'Order' => 'Befehl',
'Quantity' => 'Menge',
'Reference' => 'Bezug',
'Shipping' => 'Versand',
'Statistics' => 'Statistiken',
'Stock' => 'Aktie',
'Stocks' => '',
'Street' => 'Straße',
'Today' => 'Heute',
'Type' => 'Typ',
'Types' => '',
'Week' => 'Woche',
'Year' => 'Jahr',
'Zip' => 'Reißverschluss',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Ολα',
'Amount' => 'Ποσό',
'Arrivals' => 'Αφίξεις',
'Article' => 'Αρθρο',
'Articles' => 'Είδη',
'City' => 'Πόλη',
'Consignee' => 'Παραλήπτης',
'Consignor' => 'Αποστολέας',
'Country' => 'Χώρα',
'Date' => 'Ημερομηνία',
'Description' => 'Περιγραφή',
'Interval' => 'Διάστημα',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Τοποθεσία',
'Locations' => '',
'Matchcode' => 'Matchcode',
'Month' => 'Μήνας',
'Name' => 'Ονομα',
'Order' => 'Σειρά',
'Quantity' => 'Ποσότητα',
'Reference' => 'Αναφορά',
'Shipping' => 'Αποστολή',
'Statistics' => 'Στατιστική',
'Stock' => 'Στοκ',
'Stocks' => '',
'Street' => 'Δρόμος',
'Today' => 'Σήμερα',
'Type' => 'Τύπος',
'Types' => '',
'Week' => 'Εβδομάδα',
'Year' => 'Ετος',
'Zip' => 'Φερμουάρ',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'All',
'Amount' => 'Amount',
'Arrivals' => 'Arrivals',
'Article' => 'Article',
'Articles' => 'Articles',
'City' => 'City',
'Consignee' => 'Consignee',
'Consignor' => 'Consignor',
'Country' => 'Country',
'Date' => 'Date',
'Description' => 'Description',
'Interval' => 'Interval',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Location',
'Locations' => 'Locations',
'Matchcode' => 'Matchcode',
'Month' => 'Month',
'Name' => 'Name',
'Order' => 'Order',
'Quantity' => 'Quantity',
'Reference' => 'Reference',
'Shipping' => 'Shipping',
'Statistics' => 'Statistics',
'Stock' => 'Stock',
'Stocks' => 'Stocks',
'Street' => 'Street',
'Today' => 'Today',
'Type' => 'Type',
'Types' => 'Types',
'Week' => 'Week',
'Year' => 'Year',
'Zip' => 'Zip',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Todo',
'Amount' => 'Monto',
'Arrivals' => 'Llegadas',
'Article' => 'Artículo',
'Articles' => 'Artículos',
'City' => 'Ciudad',
'Consignee' => 'Consignatario',
'Consignor' => 'Consignador',
'Country' => 'País',
'Date' => 'Fecha',
'Description' => 'Descripción',
'Interval' => 'Intervalo',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Ubicación',
'Locations' => '',
'Matchcode' => 'Código de asociación',
'Month' => 'Mes',
'Name' => 'Nombre',
'Order' => 'Pedido',
'Quantity' => 'Cantidad',
'Reference' => 'Referencia',
'Shipping' => 'Transporte',
'Statistics' => 'Estadísticas',
'Stock' => 'Valores',
'Stocks' => '',
'Street' => 'calle',
'Today' => 'Hoy dia',
'Type' => 'Escribe',
'Types' => '',
'Week' => 'Semana',
'Year' => 'Año',
'Zip' => 'Cremallera',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Kaikki',
'Amount' => 'Määrä',
'Arrivals' => 'Saapuvat',
'Article' => 'Artikla',
'Articles' => 'Artikkelit',
'City' => 'Kaupunki',
'Consignee' => 'Vastaanottaja',
'Consignor' => 'Lähettäjä',
'Country' => 'Maa',
'Date' => 'Päivämäärä',
'Description' => 'Kuvaus',
'Interval' => 'Aikaväli',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Sijainti',
'Locations' => '',
'Matchcode' => 'Matchcode',
'Month' => 'Kuukausi',
'Name' => 'Nimi',
'Order' => 'Tilaus',
'Quantity' => 'Määrä',
'Reference' => 'Viite',
'Shipping' => 'laivaus',
'Statistics' => 'Tilastot',
'Stock' => 'Varasto',
'Stocks' => '',
'Street' => 'Katu',
'Today' => 'Tänään',
'Type' => 'Tyyppi',
'Types' => '',
'Week' => 'Viikko',
'Year' => 'Vuosi',
'Zip' => 'Postinumero',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Tout',
'Amount' => 'Quantité',
'Arrivals' => 'Arrivées',
'Article' => 'Article',
'Articles' => 'Des articles',
'City' => 'Ville',
'Consignee' => 'Destinataire',
'Consignor' => 'Expéditeur',
'Country' => 'Pays',
'Date' => 'Date',
'Description' => 'La description',
'Interval' => 'Intervalle',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Emplacement',
'Locations' => '',
'Matchcode' => 'Encadrement',
'Month' => 'Mois',
'Name' => 'Nom',
'Order' => 'Commander',
'Quantity' => 'Quantité',
'Reference' => 'Référence',
'Shipping' => 'Expédition',
'Statistics' => 'Statistiques',
'Stock' => 'Stocker',
'Stocks' => '',
'Street' => 'rue',
'Today' => 'Aujourd\'hui',
'Type' => 'Taper',
'Types' => '',
'Week' => 'La semaine',
'Year' => 'An',
'Zip' => 'Zipper',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Minden',
'Amount' => 'Összeg',
'Arrivals' => 'Érkezés',
'Article' => 'Cikk',
'Articles' => 'Árucikkek',
'City' => 'Város',
'Consignee' => 'Címzett',
'Consignor' => 'Feladó',
'Country' => 'Ország',
'Date' => 'Dátum',
'Description' => 'Leírás',
'Interval' => 'Intervallum',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Elhelyezkedés',
'Locations' => '',
'Matchcode' => 'Matchcode',
'Month' => 'Hónap',
'Name' => 'Név',
'Order' => 'Rendelés',
'Quantity' => 'Mennyiség',
'Reference' => 'Referencia',
'Shipping' => 'Szállítás',
'Statistics' => 'Statisztika',
'Stock' => 'Készlet',
'Stocks' => '',
'Street' => 'utca',
'Today' => 'Ma',
'Type' => 'típus',
'Types' => '',
'Week' => 'Hét',
'Year' => 'Év',
'Zip' => 'Postai irányítószám',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Tutto',
'Amount' => 'Quantità',
'Arrivals' => 'Arrivi',
'Article' => 'Articolo',
'Articles' => 'Artificio',
'City' => 'Città',
'Consignee' => 'Destinatario',
'Consignor' => 'Mittente',
'Country' => 'Nazione',
'Date' => 'Data',
'Description' => 'Descrizione',
'Interval' => 'Intervallo',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Posizione',
'Locations' => '',
'Matchcode' => 'Matchcode.',
'Month' => 'Mese',
'Name' => 'Nome',
'Order' => 'Ordine',
'Quantity' => 'Quantità',
'Reference' => 'Riferimento',
'Shipping' => 'Spedizione',
'Statistics' => 'Statistiche',
'Stock' => 'Azione',
'Stocks' => '',
'Street' => 'strada',
'Today' => 'Oggi',
'Type' => 'Tipo',
'Types' => '',
'Week' => 'Settimana',
'Year' => 'Anno',
'Zip' => 'Cerniera lampo',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => '全て',
'Amount' => '額',
'Arrivals' => '到着',
'Article' => '記事',
'Articles' => 'articles',
'City' => '市',
'Consignee' => '荷送人',
'Consignor' => '荷送人',
'Country' => '国',
'Date' => '日にち',
'Description' => '説明',
'Interval' => '間隔',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => '位置',
'Locations' => '',
'Matchcode' => 'マッチコード',
'Month' => '月',
'Name' => '名前',
'Order' => '注文',
'Quantity' => '量',
'Reference' => 'リファレンス',
'Shipping' => '運送',
'Statistics' => '統計学',
'Stock' => 'ストック',
'Stocks' => '',
'Street' => '街',
'Today' => '今日',
'Type' => 'タイプ',
'Types' => '',
'Week' => '週',
'Year' => '年',
'Zip' => 'ジップ',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => '모두',
'Amount' => '양',
'Arrivals' => '도착',
'Article' => '기사',
'Articles' => '조항',
'City' => '도시',
'Consignee' => '수취인',
'Consignor' => '위탁자',
'Country' => '국가',
'Date' => '날짜',
'Description' => '설명',
'Interval' => '간격',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => '위치',
'Locations' => '',
'Matchcode' => '매치 코드',
'Month' => '월',
'Name' => '이름',
'Order' => '주문하다',
'Quantity' => '수량',
'Reference' => '참조',
'Shipping' => '배송',
'Statistics' => '통계',
'Stock' => '재고',
'Stocks' => '',
'Street' => '거리',
'Today' => '오늘',
'Type' => '유형',
'Types' => '',
'Week' => '주',
'Year' => '년도',
'Zip' => '지퍼',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Alle',
'Amount' => 'Beløp',
'Arrivals' => 'Ankomster.',
'Article' => 'Artikkel',
'Articles' => 'Artikler',
'City' => 'By',
'Consignee' => 'Mottaker',
'Consignor' => 'Avsender',
'Country' => 'Land',
'Date' => 'Dato',
'Description' => 'Beskrivelse',
'Interval' => 'Intervall',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'plassering',
'Locations' => '',
'Matchcode' => 'MatchCode.',
'Month' => 'Måned',
'Name' => 'Navn',
'Order' => 'Rekkefølge',
'Quantity' => 'Mengde',
'Reference' => 'Referanse',
'Shipping' => 'Shipping',
'Statistics' => 'Statistikk',
'Stock' => 'Lager',
'Stocks' => '',
'Street' => 'gate',
'Today' => 'I dag',
'Type' => 'Type',
'Types' => '',
'Week' => 'Uke',
'Year' => 'År',
'Zip' => 'Glidelås',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Wszystkie',
'Amount' => 'Kwota',
'Arrivals' => 'Przyloty',
'Article' => 'Artykuł',
'Articles' => 'Artykuły',
'City' => 'Miasto',
'Consignee' => 'Konsygnatariusz',
'Consignor' => 'Wysyłający',
'Country' => 'Kraj',
'Date' => 'Data',
'Description' => 'Opis',
'Interval' => 'Interwał',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Lokalizacja',
'Locations' => '',
'Matchcode' => 'MatchCode.',
'Month' => 'Miesiąc',
'Name' => 'Nazwa',
'Order' => 'Zamówienie',
'Quantity' => 'Ilość',
'Reference' => 'Odniesienie',
'Shipping' => 'Wysyłka',
'Statistics' => 'Statystyka',
'Stock' => 'Magazyn',
'Stocks' => '',
'Street' => 'Ulica',
'Today' => 'Dziś',
'Type' => 'Rodzaj',
'Types' => '',
'Week' => 'Tydzień',
'Year' => 'Rok',
'Zip' => 'Zamek błyskawiczny',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Tudo',
'Amount' => 'Montante',
'Arrivals' => 'Chegadas',
'Article' => 'Artigo',
'Articles' => 'Artigos',
'City' => 'Cidade',
'Consignee' => 'Consignatário',
'Consignor' => 'Expedidor',
'Country' => 'País',
'Date' => 'Encontro',
'Description' => 'Descrição',
'Interval' => 'Intervalo',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Localização',
'Locations' => '',
'Matchcode' => 'Código de combinação',
'Month' => 'Mês',
'Name' => 'Nome',
'Order' => 'Pedido',
'Quantity' => 'Quantidade',
'Reference' => 'Referência',
'Shipping' => 'Envio',
'Statistics' => 'Estatisticas',
'Stock' => 'Estoque',
'Stocks' => '',
'Street' => 'rua',
'Today' => 'Hoje',
'Type' => 'Modelo',
'Types' => '',
'Week' => 'Semana',
'Year' => 'Ano',
'Zip' => 'Fecho eclair',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Все',
'Amount' => 'Количество',
'Arrivals' => 'Прибытие',
'Article' => 'Статья',
'Articles' => 'Статьи',
'City' => 'Город',
'Consignee' => 'Грузополучатель',
'Consignor' => 'Грузоподъемность',
'Country' => 'Страна',
'Date' => 'Дата',
'Description' => 'Описание',
'Interval' => 'Интервал',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Место расположения',
'Locations' => '',
'Matchcode' => 'MatchCode.',
'Month' => 'Месяц',
'Name' => 'Имя',
'Order' => 'Заказ',
'Quantity' => 'Количество',
'Reference' => 'Ссылка',
'Shipping' => 'Перевозки',
'Statistics' => 'Статистика',
'Stock' => 'Склад',
'Stocks' => '',
'Street' => 'улица',
'Today' => 'Сегодня',
'Type' => 'Тип',
'Types' => '',
'Week' => 'Неделю',
'Year' => 'Год',
'Zip' => 'Zip.',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Allt',
'Amount' => 'Belopp',
'Arrivals' => 'ankomster',
'Article' => 'Artikel',
'Articles' => 'Artiklar',
'City' => 'Stad',
'Consignee' => 'Mottagare',
'Consignor' => 'Avsändare',
'Country' => 'Land',
'Date' => 'Datum',
'Description' => 'Beskrivning',
'Interval' => 'Intervall',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Plats',
'Locations' => '',
'Matchcode' => 'Matchcode',
'Month' => 'Månad',
'Name' => 'namn',
'Order' => 'Beställa',
'Quantity' => 'Kvantitet',
'Reference' => 'Referens',
'Shipping' => 'Frakt',
'Statistics' => 'Statistik',
'Stock' => 'Stock',
'Stocks' => '',
'Street' => 'Gata',
'Today' => 'I dag',
'Type' => 'Typ',
'Types' => '',
'Week' => 'Vecka',
'Year' => 'År',
'Zip' => 'Blixtlås',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'ทั้งหมด',
'Amount' => 'จำนวน',
'Arrivals' => 'ขาเข้า',
'Article' => 'บทความ',
'Articles' => 'บทความ',
'City' => 'เมือง',
'Consignee' => 'ผู้รับ',
'Consignor' => 'ผู้ตราส่ง',
'Country' => 'ประเทศ',
'Date' => 'วันที่',
'Description' => 'คำอธิบาย',
'Interval' => 'ช่วงเวลา',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'ที่ตั้ง',
'Locations' => '',
'Matchcode' => 'การจับคู่',
'Month' => 'เดือน',
'Name' => 'ชื่อ',
'Order' => 'คำสั่ง',
'Quantity' => 'ปริมาณ',
'Reference' => 'อ้างอิง',
'Shipping' => 'การส่งสินค้า',
'Statistics' => 'สถิติ',
'Stock' => 'คลังสินค้า',
'Stocks' => '',
'Street' => 'ถนน',
'Today' => 'วันนี้',
'Type' => 'พิมพ์',
'Types' => '',
'Week' => 'สัปดาห์',
'Year' => 'ปี',
'Zip' => 'ซิป',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Herşey',
'Amount' => 'Miktar',
'Arrivals' => 'Geliş',
'Article' => 'Madde',
'Articles' => 'Nesne',
'City' => 'Şehir',
'Consignee' => 'Alıcı',
'Consignor' => 'Gönderici',
'Country' => 'Ülke',
'Date' => 'Tarih',
'Description' => 'Açıklama',
'Interval' => 'Aralık',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Konum',
'Locations' => '',
'Matchcode' => 'Maç Kodu',
'Month' => 'Ay',
'Name' => 'İsim',
'Order' => 'Emir',
'Quantity' => 'Miktar',
'Reference' => 'Referans',
'Shipping' => 'Nakliye',
'Statistics' => 'İstatistik',
'Stock' => 'Stoklamak',
'Stocks' => '',
'Street' => 'sokak',
'Today' => 'Bugün',
'Type' => 'Tip',
'Types' => '',
'Week' => 'Hafta',
'Year' => 'Yıl',
'Zip' => 'Zip',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => 'Все',
'Amount' => 'Сума',
'Arrivals' => 'Прибуття',
'Article' => 'Стаття',
'Articles' => 'Статті',
'City' => 'Місто',
'Consignee' => 'Вантажоодержувач',
'Consignor' => 'Вантажовідправність',
'Country' => 'Країна',
'Date' => 'Дата',
'Description' => 'Опис',
'Interval' => 'Інтервал',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => 'Місцезнаходження',
'Locations' => '',
'Matchcode' => 'Матч',
'Month' => 'Місяць',
'Name' => 'Назва',
'Order' => 'Порядок',
'Quantity' => 'Кількість',
'Reference' => 'Довідник',
'Shipping' => 'Доставка',
'Statistics' => 'Статистика',
'Stock' => 'Запас',
'Stocks' => '',
'Street' => 'Вулиця',
'Today' => 'Сьогодні',
'Type' => 'Тип',
'Types' => '',
'Week' => 'Тиждень',
'Year' => 'Рік',
'Zip' => 'Блиск',
]];

View File

@ -13,38 +13,12 @@
declare(strict_types=1);
return ['WarehouseManagement' => [
'All' => '全部',
'Amount' => '数量',
'Arrivals' => '到达',
'Article' => '文章',
'Articles' => '文章',
'City' => '城市',
'Consignee' => '收货人',
'Consignor' => '托运人',
'Country' => '国家',
'Date' => '日期',
'Description' => '描述',
'Interval' => '间隔',
'Language' => '',
'Localization' => '',
'Localizations' => '',
'Location' => '地点',
'Locations' => '',
'Matchcode' => '匹配码',
'Month' => '月',
'Name' => '名称',
'Order' => '命令',
'Quantity' => '数量',
'Reference' => '参考',
'Shipping' => '船运',
'Statistics' => '统计数据',
'Stock' => '库存',
'Stocks' => '',
'Street' => '街道',
'Today' => '今天',
'Type' => '类型',
'Types' => '',
'Week' => '星期',
'Year' => '年',
'Zip' => '压缩',
]];

View File

@ -21,7 +21,7 @@ echo $this->data['nav']->render(); ?>
<div class="row">
<div class="col-xs-12">
<div class="portlet">
<div class="portlet-head"><?= $this->getHtml('Stocks'); ?><i class="lni lni-download download btn end-xs"></i></div>
<div class="portlet-head"><?= $this->getHtml('Stocks'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table id="stockList" class="default sticky">
<thead>

View File

@ -21,7 +21,7 @@ echo $this->data['nav']->render(); ?>
<div class="row">
<div class="col-xs-12">
<div class="portlet">
<div class="portlet-head"><?= $this->getHtml('Locations'); ?><i class="lni lni-download download btn end-xs"></i></div>
<div class="portlet-head"><?= $this->getHtml('Locations'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table id="stockList" class="default sticky">
<thead>

View File

@ -21,7 +21,7 @@ echo $this->data['nav']->render(); ?>
<div class="row">
<div class="col-xs-12">
<div class="portlet">
<div class="portlet-head"><?= $this->getHtml('Stocks'); ?><i class="lni lni-download download btn end-xs"></i></div>
<div class="portlet-head"><?= $this->getHtml('Stocks'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table id="stockList" class="default sticky">
<thead>

View File

@ -31,7 +31,7 @@ echo $this->data['nav']->render();
<div class="col-xs-12 col-md-6">
<section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Localizations'); ?><i class="lni lni-download download btn end-xs"></i></div>
<div class="portlet-head"><?= $this->getHtml('Localizations'); ?><i class="g-icon download btn end-xs">download</i></div>
<div class="slider">
<table id="localizationTable" class="default sticky fixed-5"
data-tag="form"
@ -42,16 +42,16 @@ echo $this->data['nav']->render();
<tr>
<td>
<td><?= $this->getHtml('ID', '0', '0'); ?>
<td><?= $this->getHtml('Name'); ?><i class="sort-asc fa fa-chevron-up"></i><i class="sort-desc fa fa-chevron-down"></i>
<td><?= $this->getHtml('Language'); ?><i class="sort-asc fa fa-chevron-up"></i><i class="sort-desc fa fa-chevron-down"></i>
<td class="wf-100"><?= $this->getHtml('Localization'); ?><i class="sort-asc fa fa-chevron-up"></i><i class="sort-desc fa fa-chevron-down"></i>
<td><?= $this->getHtml('Name'); ?><i class="sort-asc g-icon">expand_less</i><i class="sort-desc g-icon">expand_more</i>
<td><?= $this->getHtml('Language'); ?><i class="sort-asc g-icon">expand_less</i><i class="sort-desc g-icon">expand_more</i>
<td class="wf-100"><?= $this->getHtml('Localization'); ?><i class="sort-asc g-icon">expand_less</i><i class="sort-desc g-icon">expand_more</i>
<tbody>
<template class="oms-add-tpl-attribute">
<tr data-id="" draggable="false">
<td>
<i class="fa fa-cogs btn update-form"></i>
<input id="attributeTable-remove-0" type="checkbox" class="hidden">
<label for="attributeTable-remove-0" class="checked-visibility-alt"><i class="fa fa-times btn form-action"></i></label>
<i class="g-icon btn update-form">settings</i>
<input id="attributeTable-remove-0" type="checkbox" class="vh">
<label for="attributeTable-remove-0" class="checked-visibility-alt"><i class="g-icon btn form-action">close</i></label>
<span class="checked-visibility">
<label for="attributeTable-remove-0" class="link default"><?= $this->getHtml('Cancel', '0', '0'); ?></label>
<label for="attributeTable-remove-0" class="remove-form link cancel"><?= $this->getHtml('Delete', '0', '0'); ?></label>
@ -68,10 +68,10 @@ echo $this->data['nav']->render();
foreach ($itemL11n as $value) : ++$c; ?>
<tr data-id="<?= $value->id; ?>">
<td>
<i class="fa fa-cogs btn update-form"></i>
<i class="g-icon btn update-form">settings</i>
<?php if (!$value->type->isRequired) : ?>
<input id="localizationTable-remove-<?= $value->id; ?>" type="checkbox" class="hidden">
<label for="localizationTable-remove-<?= $value->id; ?>" class="checked-visibility-alt"><i class="fa fa-times btn form-action"></i></label>
<input id="localizationTable-remove-<?= $value->id; ?>" type="checkbox" class="vh">
<label for="localizationTable-remove-<?= $value->id; ?>" class="checked-visibility-alt"><i class="g-icon btn form-action">close</i></label>
<span class="checked-visibility">
<label for="localizationTable-remove-<?= $value->id; ?>" class="link default"><?= $this->getHtml('Cancel', '0', '0'); ?></label>
<label for="localizationTable-remove-<?= $value->id; ?>" class="remove-form link cancel"><?= $this->getHtml('Delete', '0', '0'); ?></label>
@ -79,7 +79,7 @@ echo $this->data['nav']->render();
<?php endif; ?>
<td data-tpl-text="/id" data-tpl-value="/id"><?= $value->id; ?>
<td data-tpl-text="/type" data-tpl-value="/type" data-value="<?= $value->type->id; ?>"><?= $this->printHtml($value->type->title); ?>
<td data-tpl-text="/language" data-tpl-value="/language"><?= $this->printHtml($value->getLanguage()); ?>
<td data-tpl-text="/language" data-tpl-value="/language"><?= $this->printHtml($value->language); ?>
<td data-tpl-text="/l11n" data-tpl-value="/l11n" data-value="<?= \nl2br($this->printHtml($value->content)); ?>"><?= \nl2br($this->printHtml(\substr($value->content, 0, 100))); ?>
<?php endforeach; ?>
<?php if ($c === 0) : ?>

View File

@ -75,8 +75,8 @@ final class Autoloader
*/
public static function defaultAutoloader(string $class) : void
{
$class = \ltrim($class, '\\');
$class = \strtr($class, '_\\', '//');
$class = \ltrim($class, '\\');
$class = \strtr($class, '_\\', '//');
if (\stripos($class, 'Web/Backend') !== false || \stripos($class, 'Web/Api') !== false) {
$class = \is_dir(__DIR__ . '/Web') ? $class : \str_replace('Web/', 'MainRepository/Web/', $class);

View File

@ -1,4 +1,15 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package Modules\WarehouseManagement\tests
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
\ini_set('memory_limit', '2048M');
@ -67,10 +78,10 @@ $GLOBALS['is_github'] = $IS_GITHUB;
$tmp = FileLogger::getInstance(__DIR__ . '/../Logs');
$CONFIG = [
'db' => [
'db' => [
'core' => [
'masters' => [
'admin' => [
'admin' => [
'db' => 'mysql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '3306', /* db host port */
@ -80,7 +91,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'insert' => [
'insert' => [
'db' => 'mysql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '3306', /* db host port */
@ -90,7 +101,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'select' => [
'select' => [
'db' => 'mysql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '3306', /* db host port */
@ -100,7 +111,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'update' => [
'update' => [
'db' => 'mysql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '3306', /* db host port */
@ -110,7 +121,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'delete' => [
'delete' => [
'db' => 'mysql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '3306', /* db host port */
@ -120,7 +131,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'schema' => [
'schema' => [
'db' => 'mysql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '3306', /* db host port */
@ -132,7 +143,7 @@ $CONFIG = [
],
],
'postgresql' => [
'admin' => [
'admin' => [
'db' => 'pgsql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '5432', /* db host port */
@ -142,7 +153,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'insert' => [
'insert' => [
'db' => 'pgsql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '5432', /* db host port */
@ -152,7 +163,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'select' => [
'select' => [
'db' => 'pgsql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '5432', /* db host port */
@ -162,7 +173,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'update' => [
'update' => [
'db' => 'pgsql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '5432', /* db host port */
@ -172,7 +183,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'delete' => [
'delete' => [
'db' => 'pgsql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '5432', /* db host port */
@ -182,7 +193,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'schema' => [
'schema' => [
'db' => 'pgsql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '5432', /* db host port */
@ -194,37 +205,37 @@ $CONFIG = [
],
],
'sqlite' => [
'admin' => [
'admin' => [
'db' => 'sqlite', /* db type */
'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'insert' => [
'insert' => [
'db' => 'sqlite', /* db type */
'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'select' => [
'select' => [
'db' => 'sqlite', /* db type */
'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'update' => [
'update' => [
'db' => 'sqlite', /* db type */
'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'delete' => [
'delete' => [
'db' => 'sqlite', /* db type */
'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'schema' => [
'schema' => [
'db' => 'sqlite', /* db type */
'database' => __DIR__ . '/../Karaka/phpOMS/Localization/Defaults/localization.sqlite', /* db name */
'weight' => 1000, /* db table prefix */
@ -232,7 +243,7 @@ $CONFIG = [
],
],
'mssql' => [
'admin' => [
'admin' => [
'db' => 'mssql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '1433', /* db host port */
@ -242,7 +253,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'insert' => [
'insert' => [
'db' => 'mssql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '1433', /* db host port */
@ -252,7 +263,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'select' => [
'select' => [
'db' => 'mssql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '1433', /* db host port */
@ -262,7 +273,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'update' => [
'update' => [
'db' => 'mssql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '1433', /* db host port */
@ -272,7 +283,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'delete' => [
'delete' => [
'db' => 'mssql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '1433', /* db host port */
@ -282,7 +293,7 @@ $CONFIG = [
'weight' => 1000, /* db table prefix */
'datetimeformat' => 'Y-m-d H:i:s',
],
'schema' => [
'schema' => [
'db' => 'mssql', /* db type */
'host' => '127.0.0.1', /* db host address */
'port' => '1433', /* db host port */
@ -322,16 +333,16 @@ $CONFIG = [
'password' => '123456',
],
],
'log' => [
'log' => [
'file' => [
'path' => __DIR__ . '/Logs',
],
],
'page' => [
'page' => [
'root' => '/',
'https' => false,
],
'app' => [
'app' => [
'path' => __DIR__,
'default' => [
'app' => 'Backend',
@ -350,7 +361,7 @@ $CONFIG = [
],
],
],
'socket' => [
'socket' => [
'master' => [
'host' => '127.0.0.1',
'limit' => 300,
@ -360,7 +371,7 @@ $CONFIG = [
'language' => [
'en',
],
'apis' => [
'apis' => [
],
];

View File

@ -0,0 +1,52 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\tests\Models;
use Modules\WarehouseManagement\Models\NullStockLocation;
/**
* @internal
*/
final class NullStockLocationTest extends \PHPUnit\Framework\TestCase
{
/**
* @covers Modules\WarehouseManagement\Models\NullStockLocation
* @group module
*/
public function testNull() : void
{
self::assertInstanceOf('\Modules\WarehouseManagement\Models\StockLocation', new NullStockLocation());
}
/**
* @covers Modules\WarehouseManagement\Models\NullStockLocation
* @group module
*/
public function testId() : void
{
$null = new NullStockLocation(2);
self::assertEquals(2, $null->id);
}
/**
* @covers Modules\WarehouseManagement\Models\NullStockLocation
* @group module
*/
public function testJsonSerialize() : void
{
$null = new NullStockLocation(2);
self::assertEquals(['id' => 2], $null->jsonSerialize());
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\tests\Models;
use Modules\WarehouseManagement\Models\NullStockShelf;
/**
* @internal
*/
final class NullStockShelfTest extends \PHPUnit\Framework\TestCase
{
/**
* @covers Modules\WarehouseManagement\Models\NullStockShelf
* @group module
*/
public function testNull() : void
{
self::assertInstanceOf('\Modules\WarehouseManagement\Models\StockShelf', new NullStockShelf());
}
/**
* @covers Modules\WarehouseManagement\Models\NullStockShelf
* @group module
*/
public function testId() : void
{
$null = new NullStockShelf(2);
self::assertEquals(2, $null->id);
}
/**
* @covers Modules\WarehouseManagement\Models\NullStockShelf
* @group module
*/
public function testJsonSerialize() : void
{
$null = new NullStockShelf(2);
self::assertEquals(['id' => 2], $null->jsonSerialize());
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Jingga
*
* PHP Version 8.1
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace Modules\WarehouseManagement\tests\Models;
use Modules\WarehouseManagement\Models\NullStock;
/**
* @internal
*/
final class NullStockTest extends \PHPUnit\Framework\TestCase
{
/**
* @covers Modules\WarehouseManagement\Models\NullStock
* @group module
*/
public function testNull() : void
{
self::assertInstanceOf('\Modules\WarehouseManagement\Models\Stock', new NullStock());
}
/**
* @covers Modules\WarehouseManagement\Models\NullStock
* @group module
*/
public function testId() : void
{
$null = new NullStock(2);
self::assertEquals(2, $null->id);
}
/**
* @covers Modules\WarehouseManagement\Models\NullStock
* @group module
*/
public function testJsonSerialize() : void
{
$null = new NullStock(2);
self::assertEquals(['id' => 2], $null->jsonSerialize());
}
}

View File

@ -14,25 +14,25 @@ declare(strict_types=1);
namespace Modules\WarehouseManagement\tests\Models;
use Modules\WarehouseManagement\Models\StockMovement;
use Modules\WarehouseManagement\Models\StockTransaction;
/**
* @internal
*/
final class StockMovementTest extends \PHPUnit\Framework\TestCase
final class StockTransactionTest extends \PHPUnit\Framework\TestCase
{
private StockMovement $movement;
private StockTransaction $movement;
/**
* {@inheritdoc}
*/
protected function setUp() : void
{
$this->movement = new StockMovement();
$this->movement = new StockTransaction();
}
/**
* @covers Modules\WarehouseManagement\Models\StockMovement
* @covers Modules\WarehouseManagement\Models\StockTransaction
* @group module
*/
public function testDefault() : void