mirror of
https://github.com/Karaka-Management/oms-WarehouseManagement.git
synced 2026-02-18 15:08:41 +00:00
auto fixes + some impl.
This commit is contained in:
parent
17fb0226d4
commit
cd18f753ca
43
Admin/Install/ClientManagement.php
Normal file
43
Admin/Install/ClientManagement.php
Normal 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');
|
||||
}
|
||||
}
|
||||
43
Admin/Install/SupplierManagement.php
Normal file
43
Admin/Install/SupplierManagement.php
Normal 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');
|
||||
}
|
||||
}
|
||||
|
|
@ -14,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",
|
||||
|
|
@ -21,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",
|
||||
|
|
@ -273,6 +292,11 @@
|
|||
"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",
|
||||
|
|
@ -635,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_stock": {
|
||||
"name": "warehousemgmt_stock_transaction_from_stock",
|
||||
"type": "INT",
|
||||
"null": false,
|
||||
"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_stock": {
|
||||
"name": "warehousemgmt_stock_transaction_to_stock",
|
||||
"type": "INT",
|
||||
"null": false,
|
||||
"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"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -81,32 +76,13 @@ final class Installer extends InstallerAbstract
|
|||
$module = $app->moduleManager->getModuleInstance('WarehouseManagement', 'Api');
|
||||
|
||||
$response = new HttpResponse();
|
||||
$request = new HttpRequest(new HttpUri(''));
|
||||
$request = new HttpRequest();
|
||||
|
||||
$request->header->account = 1;
|
||||
$request->setData('name', 'Default');
|
||||
$request->setData('unit', 1);
|
||||
$request->setData('inventory', true);
|
||||
$module->apiStockCreate($request, $response);
|
||||
|
||||
$responseData = $response->getData('');
|
||||
if (!\is_array($responseData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$id = $responseData['response']->id;
|
||||
|
||||
$response = new HttpResponse();
|
||||
$request = new HttpRequest(new HttpUri(''));
|
||||
|
||||
$request->header->account = 1;
|
||||
$request->setData('name', $id . '-1');
|
||||
$request->setData('stock', $id);
|
||||
$module->apiStockLocationCreate($request, $response);
|
||||
|
||||
$responseData = $response->getData('');
|
||||
if (!\is_array($responseData)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -131,7 +107,7 @@ final class Installer extends InstallerAbstract
|
|||
|
||||
foreach ($types as $type) {
|
||||
$response = new HttpResponse();
|
||||
$request = new HttpRequest(new HttpUri(''));
|
||||
$request = new HttpRequest();
|
||||
|
||||
$request->header->account = 1;
|
||||
$request->setData('name', $type['name'] ?? '');
|
||||
|
|
@ -159,7 +135,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);
|
||||
|
|
@ -172,4 +148,34 @@ 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->getModuleInstance('WarehouseManagement', 'Api');
|
||||
|
||||
$mapper = $type === 'client'
|
||||
? \Modules\ClientManagement\Models\ClientMapper::class
|
||||
: \Modules\SupplierManagement\Models\SupplierMapper::class;
|
||||
|
||||
foreach ($mapper::yield()->execute() 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -158,9 +159,7 @@ final class ApiAttributeController extends Controller
|
|||
{
|
||||
$attrL11n = new BaseStringL11n();
|
||||
$attrL11n->ref = $request->getDataInt('type') ?? 0;
|
||||
$attrL11n->setLanguage(
|
||||
$request->getDataString('language') ?? $request->header->l11n->language
|
||||
);
|
||||
$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;
|
||||
|
|
@ -382,9 +387,7 @@ final class ApiAttributeController extends Controller
|
|||
{
|
||||
$attrL11n = new BaseStringL11n();
|
||||
$attrL11n->ref = $request->getDataInt('value') ?? 0;
|
||||
$attrL11n->setLanguage(
|
||||
$request->getDataString('language') ?? $request->header->l11n->language
|
||||
);
|
||||
$attrL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language;
|
||||
$attrL11n->content = $request->getDataString('title') ?? '';
|
||||
|
||||
return $attrL11n;
|
||||
|
|
|
|||
|
|
@ -18,19 +18,21 @@ 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\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 Modules\WarehouseManagement\Models\StockShelf;
|
||||
use Modules\WarehouseManagement\Models\StockShelfMapper;
|
||||
use phpOMS\Message\Http\RequestStatusCode;
|
||||
use phpOMS\Message\RequestAbstract;
|
||||
use phpOMS\Message\ResponseAbstract;
|
||||
|
|
@ -69,6 +71,13 @@ final class ApiController extends Controller
|
|||
|
||||
$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);
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +115,10 @@ final class ApiController extends Controller
|
|||
$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($request->getDataInt('client')) : null;
|
||||
$stock->supplier = $request->hasData('supplier') ? new NullSupplier($request->getDataInt('supplier')) : null;
|
||||
|
||||
return $stock;
|
||||
}
|
||||
|
|
@ -197,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 */
|
||||
|
|
@ -234,17 +247,20 @@ 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.
|
||||
|
|
@ -255,18 +271,34 @@ final class ApiController extends Controller
|
|||
$bill = BillMapper::get()
|
||||
->with('type')
|
||||
->with('elements')
|
||||
->with('elements/container')
|
||||
->with('elements/item')
|
||||
->with('supplier')
|
||||
->with('client')
|
||||
->where('id', $isBillElement ? $new->bill->id : $new->id)
|
||||
->where('type/transferStock', true)
|
||||
->execute();
|
||||
|
||||
// Has stock movement?
|
||||
if (!$bill->type->transferStock) {
|
||||
if ($bill->id === 0 || !$bill->type->transferStock) {
|
||||
return;
|
||||
}
|
||||
|
||||
$billElements = $isBillElement ? [$new] : $bill->elements;
|
||||
/*
|
||||
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();
|
||||
}
|
||||
*/
|
||||
|
||||
// @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
|
||||
|
|
@ -276,7 +308,7 @@ final class ApiController extends Controller
|
|||
// 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 ($billElements as $element) {
|
||||
foreach ($bill->elements as $element) {
|
||||
if ($element->item === 0 || $element->item === null
|
||||
|| $element->item->stockIdentifier === StockIdentifierType::NONE
|
||||
) {
|
||||
|
|
@ -288,15 +320,14 @@ final class ApiController extends Controller
|
|||
->where('stock', 1) // @todo fix
|
||||
->where('stockType', 1) // @todo fix
|
||||
->where('lot', $element->item->stockIdentifier === StockIdentifierType::NUMBER ? null : '')
|
||||
->limit(1)
|
||||
->execute();
|
||||
|
||||
$transaction = new StockTransaction();
|
||||
|
||||
// @todo how to handle only reserving items for drafted bills (not yet shipped)
|
||||
|
||||
if ($trigger === 'POST:Module:Billing-bill_element-create') {
|
||||
if ($trigger === 'Billing-bill_element-create') {
|
||||
// Check stock availability
|
||||
if ($bill->type->sign < 0 && $dist->quantity < $element->quantity) {
|
||||
if ($bill->type->sign > 0 && $dist->quantity < $element->quantity->getInt()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -306,15 +337,14 @@ final class ApiController extends Controller
|
|||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// @todo handle stock returns!!!
|
||||
if ($bill->type->sign < 0) {
|
||||
$dist->quantity -= $element->quantity;
|
||||
if ($bill->type->sign > 0) {
|
||||
$dist->quantity -= $element->quantity->getInt();
|
||||
|
||||
StockDistributionMapper::update()->execute($dist);
|
||||
} else {
|
||||
if ($dist->id === 0) {
|
||||
} elseif ($dist->id === 0) {
|
||||
$dist = new StockDistribution();
|
||||
$dist->item = $element->item->id;
|
||||
$dist->quantity = $element->quantity;
|
||||
$dist->quantity = $element->quantity->getInt();
|
||||
|
||||
$dist->lot = null; // @todo handle correct
|
||||
$dist->stock = 1; // @todo handle correct
|
||||
|
|
@ -322,15 +352,15 @@ final class ApiController extends Controller
|
|||
|
||||
StockDistributionMapper::create()->execute($dist);
|
||||
} else {
|
||||
$dist->quantity += $element->quantity;
|
||||
$dist->quantity += $element->quantity->getInt();
|
||||
|
||||
StockDistributionMapper::update()->execute($dist);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle transfer protocol
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
$transaction = new StockTransaction();
|
||||
$transaction->billElement = $new->id;
|
||||
$transaction->state = StockTransactionState::DRAFT;
|
||||
|
||||
|
|
@ -338,7 +368,8 @@ final class ApiController extends Controller
|
|||
// @todo find stock candidates
|
||||
|
||||
$transaction->type = StockTransactionType::TRANSFER; // @todo depends on bill type
|
||||
$transaction->quantity = $new->getQuantity(); // @todo may require split quantity if not sufficient available from one lost
|
||||
$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
|
||||
|
|
@ -347,8 +378,13 @@ final class ApiController extends Controller
|
|||
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 */
|
||||
|
|
@ -362,10 +398,13 @@ final class ApiController extends Controller
|
|||
if ($bill->type->transferType === BillTransferType::SALES) {
|
||||
$transaction->subtype = StockTransactionType::SALE;
|
||||
} elseif ($bill->type->transferType === BillTransferType::PURCHASE) {
|
||||
$transaction->subtype = StockTransactionType::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 */
|
||||
|
|
@ -378,16 +417,18 @@ final class ApiController extends Controller
|
|||
|
||||
// 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
|
||||
|| $bill->type->transferType === BillTransferType::PURCHASE
|
||||
) {
|
||||
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 === 'POST:Module:Billing-bill_element-update') {
|
||||
} elseif ($trigger === 'Billing-bill_element-update') {
|
||||
/** @var \Modules\Billing\Models\BillElement $new */
|
||||
/** @var \Modules\Billing\Models\BillElement $old */
|
||||
/** @var \Modules\WarehouseManagement\Models\StockTransaction[] $transactions */
|
||||
|
|
@ -406,15 +447,18 @@ final class ApiController extends Controller
|
|||
// and then do normal algorithm like for a new element
|
||||
}
|
||||
*/
|
||||
if ($new->item !== $old->item) {
|
||||
if ($new->item->id !== $old->item->id) {
|
||||
// @todo: also undo stock amount in stock distribution
|
||||
StockTransactionMapper::delete()->execute($transactions);
|
||||
|
||||
$this->eventBillUpdateInternal(
|
||||
$account, $old, $new,
|
||||
$type, 'POST:Module:Billing-bill_element-create', $module, $ref, $content, $ip
|
||||
$type, 'Billing-bill_element-create', $module, $ref, $content, $ip
|
||||
);
|
||||
}
|
||||
} elseif ($trigger === 'POST:Module:Billing-bill_element-delete') {
|
||||
|
||||
// @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()
|
||||
|
|
@ -422,17 +466,7 @@ final class ApiController extends Controller
|
|||
->execute();
|
||||
|
||||
StockTransactionMapper::delete()->execute($transactions);
|
||||
} 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();
|
||||
|
||||
} elseif ($trigger === 'Billing-bill-delete') {
|
||||
foreach ($bill->elements as $element) {
|
||||
/** @var \Modules\WarehouseManagement\Models\StockTransaction[] $transactions */
|
||||
$transactions = StockTransactionMapper::getAll()
|
||||
|
|
@ -442,7 +476,7 @@ final class ApiController extends Controller
|
|||
StockTransactionMapper::delete()->execute($transactions);
|
||||
// @todo consider not to delete but mark as deleted?
|
||||
}
|
||||
} elseif ($trigger === 'POST:Module:Billing-bill-update') {
|
||||
} elseif ($trigger === 'Billing-bill-update') {
|
||||
// is receiver update -> change all movements
|
||||
// is status update -> change all movements (delete = delete)
|
||||
|
||||
|
|
@ -450,18 +484,9 @@ final class ApiController extends Controller
|
|||
if ($new->status === BillStatus::DELETED) {
|
||||
$this->eventBillUpdateInternal(
|
||||
$account, $old, $new,
|
||||
$type, 'POST:Module:Billing-bill-delete', $module, $ref, $content, $ip
|
||||
$type, '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)
|
||||
->execute();
|
||||
|
||||
foreach ($bill->elements as $element) {
|
||||
/** @var \Modules\WarehouseManagement\Models\StockTransaction[] $transactions */
|
||||
$transactions = StockTransactionMapper::getAll()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -140,9 +143,7 @@ final class ApiStockTypeController extends Controller
|
|||
{
|
||||
$stockTypeL11n = new BaseStringL11n();
|
||||
$stockTypeL11n->ref = $request->getDataInt('type') ?? 0;
|
||||
$stockTypeL11n->setLanguage(
|
||||
$request->getDataString('language') ?? $request->header->l11n->language
|
||||
);
|
||||
$stockTypeL11n->language = ISO639x1Enum::tryFromValue($request->getDataString('language')) ?? $request->header->l11n->language;
|
||||
$stockTypeL11n->content = $request->getDataString('title') ?? '';
|
||||
|
||||
return $stockTypeL11n;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace Modules\WarehouseManagement\Models;
|
||||
|
||||
use Modules\ClientManagement\Models\Client;
|
||||
use Modules\SupplierManagement\Models\Supplier;
|
||||
use phpOMS\Stdlib\Base\Address;
|
||||
|
||||
/**
|
||||
|
|
@ -44,8 +46,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 +65,4 @@ class Stock
|
|||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getId() : int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class StockDistribution
|
|||
|
||||
public int $quantity = 0;
|
||||
|
||||
public int $lot = 0;
|
||||
public ?int $lot = null;
|
||||
|
||||
public int $item = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,16 +55,4 @@ class StockLocation
|
|||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getId() : int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ declare(strict_types=1);
|
|||
namespace Modules\WarehouseManagement\Models;
|
||||
|
||||
use Modules\Admin\Models\AddressMapper;
|
||||
use Modules\ClientManagement\Models\ClientMapper;
|
||||
use Modules\SupplierManagement\Models\SupplierMapper;
|
||||
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
|
||||
|
||||
/**
|
||||
|
|
@ -40,6 +42,9 @@ final class StockMapper extends DataMapperFactory
|
|||
'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 +61,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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -55,16 +55,4 @@ class StockShelf
|
|||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getId() : int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,13 +55,17 @@ class StockTransaction
|
|||
|
||||
public int $item = 0;
|
||||
|
||||
public int $fromLot = 0;
|
||||
public int $fromStock = 0;
|
||||
public int $fromStockType = 0;
|
||||
public ?int $fromLot = null;
|
||||
|
||||
public int $toLot = 0;
|
||||
public int $toStock = 0;
|
||||
public int $toStockType = 0;
|
||||
public ?int $fromStock = null;
|
||||
|
||||
public ?int $fromStockType = null;
|
||||
|
||||
public ?int $toLot = null;
|
||||
|
||||
public ?int $toStock = null;
|
||||
|
||||
public ?int $toStockType = null;
|
||||
|
||||
/**
|
||||
* Creator.
|
||||
|
|
@ -89,16 +93,4 @@ class StockTransaction
|
|||
$this->createdBy = new NullAccount();
|
||||
$this->createdAt = new \DateTimeImmutable('now');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ID.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,12 +66,12 @@ class StockType
|
|||
$this->l11n = $l11n;
|
||||
} elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) {
|
||||
$this->l11n->content = $l11n;
|
||||
$this->l11n->setLanguage($lang);
|
||||
$this->l11n->language = $lang;
|
||||
} else {
|
||||
$this->l11n = new BaseStringL11n();
|
||||
$this->l11n->content = $l11n;
|
||||
$this->l11n->ref = $this->id;
|
||||
$this->l11n->setLanguage($lang);
|
||||
$this->l11n->language = $lang;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) : ?>
|
||||
|
|
@ -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');
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user